- Timestamp:
- 2011-08-12T09:57:26+12:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java
r24361 r24393 23 23 import org.greenstone.gsdl3.service.*; 24 24 25 26 25 // java XML classes we're using 27 import org.w3c.dom.Document; 28 import org.w3c.dom.Node; 29 import org.w3c.dom.Element; 30 import org.w3c.dom.NodeList; 26 import org.w3c.dom.Document; 27 import org.w3c.dom.Node; 28 import org.w3c.dom.Element; 29 import org.w3c.dom.NodeList; 31 30 32 31 import java.io.*; … … 49 48 50 49 /** 51 * Represents a collection in Greenstone. A collection is an extension of 52 * aServiceCluster - it has local data that the services use.53 * 50 * Represents a collection in Greenstone. A collection is an extension of a 51 * ServiceCluster - it has local data that the services use. 52 * 54 53 * @author <a href="mailto:[email protected]">Katherine Don</a> 55 54 * @see ModuleInterface 56 55 */ 57 public class Collection 58 extends ServiceCluster { 59 60 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.Collection.class.getName()); 61 62 /** is this collection being tidied */ 63 protected boolean useBook = false; 64 /** is this collection public or private */ 65 protected boolean is_public = true; 66 67 /** does this collection provide the OAI service */ 68 protected boolean has_oai = true; 69 /** time when this collection was built */ 70 protected long lastmodified = 0; 71 /** earliestDatestamp of this collection. Necessary for OAI */ 72 protected long earliestDatestamp = 0; 73 74 75 /** An element containing the serviceRackList element of buildConfig.xml, used to determine whether it contains 76 * the OAIPMH serviceRack 77 */ 78 //protected Element service_rack_list = null; 79 80 protected XMLTransformer transformer = null; 81 /** same as setClusterName */ 82 public void setCollectionName(String name) { 83 setClusterName(name); 84 } 85 86 public Collection() { 87 super(); 88 this.description = this.doc.createElement(GSXML.COLLECTION_ELEM); 89 90 } 91 92 /** 93 * Configures the collection. 94 * 95 * gsdlHome and collectionName must be set before configure is called. 96 * 97 * the file buildcfg.xml is located in gsdlHome/collect/collectionName 98 * collection metadata is obtained, and services loaded. 99 * 100 * @return true/false on success/fail 101 */ 102 public boolean configure() { 103 104 if (this.site_home == null || this.cluster_name== null) { 105 logger.error("Collection: site_home and collection_name must be set before configure called!"); 106 return false; 107 } 108 109 Element coll_config_xml = loadCollConfigFile(); 110 Element build_config_xml = loadBuildConfigFile(); 111 112 if (coll_config_xml==null||build_config_xml==null) { 113 return false; 114 } 115 116 // get the collection type attribute 117 Element search = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SEARCH_ELEM); 118 if(search!=null) { 119 col_type = search.getAttribute(GSXML.TYPE_ATT); 120 } 121 122 // process the metadata and display items 123 findAndLoadInfo(coll_config_xml, build_config_xml); 124 125 // now do the services 126 configureServiceRacks(coll_config_xml, build_config_xml); 127 128 return true; 129 130 } 131 132 public boolean useBook() { 133 return useBook; 134 } 135 136 public boolean isPublic() { 137 return is_public; 138 } 139 // Not used anymore by the OAIReceptionist to find out the earliest datestamp 140 // amongst all oai collections in the repository. May be useful generally. 141 public long getLastmodified() { 142 return lastmodified; 143 } 144 //used by the OAIReceptionist to find out the earliest datestamp amongst all oai collections in the repository 145 public long getEarliestDatestamp() { 146 return earliestDatestamp; 147 } 148 149 /** whether the service_map in ServiceCluster.java contains the service 'OAIPMH' 150 * 11/06/2007 xiao 151 */ 152 public boolean hasOAI() { 153 return has_oai; 154 } 155 /** 156 * load in the collection config file into a DOM Element 157 */ 158 protected Element loadCollConfigFile() { 159 160 File coll_config_file = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)); 161 162 if (!coll_config_file.exists()) { 163 logger.error("Collection: couldn't configure collection: "+this.cluster_name+", "+coll_config_file+" does not exist"); 164 return null; 165 } 166 // get the xml for both files 167 Document coll_config_doc = this.converter.getDOM(coll_config_file, CONFIG_ENCODING); 168 Element coll_config_elem = null; 169 if (coll_config_doc != null) { 170 coll_config_elem = coll_config_doc.getDocumentElement(); 171 } 172 return coll_config_elem; 173 174 } 175 176 /** 177 * load in the collection build config file into a DOM Element 178 */ 179 protected Element loadBuildConfigFile() { 180 181 File build_config_file = new File(GSFile.collectionBuildConfigFile(this.site_home, this.cluster_name)); 182 if (!build_config_file.exists()) { 183 logger.error("Collection: couldn't configure collection: "+this.cluster_name+", "+build_config_file+" does not exist"); 184 return null; 185 } 186 Document build_config_doc = this.converter.getDOM(build_config_file, CONFIG_ENCODING); 187 Element build_config_elem = null; 188 if (build_config_doc != null) { 189 build_config_elem = build_config_doc.getDocumentElement(); 190 } 191 192 lastmodified = build_config_file.lastModified(); 193 194 return build_config_elem; 195 } 196 197 /** 198 * find the metadata and display elems from the two config files and add it to the appropriate lists 199 */ 200 protected boolean findAndLoadInfo(Element coll_config_xml, 201 Element build_config_xml){ 202 203 // metadata 204 Element meta_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER); 205 addMetadata(meta_list); 206 meta_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER); 207 addMetadata(meta_list); 208 209 meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 210 GSXML.addMetadata(this.doc, meta_list, "httpPath", this.site_http_address+"/collect/"+this.cluster_name); 211 addMetadata(meta_list); 212 213 // display stuff 214 Element display_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER); 215 if (display_list != null) { 216 resolveMacros(display_list); 217 addDisplayItems(display_list); 218 } 219 220 //check whether the html are tidy or not 221 Element import_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.IMPORT_ELEM); 222 if (import_list != null) { 223 Element plugin_list = (Element)GSXML.getChildByTagName(import_list, GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER); 224 addPlugins(plugin_list); 225 if (plugin_list != null){ 226 Element plugin_elem = (Element)GSXML.getNamedElement(plugin_list, GSXML.PLUGIN_ELEM, GSXML.NAME_ATT, "HTMLPlugin"); 227 if (plugin_elem != null) { 228 //get the option 229 Element option_elem = (Element)GSXML.getNamedElement(plugin_elem, GSXML.PARAM_OPTION_ELEM, GSXML.NAME_ATT, "-use_realistic_book"); 230 if (option_elem != null) { 231 useBook = true; 232 } 233 } 234 } 235 } 236 meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 237 if (useBook == true) 238 GSXML.addMetadata(this.doc, meta_list, "tidyoption", "tidy"); 239 else 240 GSXML.addMetadata(this.doc, meta_list, "tidyoption", "untidy"); 241 addMetadata(meta_list); 242 243 // check whether we are public or not 244 if (meta_list != null) { 245 Element meta_elem = (Element) GSXML.getNamedElement(metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "public"); 246 if (meta_elem != null) { 247 String value = GSXML.getValue(meta_elem).toLowerCase().trim(); 248 if (value.equals("false")) { 249 is_public = false; 250 } 251 } 252 } 253 return true; 254 255 } 256 257 protected boolean configureServiceRacks(Element coll_config_xml, 258 Element build_config_xml){ 259 clearServices(); 260 Element service_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER); 261 configureServiceRackList(service_list, coll_config_xml); 262 263 // collection Config may also contain manually added service racks 264 service_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER); 265 if (service_list != null) { 266 configureServiceRackList(service_list, build_config_xml); 267 268 // Check for oai 269 Element oai_service_rack = GSXML.getNamedElement(service_list, GSXML.SERVICE_CLASS_ELEM, OAIXML.NAME, OAIXML.OAIPMH); 270 if (oai_service_rack == null) { 271 has_oai = false; 272 logger.info("No oai for collection: " + this.cluster_name); 273 274 } else { 275 has_oai = true; 276 277 // extract earliestDatestamp from the buildconfig.xml for OAI 278 Element metadata_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER); 279 280 if(metadata_list != null) { 281 NodeList children = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM); 282 // can't do getChildNodes(), because whitespace, such as newlines, creates Text nodes 283 for (int i = 0; i < children.getLength(); i++) { 284 Element metadata = (Element)children.item(i); 285 if(metadata.getAttribute(GSXML.NAME_ATT).equals(OAIXML.EARLIEST_DATESTAMP)) { 286 String earliestDatestampStr = GSXML.getValue(metadata); 287 if(!earliestDatestampStr.equals("")) { 288 earliestDatestamp = Long.parseLong(earliestDatestampStr); 289 } 290 break; // found a metadata element with name=earliestDatestamp in buildconfig 291 } 292 } 293 } 294 295 // If at the end of this, there is no value for earliestDatestamp, print out a warning 296 logger.warn("No earliestDatestamp in buildConfig.xml for collection: " + this.cluster_name + ". Defaulting to 0."); 297 298 } 299 } else { // no list of services (no ServiceRackList), so no oai_service_rack either 300 // explicitly set has_oai to false here, since it's initialised to true by default 301 has_oai = false; 302 } 303 return true; 304 } 305 306 protected boolean resolveMacros(Element display_list) { 307 if (display_list==null) return false; 308 NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM); 309 if (displaynodes.getLength()>0) { 310 String http_site = this.site_http_address; 311 String http_collection = this.site_http_address +"/collect/"+this.cluster_name; 312 for(int k=0; k<displaynodes.getLength(); k++) { 313 Element d = (Element) displaynodes.item(k); 314 String text = GSXML.getNodeText(d); 315 text = StringUtils.replace(text, "_httpsite_", http_site); 316 text = StringUtils.replace(text, "_httpcollection_", http_collection); 317 GSXML.setNodeText(d, text); 318 } 319 } 320 return true; 321 } 322 /** 323 * do a configure on only part of the collection 324 */ 325 protected boolean configureSubset(String subset) { 326 327 // need the coll config files 328 Element coll_config_elem = loadCollConfigFile(); 329 Element build_config_elem = loadBuildConfigFile(); 330 if (coll_config_elem == null||build_config_elem == null) { 331 // wont be able to do any of the requests 332 return false; 333 } 334 335 if (subset.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) { 336 return configureServiceRacks(coll_config_elem, build_config_elem); 337 } 338 339 if (subset.equals(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER) || subset.equals(GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER) || subset.equals(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER)) { 340 return findAndLoadInfo(coll_config_elem, build_config_elem); 341 342 } 343 344 logger.error("Collection: cant process system request, configure "+subset); 345 return false; 346 } 347 348 /** handles requests made to the ServiceCluster itself 349 * 350 * @param req - the request Element- <request> 351 * @return the result Element - should be <response> 352 */ 353 protected Element processMessage(Element request) { 354 355 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 356 response.setAttribute(GSXML.FROM_ATT, this.cluster_name); 357 String type = request.getAttribute(GSXML.TYPE_ATT); 358 String lang = request.getAttribute(GSXML.LANG_ATT); 359 response.setAttribute(GSXML.TYPE_ATT, type); 360 361 logger.debug("Collection received a message, attempting to process"); 362 363 if (type.equals(GSXML.REQUEST_TYPE_FORMAT_STRING)) { 364 logger.error("Received format string request"); 365 366 String subaction = request.getAttribute("subaction"); 367 logger.error("Subaction is " + subaction); 368 369 String service = request.getAttribute("service"); 370 logger.error("Service is " + service); 371 372 String classifier = null; 373 if(service.equals("ClassifierBrowse")) 374 { 375 classifier = request.getAttribute("classifier"); 376 logger.error("Classifier is " + classifier); 377 } 378 379 //logger.error("Format string: " + format_string); 380 logger.error("Config file location = " + GSFile.collectionConfigFile(this.site_home, this.cluster_name)); 381 382 // check for version file 383 384 String directory = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)).getParent() + File.separator; 385 logger.error("Directory is " + directory); 386 387 String version_filename = ""; 388 if(service.equals("ClassifierBrowse")) 389 version_filename = directory + "browse_"+classifier+"_format_statement_version.txt"; 390 else 391 version_filename = directory + "query_format_statement_version.txt"; 392 393 File version_file = new File(version_filename); 394 logger.error("Version filename is " + version_filename); 395 396 397 if(subaction.equals("update")) 398 { 399 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM); 400 //String format_string = GSXML.getNodeText(format_element); 401 Element format_statement = (Element) format_element.getFirstChild(); 402 403 404 String version_number = "1"; 405 BufferedWriter writer; 406 407 try{ 408 409 if(version_file.exists()) 410 { 411 // Read version 412 BufferedReader reader = new BufferedReader(new FileReader(version_filename)); 413 version_number = reader.readLine(); 414 int aInt = Integer.parseInt(version_number) + 1; 415 version_number = Integer.toString(aInt); 416 reader.close(); 417 } 418 else{ 419 // Create 420 version_file.createNewFile(); 421 writer = new BufferedWriter(new FileWriter(version_filename)); 422 writer.write(version_number); 423 writer.close(); 424 } 425 426 // Write version file 427 String format_statement_filename = ""; 428 429 if(service.equals("ClassifierBrowse")) 430 format_statement_filename = directory + "browse_"+classifier+"_format_statement_v" + version_number + ".txt"; 431 else 432 format_statement_filename = directory + "query_format_statement_v" + version_number + ".txt"; 433 434 logger.error("Format statement filename is " + format_statement_filename); 435 436 // Write format statement 437 String format_string = this.converter.getString(format_statement); //GSXML.xmlNodeToString(format_statement); 438 writer = new BufferedWriter(new FileWriter(format_statement_filename)); 439 writer.write(format_string); 440 writer.close(); 441 442 // Update version number 443 writer = new BufferedWriter(new FileWriter(version_filename)); 444 writer.write(version_number); 445 writer.close(); 446 447 } catch (IOException e) { 448 logger.error("IO Exception "+e); 449 } 450 } 451 452 if(subaction.equals("saveDocument")) 453 { 454 int k; 455 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM); 456 //String format_string = GSXML.getNodeText(format_element); 457 // Get display tag 458 Element display_format = (Element) format_element.getFirstChild(); 459 460 logger.error("I have received a save document request"); 461 String format_string = GSXML.xmlNodeToString(display_format); 462 logger.error("Param="+format_string); 463 String collection_config = directory + "collectionConfig.xml"; 464 Document config = this.converter.getDOM(new File(collection_config), "UTF-8"); 465 466 Node current_node = GSXML.getChildByTagName(config, "CollectionConfig"); 467 468 // Get display child 469 if(GSXML.getChildByTagName(current_node, "display") == null) 470 { 471 logger.error("ERROR: does not have a display child"); 472 // well then create a format tag 473 Element display_tag = config.createElement("display"); 474 current_node = (Node) current_node.appendChild(display_tag); 475 //current_node = (Node) format_tag; 476 } 477 478 else{ 479 current_node = GSXML.getChildByTagName(current_node, "display"); 480 } 481 482 if(GSXML.getChildByTagName(current_node, "format") == null) 483 { 484 logger.error("ERROR: does not have a format child"); 485 // well then create a format tag 486 Element format_tag = config.createElement("format"); 487 current_node.appendChild(format_tag); 488 //current_node = (Node) format_tag; 489 } 490 491 492 current_node.replaceChild(config.importNode(display_format,true), GSXML.getChildByTagName(current_node, "format")); 493 494 logger.error(GSXML.xmlNodeToString(current_node)); 495 496 logger.error("Convert config to string"); 497 String new_config = this.converter.getString(config); 498 499 new_config = StringUtils.replace(new_config, "<", "<"); 500 new_config = StringUtils.replace(new_config, ">", ">"); 501 new_config = StringUtils.replace(new_config, """, "\""); 502 503 try{ 504 // Write to file (not original! for now) 505 BufferedWriter writer = new BufferedWriter(new FileWriter(collection_config+".new")); 506 writer.write(new_config); 507 writer.close(); 508 logger.error("All is happy with collection saveDocument"); 509 } catch (IOException e) { 510 logger.error("IO Exception "+e); 511 } 512 } 513 514 if(subaction.equals("save")) 515 { 516 logger.error("SAVE format statement"); 517 518 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM); 519 //String format_string = GSXML.getNodeText(format_element); 520 Element format_statement = (Element) format_element.getFirstChild(); 521 522 try{ 523 524 // open collectionConfig.xml and read in to w3 Document 525 String collection_config = directory + "collectionConfig.xml"; 526 Document config = this.converter.getDOM(new File(collection_config), "UTF-8"); 527 528 //String tag_name = ""; 529 int k; 530 int index; 531 Element elem; 532 // Try importing entire tree to this.doc so we can add and remove children at ease 533 //Node current_node = this.doc.importNode(GSXML.getChildByTagName(config, "CollectionConfig"),true); 534 Node current_node = GSXML.getChildByTagName(config, "CollectionConfig"); 535 NodeList current_node_list; 536 537 logger.error("Service is "+service); 538 539 if(service.equals("ClassifierBrowse")) 540 { 541 //tag_name = "browse"; 542 // if CLX then need to look in <classifier> X then <format> 543 // default is <browse><format> 544 545 logger.error("Looking for browse"); 546 current_node = GSXML.getChildByTagName(current_node, "browse"); 547 548 // find CLX 549 if(classifier != null) 550 { 551 logger.error("Classifier is not null"); 552 logger.error("Classifier is "+classifier); 553 current_node_list = GSXML.getChildrenByTagName(current_node, "classifier"); 554 index = Integer.parseInt(classifier.substring(2)) - 1; 555 logger.error("classifier index is "+index); 556 // index should be given by X-1 557 current_node = current_node_list.item(index); 558 // what if classifier does not have a format tag? 559 if(GSXML.getChildByTagName(current_node, "format") == null) 560 { 561 logger.error("ERROR: valid classifier but does not have a format child"); 562 // well then create a format tag 563 Element format_tag = config.createElement("format"); 564 current_node.appendChild(format_tag); 565 //current_node = (Node) format_tag; 566 } 567 } 568 else{ 569 logger.error("Classifier is null"); 570 // To support all classifiers, set classifier to null? There is the chance here that the format tag does not exist 571 if(GSXML.getChildByTagName(current_node, "format") == null) 572 { 573 logger.error("ERROR: classifier does not have a format child"); 574 // well then create a format tag 575 Element format_tag = config.createElement("format"); 576 current_node.appendChild(format_tag); 577 //current_node = (Node) format_tag; 578 } 579 } 580 } 581 else if(service.equals("AllClassifierBrowse")) 582 { 583 logger.error("Looking for browse"); 584 current_node = GSXML.getChildByTagName(current_node, "browse"); 585 if(GSXML.getChildByTagName(current_node, "format") == null) 586 { 587 logger.error("ERROR AllClassifierBrowse: all classifiers do not have a format child"); 588 // well then create a format tag 589 Element format_tag = config.createElement("format"); 590 current_node.appendChild(format_tag); 591 //current_node = (Node) format_tag; 592 } 593 } 594 else 595 { 596 // look in <format> with no attributes 597 logger.error("I presume this is search"); 598 599 current_node_list = GSXML.getChildrenByTagName(current_node, "search"); 600 for(k=0; k<current_node_list.getLength(); k++) 601 { 602 current_node = current_node_list.item(k); 603 // if current_node has no attributes then break 604 elem = (Element) current_node; 605 if(elem.hasAttribute("name")==false) 606 break; 607 } 608 } 609 610 current_node.replaceChild(config.importNode(format_statement,true), GSXML.getChildByTagName(current_node, "format")); 611 612 // Now convert config document to string for writing to file 613 logger.error("Convert config to string"); 614 String new_config = this.converter.getString(config); 615 616 new_config = StringUtils.replace(new_config, "<", "<"); 617 new_config = StringUtils.replace(new_config, ">", ">"); 618 new_config = StringUtils.replace(new_config, """, "\""); 619 620 // Write to file (not original! for now) 621 BufferedWriter writer = new BufferedWriter(new FileWriter(collection_config+".new")); 622 writer.write(new_config); 623 writer.close(); 624 logger.error("All is happy with collection"); 625 626 } catch( Exception ex ) { 627 logger.error("There was an exception "+ex); 628 629 StringWriter sw = new StringWriter(); 630 PrintWriter pw = new PrintWriter(sw, true); 631 ex.printStackTrace(pw); 632 pw.flush(); 633 sw.flush(); 634 logger.error(sw.toString()); 635 } 636 637 } 638 } 639 else { // unknown type 640 return super.processMessage(request); 641 642 } 643 return response; 644 } 56 public class Collection extends ServiceCluster 57 { 58 59 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.Collection.class.getName()); 60 61 /** is this collection being tidied */ 62 protected boolean useBook = false; 63 /** is this collection public or private */ 64 protected boolean is_public = true; 65 66 /** does this collection provide the OAI service */ 67 protected boolean has_oai = true; 68 /** time when this collection was built */ 69 protected long lastmodified = 0; 70 /** earliestDatestamp of this collection. Necessary for OAI */ 71 protected long earliestDatestamp = 0; 72 73 /** 74 * An element containing the serviceRackList element of buildConfig.xml, 75 * used to determine whether it contains the OAIPMH serviceRack 76 */ 77 //protected Element service_rack_list = null; 78 79 protected XMLTransformer transformer = null; 80 81 /** same as setClusterName */ 82 public void setCollectionName(String name) 83 { 84 setClusterName(name); 85 } 86 87 public Collection() 88 { 89 super(); 90 this.description = this.doc.createElement(GSXML.COLLECTION_ELEM); 91 92 } 93 94 /** 95 * Configures the collection. 96 * 97 * gsdlHome and collectionName must be set before configure is called. 98 * 99 * the file buildcfg.xml is located in gsdlHome/collect/collectionName 100 * collection metadata is obtained, and services loaded. 101 * 102 * @return true/false on success/fail 103 */ 104 public boolean configure() 105 { 106 107 if (this.site_home == null || this.cluster_name == null) 108 { 109 logger.error("Collection: site_home and collection_name must be set before configure called!"); 110 return false; 111 } 112 113 Element coll_config_xml = loadCollConfigFile(); 114 Element build_config_xml = loadBuildConfigFile(); 115 116 if (coll_config_xml == null || build_config_xml == null) 117 { 118 return false; 119 } 120 121 // get the collection type attribute 122 Element search = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SEARCH_ELEM); 123 if (search != null) 124 { 125 col_type = search.getAttribute(GSXML.TYPE_ATT); 126 } 127 128 Element browse = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.INFODB_ELEM); 129 if (browse != null) 130 { 131 db_type = browse.getAttribute(GSXML.TYPE_ATT); 132 } 133 else 134 { 135 db_type = "gdbm"; //Default database type 136 } 137 138 // process the metadata and display items 139 findAndLoadInfo(coll_config_xml, build_config_xml); 140 141 // now do the services 142 configureServiceRacks(coll_config_xml, build_config_xml); 143 144 return true; 145 146 } 147 148 public boolean useBook() 149 { 150 return useBook; 151 } 152 153 public boolean isPublic() 154 { 155 return is_public; 156 } 157 158 // Not used anymore by the OAIReceptionist to find out the earliest datestamp 159 // amongst all oai collections in the repository. May be useful generally. 160 public long getLastmodified() 161 { 162 return lastmodified; 163 } 164 165 //used by the OAIReceptionist to find out the earliest datestamp amongst all oai collections in the repository 166 public long getEarliestDatestamp() 167 { 168 return earliestDatestamp; 169 } 170 171 /** 172 * whether the service_map in ServiceCluster.java contains the service 173 * 'OAIPMH' 11/06/2007 xiao 174 */ 175 public boolean hasOAI() 176 { 177 return has_oai; 178 } 179 180 /** 181 * load in the collection config file into a DOM Element 182 */ 183 protected Element loadCollConfigFile() 184 { 185 186 File coll_config_file = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)); 187 188 if (!coll_config_file.exists()) 189 { 190 logger.error("Collection: couldn't configure collection: " + this.cluster_name + ", " + coll_config_file + " does not exist"); 191 return null; 192 } 193 // get the xml for both files 194 Document coll_config_doc = this.converter.getDOM(coll_config_file, CONFIG_ENCODING); 195 Element coll_config_elem = null; 196 if (coll_config_doc != null) 197 { 198 coll_config_elem = coll_config_doc.getDocumentElement(); 199 } 200 return coll_config_elem; 201 202 } 203 204 /** 205 * load in the collection build config file into a DOM Element 206 */ 207 protected Element loadBuildConfigFile() 208 { 209 210 File build_config_file = new File(GSFile.collectionBuildConfigFile(this.site_home, this.cluster_name)); 211 if (!build_config_file.exists()) 212 { 213 logger.error("Collection: couldn't configure collection: " + this.cluster_name + ", " + build_config_file + " does not exist"); 214 return null; 215 } 216 Document build_config_doc = this.converter.getDOM(build_config_file, CONFIG_ENCODING); 217 Element build_config_elem = null; 218 if (build_config_doc != null) 219 { 220 build_config_elem = build_config_doc.getDocumentElement(); 221 } 222 223 lastmodified = build_config_file.lastModified(); 224 225 return build_config_elem; 226 } 227 228 /** 229 * find the metadata and display elems from the two config files and add it 230 * to the appropriate lists 231 */ 232 protected boolean findAndLoadInfo(Element coll_config_xml, Element build_config_xml) 233 { 234 235 // metadata 236 Element meta_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 237 addMetadata(meta_list); 238 meta_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 239 addMetadata(meta_list); 240 241 meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 242 GSXML.addMetadata(this.doc, meta_list, "httpPath", this.site_http_address + "/collect/" + this.cluster_name); 243 addMetadata(meta_list); 244 245 // display stuff 246 Element display_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER); 247 if (display_list != null) 248 { 249 resolveMacros(display_list); 250 addDisplayItems(display_list); 251 } 252 253 //check whether the html are tidy or not 254 Element import_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.IMPORT_ELEM); 255 if (import_list != null) 256 { 257 Element plugin_list = (Element) GSXML.getChildByTagName(import_list, GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER); 258 addPlugins(plugin_list); 259 if (plugin_list != null) 260 { 261 Element plugin_elem = (Element) GSXML.getNamedElement(plugin_list, GSXML.PLUGIN_ELEM, GSXML.NAME_ATT, "HTMLPlugin"); 262 if (plugin_elem != null) 263 { 264 //get the option 265 Element option_elem = (Element) GSXML.getNamedElement(plugin_elem, GSXML.PARAM_OPTION_ELEM, GSXML.NAME_ATT, "-use_realistic_book"); 266 if (option_elem != null) 267 { 268 useBook = true; 269 } 270 } 271 } 272 } 273 meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 274 if (useBook == true) 275 GSXML.addMetadata(this.doc, meta_list, "tidyoption", "tidy"); 276 else 277 GSXML.addMetadata(this.doc, meta_list, "tidyoption", "untidy"); 278 addMetadata(meta_list); 279 280 // check whether we are public or not 281 if (meta_list != null) 282 { 283 Element meta_elem = (Element) GSXML.getNamedElement(metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "public"); 284 if (meta_elem != null) 285 { 286 String value = GSXML.getValue(meta_elem).toLowerCase().trim(); 287 if (value.equals("false")) 288 { 289 is_public = false; 290 } 291 } 292 } 293 return true; 294 295 } 296 297 protected boolean configureServiceRacks(Element coll_config_xml, Element build_config_xml) 298 { 299 clearServices(); 300 Element service_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER); 301 configureServiceRackList(service_list, coll_config_xml); 302 303 // collection Config may also contain manually added service racks 304 service_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER); 305 if (service_list != null) 306 { 307 configureServiceRackList(service_list, build_config_xml); 308 309 // Check for oai 310 Element oai_service_rack = GSXML.getNamedElement(service_list, GSXML.SERVICE_CLASS_ELEM, OAIXML.NAME, OAIXML.OAIPMH); 311 if (oai_service_rack == null) 312 { 313 has_oai = false; 314 logger.info("No oai for collection: " + this.cluster_name); 315 316 } 317 else 318 { 319 has_oai = true; 320 321 // extract earliestDatestamp from the buildconfig.xml for OAI 322 Element metadata_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 323 324 if (metadata_list != null) 325 { 326 NodeList children = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM); 327 // can't do getChildNodes(), because whitespace, such as newlines, creates Text nodes 328 for (int i = 0; i < children.getLength(); i++) 329 { 330 Element metadata = (Element) children.item(i); 331 if (metadata.getAttribute(GSXML.NAME_ATT).equals(OAIXML.EARLIEST_DATESTAMP)) 332 { 333 String earliestDatestampStr = GSXML.getValue(metadata); 334 if (!earliestDatestampStr.equals("")) 335 { 336 earliestDatestamp = Long.parseLong(earliestDatestampStr); 337 } 338 break; // found a metadata element with name=earliestDatestamp in buildconfig 339 } 340 } 341 } 342 343 // If at the end of this, there is no value for earliestDatestamp, print out a warning 344 logger.warn("No earliestDatestamp in buildConfig.xml for collection: " + this.cluster_name + ". Defaulting to 0."); 345 346 } 347 } 348 else 349 { // no list of services (no ServiceRackList), so no oai_service_rack either 350 // explicitly set has_oai to false here, since it's initialised to true by default 351 has_oai = false; 352 } 353 return true; 354 } 355 356 protected boolean resolveMacros(Element display_list) 357 { 358 if (display_list == null) 359 return false; 360 NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM); 361 if (displaynodes.getLength() > 0) 362 { 363 String http_site = this.site_http_address; 364 String http_collection = this.site_http_address + "/collect/" + this.cluster_name; 365 for (int k = 0; k < displaynodes.getLength(); k++) 366 { 367 Element d = (Element) displaynodes.item(k); 368 String text = GSXML.getNodeText(d); 369 text = StringUtils.replace(text, "_httpsite_", http_site); 370 text = StringUtils.replace(text, "_httpcollection_", http_collection); 371 GSXML.setNodeText(d, text); 372 } 373 } 374 return true; 375 } 376 377 /** 378 * do a configure on only part of the collection 379 */ 380 protected boolean configureSubset(String subset) 381 { 382 383 // need the coll config files 384 Element coll_config_elem = loadCollConfigFile(); 385 Element build_config_elem = loadBuildConfigFile(); 386 if (coll_config_elem == null || build_config_elem == null) 387 { 388 // wont be able to do any of the requests 389 return false; 390 } 391 392 if (subset.equals(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER)) 393 { 394 return configureServiceRacks(coll_config_elem, build_config_elem); 395 } 396 397 if (subset.equals(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER) || subset.equals(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER) || subset.equals(GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER)) 398 { 399 return findAndLoadInfo(coll_config_elem, build_config_elem); 400 401 } 402 403 logger.error("Collection: cant process system request, configure " + subset); 404 return false; 405 } 406 407 /** 408 * handles requests made to the ServiceCluster itself 409 * 410 * @param req 411 * - the request Element- <request> 412 * @return the result Element - should be <response> 413 */ 414 protected Element processMessage(Element request) 415 { 416 417 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 418 response.setAttribute(GSXML.FROM_ATT, this.cluster_name); 419 String type = request.getAttribute(GSXML.TYPE_ATT); 420 String lang = request.getAttribute(GSXML.LANG_ATT); 421 response.setAttribute(GSXML.TYPE_ATT, type); 422 423 logger.error("Collection received a message, attempting to process"); 424 425 if (type.equals(GSXML.REQUEST_TYPE_FORMAT_STRING)) 426 { 427 logger.error("Received format string request"); 428 429 String subaction = request.getAttribute("subaction"); 430 logger.error("Subaction is " + subaction); 431 432 String service = request.getAttribute("service"); 433 logger.error("Service is " + service); 434 435 String classifier = null; 436 if (service.equals("ClassifierBrowse")) 437 { 438 classifier = request.getAttribute("classifier"); 439 logger.error("Classifier is " + classifier); 440 } 441 442 //logger.error("Format string: " + format_string); 443 logger.error("Config file location = " + GSFile.collectionConfigFile(this.site_home, this.cluster_name)); 444 445 // check for version file 446 447 String directory = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)).getParent() + File.separator; 448 logger.error("Directory is " + directory); 449 450 String version_filename = ""; 451 if (service.equals("ClassifierBrowse")) 452 version_filename = directory + "browse_" + classifier + "_format_statement_version.txt"; 453 else 454 version_filename = directory + "query_format_statement_version.txt"; 455 456 File version_file = new File(version_filename); 457 logger.error("Version filename is " + version_filename); 458 459 if (subaction.equals("update")) 460 { 461 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM); 462 //String format_string = GSXML.getNodeText(format_element); 463 Element format_statement = (Element) format_element.getFirstChild(); 464 465 String version_number = "1"; 466 BufferedWriter writer; 467 468 try 469 { 470 471 if (version_file.exists()) 472 { 473 // Read version 474 BufferedReader reader = new BufferedReader(new FileReader(version_filename)); 475 version_number = reader.readLine(); 476 int aInt = Integer.parseInt(version_number) + 1; 477 version_number = Integer.toString(aInt); 478 reader.close(); 479 } 480 else 481 { 482 // Create 483 version_file.createNewFile(); 484 writer = new BufferedWriter(new FileWriter(version_filename)); 485 writer.write(version_number); 486 writer.close(); 487 } 488 489 // Write version file 490 String format_statement_filename = ""; 491 492 if (service.equals("ClassifierBrowse")) 493 format_statement_filename = directory + "browse_" + classifier + "_format_statement_v" + version_number + ".txt"; 494 else 495 format_statement_filename = directory + "query_format_statement_v" + version_number + ".txt"; 496 497 logger.error("Format statement filename is " + format_statement_filename); 498 499 // Write format statement 500 String format_string = this.converter.getString(format_statement); //GSXML.xmlNodeToString(format_statement); 501 writer = new BufferedWriter(new FileWriter(format_statement_filename)); 502 writer.write(format_string); 503 writer.close(); 504 505 // Update version number 506 writer = new BufferedWriter(new FileWriter(version_filename)); 507 writer.write(version_number); 508 writer.close(); 509 510 } 511 catch (IOException e) 512 { 513 logger.error("IO Exception " + e); 514 } 515 } 516 517 if (subaction.equals("saveDocument")) 518 { 519 int k; 520 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM); 521 //String format_string = GSXML.getNodeText(format_element); 522 // Get display tag 523 Element display_format = (Element) format_element.getFirstChild(); 524 525 logger.error("I have received a save document request"); 526 String format_string = GSXML.xmlNodeToString(display_format); 527 logger.error("Param=" + format_string); 528 String collection_config = directory + "collectionConfig.xml"; 529 Document config = this.converter.getDOM(new File(collection_config), "UTF-8"); 530 531 Node current_node = GSXML.getChildByTagName(config, "CollectionConfig"); 532 533 // Get display child 534 if (GSXML.getChildByTagName(current_node, "display") == null) 535 { 536 logger.error("ERROR: does not have a display child"); 537 // well then create a format tag 538 Element display_tag = config.createElement("display"); 539 current_node = (Node) current_node.appendChild(display_tag); 540 //current_node = (Node) format_tag; 541 } 542 543 else 544 { 545 current_node = GSXML.getChildByTagName(current_node, "display"); 546 } 547 548 if (GSXML.getChildByTagName(current_node, "format") == null) 549 { 550 logger.error("ERROR: does not have a format child"); 551 // well then create a format tag 552 Element format_tag = config.createElement("format"); 553 current_node.appendChild(format_tag); 554 //current_node = (Node) format_tag; 555 } 556 557 current_node.replaceChild(config.importNode(display_format, true), GSXML.getChildByTagName(current_node, "format")); 558 559 logger.error(GSXML.xmlNodeToString(current_node)); 560 561 logger.error("Convert config to string"); 562 String new_config = this.converter.getString(config); 563 564 new_config = StringUtils.replace(new_config, "<", "<"); 565 new_config = StringUtils.replace(new_config, ">", ">"); 566 new_config = StringUtils.replace(new_config, """, "\""); 567 568 try 569 { 570 // Write to file (not original! for now) 571 BufferedWriter writer = new BufferedWriter(new FileWriter(collection_config + ".new")); 572 writer.write(new_config); 573 writer.close(); 574 logger.error("All is happy with collection saveDocument"); 575 } 576 catch (IOException e) 577 { 578 logger.error("IO Exception " + e); 579 } 580 } 581 582 if (subaction.equals("save")) 583 { 584 logger.error("SAVE format statement"); 585 586 Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM); 587 //String format_string = GSXML.getNodeText(format_element); 588 Element format_statement = (Element) format_element.getFirstChild(); 589 590 try 591 { 592 593 // open collectionConfig.xml and read in to w3 Document 594 String collection_config = directory + "collectionConfig.xml"; 595 Document config = this.converter.getDOM(new File(collection_config), "UTF-8"); 596 597 //String tag_name = ""; 598 int k; 599 int index; 600 Element elem; 601 // Try importing entire tree to this.doc so we can add and remove children at ease 602 //Node current_node = this.doc.importNode(GSXML.getChildByTagName(config, "CollectionConfig"),true); 603 Node current_node = GSXML.getChildByTagName(config, "CollectionConfig"); 604 NodeList current_node_list; 605 606 logger.error("Service is " + service); 607 608 if (service.equals("ClassifierBrowse")) 609 { 610 //tag_name = "browse"; 611 // if CLX then need to look in <classifier> X then <format> 612 // default is <browse><format> 613 614 logger.error("Looking for browse"); 615 current_node = GSXML.getChildByTagName(current_node, "browse"); 616 617 // find CLX 618 if (classifier != null) 619 { 620 logger.error("Classifier is not null"); 621 logger.error("Classifier is " + classifier); 622 current_node_list = GSXML.getChildrenByTagName(current_node, "classifier"); 623 index = Integer.parseInt(classifier.substring(2)) - 1; 624 logger.error("classifier index is " + index); 625 // index should be given by X-1 626 current_node = current_node_list.item(index); 627 // what if classifier does not have a format tag? 628 if (GSXML.getChildByTagName(current_node, "format") == null) 629 { 630 logger.error("ERROR: valid classifier but does not have a format child"); 631 // well then create a format tag 632 Element format_tag = config.createElement("format"); 633 current_node.appendChild(format_tag); 634 //current_node = (Node) format_tag; 635 } 636 } 637 else 638 { 639 logger.error("Classifier is null"); 640 // To support all classifiers, set classifier to null? There is the chance here that the format tag does not exist 641 if (GSXML.getChildByTagName(current_node, "format") == null) 642 { 643 logger.error("ERROR: classifier does not have a format child"); 644 // well then create a format tag 645 Element format_tag = config.createElement("format"); 646 current_node.appendChild(format_tag); 647 //current_node = (Node) format_tag; 648 } 649 } 650 } 651 else if (service.equals("AllClassifierBrowse")) 652 { 653 logger.error("Looking for browse"); 654 current_node = GSXML.getChildByTagName(current_node, "browse"); 655 if (GSXML.getChildByTagName(current_node, "format") == null) 656 { 657 logger.error("ERROR AllClassifierBrowse: all classifiers do not have a format child"); 658 // well then create a format tag 659 Element format_tag = config.createElement("format"); 660 current_node.appendChild(format_tag); 661 //current_node = (Node) format_tag; 662 } 663 } 664 else 665 { 666 // look in <format> with no attributes 667 logger.error("I presume this is search"); 668 669 current_node_list = GSXML.getChildrenByTagName(current_node, "search"); 670 for (k = 0; k < current_node_list.getLength(); k++) 671 { 672 current_node = current_node_list.item(k); 673 // if current_node has no attributes then break 674 elem = (Element) current_node; 675 if (elem.hasAttribute("name") == false) 676 break; 677 } 678 } 679 680 current_node.replaceChild(config.importNode(format_statement, true), GSXML.getChildByTagName(current_node, "format")); 681 682 // Now convert config document to string for writing to file 683 logger.error("Convert config to string"); 684 String new_config = this.converter.getString(config); 685 686 new_config = StringUtils.replace(new_config, "<", "<"); 687 new_config = StringUtils.replace(new_config, ">", ">"); 688 new_config = StringUtils.replace(new_config, """, "\""); 689 690 // Write to file (not original! for now) 691 BufferedWriter writer = new BufferedWriter(new FileWriter(collection_config + ".new")); 692 writer.write(new_config); 693 writer.close(); 694 logger.error("All is happy with collection"); 695 696 } 697 catch (Exception ex) 698 { 699 logger.error("There was an exception " + ex); 700 701 StringWriter sw = new StringWriter(); 702 PrintWriter pw = new PrintWriter(sw, true); 703 ex.printStackTrace(pw); 704 pw.flush(); 705 sw.flush(); 706 logger.error(sw.toString()); 707 } 708 709 } 710 } 711 else 712 { // unknown type 713 return super.processMessage(request); 714 715 } 716 return response; 717 } 645 718 646 719 } 647 648 649 650
Note:
See TracChangeset
for help on using the changeset viewer.