Changeset 24393 for main/trunk/greenstone3
- Timestamp:
- 2011-08-12T09:57:26+12:00 (13 years ago)
- Location:
- main/trunk/greenstone3/src/java/org/greenstone/gsdl3
- Files:
-
- 5 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/Action.java
r24254 r24393 77 77 } 78 78 79 79 protected void extractMetadataNames(Element format, HashSet meta_names) { 80 80 //NodeList nodes = format.getElementsByTagNameNS("metadata", "http://www.greenstone.org/configformat"); 81 81 NodeList metadata_nodes = format.getElementsByTagName("gsf:metadata"); … … 90 90 metadata.append("all"); 91 91 metadata.append(GSConstants.META_RELATION_SEP); 92 } else if (all.equals("offset")) { // multiple is no longer boolean. 93 // Can be "true", "false" or it can be "offset" (when requested to use mdoffset) 94 metadata.append("offset"); 95 metadata.append(GSConstants.META_RELATION_SEP); 96 } // if multiple=false, then get first value for the metadata 92 } 97 93 if (!select.equals("")) { 98 94 metadata.append(select); -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/GS2BrowseAction.java
r24254 r24393 272 272 Element d = this.doc.createElement(GSXML.DOC_NODE_ELEM); 273 273 d.setAttribute(GSXML.NODE_ID_ATT, ((Element)doc_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT)); 274 if(((Element)doc_nodes.item(c)).hasAttribute(GSXML.NODE_MDOFFSET_ATT)) {275 d.setAttribute(GSXML.NODE_MDOFFSET_ATT, ((Element)doc_nodes.item(c)).getAttribute(GSXML.NODE_MDOFFSET_ATT));276 }277 274 doc_list.appendChild(d); 278 275 } -
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 -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractBrowse.java
r24254 r24393 574 574 * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/> 575 575 */ 576 protected Element createDocNode(String node_id , int offset) {576 protected Element createDocNode(String node_id) { 577 577 Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM); 578 578 node.setAttribute(GSXML.NODE_ID_ATT, node_id); … … 587 587 String node_type = getNodeType(node_id, doc_type); 588 588 node.setAttribute(GSXML.NODE_TYPE_ATT, node_type); 589 590 // mdoffset information stored in DB determines which of multiple values for591 // a metadata needs to be displayed when a classifier is built on that metadata592 node.setAttribute(GSXML.NODE_MDOFFSET_ATT, Integer.toString(offset));593 589 return node; 594 590 } … … 625 621 ArrayList child_ids = getChildrenIds(node_id); 626 622 if (child_ids==null) return; 627 628 // get a list of all mdoffsets at this point629 ArrayList child_offsets = getOffsetsForChildrenIds(node_id);630 // make sure that if it's doesn't match up with child_ids in length,631 // it is padded with 0s to make up the length632 if(child_offsets == null) {633 child_offsets = new ArrayList(child_ids.size());634 }635 if(child_offsets.size() < child_ids.size()) {636 Integer zero = new Integer(0);637 for(int i = child_offsets.size()-1; i < child_ids.size(); i++) {638 child_offsets.add(zero);639 }640 }641 642 623 for (int i=0; i< child_ids.size(); i++) { 643 624 String child_id = (String)child_ids.get(i); 644 int child_offset = ((Integer)child_offsets.get(i)).intValue(); // counts both docnodes and classnodes at the childlevel, is this right?645 625 Element child_elem; 646 626 if (isDocumentId(child_id)) { 647 child_elem = createDocNode(child_id , child_offset);627 child_elem = createDocNode(child_id); 648 628 } else { 649 629 child_elem = createClassifierNode(child_id); … … 704 684 } 705 685 706 /** Override to get a list of mdoffsets of children. Return null if no children or if no mdoffsets for them */707 protected ArrayList getOffsetsForChildrenIds(String node_id) {708 return null;709 }710 711 686 /** if id ends in .fc, .pc etc, then translate it to the correct id */ 712 687 abstract protected String translateId(String node_id); -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractDocumentRetrieve.java
r24334 r24393 241 241 Element request_node = (Element) request_nodes.item(i); 242 242 String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT); 243 244 // make a custom copy of metadata_names_list for each docID, since mdoffset value varies for each doc245 ArrayList customised_metadata_names_list = new ArrayList(metadata_names_list.size());246 int mdoffset = 0;247 if(request_node.hasAttribute(GSXML.NODE_MDOFFSET_ATT)) {248 String offset = request_node.getAttribute(GSXML.NODE_MDOFFSET_ATT);249 mdoffset = Integer.parseInt(offset);250 }251 for(int x = 0; x < metadata_names_list.size(); x++) {252 String metaname = (String)metadata_names_list.get(x);253 if(metaname.indexOf("offset" + GSConstants.META_RELATION_SEP) != -1) {254 // append offset number to the metaname255 metaname = metaname.replace("offset"+GSConstants.META_RELATION_SEP, "offset"+mdoffset+GSConstants.META_RELATION_SEP);256 }257 customised_metadata_names_list.add(x, metaname);258 }259 260 243 261 244 boolean is_external_link = false; … … 289 272 if (!is_external_link){ 290 273 try { 291 Element metadata_list = getMetadataList(node_id, all_metadata, customised_metadata_names_list);274 Element metadata_list = getMetadataList(node_id, all_metadata, metadata_names_list); 292 275 request_node.appendChild(metadata_list); 293 276 } catch (GSException e) { -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractGS2DocumentRetrieve.java
r24254 r24393 41 41 import java.util.Iterator; 42 42 import java.util.ArrayList; 43 import java.util.regex.Matcher;44 import java.util.regex.Pattern;45 43 46 44 import org.apache.log4j.*; … … 198 196 199 197 } else { 200 // prepare regex to work with mdoffset: looking for <offset\d*_>201 Pattern pattern = Pattern.compile("offset[0-9]*" + GSConstants.META_RELATION_SEP);202 203 198 for (int i=0; i<metadata_names.size(); i++) { 204 199 String meta_name = (String) metadata_names.get(i); 205 200 String value = getMetadata(node_id, info, meta_name, lang); 206 207 // Remove the occurrence (if any) in this metaname of the mdoffset number in the pattern <offset\d*_>208 // Leaving string "offset" in at this point: it will be handled in config_format.xsl's gsf:metadata template match209 Matcher matcher = pattern.matcher(meta_name);210 meta_name = matcher.replaceFirst("offset" + GSConstants.META_RELATION_SEP);211 //replaceFirst(""); // if removing the occurrence (if any) of entire pattern <offset\d*_> in input212 213 201 GSXML.addMetadata(this.doc, metadata_list, meta_name, value); 214 202 } … … 329 317 protected String getMetadata(String node_id, DBInfo info, 330 318 String metadata, String lang) { 331 String multiple = "false"; // multiple can now be "true", "false" or "offset<number>". It's no longer a boolean319 boolean multiple = false; 332 320 String relation = ""; 333 321 String separator = ", "; … … 358 346 metadata = metadata.substring(pos+1); 359 347 // check for all on the front 360 if (temp.equals("all") || temp.startsWith("offset")) { // multiple can now be "true", "false" or "offset"361 multiple = temp; // multiple=true;348 if (temp.equals("all")) { 349 multiple=true; 362 350 pos = metadata.indexOf(GSConstants.META_RELATION_SEP); 363 351 if (pos ==-1) { … … 411 399 StringBuffer result = new StringBuffer(); 412 400 413 if ( multiple.equals("false")) {401 if (!multiple) { 414 402 result.append(this.macro_resolver.resolve(relation_info.getInfo(metadata), lang, MacroResolver.SCOPE_META, relation_id)); 415 } else if(multiple.startsWith("offset")) { // multiple = offset 416 String offset = multiple.substring("offset".length(), multiple.length()); 417 int offsetVal = offset.equals("") ? 0 : Integer.parseInt(offset); 418 String value = relation_info.getInfoOffset(metadata, offsetVal); // what if this metadata is not the one we need to get the offset for? MDTYPE! 419 // at the moment, do we assume the user will specify retrieving the offset only for such metadata as has an offset? 420 // At least, getInfoOffset will return the firstelement if the offset exceeds the bounds of the values for this metadata key 421 422 result.append(this.macro_resolver.resolve(value, lang, MacroResolver.SCOPE_META, relation_id)); 423 424 } else { // multiple = true, we have multiple meta 403 } else { 404 // we have multiple meta 425 405 Vector values = relation_info.getMultiInfo(metadata); 426 if (values != null) {406 if (values != null) { 427 407 boolean first = true; 428 408 for (int i=0; i<values.size(); i++) { … … 435 415 } 436 416 } 437 logger.info(result); 417 logger.info(result); 438 418 } 439 419 // if not ancestors, then this is all we do … … 448 428 relation_info = this.coll_db.getInfo(relation_id); 449 429 if (relation_info == null) return result.toString(); 450 if ( multiple.equals("false")) { //if (!multiple)430 if (!multiple) { 451 431 result.insert(0, separator); 452 432 result.insert(0, this.macro_resolver.resolve(relation_info.getInfo(metadata), lang, MacroResolver.SCOPE_META, relation_id)); -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/GS2Browse.java
r24254 r24393 175 175 176 176 } 177 /** returns a list of the mdoffset values in order for the children, null is178 * returned if there are no children or if the mdoffset field is empty */179 protected ArrayList getOffsetsForChildrenIds(String node_id) {180 DBInfo info = this.coll_db.getInfo(node_id);181 if (info == null) {182 return null;183 }184 185 ArrayList childrenOffsets = new ArrayList();186 187 String offset = info.getInfo("mdoffset").trim();188 if(offset.equals("")) {189 return null;190 }191 StringTokenizer st = new StringTokenizer(offset, ";");192 while (st.hasMoreTokens()) {193 String val = st.nextToken().trim();194 childrenOffsets.add(Integer.valueOf(val));195 }196 return childrenOffsets;197 }198 199 177 /** returns the node id of the parent node, null if no parent */ 200 178 protected String getParentId(String node_id){ -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ServiceRack.java
r21781 r24393 24 24 25 25 // xml classes 26 import org.w3c.dom.Node; 27 import org.w3c.dom.NodeList; 28 import org.w3c.dom.Element; 29 import org.w3c.dom.Document; 26 import org.w3c.dom.Node; 27 import org.w3c.dom.NodeList; 28 import org.w3c.dom.Element; 29 import org.w3c.dom.Document; 30 30 import org.xml.sax.InputSource; 31 31 import javax.xml.parsers.*; … … 45 45 /** 46 46 * ServiceRack - abstract base class for services 47 * 48 * A ServiceRack provides one or more Services. 49 * This base class implements the process method. 50 *Each service is invoked 51 * by a method called process<service name> which takes one parameter - the xml request Element, and returns an XML response Element. 52 * for example, the TextQuery service would be invoked by 47 * 48 * A ServiceRack provides one or more Services. This base class implements the 49 * process method. Each service is invoked by a method called process<service 50 * name> which takes one parameter - the xml request Element, and returns an XML 51 * response Element. for example, the TextQuery service would be invoked by 53 52 * processTextQuery(Element request) 54 * 53 * 55 54 * @author Katherine Don 56 55 */ 57 public abstract class ServiceRack 58 implements ModuleInterface 56 public abstract class ServiceRack implements ModuleInterface 59 57 { 60 58 61 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.ServiceRack.class.getName()); 62 63 /** the absolute address of the site home */ 64 protected String site_home =null; 65 /** the http address of the site home */ 66 protected String site_http_address =null; 67 68 protected String library_name = null; 69 /** the name of the cluster (or collection) that this service 70 belongs to - if any */ 71 protected String cluster_name = null; 72 73 /** some services can talk back to the message router */ 74 protected MessageRouter router = null; 75 76 /** a converter class to create Documents etc */ 77 protected XMLConverter converter = null; 78 79 /** the original config info - if need to store it */ 80 protected Element config_info = null; 81 82 /** XML element for describe requests - the container doc */ 83 protected Document doc = null; 84 85 /** XML element for describe requests - list of supported services 86 - this is static */ 87 protected Element short_service_info = null; 88 89 /** XML element for stylesheet requests - map of service name to format 90 elem */ 91 protected HashMap format_info_map = null; 92 93 /** A class loader that knows about the collection resources directory 94 * can put properties files, dtds etc in here */ 95 CollectionClassLoader class_loader = null; 96 97 /** sets the cluster name */ 98 public void setClusterName(String cluster_name) { 99 this.cluster_name = cluster_name; 100 } 101 /** sets the collect name */ 102 public void setCollectionName(String coll_name) { 103 setClusterName(coll_name); 104 } 105 106 public void cleanUp() {} 107 108 /** sets the site home */ 109 public void setSiteHome(String site_home) { 110 this.site_home = site_home; 111 } 112 /** sets the site http address */ 113 public void setSiteAddress(String site_address) { 114 this.site_http_address = site_address; 115 } 116 117 public void setLibraryName(String library_name) { 118 this.library_name = library_name; 119 } 120 public String getLibraryName() { 121 return this.library_name; 122 } 123 /** sets the message router */ 124 public void setMessageRouter(MessageRouter m) { 125 this.router = m; 126 setLibraryName(m.getLibraryName()); 127 } 128 129 /** the no-args constructor */ 130 public ServiceRack() { 131 this.converter = new XMLConverter(); 132 this.doc = this.converter.newDOM(); 133 this.short_service_info = this.doc.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER); 134 this.format_info_map = new HashMap(); 135 } 136 137 138 /** configure the service module 139 * 140 * @param info the XML node <serviceRack name="XXX"/> with name equal 141 * to the class name (of the subclass) 142 * 143 * must configure short_service_info_ and service_info_map_ 144 * @return true if configured ok 145 * must be implemented in subclasses 146 */ 147 public boolean configure(Element info) { 148 return configure(info, null); 149 } 150 151 public boolean configure(Element info, Element extra_info) { 152 // set up the class loader 153 this.class_loader = new CollectionClassLoader(this.getClass().getClassLoader(), this.site_home, this.cluster_name); 154 return true; 155 } 156 157 /** 158 * Process an XML document - convenience method that uses Strings rather than Elements. just calls process(Element). 159 * 160 * @param xml_in the Document to process - a string 161 * @return the resultant document as a string - contains any error messages 162 * @see String 163 */ 164 public String process(String xml_in) { 165 166 Document doc = this.converter.getDOM(xml_in); 167 if (doc == null) { 168 logger.error("Couldn't parse request"); 169 logger.error(xml_in); 170 return null; 171 } 172 Node res = process(doc); 173 return this.converter.getString(res); 174 175 } 176 177 /** process an XML request in DOM form 178 * 179 * @param message the Node node containing the request 180 * should be <message> 181 * @return an Node with the result XML 182 * @see Node/Element 183 */ 184 public Node process(Node message_node) { 185 186 Element message = this.converter.nodeToElement(message_node); 187 188 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM); 189 Document mess_doc = message.getOwnerDocument(); 190 Element mainResult = this.doc.createElement(GSXML.MESSAGE_ELEM); 191 if (requests.getLength()==0) { 192 // no requests 193 return mainResult; // empty message for now 194 } 195 196 for (int i=0; i<requests.getLength(); i++) { 197 Element request = (Element)requests.item(i); 198 199 String type = request.getAttribute(GSXML.TYPE_ATT); 200 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) { 201 Element response = processDescribe(request); 202 if (response !=null) { 203 mainResult.appendChild(this.doc.importNode(response, true)); 204 } 205 206 } else if (type.equals(GSXML.REQUEST_TYPE_FORMAT)) { 207 Element response = processFormat(request); 208 mainResult.appendChild(this.doc.importNode(response, true)); 209 210 211 } else { 212 // other type of request, must be processed by the subclass - 213 // send to the service method 214 StringBuffer error_string = new StringBuffer(); 215 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 216 Element response = null; 217 try { 218 Class c = this.getClass(); 219 Class []params = {Class.forName("org.w3c.dom.Element")}; 220 221 String method_name = "process"+to; 222 Method m = null; 223 while (c != null) { 224 225 try { 226 m = c.getDeclaredMethod(method_name, params); 227 // if this has worked, break 228 break; 229 } catch (NoSuchMethodException e) { 230 c = c.getSuperclass(); 231 } catch (SecurityException e) { 232 logger.error("security exception for finding method "+method_name); 233 error_string.append("ServiceRack.process: security exception for finding method "+method_name); 59 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.ServiceRack.class.getName()); 60 61 /** the absolute address of the site home */ 62 protected String site_home = null; 63 /** the http address of the site home */ 64 protected String site_http_address = null; 65 66 protected String library_name = null; 67 /** 68 * the name of the cluster (or collection) that this service belongs to - if 69 * any 70 */ 71 protected String cluster_name = null; 72 73 /** some services can talk back to the message router */ 74 protected MessageRouter router = null; 75 76 /** a converter class to create Documents etc */ 77 protected XMLConverter converter = null; 78 79 /** the original config info - if need to store it */ 80 protected Element config_info = null; 81 82 /** XML element for describe requests - the container doc */ 83 protected Document doc = null; 84 85 /** 86 * XML element for describe requests - list of supported services - this is 87 * static 88 */ 89 protected Element short_service_info = null; 90 91 /** 92 * XML element for stylesheet requests - map of service name to format elem 93 */ 94 protected HashMap format_info_map = null; 95 96 /** 97 * A class loader that knows about the collection resources directory can 98 * put properties files, dtds etc in here 99 */ 100 CollectionClassLoader class_loader = null; 101 102 /** sets the cluster name */ 103 public void setClusterName(String cluster_name) 104 { 105 this.cluster_name = cluster_name; 106 } 107 108 /** sets the collect name */ 109 public void setCollectionName(String coll_name) 110 { 111 setClusterName(coll_name); 112 } 113 114 public void cleanUp() 115 { 116 } 117 118 /** sets the site home */ 119 public void setSiteHome(String site_home) 120 { 121 this.site_home = site_home; 122 } 123 124 /** sets the site http address */ 125 public void setSiteAddress(String site_address) 126 { 127 this.site_http_address = site_address; 128 } 129 130 public void setLibraryName(String library_name) 131 { 132 this.library_name = library_name; 133 } 134 135 public String getLibraryName() 136 { 137 return this.library_name; 138 } 139 140 /** sets the message router */ 141 public void setMessageRouter(MessageRouter m) 142 { 143 this.router = m; 144 setLibraryName(m.getLibraryName()); 145 } 146 147 /** the no-args constructor */ 148 public ServiceRack() 149 { 150 this.converter = new XMLConverter(); 151 this.doc = this.converter.newDOM(); 152 this.short_service_info = this.doc.createElement(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER); 153 this.format_info_map = new HashMap(); 154 } 155 156 /** 157 * configure the service module 158 * 159 * @param info 160 * the XML node <serviceRack name="XXX"/> with name equal to the 161 * class name (of the subclass) 162 * 163 * must configure short_service_info_ and service_info_map_ 164 * @return true if configured ok must be implemented in subclasses 165 */ 166 public boolean configure(Element info) 167 { 168 return configure(info, null); 169 } 170 171 public boolean configure(Element info, Element extra_info) 172 { 173 // set up the class loader 174 this.class_loader = new CollectionClassLoader(this.getClass().getClassLoader(), this.site_home, this.cluster_name); 175 return true; 176 } 177 178 /** 179 * Process an XML document - convenience method that uses Strings rather 180 * than Elements. just calls process(Element). 181 * 182 * @param xml_in 183 * the Document to process - a string 184 * @return the resultant document as a string - contains any error messages 185 * @see String 186 */ 187 public String process(String xml_in) 188 { 189 190 Document doc = this.converter.getDOM(xml_in); 191 if (doc == null) 192 { 193 logger.error("Couldn't parse request"); 194 logger.error(xml_in); 195 return null; 196 } 197 Node res = process(doc); 198 return this.converter.getString(res); 199 200 } 201 202 /** 203 * process an XML request in DOM form 204 * 205 * @param message 206 * the Node node containing the request should be <message> 207 * @return an Node with the result XML 208 * @see Node/Element 209 */ 210 public Node process(Node message_node) 211 { 212 213 Element message = this.converter.nodeToElement(message_node); 214 215 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM); 216 Document mess_doc = message.getOwnerDocument(); 217 Element mainResult = this.doc.createElement(GSXML.MESSAGE_ELEM); 218 if (requests.getLength() == 0) 219 { 220 // no requests 221 return mainResult; // empty message for now 222 } 223 224 for (int i = 0; i < requests.getLength(); i++) 225 { 226 Element request = (Element) requests.item(i); 227 228 String type = request.getAttribute(GSXML.TYPE_ATT); 229 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) 230 { 231 Element response = processDescribe(request); 232 if (response != null) 233 { 234 mainResult.appendChild(this.doc.importNode(response, true)); 235 } 236 234 237 } 235 } // while 236 if (m != null) { 237 Object []args = {request}; 238 try { 239 response = (Element)m.invoke(this, args); 240 241 } catch (Exception e) { 242 logger.error("Trying to call a processService type method (process"+to+") on a subclass("+this.getClass().getName()+"), but an exception happened:"+e.toString(), e); 243 244 error_string.append("Trying to call a processService type method (process"+to+") on a subclass("+this.getClass().getName()+"), but an exception happened:"+e.toString()); 238 else if (type.equals(GSXML.REQUEST_TYPE_FORMAT)) 239 { 240 Element response = processFormat(request); 241 mainResult.appendChild(this.doc.importNode(response, true)); 242 245 243 } 246 } else { 247 logger.error("method "+method_name+" not found for class "+this.getClass().getName()); 248 error_string.append("ServiceRack.process: method "+method_name+" not found for class "+this.getClass().getName()); 249 } 250 251 } catch (ClassNotFoundException e) { 252 logger.error("Element class not found"); 253 error_string.append("Element class not found"); 254 } 255 if (response !=null) { 256 mainResult.appendChild(this.doc.importNode(response, true)); 257 } else { 258 // add in a dummy response 259 logger.error("adding in an error element\n"); 260 response = this.doc.createElement(GSXML.RESPONSE_ELEM); 261 GSXML.addError(this.doc, response, error_string.toString()); 262 mainResult.appendChild(response); 263 264 } 265 266 } // else process request 267 } // for each request 268 269 return mainResult; 270 271 } 272 273 274 275 /** process method for describe requests 276 */ 277 protected Element processDescribe(Element request) { 278 279 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 280 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE); 281 282 String lang = request.getAttribute(GSXML.LANG_ATT); 283 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 284 if (to.equals("")) { // return the service list 285 response.appendChild(getServiceList(lang)); 286 return response; 287 } 288 response.setAttribute(GSXML.FROM_ATT, to); 289 Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 290 Element description = null; 291 if (param_list == null) { 292 description = getServiceDescription(to, lang, null); 293 } else { 294 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM); 295 for (int i=0; i<params.getLength(); i++) { 296 297 Element param = (Element)params.item(i); 298 // Identify the structure information desired 299 if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM )) { 300 String info = param.getAttribute(GSXML.VALUE_ATT); 301 if (description == null) { 302 description = getServiceDescription(to, lang, info); 303 } else { 304 Element temp = getServiceDescription(to, lang, info); 305 GSXML.mergeElements(description, temp); 306 } 307 } 308 } 309 } 310 if (description != null) { // may be null if non-existant service 311 response.appendChild(description); 312 } 313 return response; 314 315 } 316 317 /** process method for stylesheet requests 318 */ 319 protected Element processFormat(Element request) { 320 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 321 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_FORMAT); 322 323 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 324 325 if (to.equals("")) { // serviceRack query - is this appropriate?? 326 return response; 327 } 328 329 330 // describe a particular service 331 if (this.format_info_map.containsKey(to)) { 332 response.appendChild(getServiceFormat(to)); 333 response.setAttribute(GSXML.FROM_ATT, to); 334 return response; 335 } 336 // else no format info 337 logger.error("ServiceRack describe request: no format info for "+to+"."); 338 return response; 339 } 340 341 /** returns the service list for the subclass */ 342 protected Element getServiceList(String lang) { 343 // for now, it is static and has no language stuff 344 return (Element) this.short_service_info.cloneNode(true); 345 } 346 347 /** returns a specific service description */ 348 abstract protected Element getServiceDescription(String service, String lang, String subset); 349 350 protected Element getServiceFormat(String service) { 351 Element format = (Element)((Element)this.format_info_map.get(service)).cloneNode(true); 352 return format; 353 } 354 355 /** overloaded version for no args case */ 356 protected String getTextString(String key, String lang) { 357 return getTextString(key, lang, null, null); 358 } 359 360 protected String getTextString(String key, String lang, String dictionary) { 361 return getTextString(key, lang, dictionary, null); 362 } 363 protected String getTextString(String key, String lang, String [] args) { 364 return getTextString(key, lang, null, args); 365 } 366 367 /** getTextString - retrieves a language specific text string for the given 368 key and locale, from the specified resource_bundle (dictionary) 369 */ 370 protected String getTextString(String key, String lang, String dictionary, String[] args) { 371 372 // we want to use the collection class loader in case there are coll specific files 373 if (dictionary != null) { 374 // just try the one specified dictionary 375 Dictionary dict = new Dictionary(dictionary, lang, this.class_loader); 376 String result = dict.get(key, args); 377 if (result == null) { // not found 378 return "_"+key+"_"; 379 } 380 return result; 381 } 382 383 // now we try class names for dictionary names 384 String class_name = this.getClass().getName(); 385 class_name = class_name.substring(class_name.lastIndexOf('.')+1); 386 Dictionary dict = new Dictionary(class_name, lang, this.class_loader); 387 String result = dict.get(key, args); 388 if (result != null) { 389 return result; 390 } 391 392 // we have to try super classes 393 Class c = this.getClass().getSuperclass(); 394 while (result == null && c != null) { 395 class_name = c.getName(); 396 class_name = class_name.substring(class_name.lastIndexOf('.')+1); 397 if (class_name.equals("ServiceRack")) { 398 // this is as far as we go 399 break; 400 } 401 dict = new Dictionary(class_name, lang, this.class_loader); 402 result = dict.get(key, args); 403 c = c.getSuperclass(); 404 } 405 if (result == null) { 406 return "_"+key+"_"; 407 } 408 return result; 409 410 } 411 412 protected String getMetadataNameText(String key, String lang) { 413 414 String properties_name = "metadata_names"; 415 Dictionary dict = new Dictionary(properties_name, lang); 416 417 String result = dict.get(key); 418 if (result == null) { // not found 419 return null; 420 } 421 return result; 422 } 244 else 245 { 246 // other type of request, must be processed by the subclass - 247 // send to the service method 248 StringBuffer error_string = new StringBuffer(); 249 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 250 Element response = null; 251 try 252 { 253 Class c = this.getClass(); 254 Class[] params = { Class.forName("org.w3c.dom.Element") }; 255 256 String method_name = "process" + to; 257 Method m = null; 258 while (c != null) 259 { 260 261 try 262 { 263 m = c.getDeclaredMethod(method_name, params); 264 // if this has worked, break 265 break; 266 } 267 catch (NoSuchMethodException e) 268 { 269 c = c.getSuperclass(); 270 } 271 catch (SecurityException e) 272 { 273 logger.error("security exception for finding method " + method_name); 274 error_string.append("ServiceRack.process: security exception for finding method " + method_name); 275 } 276 } // while 277 if (m != null) 278 { 279 Object[] args = { request }; 280 try 281 { 282 response = (Element) m.invoke(this, args); 283 284 } 285 catch (Exception e) 286 { 287 logger.error("Trying to call a processService type method (process" + to + ") on a subclass(" + this.getClass().getName() + "), but an exception happened:" + e.toString(), e); 288 289 error_string.append("Trying to call a processService type method (process" + to + ") on a subclass(" + this.getClass().getName() + "), but an exception happened:" + e.toString()); 290 } 291 } 292 else 293 { 294 logger.error("method " + method_name + " not found for class " + this.getClass().getName()); 295 error_string.append("ServiceRack.process: method " + method_name + " not found for class " + this.getClass().getName()); 296 } 297 298 } 299 catch (ClassNotFoundException e) 300 { 301 logger.error("Element class not found"); 302 error_string.append("Element class not found"); 303 } 304 if (response != null) 305 { 306 mainResult.appendChild(this.doc.importNode(response, true)); 307 } 308 else 309 { 310 // add in a dummy response 311 logger.error("adding in an error element\n"); 312 response = this.doc.createElement(GSXML.RESPONSE_ELEM); 313 GSXML.addError(this.doc, response, error_string.toString()); 314 mainResult.appendChild(response); 315 316 } 317 318 } // else process request 319 } // for each request 320 321 return mainResult; 322 323 } 324 325 /** 326 * process method for describe requests 327 */ 328 protected Element processDescribe(Element request) 329 { 330 331 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 332 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE); 333 334 String lang = request.getAttribute(GSXML.LANG_ATT); 335 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 336 if (to.equals("")) 337 { // return the service list 338 response.appendChild(getServiceList(lang)); 339 return response; 340 } 341 response.setAttribute(GSXML.FROM_ATT, to); 342 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 343 Element description = null; 344 if (param_list == null) 345 { 346 description = getServiceDescription(to, lang, null); 347 } 348 else 349 { 350 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM); 351 for (int i = 0; i < params.getLength(); i++) 352 { 353 354 Element param = (Element) params.item(i); 355 // Identify the structure information desired 356 if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM)) 357 { 358 String info = param.getAttribute(GSXML.VALUE_ATT); 359 if (description == null) 360 { 361 description = getServiceDescription(to, lang, info); 362 } 363 else 364 { 365 Element temp = getServiceDescription(to, lang, info); 366 GSXML.mergeElements(description, temp); 367 } 368 } 369 } 370 } 371 if (description != null) 372 { // may be null if non-existant service 373 response.appendChild(description); 374 } 375 return response; 376 377 } 378 379 /** 380 * process method for stylesheet requests 381 */ 382 protected Element processFormat(Element request) 383 { 384 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 385 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_FORMAT); 386 387 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 388 389 if (to.equals("")) 390 { // serviceRack query - is this appropriate?? 391 return response; 392 } 393 394 // describe a particular service 395 if (this.format_info_map.containsKey(to)) 396 { 397 response.appendChild(getServiceFormat(to)); 398 response.setAttribute(GSXML.FROM_ATT, to); 399 return response; 400 } 401 // else no format info 402 logger.error("ServiceRack describe request: no format info for " + to + "."); 403 return response; 404 } 405 406 /** returns the service list for the subclass */ 407 protected Element getServiceList(String lang) 408 { 409 // for now, it is static and has no language stuff 410 return (Element) this.short_service_info.cloneNode(true); 411 } 412 413 /** returns a specific service description */ 414 abstract protected Element getServiceDescription(String service, String lang, String subset); 415 416 protected Element getServiceFormat(String service) 417 { 418 Element format = (Element) ((Element) this.format_info_map.get(service)).cloneNode(true); 419 return format; 420 } 421 422 /** overloaded version for no args case */ 423 protected String getTextString(String key, String lang) 424 { 425 return getTextString(key, lang, null, null); 426 } 427 428 protected String getTextString(String key, String lang, String dictionary) 429 { 430 return getTextString(key, lang, dictionary, null); 431 } 432 433 protected String getTextString(String key, String lang, String[] args) 434 { 435 return getTextString(key, lang, null, args); 436 } 437 438 /** 439 * getTextString - retrieves a language specific text string for the given 440 * key and locale, from the specified resource_bundle (dictionary) 441 */ 442 protected String getTextString(String key, String lang, String dictionary, String[] args) 443 { 444 445 // we want to use the collection class loader in case there are coll specific files 446 if (dictionary != null) 447 { 448 // just try the one specified dictionary 449 Dictionary dict = new Dictionary(dictionary, lang, this.class_loader); 450 String result = dict.get(key, args); 451 if (result == null) 452 { // not found 453 return "_" + key + "_"; 454 } 455 return result; 456 } 457 458 // now we try class names for dictionary names 459 String class_name = this.getClass().getName(); 460 class_name = class_name.substring(class_name.lastIndexOf('.') + 1); 461 Dictionary dict = new Dictionary(class_name, lang, this.class_loader); 462 String result = dict.get(key, args); 463 if (result != null) 464 { 465 return result; 466 } 467 468 // we have to try super classes 469 Class c = this.getClass().getSuperclass(); 470 while (result == null && c != null) 471 { 472 class_name = c.getName(); 473 class_name = class_name.substring(class_name.lastIndexOf('.') + 1); 474 if (class_name.equals("ServiceRack")) 475 { 476 // this is as far as we go 477 break; 478 } 479 dict = new Dictionary(class_name, lang, this.class_loader); 480 result = dict.get(key, args); 481 c = c.getSuperclass(); 482 } 483 if (result == null) 484 { 485 return "_" + key + "_"; 486 } 487 return result; 488 489 } 490 491 protected String getMetadataNameText(String key, String lang) 492 { 493 494 String properties_name = "metadata_names"; 495 Dictionary dict = new Dictionary(properties_name, lang); 496 497 String result = dict.get(key); 498 if (result == null) 499 { // not found 500 return null; 501 } 502 return result; 503 } 423 504 } 424 -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DBInfo.java
r24254 r24393 22 22 import java.util.HashMap; 23 23 import java.util.Set; 24 /** class to hold info from a gdbm (or equiv) query 25 * maps a String key to a list of Strings (values) 26 * at the moment, the user must know if something has a single value or not 24 25 /** 26 * class to hold info from a gdbm (or equiv) query maps a String key to a list 27 * of Strings (values) at the moment, the user must know if something has a 28 * single value or not 27 29 */ 28 public class DBInfo { 30 public class DBInfo 31 { 32 protected HashMap info_map_; 29 33 30 protected HashMap info_map_; 34 public DBInfo() 35 { 36 info_map_ = new HashMap(); 37 } 31 38 32 public DBInfo() { 33 info_map_ = new HashMap(); 34 } 39 // methods for keys that can have a single value 35 40 36 // methods for keys that can have a single value 41 /** set the value for a key - replaces any existing value */ 42 public void setInfo(String key, String value) 43 { 44 Vector v = new Vector(); 45 v.add(value); 46 info_map_.put(key, v); 47 } 37 48 38 /** set the value for a key - replaces any existing value */ 39 public void setInfo(String key, String value) { 40 Vector v = new Vector(); 41 v.add(value); 42 info_map_.put(key, v); 43 } 49 /** 50 * get the value - used for keys that have one value, otherwise just returns 51 * the first one 52 */ 53 public String getInfo(String key) 54 { 55 Vector items = (Vector) info_map_.get(key); 56 if (items == null) 57 { 58 return ""; 59 } 60 return (String) items.firstElement(); 61 } 44 62 45 /** get the value - used for keys that have one value, otherwise just 46 * returns the first one */ 47 public String getInfo(String key) { 48 Vector items = (Vector)info_map_.get(key); 49 if (items==null) { 50 return ""; 63 // methods for keys that can have multiple values 64 65 /** add a value to a key - for keys that can have multiple values */ 66 public void addInfo(String key, String value) 67 { 68 Vector v = (Vector) info_map_.get(key); 69 if (v == null) 70 { 71 v = new Vector(); 72 } 73 v.add(value); 74 info_map_.put(key, v); 51 75 } 52 return (String)items.firstElement();53 }54 76 55 /** get the value for the key at offset. If offset out of bounds, 56 * just return the first one. */ 57 public String getInfoOffset(String key, int offset) { 58 Vector items = (Vector)info_map_.get(key); 59 if (items==null) { 60 return ""; 77 /** 78 * return a vector of all values associated with a key 79 * 80 * @return Vector of Strings 81 */ 82 public Vector getMultiInfo(String key) 83 { 84 return (Vector) info_map_.get(key); 61 85 } 62 if(offset >= 0 && offset < items.size()) {63 return (String)items.get(offset);64 } // else65 return (String)items.firstElement();66 }67 86 87 /** returns a list of all the keys in the info */ 88 public Set getKeys() 89 { 90 return info_map_.keySet(); 91 } 68 92 69 // methods for keys that can have multiple values 70 71 /** add a value to a key - for keys that can have multiple values */ 72 public void addInfo(String key, String value) { 73 Vector v = (Vector)info_map_.get(key); 74 if (v==null) { 75 v = new Vector(); 93 /** returns the Info as a string */ 94 public String toString() 95 { 96 return info_map_.toString(); 97 76 98 } 77 v.add(value);78 info_map_.put(key, v);79 }80 /** return a vector of all values associated with a key81 * @return Vector of Strings82 */83 public Vector getMultiInfo(String key) {84 return (Vector)info_map_.get(key);85 }86 87 /** returns a list of all the keys in the info */88 public Set getKeys() {89 return info_map_.keySet();90 }91 /** returns the Info as a string */92 public String toString() {93 return info_map_.toString();94 95 }96 99 } -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/FlatDatabaseWrapper.java
r16797 r24393 37 37 /** returns the value associated with the key */ 38 38 public String getValue(String key); 39 40 /** sets the given key to the given value in the database */ 41 public boolean setValue(String key, String value); 42 43 /** deletes the given key from the database */ 44 public boolean deleteKey(String key); 39 45 40 46 /** returns a string of key-value entries that can be -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GDBMWrapper.java
r21912 r24393 28 28 import java.io.File; 29 29 30 /** java wrapper class for gdbm - uses Java-GDBM written by Martin Pool 31 * replaces gdbmclass in the old version 30 /** 31 * java wrapper class for gdbm - uses Java-GDBM written by Martin Pool replaces 32 * gdbmclass in the old version 32 33 */ 33 34 34 public class GDBMWrapper 35 implements FlatDatabaseWrapper { 36 37 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GDBMWrapper.class.getName()); 38 39 /* GdbmFile modes: 40 READER - read access, many readers may share the database 41 WRITER - read/write access, exclusive access 42 WRCREAT - read/write access, create db if doesn't exist 43 NEWDB - read/write access, db should be replaced if exists 44 */ 45 46 47 protected GdbmFile db_=null; 48 49 /** open the database filename, with mode mode - uses the constants 50 above, eg GdbmFile.WRITER */ 51 public boolean openDatabase(String filename, int mode) { 52 // need to convert mode to GdbmFile mode 53 if (mode == READ) { 54 mode = GdbmFile.READER; 55 } else if (mode == WRITE) { 56 mode = GdbmFile.WRITER; 57 } else { 58 logger.error ("invalid mode, "+mode+ ", opening db for reading only"); 59 mode = GdbmFile.READER; 60 } 61 try { 62 if (db_!=null) { 63 db_.close(); 64 } 65 66 // The java version of the C++ code in common-src/src/lib/gdbmclass.cpp 67 if(mode == GdbmFile.READER) { 68 // Looking to read in the database 69 // we now use gdb extension. Check for ldb/bdb in case of legacy collection 70 // if not (first time) then generate using txt2db 71 if (!new File(filename).exists()) { 72 logger.warn("Database file " + filename + " does not exist. Looking for ldb/bdb version"); 73 int extension = filename.lastIndexOf('.'); 74 String filename_head = filename.substring(0, extension); 75 filename = filename_head + ".ldb"; 76 if (!new File(filename).exists()) { 77 filename = filename_head + ".bdb"; 35 public class GDBMWrapper implements FlatDatabaseWrapper 36 { 37 38 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GDBMWrapper.class.getName()); 39 40 /* 41 * GdbmFile modes: READER - read access, many readers may share the database 42 * WRITER - read/write access, exclusive access WRCREAT - read/write access, 43 * create db if doesn't exist NEWDB - read/write access, db should be 44 * replaced if exists 45 */ 46 47 protected GdbmFile db_ = null; 48 49 /** 50 * open the database filename, with mode mode - uses the constants above, eg 51 * GdbmFile.WRITER 52 */ 53 public boolean openDatabase(String filename, int mode) 54 { 55 // need to convert mode to GdbmFile mode 56 if (mode == READ) 57 { 58 mode = GdbmFile.READER; 59 } 60 else if (mode == WRITE) 61 { 62 mode = GdbmFile.WRITER; 63 } 64 else 65 { 66 logger.error("invalid mode, " + mode + ", opening db for reading only"); 67 mode = GdbmFile.READER; 68 } 69 try 70 { 71 if (db_ != null) 72 { 73 db_.close(); 74 } 75 76 // The java version of the C++ code in common-src/src/lib/gdbmclass.cpp 77 if (mode == GdbmFile.READER) 78 { 79 // Looking to read in the database 80 // we now use gdb extension. Check for ldb/bdb in case of legacy collection 81 // if not (first time) then generate using txt2db 82 if (!new File(filename).exists()) 83 { 84 logger.warn("Database file " + filename + " does not exist. Looking for ldb/bdb version"); 85 int extension = filename.lastIndexOf('.'); 86 String filename_head = filename.substring(0, extension); 87 filename = filename_head + ".ldb"; 88 if (!new File(filename).exists()) 89 { 90 filename = filename_head + ".bdb"; 91 92 if (!new File(filename).exists()) 93 { 94 logger.warn("ldb/bdb version of database file " + filename + " does not exist. Looking for txtgz version of db file."); 95 // put the filename back to gdb 96 filename = filename_head + ".gdb"; 97 // need to generate architecture native GDBM file using txt2db 98 99 // replace sought after gdbm filename ext with ".txt.gz" 100 101 String txtgzFilename = filename_head + ".txt.gz"; 102 if (new File(txtgzFilename).exists()) 103 { 104 // Test to make sure Perl is on the path 105 // On Linux, the output of the test goes to STDOUT so redirect it to STDERR 106 String cmdTest = "perl -v 2>&1"; 107 //String cmdTest = "echo %PATH%"; 108 int returnValue = Processing.runProcess(cmdTest); 109 if (returnValue != 0) 110 { 111 logger.error("Tried to find Perl. Return exit value of running " + cmdTest + ": " + returnValue + ", (expected this to be 0)"); 112 logger.error("Check that Perl is set in your PATH environment variable."); 113 //log.error("At present, PATH=" + System.getenv("PATH")); 114 } 115 116 String cmd = "perl -S txtgz-to-gdbm.pl \"" + txtgzFilename + "\" \"" + filename + "\""; 117 returnValue = Processing.runProcess(cmd); 118 // For some reason, launching this command with gsdl_system() still returns 1 119 // even when it returns 0 when run from the command-line. We can check whether 120 // we succeeded by looking at whether the output database file was created. 121 if (returnValue != 0) 122 { 123 logger.warn("Warning, non-zero return value on running command \"" + cmd + "\": " + returnValue); 124 if (!new File(filename).exists()) 125 { 126 logger.error("Tried to run command \"" + cmd + "\", but it failed"); 127 } 128 } 129 } 130 } 131 } 132 133 } 134 } 135 136 db_ = new GdbmFile(filename, mode); 137 } 138 catch (GdbmException e) 139 { // the database wasn't opened or created 140 logger.error("couldn't open database " + filename); 141 return false; 142 } 143 db_.setKeyPacking(new StringPacking()); 144 db_.setValuePacking(new StringPacking()); 145 return true; 146 } 147 148 /** close the database associated with this wrapper */ 149 public void closeDatabase() 150 { 151 try 152 { 153 if (db_ != null) 154 { 155 db_.close(); 156 db_ = null; 157 if (System.getProperty("os.name").startsWith("Windows")) 158 { 159 //Hack: force Windows to let go of the gdb file 160 System.gc(); 161 } 162 } 163 } 164 catch (GdbmException e) 165 { 166 // should never get here - close never actually throws an exception 167 logger.error("error on close()"); 168 } 169 } 170 171 public String getValue(String key) 172 { 173 if (db_ == null) 174 { 175 return null; 176 } 177 String s_info; 178 try 179 { 180 try 181 { 182 // The key is UTF8: do db lookup using the UTF8 version of key 183 s_info = (String) db_.fetch(key.getBytes("UTF-8")); 184 } 185 catch (UnsupportedEncodingException e) 186 { 187 logger.warn("utf8 key for " + key + " unrecognised. Retrying with default encoding."); 188 // retry db lookup using default encoding of key instead of UTF8 189 s_info = (String) db_.fetch(key); 190 } 191 } 192 catch (GdbmException e) 193 { 194 logger.error("couldn't get record"); 195 return null; 196 } 197 if (s_info == null) 198 { 199 // record not present 200 logger.error("key " + key + " not present in db"); 201 return null; 202 } 203 return s_info; 204 } 205 206 /** 207 * sets the given key to the given value in the database 208 */ 209 public boolean setValue(String key, String value) 210 { 211 if (db_ == null || !db_.isWritable()) 212 { 213 logger.error("GDBM database is either null or not writable"); 214 return false; 215 } 78 216 79 if (!new File(filename).exists()) { 80 logger.warn("ldb/bdb version of database file " + filename + " does not exist. Looking for txtgz version of db file."); 81 // put the filename back to gdb 82 filename = filename_head + ".gdb"; 83 // need to generate architecture native GDBM file using txt2db 217 try 218 { 219 db_.store(key, value); 220 } 221 catch (GdbmException ex) 222 { 223 logger.error("Error storing " + key + " = " + value + " in GDBM database"); 224 logger.error("Error message is: " + ex.getMessage()); 225 return false; 226 } 227 return true; 228 } 229 230 /** 231 * deletes the entry for given key 232 */ 233 public boolean deleteKey(String key) 234 { 235 if (db_ == null) 236 { 237 logger.error("GDBM database is null"); 238 return false; 239 } 84 240 85 // replace sought after gdbm filename ext with ".txt.gz" 241 try 242 { 243 db_.delete(key); 244 } 245 catch (GdbmException ex) 246 { 247 logger.error("Error deleting key " + key + " from the database"); 248 logger.error("Error message is: " + ex.getMessage()); 249 return false; 250 } 86 251 87 String txtgzFilename = filename_head + ".txt.gz"; 88 if(new File(txtgzFilename).exists()) { 89 // Test to make sure Perl is on the path 90 // On Linux, the output of the test goes to STDOUT so redirect it to STDERR 91 String cmdTest = "perl -v 2>&1"; 92 //String cmdTest = "echo %PATH%"; 93 int returnValue = Processing.runProcess(cmdTest); 94 if (returnValue != 0) { 95 logger.error("Tried to find Perl. Return exit value of running " 96 + cmdTest + ": " + returnValue + ", (expected this to be 0)"); 97 logger.error("Check that Perl is set in your PATH environment variable."); 98 //log.error("At present, PATH=" + System.getenv("PATH")); 99 } 100 101 String cmd = "perl -S txtgz-to-gdbm.pl \"" + txtgzFilename + "\" \"" + filename + "\""; 102 returnValue = Processing.runProcess(cmd); 103 // For some reason, launching this command with gsdl_system() still returns 1 104 // even when it returns 0 when run from the command-line. We can check whether 105 // we succeeded by looking at whether the output database file was created. 106 if (returnValue != 0) { 107 logger.warn("Warning, non-zero return value on running command \"" + cmd + "\": " + returnValue); 108 if (!new File(filename).exists()) { 109 logger.error("Tried to run command \"" + cmd + "\", but it failed"); 110 } 111 } 112 } 113 } 114 } 115 116 } 117 } 118 119 db_ = new GdbmFile(filename, mode); 120 } catch ( GdbmException e) { // the database wasn't opened or created 121 logger.error("couldn't open database "+filename); 122 return false; 123 } 124 db_.setKeyPacking(new StringPacking()); 125 db_.setValuePacking(new StringPacking()); 126 return true; 127 } 128 129 /** close the database associated with this wrapper */ 130 public void closeDatabase() { 131 try { 132 if (db_ != null) { 133 db_.close(); 134 db_ = null; 135 if(System.getProperty("os.name").startsWith("Windows")) { 136 //Hack: force Windows to let go of the gdb file 137 System.gc(); 138 } 139 } 140 } catch (GdbmException e) { 141 // should never get here - close never actually throws an exception 142 logger.error("error on close()"); 143 } 144 } 145 146 public String getValue(String key) { 147 if (db_==null) { 148 return null; 149 } 150 String s_info; 151 try { 152 try { 153 // The key is UTF8: do db lookup using the UTF8 version of key 154 s_info = (String)db_.fetch(key.getBytes("UTF-8")); 155 } catch(UnsupportedEncodingException e) { 156 logger.warn("utf8 key for " + key 157 + " unrecognised. Retrying with default encoding."); 158 // retry db lookup using default encoding of key instead of UTF8 159 s_info = (String)db_.fetch(key); 160 } 161 } catch (GdbmException e) { 162 logger.error("couldn't get record"); 163 return null; 164 } 165 if (s_info==null) { 166 // record not present 167 logger.error("key "+key+" not present in db"); 168 return null; 169 } 170 return s_info; 171 } 172 173 /** sets the key value as info 174 * TODO - not implemented yet */ 175 public boolean setValue (String key, String value) { 176 if (db_==null) { 177 return false; 178 } 179 return false; 180 } 181 /** deletes the entry for key 182 * TODO - not implemented yet */ 183 public boolean deleteKey(String key) { 184 if (db_==null) { 185 return false; 186 } 187 return false; 188 } 189 190 /** returns a string of key-value entries that 191 * can be printed for debugging purposes. */ 192 public String displayAllEntries() { 193 StringBuffer output = new StringBuffer(); 194 try{ 195 java.util.Enumeration e = db_.keys(); 196 while(e.hasMoreElements()) { 197 Object key = e.nextElement(); 198 Object value = db_.fetch(key); 199 200 output.append("key href: "); 201 output.append((String)key); 202 output.append("\tvalue ID: "); 203 output.append((String)value); 204 output.append("\n"); 205 //logger.warn("key: " + key + "\tvalue: " + value); 206 207 String urlkey = java.net.URLEncoder.encode((String)key, "UTF8"); 208 output.append("URL encoded key: " + urlkey); 209 //logger.warn("URL encoded key: " + urlkey); 210 } 211 } catch(UnsupportedEncodingException e) { 212 logger.warn("Trouble converting key to UTF-8."); 213 } catch(Exception e) { 214 logger.warn("Exception encountered when trying to displayAllEntries():" + e); 215 } 216 return output.toString(); 217 } 252 return true; 253 } 254 255 /** 256 * returns a string of key-value entries that can be printed for debugging 257 * purposes. 258 */ 259 public String displayAllEntries() 260 { 261 StringBuffer output = new StringBuffer(); 262 try 263 { 264 java.util.Enumeration e = db_.keys(); 265 while (e.hasMoreElements()) 266 { 267 Object key = e.nextElement(); 268 Object value = db_.fetch(key); 269 270 output.append("key href: "); 271 output.append((String) key); 272 output.append("\tvalue ID: "); 273 output.append((String) value); 274 output.append("\n"); 275 //logger.warn("key: " + key + "\tvalue: " + value); 276 277 String urlkey = java.net.URLEncoder.encode((String) key, "UTF8"); 278 output.append("URL encoded key: " + urlkey); 279 //logger.warn("URL encoded key: " + urlkey); 280 } 281 } 282 catch (UnsupportedEncodingException e) 283 { 284 logger.warn("Trouble converting key to UTF-8."); 285 } 286 catch (Exception e) 287 { 288 logger.warn("Exception encountered when trying to displayAllEntries():" + e); 289 } 290 return output.toString(); 291 } 218 292 } -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java
r24254 r24393 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 2 * GSXML.java 3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 19 package org.greenstone.gsdl3.util; 20 20 … … 26 26 import org.w3c.dom.Text; 27 27 28 29 28 import javax.xml.transform.TransformerFactory; 30 29 import javax.xml.transform.Transformer; … … 46 45 /** various functions for extracting info out of GS XML */ 47 46 public class GSXML { 48 49 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GSXML.class.getName()); 50 51 // greenstone xml elements 52 public static final String MESSAGE_ELEM = "message"; 53 public static final String REQUEST_ELEM = "request"; 54 public static final String RESPONSE_ELEM = "response"; 55 public static final String COLLECTION_ELEM = "collection"; 56 public static final String SERVICE_ELEM = "service"; 57 public static final String CLUSTER_ELEM = "serviceCluster"; 58 public static final String SITE_ELEM = "site"; 59 public static final String PARAM_ELEM = "param"; 60 public static final String PARAM_OPTION_ELEM = "option"; 61 public static final String CONTENT_ELEM = "content"; 62 public static final String RESOURCE_ELEM = "resource"; 63 public static final String DOCUMENT_ELEM = "document"; 64 public static final String METADATA_ELEM = "metadata"; 65 public static final String SERVICE_CLASS_ELEM = "serviceRack"; 66 public static final String CLASSIFIER_ELEM = "classifier"; 67 public static final String APPLET_ELEM = "applet"; 68 public static final String APPLET_DATA_ELEM = "appletData"; 69 public static final String CONFIGURE_ELEM = "configure"; 70 public static final String STATUS_ELEM = "status"; 71 public static final String ERROR_ELEM = "error"; 72 public static final String DEFAULT_ELEM = "default"; 73 public static final String STYLESHEET_ELEM = "format";//"stylesheet"; // any additional stylesheet stuff is carried in the message inside this elem 74 public static final String FORMAT_ELEM = "format"; // config files use format - should we use this instead of stylesheet?? 75 public static final String TERM_ELEM = "term"; 76 public static final String STOPWORD_ELEM = "stopword"; 77 public static final String SYSTEM_ELEM = "system"; 78 public static final String FORMAT_STRING_ELEM = "formatString"; 79 80 //config file elems 81 public static final String COLLECTION_CONFIG_ELEM = "collectionConfig"; 82 public static final String COLLECTION_BUILD_ELEM = "buildConfig"; 83 public static final String COLLECTION_INIT_ELEM = "collectionInit"; 84 public static final String RECOGNISE_ELEM = "recognise"; 85 public static final String DOC_TYPE_ELEM = "docType"; 86 public static final String SEARCH_ELEM = "search"; 87 public static final String INFODB_ELEM = "infodb"; 88 public static final String INDEX_ELEM = "index"; 89 public static final String INDEX_STEM_ELEM = "indexStem"; 90 public static final String INDEX_OPTION_ELEM = "indexOption"; 91 public static final String BROWSE_ELEM = "browse"; 92 public static final String DISPLAY_ELEM = "display"; 93 public static final String LEVEL_ELEM = "level"; 94 95 public static final String DBINFO_ELEM = "dbInfo"; 96 public static final String DBNAME_ATT = "dbname"; 97 public static final String DBPATH_ATT = "dbpath"; 98 public static final String SQLSTATE_ATT = "sqlstate"; 99 public static final String DATABASE_TYPE_ELEM = "databaseType"; 100 public static final String SHORTNAME_ATT = "shortname"; 101 public static final String NOTIFY_ELEM = "notify"; 102 public static final String NOTIFY_HOST_ATT = "host"; 103 104 105 106 // elems for the pages to be processed by xslt 107 public final static String PAGE_ELEM = "page"; 108 public final static String CONFIGURATION_ELEM = "config"; 109 public final static String PAGE_REQUEST_ELEM = "pageRequest"; 110 public final static String PAGE_RESPONSE_ELEM = "pageResponse"; 111 public final static String PAGE_EXTRA_ELEM = "pageExtra"; 112 113 //public final static String DESCRIPTION_ELEM = "description"; 114 115 public static final String ACTION_ELEM = "action"; 116 public static final String SUBACTION_ELEM = "subaction"; 117 118 // add on to another elem type to get a list of that type 119 public static final String LIST_MODIFIER = "List"; 120 121 // greenstone xml attributes 122 public static final String NAME_ATT = "name"; 123 public static final String TO_ATT = "to"; 124 public static final String USER_ID_ATT = "uid"; 125 public static final String FROM_ATT = "from"; 126 public static final String LANG_ATT = "lang"; 127 public static final String TYPE_ATT = "type"; 128 public static final String DB_TYPE_ATT = "dbType"; 129 public static final String VALUE_ATT = "value"; 130 public static final String DEFAULT_ATT = "default"; 131 public static final String INFO_ATT = "info"; 132 public static final String ACTION_ATT = "action"; 133 public static final String SUBACTION_ATT = "subaction"; 134 public static final String OUTPUT_ATT = "output"; 135 public static final String ADDRESS_ATT = "address"; 136 public static final String LOCAL_SITE_ATT = "localSite"; 137 public static final String LOCAL_SITE_NAME_ATT = "localSiteName"; 138 public static final String STATUS_ERROR_CODE_ATT = "code"; 139 public static final String STATUS_PROCESS_ID_ATT = "pid"; 140 public static final String PARAM_SHORTNAME_ATT = "shortname"; 141 public static final String PARAM_IGNORE_POS_ATT = "ignore"; 142 public static final String CLASSIFIER_CONTENT_ATT = "content"; 143 public static final String ERROR_TYPE_ATT = "type"; 144 public static final String COLLECT_TYPE_ATT = "ct"; 145 public static final String HIDDEN_ATT = "hidden"; 146 147 // document stuff 148 public static final String DOC_TYPE_ATT = "docType"; 149 public static final String DOC_NODE_ELEM = "documentNode"; 150 public static final String NODE_CONTENT_ELEM = "nodeContent"; 151 public static final String NODE_STRUCTURE_ELEM = "nodeStructure"; 152 public static final String NODE_ID_ATT = "nodeID"; 153 public static final String NODE_NAME_ATT = "nodeName"; 154 public static final String NODE_TYPE_ATT = "nodeType"; 155 public static final String NODE_RANK_ATT = "rank"; 156 public static final String NODE_TYPE_ROOT = "root"; 157 public static final String NODE_TYPE_INTERNAL = "internal"; 158 public static final String NODE_TYPE_LEAF = "leaf"; 159 public static final String NODE_MDOFFSET_ATT = "mdoffset"; 160 161 public static final String DOC_TYPE_SIMPLE = "simple"; 162 public static final String DOC_TYPE_PAGED = "paged"; 163 public static final String DOC_TYPE_HIERARCHY = "hierarchy"; 164 165 public static final String SESSION_EXPIRATION = "session_expiration"; 166 public static final String USER_SESSION_CACHE_ATT = "user_session_cache"; 167 168 // classifier stuff 169 public static final String CLASS_NODE_ELEM = "classifierNode"; 170 public static final String CLASS_NODE_ORIENTATION_ATT = "orientation"; 171 172 // parameter types 173 public static final String PARAM_TYPE_INTEGER = "integer"; 174 public static final String PARAM_TYPE_BOOLEAN = "boolean"; 175 public static final String PARAM_TYPE_ENUM_START = "enum"; 176 public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single"; 177 public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi"; 178 public static final String PARAM_TYPE_STRING = "string"; 179 public static final String PARAM_TYPE_TEXT = "text"; 180 public static final String PARAM_TYPE_MULTI = "multi"; 181 public static final String PARAM_TYPE_FILE = "file"; 182 public static final String PARAM_TYPE_INVISIBLE = "invisible"; 183 // stuff for text strings 184 public static final String DISPLAY_TEXT_ELEM = "displayItem"; 185 // the following are used for the name attributes 186 public static final String DISPLAY_TEXT_NAME = "name"; 187 public static final String DISPLAY_TEXT_SUBMIT = "submit"; 188 public static final String DISPLAY_TEXT_DESCRIPTION = "description"; 189 190 // request types 191 // get the module description 192 public static final String REQUEST_TYPE_DESCRIBE = "describe"; 193 // startup a process 194 public static final String REQUEST_TYPE_PROCESS = "process"; 195 // get the status of an ongoing process 196 public static final String REQUEST_TYPE_STATUS = "status"; 197 // system type request - eg reload a collection 198 public static final String REQUEST_TYPE_SYSTEM = "system"; 199 // page requests to the Receptionist/Actions 200 public static final String REQUEST_TYPE_PAGE = "page"; // used to be cgi 201 // get any format info for a service 202 public static final String REQUEST_TYPE_FORMAT = "format"; 203 // modify the requests 204 public static final String REQUEST_TYPE_MESSAGING = "messaging"; 205 // save the format string 206 public static final String REQUEST_TYPE_FORMAT_STRING = "formatString"; 207 208 // service types 209 public static final String SERVICE_TYPE_QUERY = "query"; 210 public static final String SERVICE_TYPE_RETRIEVE = "retrieve"; 211 public static final String SERVICE_TYPE_BROWSE = "browse"; 212 public static final String SERVICE_TYPE_APPLET = "applet"; 213 public static final String SERVICE_TYPE_PROCESS = "process"; 214 public static final String SERVICE_TYPE_ENRICH = "enrich"; 215 public static final String SERVICE_TYPE_OAI = "oai"; 216 public static final String FLAX_PAGE = "flaxPage"; 217 public static final String FLAX_PAGE_GENERATION = "FlaxPageGeneration"; 218 219 // system command types and attributes 220 public static final String SYSTEM_TYPE_CONFIGURE = "configure"; 221 public static final String SYSTEM_TYPE_ACTIVATE = "activate"; 222 public static final String SYSTEM_TYPE_DEACTIVATE = "deactivate"; 223 224 public static final String SYSTEM_SUBSET_ATT = "subset"; 225 public static final String SYSTEM_MODULE_TYPE_ATT = "moduleType"; 226 public static final String SYSTEM_MODULE_NAME_ATT = "moduleName"; 227 228 // communicator types 229 public static final String COMM_TYPE_SOAP_JAVA = "soap"; 230 231 // error types 232 public static final String ERROR_TYPE_SYNTAX = "syntax"; 233 public static final String ERROR_TYPE_SYSTEM = "system"; 234 public static final String ERROR_TYPE_INVALID_ID = "invalid_id"; 235 public static final String ERROR_TYPE_OTHER = "other"; 236 237 // some system wide param names 238 public static final String SUBSET_PARAM = "subset"; 239 240 //for plugin 241 public static final String PLUGIN_ELEM = "plugin"; 242 public static final String IMPORT_ELEM = "import"; 243 244 //for authentication 245 public static final String AUTHEN_NODE_ELEM="authenticationNode"; 246 public static final String USER_NODE_ELEM="userNode"; 247 248 //for configure action results 249 public static final String SUCCESS = "success"; 250 public static final String ERROR = "error"; 251 252 /** takes a list of elements, and returns an array of strings 253 * of the values of attribute att_name */ 254 public static String [] getAttributeValuesFromList(Element list, 255 String att_name) { 256 257 NodeList children = list.getChildNodes(); 258 259 int num_nodes = children.getLength(); 260 String []ids = new String[num_nodes]; 261 for (int i=0; i<num_nodes; i++) { 262 Element e = (Element)children.item(i); 263 String id = e.getAttribute(att_name); 264 ids[i] = id; 265 } 266 267 return ids; 268 } 269 270 public static HashMap extractParams(Element xml, boolean deep) { 271 return extractParams(xml, deep, null); 272 } 273 274 /** takes a paramList element, and gets a HashMap of name-value pairs 275 * if deep=true, extracts embedded params, otherwise just top level 276 * params*/ 277 public static HashMap extractParams(Element xml, boolean deep, String toFind) { 278 279 if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) { 280 logger.error("paramList element should have been passed to extractParams, instead it was "+xml.getNodeName()); 281 return null; 282 } 283 284 NodeList params = null; 285 if (deep) { // get all the nested ones 286 params = xml.getElementsByTagName(PARAM_ELEM); 287 } else { // just get the top level ones 288 params = xml.getChildNodes(); 289 } 290 HashMap param_map = new HashMap(); 291 for (int i=0; i<params.getLength(); i++) { 292 if (params.item(i).getNodeName().equals(PARAM_ELEM)) { 293 Element param = (Element)params.item(i); 294 String name=param.getAttribute(NAME_ATT); 295 String value=getValue(param); //att or content 296 297 // For only one parameter 298 if(toFind != null && name.equals(toFind)) { 299 param_map.put(name, value); 47 48 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GSXML.class.getName()); 49 50 // greenstone xml elements 51 public static final String MESSAGE_ELEM = "message"; 52 public static final String REQUEST_ELEM = "request"; 53 public static final String RESPONSE_ELEM = "response"; 54 public static final String COLLECTION_ELEM = "collection"; 55 public static final String SERVICE_ELEM = "service"; 56 public static final String CLUSTER_ELEM = "serviceCluster"; 57 public static final String SITE_ELEM = "site"; 58 public static final String PARAM_ELEM = "param"; 59 public static final String PARAM_OPTION_ELEM = "option"; 60 public static final String CONTENT_ELEM = "content"; 61 public static final String RESOURCE_ELEM = "resource"; 62 public static final String DOCUMENT_ELEM = "document"; 63 public static final String METADATA_ELEM = "metadata"; 64 public static final String SERVICE_CLASS_ELEM = "serviceRack"; 65 public static final String CLASSIFIER_ELEM = "classifier"; 66 public static final String APPLET_ELEM = "applet"; 67 public static final String APPLET_DATA_ELEM = "appletData"; 68 public static final String CONFIGURE_ELEM = "configure"; 69 public static final String STATUS_ELEM = "status"; 70 public static final String ERROR_ELEM = "error"; 71 public static final String DEFAULT_ELEM = "default"; 72 public static final String STYLESHEET_ELEM = "format";//"stylesheet"; // any additional stylesheet stuff is carried in the message inside this elem 73 public static final String FORMAT_ELEM = "format"; // config files use format - should we use this instead of stylesheet?? 74 public static final String TERM_ELEM = "term"; 75 public static final String STOPWORD_ELEM = "stopword"; 76 public static final String SYSTEM_ELEM = "system"; 77 public static final String FORMAT_STRING_ELEM = "formatString"; 78 79 //config file elems 80 public static final String COLLECTION_CONFIG_ELEM = "collectionConfig"; 81 public static final String COLLECTION_BUILD_ELEM = "buildConfig"; 82 public static final String COLLECTION_INIT_ELEM = "collectionInit"; 83 public static final String RECOGNISE_ELEM = "recognise"; 84 public static final String DOC_TYPE_ELEM = "docType"; 85 public static final String SEARCH_ELEM = "search"; 86 public static final String INFODB_ELEM = "infodb"; 87 public static final String INDEX_ELEM = "index"; 88 public static final String INDEX_STEM_ELEM = "indexStem"; 89 public static final String INDEX_OPTION_ELEM = "indexOption"; 90 public static final String BROWSE_ELEM = "browse"; 91 public static final String DISPLAY_ELEM = "display"; 92 public static final String LEVEL_ELEM = "level"; 93 94 public static final String DBINFO_ELEM = "dbInfo"; 95 public static final String DBNAME_ATT = "dbname"; 96 public static final String DBPATH_ATT = "dbpath"; 97 public static final String SQLSTATE_ATT = "sqlstate"; 98 public static final String DATABASE_TYPE_ELEM = "databaseType"; 99 public static final String SHORTNAME_ATT = "shortname"; 100 public static final String NOTIFY_ELEM = "notify"; 101 public static final String NOTIFY_HOST_ATT = "host"; 102 103 //doc.xml file elems 104 public static final String DOCXML_SECTION_ELEM = "Section"; 105 public static final String DOCXML_DESCRIPTION_ELEM = "Description"; 106 public static final String DOCXML_METADATA_ELEM = "Metadata"; 107 public static final String DOCXML_CONTENT_ELEM = "Content"; 108 109 // elems for the pages to be processed by xslt 110 public final static String PAGE_ELEM = "page"; 111 public final static String CONFIGURATION_ELEM = "config"; 112 public final static String PAGE_REQUEST_ELEM = "pageRequest"; 113 public final static String PAGE_RESPONSE_ELEM = "pageResponse"; 114 public final static String PAGE_EXTRA_ELEM = "pageExtra"; 115 116 //public final static String DESCRIPTION_ELEM = "description"; 117 118 public static final String ACTION_ELEM = "action"; 119 public static final String SUBACTION_ELEM = "subaction"; 120 121 // add on to another elem type to get a list of that type 122 public static final String LIST_MODIFIER = "List"; 123 124 // greenstone xml attributes 125 public static final String COLLECTION_ATT = "collection"; 126 public static final String NAME_ATT = "name"; 127 public static final String TO_ATT = "to"; 128 public static final String USER_ID_ATT = "uid"; 129 public static final String FROM_ATT = "from"; 130 public static final String LANG_ATT = "lang"; 131 public static final String TYPE_ATT = "type"; 132 public static final String DB_TYPE_ATT = "dbType"; 133 public static final String VALUE_ATT = "value"; 134 public static final String DEFAULT_ATT = "default"; 135 public static final String INFO_ATT = "info"; 136 public static final String ACTION_ATT = "action"; 137 public static final String SUBACTION_ATT = "subaction"; 138 public static final String OUTPUT_ATT = "output"; 139 public static final String ADDRESS_ATT = "address"; 140 public static final String LOCAL_SITE_ATT = "localSite"; 141 public static final String LOCAL_SITE_NAME_ATT = "localSiteName"; 142 public static final String STATUS_ERROR_CODE_ATT = "code"; 143 public static final String STATUS_PROCESS_ID_ATT = "pid"; 144 public static final String PARAM_SHORTNAME_ATT = "shortname"; 145 public static final String PARAM_IGNORE_POS_ATT = "ignore"; 146 public static final String CLASSIFIER_CONTENT_ATT = "content"; 147 public static final String ERROR_TYPE_ATT = "type"; 148 public static final String COLLECT_TYPE_ATT = "ct"; 149 public static final String HIDDEN_ATT = "hidden"; 150 151 // document stuff 152 public static final String DOC_TYPE_ATT = "docType"; 153 public static final String DOC_NODE_ELEM = "documentNode"; 154 public static final String NODE_CONTENT_ELEM = "nodeContent"; 155 public static final String NODE_STRUCTURE_ELEM = "nodeStructure"; 156 public static final String NODE_ID_ATT = "nodeID"; 157 public static final String NODE_NAME_ATT = "nodeName"; 158 public static final String NODE_TYPE_ATT = "nodeType"; 159 public static final String NODE_RANK_ATT = "rank"; 160 public static final String NODE_TYPE_ROOT = "root"; 161 public static final String NODE_TYPE_INTERNAL = "internal"; 162 public static final String NODE_TYPE_LEAF = "leaf"; 163 164 public static final String DOC_TYPE_SIMPLE = "simple"; 165 public static final String DOC_TYPE_PAGED = "paged"; 166 public static final String DOC_TYPE_HIERARCHY = "hierarchy"; 167 168 public static final String SESSION_EXPIRATION = "session_expiration"; 169 public static final String USER_SESSION_CACHE_ATT = "user_session_cache"; 170 171 // classifier stuff 172 public static final String CLASS_NODE_ELEM = "classifierNode"; 173 public static final String CLASS_NODE_ORIENTATION_ATT = "orientation"; 174 175 // parameter types 176 public static final String PARAM_TYPE_INTEGER = "integer"; 177 public static final String PARAM_TYPE_BOOLEAN = "boolean"; 178 public static final String PARAM_TYPE_ENUM_START = "enum"; 179 public static final String PARAM_TYPE_ENUM_SINGLE = "enum_single"; 180 public static final String PARAM_TYPE_ENUM_MULTI = "enum_multi"; 181 public static final String PARAM_TYPE_STRING = "string"; 182 public static final String PARAM_TYPE_TEXT = "text"; 183 public static final String PARAM_TYPE_MULTI = "multi"; 184 public static final String PARAM_TYPE_FILE = "file"; 185 public static final String PARAM_TYPE_INVISIBLE = "invisible"; 186 // stuff for text strings 187 public static final String DISPLAY_TEXT_ELEM = "displayItem"; 188 // the following are used for the name attributes 189 public static final String DISPLAY_TEXT_NAME = "name"; 190 public static final String DISPLAY_TEXT_SUBMIT = "submit"; 191 public static final String DISPLAY_TEXT_DESCRIPTION = "description"; 192 193 // request types 194 // get the module description 195 public static final String REQUEST_TYPE_DESCRIBE = "describe"; 196 // startup a process 197 public static final String REQUEST_TYPE_PROCESS = "process"; 198 // get the status of an ongoing process 199 public static final String REQUEST_TYPE_STATUS = "status"; 200 // system type request - eg reload a collection 201 public static final String REQUEST_TYPE_SYSTEM = "system"; 202 // page requests to the Receptionist/Actions 203 public static final String REQUEST_TYPE_PAGE = "page"; // used to be cgi 204 // get any format info for a service 205 public static final String REQUEST_TYPE_FORMAT = "format"; 206 // modify the requests 207 public static final String REQUEST_TYPE_MESSAGING = "messaging"; 208 // save the format string 209 public static final String REQUEST_TYPE_FORMAT_STRING = "formatString"; 210 211 // service types 212 public static final String SERVICE_TYPE_QUERY = "query"; 213 public static final String SERVICE_TYPE_RETRIEVE = "retrieve"; 214 public static final String SERVICE_TYPE_BROWSE = "browse"; 215 public static final String SERVICE_TYPE_APPLET = "applet"; 216 public static final String SERVICE_TYPE_PROCESS = "process"; 217 public static final String SERVICE_TYPE_ENRICH = "enrich"; 218 public static final String SERVICE_TYPE_OAI = "oai"; 219 public static final String FLAX_PAGE = "flaxPage"; 220 public static final String FLAX_PAGE_GENERATION = "FlaxPageGeneration"; 221 222 // system command types and attributes 223 public static final String SYSTEM_TYPE_CONFIGURE = "configure"; 224 public static final String SYSTEM_TYPE_ACTIVATE = "activate"; 225 public static final String SYSTEM_TYPE_DEACTIVATE = "deactivate"; 226 227 public static final String SYSTEM_SUBSET_ATT = "subset"; 228 public static final String SYSTEM_MODULE_TYPE_ATT = "moduleType"; 229 public static final String SYSTEM_MODULE_NAME_ATT = "moduleName"; 230 231 // communicator types 232 public static final String COMM_TYPE_SOAP_JAVA = "soap"; 233 234 // error types 235 public static final String ERROR_TYPE_SYNTAX = "syntax"; 236 public static final String ERROR_TYPE_SYSTEM = "system"; 237 public static final String ERROR_TYPE_INVALID_ID = "invalid_id"; 238 public static final String ERROR_TYPE_OTHER = "other"; 239 240 // some system wide param names 241 public static final String SUBSET_PARAM = "subset"; 242 243 //for plugin 244 public static final String PLUGIN_ELEM = "plugin"; 245 public static final String IMPORT_ELEM = "import"; 246 247 //for authentication 248 public static final String AUTHEN_NODE_ELEM="authenticationNode"; 249 public static final String USER_NODE_ELEM="userNode"; 250 251 //for configure action results 252 public static final String SUCCESS = "success"; 253 public static final String ERROR = "error"; 254 255 /** takes a list of elements, and returns an array of strings 256 * of the values of attribute att_name */ 257 public static String [] getAttributeValuesFromList(Element list, 258 String att_name) { 259 260 NodeList children = list.getChildNodes(); 261 262 int num_nodes = children.getLength(); 263 String []ids = new String[num_nodes]; 264 for (int i=0; i<num_nodes; i++) { 265 Element e = (Element)children.item(i); 266 String id = e.getAttribute(att_name); 267 ids[i] = id; 268 } 269 270 return ids; 271 } 272 273 public static HashMap extractParams(Element xml, boolean deep) { 274 return extractParams(xml, deep, null); 275 } 276 277 /** takes a paramList element, and gets a HashMap of name-value pairs 278 * if deep=true, extracts embedded params, otherwise just top level 279 * params*/ 280 public static HashMap extractParams(Element xml, boolean deep, String toFind) { 281 282 if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) { 283 logger.error("paramList element should have been passed to extractParams, instead it was "+xml.getNodeName()); 284 return null; 285 } 286 287 NodeList params = null; 288 if (deep) { // get all the nested ones 289 params = xml.getElementsByTagName(PARAM_ELEM); 290 } else { // just get the top level ones 291 params = xml.getChildNodes(); 292 } 293 HashMap param_map = new HashMap(); 294 for (int i=0; i<params.getLength(); i++) { 295 if (params.item(i).getNodeName().equals(PARAM_ELEM)) { 296 Element param = (Element)params.item(i); 297 String name=param.getAttribute(NAME_ATT); 298 String value=getValue(param); //att or content 299 300 // For only one parameter 301 if(toFind != null && name.equals(toFind)) { 302 param_map.put(name, value); 303 return param_map; 304 } 305 else if(toFind != null) 306 continue; 307 308 int pos = name.indexOf('.'); 309 if (pos == -1) { // a base param 310 param_map.put(name, value); 311 } else { // a namespaced param 312 313 String namespace = name.substring(0, pos); 314 name = name.substring(pos+1); 315 HashMap map = (HashMap)param_map.get(namespace); 316 if (map == null) { 317 map = new HashMap(); 318 param_map.put(namespace, map); 319 } 320 map.put(name, value); 321 } 322 } 323 } 300 324 return param_map; 301 } 302 else if(toFind != null) 303 continue; 304 305 int pos = name.indexOf('.'); 306 if (pos == -1) { // a base param 307 param_map.put(name, value); 308 } else { // a namespaced param 309 310 String namespace = name.substring(0, pos); 311 name = name.substring(pos+1); 312 HashMap map = (HashMap)param_map.get(namespace); 313 if (map == null) { 314 map = new HashMap(); 315 param_map.put(namespace, map); 316 } 317 map.put(name, value); 318 } 319 } 320 } 321 return param_map; 322 } 323 324 /** gets the value att or the text content */ 325 public static String getValue(Element e) { 326 String val = e.getAttribute(VALUE_ATT); 327 if (val ==null || val.equals("")) { 328 // have to get it out of the text 329 val=getNodeText(e); 330 331 } else { 332 // unescape the xml stuff 333 val = unXmlSafe(val); 334 } 335 return val; 336 } 337 338 /** extracts the text out of a node */ 339 public static Node getNodeTextNode(Element param) { 340 param.normalize(); 341 Node n = param.getFirstChild(); 342 while (n!=null && n.getNodeType() !=Node.TEXT_NODE) { 343 n=n.getNextSibling(); 344 } 345 return n; 346 } 347 348 /** extracts the text out of a node */ 349 public static String getNodeText(Element param) { 350 Node text_node = getNodeTextNode(param); 351 if (text_node == null) { 352 return ""; 353 } 354 return text_node.getNodeValue(); 355 } 356 357 public static void setNodeText(Element elem, String text) { 358 Node old_text_node = getNodeTextNode(elem); 359 if (old_text_node != null) { 360 elem.removeChild(old_text_node); 361 } 362 Text t = elem.getOwnerDocument().createTextNode(text); 363 elem.appendChild(t); 364 } 365 366 /** add text to a document/subsection element */ 367 public static boolean addDocText(Document owner, Element doc, String text) { 368 369 Element content = owner.createElement(NODE_CONTENT_ELEM); 370 Text t = owner.createTextNode(text); 371 content.appendChild(t); 372 doc.appendChild(content); 373 return true; 374 } 375 376 /** add an error message, unknown error type */ 377 public static boolean addError(Document owner, Element doc, String text) { 378 return addError(owner, doc, text, ERROR_TYPE_OTHER); 379 } 380 /** add an error message */ 381 public static boolean addError(Document owner, Element doc, String text, 382 String error_type) { 383 384 Element content = owner.createElement(ERROR_ELEM); 385 content.setAttribute(ERROR_TYPE_ATT, error_type); 386 Text t = owner.createTextNode(text); 387 content.appendChild(t); 388 doc.appendChild(content); 389 return true; 390 } 391 392 /** add an error message */ 393 public static boolean addError(Document owner, Element doc, Throwable error) { 394 return addError(owner, doc, error, ERROR_TYPE_OTHER); 395 } 396 397 /** add an error message */ 398 public static boolean addError(Document owner, Element doc, 399 Throwable error, String error_type) { 400 error.printStackTrace(); 401 return addError(owner, doc, error.toString(), error_type); 402 } 403 404 public static Element createMetadataParamList(Document owner, Vector meta_values) { 405 406 Element meta_param_list = owner.createElement(PARAM_ELEM+LIST_MODIFIER); 407 Iterator i = meta_values.iterator(); 408 while(i.hasNext()) { 409 String next = (String)i.next(); 410 Element meta_param = owner.createElement(PARAM_ELEM); 411 meta_param_list.appendChild(meta_param); 412 meta_param.setAttribute(NAME_ATT, "metadata"); 413 meta_param.setAttribute(VALUE_ATT, next); 414 } 415 return meta_param_list; 416 } 417 418 /** adds a metadata elem to a list */ 419 public static boolean addMetadata(Document owner, Element list, 420 String meta_name, String meta_value) { 421 if (meta_value==null || meta_value.equals("")) { 422 return false; 423 } 424 Element data = owner.createElement(METADATA_ELEM); 425 data.setAttribute(NAME_ATT, meta_name); 426 Text t = owner.createTextNode(meta_value); 427 data.appendChild(t); 428 list.appendChild(data); 429 return true; 430 431 } 432 433 /** copies the metadata out of the metadataList of 'from' into 434 * the metadataList of 'to' */ 435 public static boolean mergeMetadataLists(Node to, Node from) { 436 Node from_meta = getChildByTagName(from, METADATA_ELEM+LIST_MODIFIER); 437 if (from_meta == null) { // nothing to copy 438 return true; 439 } 440 return mergeMetadataFromList(to, from_meta); 441 } 442 443 444 /** copies the metadata out of the meta_list metadataList into 445 * the metadataList of 'to' */ 446 public static boolean mergeMetadataFromList(Node to, Node meta_list) { 447 if (meta_list == null) return false; 448 Node to_meta = getChildByTagName(to, METADATA_ELEM+LIST_MODIFIER); 449 Document to_owner = to.getOwnerDocument(); 450 if (to_meta == null) { 451 to.appendChild(to_owner.importNode(meta_list, true)); 452 return true; 453 } 454 // copy individual metadata elements 455 NodeList meta_items = ((Element)meta_list).getElementsByTagName(METADATA_ELEM); 456 for (int i=0; i<meta_items.getLength(); i++) { 457 to_meta.appendChild(to_owner.importNode(meta_items.item(i),true)); 458 } 459 return true; 460 } 461 462 /** copies all the children from from to to */ 463 public static boolean mergeElements(Element to, Element from) { 464 465 Document owner = to.getOwnerDocument(); 466 Node child = from.getFirstChild(); 467 while (child != null) { 468 to.appendChild(owner.importNode(child, true)); 469 child = child.getNextSibling(); 470 } 471 return true; 472 } 473 /** returns the (first) element child of the node n */ 474 public static Element getFirstElementChild(Node n) { 475 476 Node child = n.getFirstChild(); 477 while (child!=null) { 478 if (child.getNodeType() == Node.ELEMENT_NODE) { 479 return (Element)child; 480 } 481 child = child.getNextSibling(); 482 } 483 return null; //no element child found 484 } 485 /** returns the (first) child element with the given name */ 486 public static Node getChildByTagName(Node n, String name) { 487 if(n != null) { // this line is an attempted solution to the NullPointerException mentioned 488 // in trac bug ticket #225. If n is null can't do n.getFirstChild() below. As per bug #225: 489 // GSXML.getNodeByPath() is called by GS2BrowseAction, which then calls this method. 490 // If n is null, null will be returned which GS2BrowseAction already checks for. It's here 491 // that the NullPointerException was thrown. 492 493 Node child = n.getFirstChild(); 494 while (child!=null) { 495 if (child.getNodeName().equals(name)) { 496 return child; 497 } 498 child = child.getNextSibling(); 499 } 500 } 501 return null; //not found 502 } 503 504 /** returns the (nth) child element with the given name 505 * index numbers start at 0 */ 506 public static Node getChildByTagNameIndexed(Node n, String name, int index) { 507 if (index == -1) { 508 return getChildByTagName(n, name); 509 } 510 int count = 0; 511 Node child = n.getFirstChild(); 512 while (child!=null) { 513 if (child.getNodeName().equals(name)) { 514 if (count == index) { 515 return child; 516 } else { 517 count++; 518 } 519 } 520 child = child.getNextSibling(); 521 } 522 return null; //not found 523 } 524 525 /** takes an xpath type expression of the form name/name/... 526 * and returns the first node that matches, or null if not found */ 527 public static Node getNodeByPath(Node n, String path) { 528 529 String link = GSPath.getFirstLink(path); 530 path = GSPath.removeFirstLink(path); 531 while (!link.equals("")) { 532 n = getChildByTagName(n, link); 533 if (n==null) { 534 return null; 535 } 536 link = GSPath.getFirstLink(path); 537 path = GSPath.removeFirstLink(path); 538 } 539 return n; 540 } 541 542 /** takes an xpath type expression of the form name/name/... 543 * and returns the first node that matches, or null if not found 544 * can include [i] indices. index numbers start at 0 */ 545 public static Node getNodeByPathIndexed(Node n, String path) { 546 547 String link = GSPath.getFirstLink(path); 548 int index = GSPath.getIndex(link); 549 if (index != -1) { 550 link = GSPath.removeIndex(link); 551 } 552 path = GSPath.removeFirstLink(path); 553 while (!link.equals("")) { 554 n = getChildByTagNameIndexed(n, link, index); 555 if (n==null) { 556 return null; 557 } 558 link = GSPath.getFirstLink(path); 559 index = GSPath.getIndex(link); 560 if (index != -1) { 561 link = GSPath.removeIndex(link); 562 } 563 path = GSPath.removeFirstLink(path); 564 } 565 return n; 566 } 567 568 public static HashMap getChildrenMap(Node n) { 569 570 HashMap map= new HashMap(); 571 Node child = n.getFirstChild(); 572 while (child!=null) { 573 String name = child.getNodeName(); 574 map.put(name, child); 575 child = child.getNextSibling(); 576 } 577 return map; 578 } 579 580 public static NodeList getChildrenByTagName(Node n, String name) { 581 MyNodeList node_list = new MyNodeList(); 582 Node child = n.getFirstChild(); 583 while (child!=null) { 584 if (child.getNodeName().equals(name)) { 585 node_list.addNode(child); 586 } 587 child = child.getNextSibling(); 588 } 589 return node_list; 590 } 591 592 593 /** Duplicates an element, but gives it a new name */ 594 public static Element duplicateWithNewName(Document owner, Element element, 595 String element_name, boolean with_attributes) { 596 return duplicateWithNewNameNS(owner, element, element_name, null, with_attributes); 597 } 598 599 /** Duplicates an element, but gives it a new name */ 600 public static Element duplicateWithNewNameNS(Document owner, 601 Element element, 602 String element_name, 603 String namespace_uri, 604 boolean with_attributes) { 605 Element duplicate; 606 if (namespace_uri == null) { 607 duplicate = owner.createElement(element_name); 608 } else { 609 duplicate = owner.createElementNS(namespace_uri, element_name); 610 } 611 // Copy element attributes 612 if (with_attributes) { 613 NamedNodeMap attributes = element.getAttributes(); 614 for (int i = 0; i < attributes.getLength(); i++) { 615 Node attribute = attributes.item(i); 616 duplicate.setAttribute(attribute.getNodeName(), attribute.getNodeValue()); 617 } 618 } 619 620 // Copy element children 621 NodeList children = element.getChildNodes(); 622 for (int i = 0; i < children.getLength(); i++) { 623 Node child = children.item(i); 624 duplicate.appendChild(owner.importNode(child, true)); 625 } 626 627 return duplicate; 628 } 629 630 public static void copyAllChildren(Element to, Element from) { 631 632 Document to_doc = to.getOwnerDocument(); 633 Node child = from.getFirstChild(); 634 while (child != null) { 635 to.appendChild(to_doc.importNode(child, true)); 636 child = child.getNextSibling(); 637 } 638 } 639 /** returns a basic request message */ 640 public static Element createBasicRequest(Document owner, 641 String request_type, String to, 642 String lang, 643 String uid) { 644 Element request = owner.createElement(REQUEST_ELEM); 645 request.setAttribute(TYPE_ATT, request_type); 646 request.setAttribute(LANG_ATT, lang); 647 request.setAttribute(TO_ATT, to); 648 request.setAttribute(USER_ID_ATT, uid); 649 return request; 650 } 651 652 public static Element createTextElement(Document owner, String elem_name, 653 String text) { 654 Element e = owner.createElement(elem_name); 655 Text t = owner.createTextNode(text); 656 e.appendChild(t); 657 return e; 658 659 } 660 661 public static Element createTextElement(Document owner, String elem_name, 662 String text, String att_name, String att_value) { 663 Element e = owner.createElement(elem_name); 664 e.setAttribute(att_name, att_value); 665 Text t = owner.createTextNode(text); 666 e.appendChild(t); 667 return e; 668 669 } 670 671 public static Element createDisplayTextElement(Document owner, 672 String text_name, 673 String text) { 674 Element e = owner.createElement(DISPLAY_TEXT_ELEM); 675 e.setAttribute(NAME_ATT, text_name); 676 Text t = owner.createTextNode(text); 677 e.appendChild(t); 678 return e; 679 680 } 681 682 683 public static Element createParameter(Document owner, String name, 684 String value) { 685 Element param = owner.createElement(PARAM_ELEM); 686 param.setAttribute(NAME_ATT, name); 687 param.setAttribute(VALUE_ATT, value); 688 return param; 689 } 690 691 public static void addParametersToList(Document owner, Element param_list, 692 HashMap params) { 693 if (params == null) 325 } 326 327 /** gets the value att or the text content */ 328 public static String getValue(Element e) { 329 String val = e.getAttribute(VALUE_ATT); 330 if (val ==null || val.equals("")) { 331 // have to get it out of the text 332 val=getNodeText(e); 333 334 } else { 335 // unescape the xml stuff 336 val = unXmlSafe(val); 337 } 338 return val; 339 } 340 341 /** extracts the text out of a node */ 342 public static Node getNodeTextNode(Element param) { 343 param.normalize(); 344 Node n = param.getFirstChild(); 345 while (n!=null && n.getNodeType() !=Node.TEXT_NODE) { 346 n=n.getNextSibling(); 347 } 348 return n; 349 } 350 351 /** extracts the text out of a node */ 352 public static String getNodeText(Element param) { 353 Node text_node = getNodeTextNode(param); 354 if (text_node == null) { 355 return ""; 356 } 357 return text_node.getNodeValue(); 358 } 359 360 public static void setNodeText(Element elem, String text) { 361 Node old_text_node = getNodeTextNode(elem); 362 if (old_text_node != null) { 363 elem.removeChild(old_text_node); 364 } 365 Text t = elem.getOwnerDocument().createTextNode(text); 366 elem.appendChild(t); 367 } 368 369 /** add text to a document/subsection element */ 370 public static boolean addDocText(Document owner, Element doc, String text) { 371 372 Element content = owner.createElement(NODE_CONTENT_ELEM); 373 Text t = owner.createTextNode(text); 374 content.appendChild(t); 375 doc.appendChild(content); 376 return true; 377 } 378 379 /** add an error message, unknown error type */ 380 public static boolean addError(Document owner, Element doc, String text) { 381 return addError(owner, doc, text, ERROR_TYPE_OTHER); 382 } 383 /** add an error message */ 384 public static boolean addError(Document owner, Element doc, String text, 385 String error_type) { 386 387 Element content = owner.createElement(ERROR_ELEM); 388 content.setAttribute(ERROR_TYPE_ATT, error_type); 389 Text t = owner.createTextNode(text); 390 content.appendChild(t); 391 doc.appendChild(content); 392 return true; 393 } 394 395 /** add an error message */ 396 public static boolean addError(Document owner, Element doc, Throwable error) { 397 return addError(owner, doc, error, ERROR_TYPE_OTHER); 398 } 399 400 /** add an error message */ 401 public static boolean addError(Document owner, Element doc, 402 Throwable error, String error_type) { 403 error.printStackTrace(); 404 return addError(owner, doc, error.toString(), error_type); 405 } 406 407 public static Element createMetadataParamList(Document owner, Vector meta_values) { 408 409 Element meta_param_list = owner.createElement(PARAM_ELEM+LIST_MODIFIER); 410 Iterator i = meta_values.iterator(); 411 while(i.hasNext()) { 412 String next = (String)i.next(); 413 Element meta_param = owner.createElement(PARAM_ELEM); 414 meta_param_list.appendChild(meta_param); 415 meta_param.setAttribute(NAME_ATT, "metadata"); 416 meta_param.setAttribute(VALUE_ATT, next); 417 } 418 return meta_param_list; 419 } 420 421 /** adds a metadata elem to a list */ 422 public static boolean addMetadata(Document owner, Element list, 423 String meta_name, String meta_value) { 424 if (meta_value==null || meta_value.equals("")) { 425 return false; 426 } 427 Element data = owner.createElement(METADATA_ELEM); 428 data.setAttribute(NAME_ATT, meta_name); 429 Text t = owner.createTextNode(meta_value); 430 data.appendChild(t); 431 list.appendChild(data); 432 return true; 433 434 } 435 436 /** copies the metadata out of the metadataList of 'from' into 437 * the metadataList of 'to' */ 438 public static boolean mergeMetadataLists(Node to, Node from) { 439 Node from_meta = getChildByTagName(from, METADATA_ELEM+LIST_MODIFIER); 440 if (from_meta == null) { // nothing to copy 441 return true; 442 } 443 return mergeMetadataFromList(to, from_meta); 444 } 445 446 447 /** copies the metadata out of the meta_list metadataList into 448 * the metadataList of 'to' */ 449 public static boolean mergeMetadataFromList(Node to, Node meta_list) { 450 if (meta_list == null) return false; 451 Node to_meta = getChildByTagName(to, METADATA_ELEM+LIST_MODIFIER); 452 Document to_owner = to.getOwnerDocument(); 453 if (to_meta == null) { 454 to.appendChild(to_owner.importNode(meta_list, true)); 455 return true; 456 } 457 // copy individual metadata elements 458 NodeList meta_items = ((Element)meta_list).getElementsByTagName(METADATA_ELEM); 459 for (int i=0; i<meta_items.getLength(); i++) { 460 to_meta.appendChild(to_owner.importNode(meta_items.item(i),true)); 461 } 462 return true; 463 } 464 465 /** copies all the children from from to to */ 466 public static boolean mergeElements(Element to, Element from) { 467 468 Document owner = to.getOwnerDocument(); 469 Node child = from.getFirstChild(); 470 while (child != null) { 471 to.appendChild(owner.importNode(child, true)); 472 child = child.getNextSibling(); 473 } 474 return true; 475 } 476 /** returns the (first) element child of the node n */ 477 public static Element getFirstElementChild(Node n) { 478 479 Node child = n.getFirstChild(); 480 while (child!=null) { 481 if (child.getNodeType() == Node.ELEMENT_NODE) { 482 return (Element)child; 483 } 484 child = child.getNextSibling(); 485 } 486 return null; //no element child found 487 } 488 /** returns the (first) child element with the given name */ 489 public static Node getChildByTagName(Node n, String name) { 490 if(n != null) { // this line is an attempted solution to the NullPointerException mentioned 491 // in trac bug ticket #225. If n is null can't do n.getFirstChild() below. As per bug #225: 492 // GSXML.getNodeByPath() is called by GS2BrowseAction, which then calls this method. 493 // If n is null, null will be returned which GS2BrowseAction already checks for. It's here 494 // that the NullPointerException was thrown. 495 496 Node child = n.getFirstChild(); 497 while (child!=null) { 498 if (child.getNodeName().equals(name)) { 499 return child; 500 } 501 child = child.getNextSibling(); 502 } 503 } 504 return null; //not found 505 } 506 507 /** returns the (nth) child element with the given name 508 * index numbers start at 0 */ 509 public static Node getChildByTagNameIndexed(Node n, String name, int index) { 510 if (index == -1) { 511 return getChildByTagName(n, name); 512 } 513 int count = 0; 514 Node child = n.getFirstChild(); 515 while (child!=null) { 516 if (child.getNodeName().equals(name)) { 517 if (count == index) { 518 return child; 519 } else { 520 count++; 521 } 522 } 523 child = child.getNextSibling(); 524 } 525 return null; //not found 526 } 527 528 /** takes an xpath type expression of the form name/name/... 529 * and returns the first node that matches, or null if not found */ 530 public static Node getNodeByPath(Node n, String path) { 531 532 String link = GSPath.getFirstLink(path); 533 path = GSPath.removeFirstLink(path); 534 while (!link.equals("")) { 535 n = getChildByTagName(n, link); 536 if (n==null) { 537 return null; 538 } 539 link = GSPath.getFirstLink(path); 540 path = GSPath.removeFirstLink(path); 541 } 542 return n; 543 } 544 545 /** takes an xpath type expression of the form name/name/... 546 * and returns the first node that matches, or null if not found 547 * can include [i] indices. index numbers start at 0 */ 548 public static Node getNodeByPathIndexed(Node n, String path) { 549 550 String link = GSPath.getFirstLink(path); 551 int index = GSPath.getIndex(link); 552 if (index != -1) { 553 link = GSPath.removeIndex(link); 554 } 555 path = GSPath.removeFirstLink(path); 556 while (!link.equals("")) { 557 n = getChildByTagNameIndexed(n, link, index); 558 if (n==null) { 559 return null; 560 } 561 link = GSPath.getFirstLink(path); 562 index = GSPath.getIndex(link); 563 if (index != -1) { 564 link = GSPath.removeIndex(link); 565 } 566 path = GSPath.removeFirstLink(path); 567 } 568 return n; 569 } 570 571 public static HashMap getChildrenMap(Node n) { 572 573 HashMap map= new HashMap(); 574 Node child = n.getFirstChild(); 575 while (child!=null) { 576 String name = child.getNodeName(); 577 map.put(name, child); 578 child = child.getNextSibling(); 579 } 580 return map; 581 } 582 583 public static NodeList getChildrenByTagName(Node n, String name) { 584 MyNodeList node_list = new MyNodeList(); 585 Node child = n.getFirstChild(); 586 while (child!=null) { 587 if (child.getNodeName().equals(name)) { 588 node_list.addNode(child); 589 } 590 child = child.getNextSibling(); 591 } 592 return node_list; 593 } 594 595 596 /** Duplicates an element, but gives it a new name */ 597 public static Element duplicateWithNewName(Document owner, Element element, 598 String element_name, boolean with_attributes) { 599 return duplicateWithNewNameNS(owner, element, element_name, null, with_attributes); 600 } 601 602 /** Duplicates an element, but gives it a new name */ 603 public static Element duplicateWithNewNameNS(Document owner, 604 Element element, 605 String element_name, 606 String namespace_uri, 607 boolean with_attributes) { 608 Element duplicate; 609 if (namespace_uri == null) { 610 duplicate = owner.createElement(element_name); 611 } else { 612 duplicate = owner.createElementNS(namespace_uri, element_name); 613 } 614 // Copy element attributes 615 if (with_attributes) { 616 NamedNodeMap attributes = element.getAttributes(); 617 for (int i = 0; i < attributes.getLength(); i++) { 618 Node attribute = attributes.item(i); 619 duplicate.setAttribute(attribute.getNodeName(), attribute.getNodeValue()); 620 } 621 } 622 623 // Copy element children 624 NodeList children = element.getChildNodes(); 625 for (int i = 0; i < children.getLength(); i++) { 626 Node child = children.item(i); 627 duplicate.appendChild(owner.importNode(child, true)); 628 } 629 630 return duplicate; 631 } 632 633 public static void copyAllChildren(Element to, Element from) { 634 635 Document to_doc = to.getOwnerDocument(); 636 Node child = from.getFirstChild(); 637 while (child != null) { 638 to.appendChild(to_doc.importNode(child, true)); 639 child = child.getNextSibling(); 640 } 641 } 642 /** returns a basic request message */ 643 public static Element createBasicRequest(Document owner, 644 String request_type, String to, 645 String lang, 646 String uid) { 647 Element request = owner.createElement(REQUEST_ELEM); 648 request.setAttribute(TYPE_ATT, request_type); 649 request.setAttribute(LANG_ATT, lang); 650 request.setAttribute(TO_ATT, to); 651 request.setAttribute(USER_ID_ATT, uid); 652 return request; 653 } 654 655 public static Element createBasicResponse(Document owner, String from) 694 656 { 695 return; 657 Element response = owner.createElement(GSXML.RESPONSE_ELEM); 658 response.setAttribute(GSXML.FROM_ATT, from); 659 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS); 660 return response; 696 661 } 697 662 698 Set items = params.entrySet(); 699 Iterator i = items.iterator(); 700 while(i.hasNext()) { 701 Map.Entry m = (Map.Entry)i.next(); 702 param_list.appendChild(createParameter(owner, (String)m.getKey(), (String)m.getValue())); 703 } 704 705 } 706 707 public static Element createParameterDescription(Document owner, 708 String id, 709 String display_name, 710 String type, 711 String default_value, 712 String []option_ids, 713 String []option_names) { 714 715 716 Element p = owner.createElement(PARAM_ELEM); 717 p.setAttribute(NAME_ATT, id); 718 p.setAttribute(TYPE_ATT, type); 719 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name)); 720 721 if (default_value != null) { 722 p.setAttribute(DEFAULT_ATT, default_value); 723 } 724 if (option_ids!=null && option_names!=null) { 725 for (int i=0; i<option_ids.length; i++) { 726 Element e = owner.createElement(PARAM_OPTION_ELEM); 727 e.setAttribute(NAME_ATT, option_ids[i]); 728 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, option_names[i])); 729 p.appendChild(e); 730 } 731 } 732 return p; 733 } 734 public static Element createParameterDescription2(Document owner, 735 String id, 736 String display_name, 737 String type, 738 String default_value, 739 ArrayList option_ids, 740 ArrayList option_names) { 741 742 743 Element p = owner.createElement(PARAM_ELEM); 744 p.setAttribute(NAME_ATT, id); 745 p.setAttribute(TYPE_ATT, type); 746 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name)); 747 if (default_value != null) { 748 p.setAttribute(DEFAULT_ATT, default_value); 749 } 750 if (option_ids!=null && option_names!=null) { 751 for (int i=0; i<option_ids.size(); i++) { 752 Element e = owner.createElement(PARAM_OPTION_ELEM); 753 e.setAttribute(NAME_ATT, (String)option_ids.get(i)); 754 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, (String)option_names.get(i))); 755 p.appendChild(e); 756 } 757 } 758 return p; 759 } 760 761 762 /** returns the element parent/node_name[@attribute_name='attribute_value'] 763 */ 764 public static Element getNamedElement(Element parent, String node_name, 765 String attribute_name, 766 String attribute_value) { 767 768 NodeList children = parent.getChildNodes(); 769 for (int i=0; i<children.getLength(); i++) { 770 Node child = children.item(i); 771 if (child.getNodeName().equals(node_name)) { 772 if (((Element)child).getAttribute(attribute_name).equals(attribute_value)) 773 return (Element)child; 774 } 775 } 776 // not found 777 return null; 778 } 779 /** returns a NodeList of elements: ancestor/node_name[@attribute_name='attribute_value'] 780 */ 781 public static NodeList getNamedElements(Element ancestor, String node_name, String attribute_name, String attribute_value) { 782 MyNodeList node_list = new MyNodeList(); 783 NodeList children = ancestor.getElementsByTagName(node_name); 784 663 public static Element createMetadataElement(Document owner, String name, String value) 664 { 665 Element metaElem = owner.createElement(GSXML.METADATA_ELEM); 666 metaElem.setAttribute(GSXML.NAME_ATT, name); 667 metaElem.setAttribute(GSXML.VALUE_ATT, value); 668 return metaElem; 669 } 670 671 public static Element createTextElement(Document owner, String elem_name, 672 String text) { 673 Element e = owner.createElement(elem_name); 674 Text t = owner.createTextNode(text); 675 e.appendChild(t); 676 return e; 677 678 } 679 680 public static Element createTextElement(Document owner, String elem_name, 681 String text, String att_name, String att_value) { 682 Element e = owner.createElement(elem_name); 683 e.setAttribute(att_name, att_value); 684 Text t = owner.createTextNode(text); 685 e.appendChild(t); 686 return e; 687 688 } 689 690 public static Element createDisplayTextElement(Document owner, 691 String text_name, 692 String text) { 693 Element e = owner.createElement(DISPLAY_TEXT_ELEM); 694 e.setAttribute(NAME_ATT, text_name); 695 Text t = owner.createTextNode(text); 696 e.appendChild(t); 697 return e; 698 699 } 700 701 702 public static Element createParameter(Document owner, String name, 703 String value) { 704 Element param = owner.createElement(PARAM_ELEM); 705 param.setAttribute(NAME_ATT, name); 706 param.setAttribute(VALUE_ATT, value); 707 return param; 708 } 709 710 public static void addParametersToList(Document owner, Element param_list, 711 HashMap params) { 712 if (params == null) 713 { 714 return; 715 } 716 717 Set items = params.entrySet(); 718 Iterator i = items.iterator(); 719 while(i.hasNext()) { 720 Map.Entry m = (Map.Entry)i.next(); 721 param_list.appendChild(createParameter(owner, (String)m.getKey(), (String)m.getValue())); 722 } 723 724 } 725 726 public static Element createParameterDescription(Document owner, 727 String id, 728 String display_name, 729 String type, 730 String default_value, 731 String []option_ids, 732 String []option_names) { 733 734 735 Element p = owner.createElement(PARAM_ELEM); 736 p.setAttribute(NAME_ATT, id); 737 p.setAttribute(TYPE_ATT, type); 738 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name)); 739 740 if (default_value != null) { 741 p.setAttribute(DEFAULT_ATT, default_value); 742 } 743 if (option_ids!=null && option_names!=null) { 744 for (int i=0; i<option_ids.length; i++) { 745 Element e = owner.createElement(PARAM_OPTION_ELEM); 746 e.setAttribute(NAME_ATT, option_ids[i]); 747 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, option_names[i])); 748 p.appendChild(e); 749 } 750 } 751 return p; 752 } 753 public static Element createParameterDescription2(Document owner, 754 String id, 755 String display_name, 756 String type, 757 String default_value, 758 ArrayList option_ids, 759 ArrayList option_names) { 760 761 762 Element p = owner.createElement(PARAM_ELEM); 763 p.setAttribute(NAME_ATT, id); 764 p.setAttribute(TYPE_ATT, type); 765 p.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, display_name)); 766 if (default_value != null) { 767 p.setAttribute(DEFAULT_ATT, default_value); 768 } 769 if (option_ids!=null && option_names!=null) { 770 for (int i=0; i<option_ids.size(); i++) { 771 Element e = owner.createElement(PARAM_OPTION_ELEM); 772 e.setAttribute(NAME_ATT, (String)option_ids.get(i)); 773 e.appendChild(createDisplayTextElement(owner, GSXML.DISPLAY_TEXT_NAME, (String)option_names.get(i))); 774 p.appendChild(e); 775 } 776 } 777 return p; 778 } 779 780 781 /** returns the element parent/node_name[@attribute_name='attribute_value'] 782 */ 783 public static Element getNamedElement(Element parent, String node_name, 784 String attribute_name, 785 String attribute_value) { 786 787 NodeList children = parent.getChildNodes(); 788 for (int i=0; i<children.getLength(); i++) { 789 Node child = children.item(i); 790 if (child.getNodeName().equals(node_name)) { 791 if (((Element)child).getAttribute(attribute_name).equals(attribute_value)) 792 return (Element)child; 793 } 794 } 795 // not found 796 return null; 797 } 798 /** returns a NodeList of elements: ancestor/node_name[@attribute_name='attribute_value'] 799 */ 800 public static NodeList getNamedElements(Element ancestor, String node_name, String attribute_name, String attribute_value) { 801 MyNodeList node_list = new MyNodeList(); 802 NodeList children = ancestor.getElementsByTagName(node_name); 803 785 804 if(children != null && children.getLength() > 0) { 786 805 … … 789 808 if (child.getNodeName().equals(node_name)) { 790 809 if (((Element)child).getAttribute(attribute_name).equals(attribute_value)) 791 810 node_list.addNode(child); 792 811 } 793 812 } 794 } 795 return node_list; 796 } 797 798 public static int SORT_TYPE_STRING = 0; 799 public static int SORT_TYPE_INT = 1; 800 public static int SORT_TYPE_FLOAT = 2; 801 802 // sort type: 803 public static Element insertIntoOrderedList(Element parent_node, 804 String node_name, 805 Element start_from_elem, 806 Element new_elem, String sort_att, 807 boolean descending) { 808 if (new_elem == null) return null; 809 Element cloned_elem = (Element)parent_node.getOwnerDocument().importNode(new_elem, true); 810 if (start_from_elem == null) { 811 parent_node.appendChild(cloned_elem); 812 return cloned_elem; 813 } 814 815 Node current_node = start_from_elem; 816 String insert_att = cloned_elem.getAttribute(sort_att); 817 String list_att = start_from_elem.getAttribute(sort_att); 818 while ((!descending && list_att.compareTo(insert_att)<0) || (descending && list_att.compareTo(insert_att)>0)) { 819 current_node = current_node.getNextSibling(); 820 if (current_node == null) break; // end of the list 821 if (!current_node.getNodeName().equals(node_name)) { 822 continue; // not a valid node 823 } 824 list_att = ((Element)current_node).getAttribute(sort_att); 825 } 826 827 parent_node.insertBefore(cloned_elem, current_node); 828 return cloned_elem; 829 } 830 831 832 /** Returns the appropriate language element from a display elem, 833 * display is the containing element, name is the name of the element to 834 * look for, lang is the preferred language, lang_default is the fall back 835 * lang if neither lang is found, will return the first one it finds*/ 836 public static String getDisplayText(Element display, String name, 837 String lang, String lang_default) { 838 839 String def = null; 840 String first = null; 841 NodeList elems = display.getElementsByTagName(DISPLAY_TEXT_ELEM); 842 if (elems.getLength() == 0) return ""; 843 for (int i=0; i<elems.getLength(); i++) { 844 Element e = (Element)elems.item(i); 845 String n = e.getAttribute(NAME_ATT); 846 if (name.equals(n)) { 847 String l = e.getAttribute(LANG_ATT); 848 if (lang.equals(l)) { 849 return getNodeText(e); 850 } else if (lang_default.equals(l)) { 851 def = getNodeText(e); 852 } else if (first == null) { 853 first = getNodeText(e); 854 } 855 } else { 856 continue; 857 } 858 } 859 860 if (def != null) { 861 return def; 862 } 863 if (first != null) { 864 return first; 865 } 866 return ""; 867 } 868 869 // replaces < > " ' & in the original with their entities 870 public static String xmlSafe(String original) { 871 872 StringBuffer filtered = new StringBuffer(original.length()); 873 char c; 874 for (int i=0; i<original.length(); i++) { 875 c = original.charAt(i); 876 if (c == '>') { 877 filtered.append(">"); 878 } else if (c == '<') { 879 filtered.append("<"); 880 } else if (c == '"') { 881 filtered.append("""); 882 } else if (c == '&') { 883 filtered.append("&"); 884 } else if (c == '\'') { 885 filtered.append("'"); 886 } else { 887 filtered.append(c); 888 } 889 } 890 return filtered.toString(); 891 } 892 893 894 // replaces < > " ' & entities with their originals 895 public static String unXmlSafe(String original) { 896 897 StringBuffer filtered = new StringBuffer(original.length()); 898 char c; 899 for (int i=0; i<original.length(); i++) { 900 c = original.charAt(i); 901 if (c == '&') { 902 int pos = original.indexOf(";", i); 903 String entity = original.substring(i+1, pos); 904 if (entity.equals("gt")) { 905 filtered.append(">"); 906 } else if (entity.equals("lt")) { 907 filtered.append("<"); 908 } else if (entity.equals("apos")) { 909 filtered.append("'"); 910 } else if (entity.equals("amp")) { 911 filtered.append("&"); 912 } else if (entity.equals("quot")) { 913 filtered.append("\""); 914 } else { 915 filtered.append("&"+entity+";"); 916 } 917 i = pos; 918 } else { 919 filtered.append(c); 920 } 921 } 922 return filtered.toString(); 923 } 924 925 public static void printXMLNode(Node e, boolean printText) { 926 printXMLNode(e, 0, printText) ; 927 } 928 929 public static String xmlNodeToString(Node e){ 930 StringBuffer sb = new StringBuffer(""); 931 xmlNodeToString(sb,e,0); 932 return sb.toString(); 933 } 934 935 private static void xmlNodeToString(StringBuffer sb, Node e, int depth){ 936 937 for (int i=0 ; i<depth ; i++) 938 sb.append(' ') ; 939 940 if (e.getNodeType() == Node.TEXT_NODE){ 941 sb.append("text") ; 942 return ; 943 } 944 945 sb.append('<'); 946 sb.append(e.getNodeName()); 947 NamedNodeMap attrs = e.getAttributes(); 948 if(attrs != null) 949 { 950 for (int i = 0; i < attrs.getLength(); i++) { 951 Node attr = attrs.item(i); 952 sb.append(' '); 953 sb.append(attr.getNodeName()); 954 sb.append("=\""); 955 sb.append(attr.getNodeValue()); 956 sb.append('"'); 957 } 958 } 959 960 NodeList children = e.getChildNodes(); 961 962 if (children == null || children.getLength() == 0) 963 sb.append("/>\n") ; 964 else { 965 966 sb.append(">\n") ; 967 968 int len = children.getLength(); 969 for (int i = 0; i < len; i++) { 970 xmlNodeToString(sb,children.item(i), depth + 1); 971 } 972 973 for (int i=0 ; i<depth ; i++) 974 sb.append(' ') ; 975 976 sb.append("</" + e.getNodeName() + ">\n"); 977 } 978 979 980 } 981 982 public static void printXMLNode(Node e, int depth, boolean printText) { //recursive method call using DOM API... 983 984 if(e == null){return;} 985 986 for (int i=0 ; i<depth ; i++) 987 System.out.print(' ') ; 988 989 if (e.getNodeType() == Node.TEXT_NODE){ 990 if(printText){ 991 System.out.println(e.getNodeValue()); 992 } 993 else { 994 System.out.println("text"); 995 } 996 return ; 997 } 998 999 System.out.print('<'); 1000 System.out.print(e.getNodeName()); 1001 NamedNodeMap attrs = e.getAttributes(); 1002 1003 if (attrs != null) 1004 { 1005 for (int i = 0; i < attrs.getLength(); i++) { 1006 Node attr = attrs.item(i); 1007 System.out.print(' '); 1008 System.out.print(attr.getNodeName()); 1009 System.out.print("=\""); 1010 System.out.print(attr.getNodeValue()); 1011 System.out.print('"'); 1012 } 1013 } 1014 1015 NodeList children = e.getChildNodes(); 1016 1017 if (children == null || children.getLength() == 0) 1018 System.out.println("/>") ; 1019 else { 1020 1021 System.out.println('>') ; 1022 1023 int len = children.getLength(); 1024 for (int i = 0; i < len; i++) { 1025 printXMLNode(children.item(i), depth + 1, printText); 1026 } 1027 1028 for (int i=0 ; i<depth ; i++) 1029 System.out.print(' ') ; 1030 1031 System.out.println("</" + e.getNodeName() + ">"); 1032 } 1033 1034 } 1035 1036 public static void elementToLogAsString(Element e) { 1037 try { 1038 TransformerFactory tf = TransformerFactory.newInstance(); 1039 Transformer trans = tf.newTransformer(); 1040 StringWriter sw = new StringWriter(); 1041 trans.transform(new DOMSource(e), new StreamResult(sw)); 1042 System.err.println( sw.toString() ); // logger.info( sw.toString() ); 1043 } catch( Exception ex ) { 1044 System.err.println( "couldn't write " + e + " to log" ); 1045 } 1046 1047 } 813 } 814 return node_list; 815 } 816 817 public static int SORT_TYPE_STRING = 0; 818 public static int SORT_TYPE_INT = 1; 819 public static int SORT_TYPE_FLOAT = 2; 820 821 // sort type: 822 public static Element insertIntoOrderedList(Element parent_node, 823 String node_name, 824 Element start_from_elem, 825 Element new_elem, String sort_att, 826 boolean descending) { 827 if (new_elem == null) return null; 828 Element cloned_elem = (Element)parent_node.getOwnerDocument().importNode(new_elem, true); 829 if (start_from_elem == null) { 830 parent_node.appendChild(cloned_elem); 831 return cloned_elem; 832 } 833 834 Node current_node = start_from_elem; 835 String insert_att = cloned_elem.getAttribute(sort_att); 836 String list_att = start_from_elem.getAttribute(sort_att); 837 while ((!descending && list_att.compareTo(insert_att)<0) || (descending && list_att.compareTo(insert_att)>0)) { 838 current_node = current_node.getNextSibling(); 839 if (current_node == null) break; // end of the list 840 if (!current_node.getNodeName().equals(node_name)) { 841 continue; // not a valid node 842 } 843 list_att = ((Element)current_node).getAttribute(sort_att); 844 } 845 846 parent_node.insertBefore(cloned_elem, current_node); 847 return cloned_elem; 848 } 849 850 851 /** Returns the appropriate language element from a display elem, 852 * display is the containing element, name is the name of the element to 853 * look for, lang is the preferred language, lang_default is the fall back 854 * lang if neither lang is found, will return the first one it finds*/ 855 public static String getDisplayText(Element display, String name, 856 String lang, String lang_default) { 857 858 String def = null; 859 String first = null; 860 NodeList elems = display.getElementsByTagName(DISPLAY_TEXT_ELEM); 861 if (elems.getLength() == 0) return ""; 862 for (int i=0; i<elems.getLength(); i++) { 863 Element e = (Element)elems.item(i); 864 String n = e.getAttribute(NAME_ATT); 865 if (name.equals(n)) { 866 String l = e.getAttribute(LANG_ATT); 867 if (lang.equals(l)) { 868 return getNodeText(e); 869 } else if (lang_default.equals(l)) { 870 def = getNodeText(e); 871 } else if (first == null) { 872 first = getNodeText(e); 873 } 874 } else { 875 continue; 876 } 877 } 878 879 if (def != null) { 880 return def; 881 } 882 if (first != null) { 883 return first; 884 } 885 return ""; 886 } 887 888 // replaces < > " ' & in the original with their entities 889 public static String xmlSafe(String original) { 890 891 StringBuffer filtered = new StringBuffer(original.length()); 892 char c; 893 for (int i=0; i<original.length(); i++) { 894 c = original.charAt(i); 895 if (c == '>') { 896 filtered.append(">"); 897 } else if (c == '<') { 898 filtered.append("<"); 899 } else if (c == '"') { 900 filtered.append("""); 901 } else if (c == '&') { 902 filtered.append("&"); 903 } else if (c == '\'') { 904 filtered.append("'"); 905 } else { 906 filtered.append(c); 907 } 908 } 909 return filtered.toString(); 910 } 911 912 913 // replaces < > " ' & entities with their originals 914 public static String unXmlSafe(String original) { 915 916 StringBuffer filtered = new StringBuffer(original.length()); 917 char c; 918 for (int i=0; i<original.length(); i++) { 919 c = original.charAt(i); 920 if (c == '&') { 921 int pos = original.indexOf(";", i); 922 String entity = original.substring(i+1, pos); 923 if (entity.equals("gt")) { 924 filtered.append(">"); 925 } else if (entity.equals("lt")) { 926 filtered.append("<"); 927 } else if (entity.equals("apos")) { 928 filtered.append("'"); 929 } else if (entity.equals("amp")) { 930 filtered.append("&"); 931 } else if (entity.equals("quot")) { 932 filtered.append("\""); 933 } else { 934 filtered.append("&"+entity+";"); 935 } 936 i = pos; 937 } else { 938 filtered.append(c); 939 } 940 } 941 return filtered.toString(); 942 } 943 944 public static void printXMLNode(Node e, boolean printText) { 945 printXMLNode(e, 0, printText) ; 946 } 947 948 public static String xmlNodeToString(Node e){ 949 StringBuffer sb = new StringBuffer(""); 950 xmlNodeToString(sb,e,0); 951 return sb.toString(); 952 } 953 954 private static void xmlNodeToString(StringBuffer sb, Node e, int depth){ 955 956 for (int i=0 ; i<depth ; i++) 957 sb.append(' ') ; 958 959 if (e.getNodeType() == Node.TEXT_NODE){ 960 sb.append("text") ; 961 return ; 962 } 963 964 sb.append('<'); 965 sb.append(e.getNodeName()); 966 NamedNodeMap attrs = e.getAttributes(); 967 if(attrs != null) 968 { 969 for (int i = 0; i < attrs.getLength(); i++) { 970 Node attr = attrs.item(i); 971 sb.append(' '); 972 sb.append(attr.getNodeName()); 973 sb.append("=\""); 974 sb.append(attr.getNodeValue()); 975 sb.append('"'); 976 } 977 } 978 979 NodeList children = e.getChildNodes(); 980 981 if (children == null || children.getLength() == 0) 982 sb.append("/>\n") ; 983 else { 984 985 sb.append(">\n") ; 986 987 int len = children.getLength(); 988 for (int i = 0; i < len; i++) { 989 xmlNodeToString(sb,children.item(i), depth + 1); 990 } 991 992 for (int i=0 ; i<depth ; i++) 993 sb.append(' ') ; 994 995 sb.append("</" + e.getNodeName() + ">\n"); 996 } 997 998 999 } 1000 1001 public static void printXMLNode(Node e, int depth, boolean printText) { //recursive method call using DOM API... 1002 1003 if(e == null){return;} 1004 1005 for (int i=0 ; i<depth ; i++) 1006 System.out.print(' ') ; 1007 1008 if (e.getNodeType() == Node.TEXT_NODE){ 1009 if(printText){ 1010 System.out.println(e.getNodeValue()); 1011 } 1012 else { 1013 System.out.println("text"); 1014 } 1015 return ; 1016 } 1017 1018 System.out.print('<'); 1019 System.out.print(e.getNodeName()); 1020 NamedNodeMap attrs = e.getAttributes(); 1021 1022 if (attrs != null) 1023 { 1024 for (int i = 0; i < attrs.getLength(); i++) { 1025 Node attr = attrs.item(i); 1026 System.out.print(' '); 1027 System.out.print(attr.getNodeName()); 1028 System.out.print("=\""); 1029 System.out.print(attr.getNodeValue()); 1030 System.out.print('"'); 1031 } 1032 } 1033 1034 NodeList children = e.getChildNodes(); 1035 1036 if (children == null || children.getLength() == 0) 1037 System.out.println("/>") ; 1038 else { 1039 1040 System.out.println('>') ; 1041 1042 int len = children.getLength(); 1043 for (int i = 0; i < len; i++) { 1044 printXMLNode(children.item(i), depth + 1, printText); 1045 } 1046 1047 for (int i=0 ; i<depth ; i++) 1048 System.out.print(' ') ; 1049 1050 System.out.println("</" + e.getNodeName() + ">"); 1051 } 1052 } 1053 1054 public static void elementToLogAsString(Element e) { 1055 try { 1056 TransformerFactory tf = TransformerFactory.newInstance(); 1057 Transformer trans = tf.newTransformer(); 1058 StringWriter sw = new StringWriter(); 1059 trans.transform(new DOMSource(e), new StreamResult(sw)); 1060 System.err.println( sw.toString() ); 1061 } catch( Exception ex ) { 1062 System.err.println( "couldn't write " + e + " to log" ); 1063 } 1064 } 1048 1065 } -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/JDBMWrapper.java
r22973 r24393 36 36 import jdbm.htree.HTree; 37 37 38 public class JDBMWrapper 39 implements FlatDatabaseWrapper { 40 41 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.JDBMWrapper.class.getName()); 42 43 static String TNAME = "greenstone"; 44 45 RecordManager recman_ = null; 46 HTree hashtable_; 47 48 String db_filename_; 49 50 static private PrintWriter utf8out = null; 51 52 static 53 { 54 try { 55 OutputStreamWriter osw = new OutputStreamWriter(System.out, "UTF-8"); 56 utf8out = new PrintWriter(osw, true); 57 } 58 catch (UnsupportedEncodingException e) { 59 System.out.println(e); 60 } 61 } 62 63 64 /** open database named filename, using mode */ 65 public boolean openDatabase(String db_filename, int mode) { 66 67 68 if (db_filename.endsWith(".jdb")) { 69 // remove file extension as JDBM does not expect it 70 db_filename = db_filename.substring(0,db_filename.length()-4); 71 } 72 73 // Map the mode value into equivalent JDBM 'must_exist' value 74 // currently this is very simple as there is only READ and WRITE 75 // (no WRITER_CREATE) 76 // => assume the database must exist 77 boolean must_exist = true; // default 78 79 if (recman_ != null) { 80 String message = "openDatabase() called when the class already has a database open\n"; 81 message += " Use closeDatabase before opening the next one.\n"; 82 message += " Existing database file: " + db_filename_ + "\n"; 83 message += " New database file: " + db_filename + "\n"; 84 logger.warn(message); 85 // consider closing it automatically? 86 } 87 88 89 try { 90 // create or open a record manager 91 Properties props = new Properties(); 92 recman_ = RecordManagerFactory.createRecordManager(db_filename, props); 93 94 // load existing table (if exists) otherwise create new one 95 long recid = recman_.getNamedObject(TNAME); 96 97 if (recid != 0) { 98 System.err.println("# Loading existing database table '" + TNAME +"' ..."); 99 hashtable_ = HTree.load(recman_, recid); 100 } 101 else { 102 103 if (must_exist) { 104 recman_.close(); 105 recman_ = null; 106 db_filename_ = null; 107 108 System.err.println("Database table '" + TNAME +"' does not exist."); 109 throw new IOException(); 110 } 111 else { 112 System.err.println("# No database table '" + TNAME +"' to set. Creating new one"); 113 hashtable_ = HTree.createInstance(recman_); 114 recman_.setNamedObject(TNAME, hashtable_.getRecid()); 115 } 116 } 117 } 118 catch (IOException e) { 119 logger.error("couldn't open database "+ db_filename); 120 return false; 121 } 122 123 db_filename_ = db_filename; 124 125 return true; 126 } 127 128 129 /** close the database associated with this wrapper */ 130 public void closeDatabase() { 131 try { 132 if (recman_ != null) { 133 recman_.close(); 134 recman_ = null; 135 db_filename_ = null; 136 } 137 } 138 catch (IOException e) { 139 logger.error("Failed to close JDBM database"); 140 } 141 } 142 143 /** returns the value associated with the key */ 144 public String getValue(String key) { 145 146 String val; 147 148 try { 149 val = (String) hashtable_.get(key); 150 151 recman_.commit(); 152 } 153 catch (IOException e) { 154 logger.error("Failed get key " + key + "from JDBM database"); 155 return null; 156 } 157 158 return val; 159 } 160 161 /** returns a string of key-value entries that can be 162 * printed for debugging purposes*/ 163 public String displayAllEntries() { 164 165 StringBuffer keys = new StringBuffer(); 166 167 try { 168 FastIterator iter = hashtable_.keys(); 169 String key = (String) iter.next(); 170 171 String nl = System.getProperty("line.separator"); 172 173 while (key != null) { 174 String val = (String) hashtable_.get(key); 175 keys.append("[" + key + "]" + nl); 176 keys.append(val + nl); 177 // 70 hypens 178 keys.append("----------------------------------------------------------------------" + nl); 179 key = (String) iter.next(); 180 } 181 182 recman_.commit(); 183 } 184 catch (IOException e) { 185 logger.error("Failed get all keys and values from JDBM database"); 186 return null; 187 } 188 189 return keys.toString(); 190 } 38 public class JDBMWrapper implements FlatDatabaseWrapper 39 { 40 41 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.JDBMWrapper.class.getName()); 42 43 static String TNAME = "greenstone"; 44 45 RecordManager recman_ = null; 46 HTree hashtable_; 47 48 String db_filename_; 49 50 static private PrintWriter utf8out = null; 51 52 static 53 { 54 try 55 { 56 OutputStreamWriter osw = new OutputStreamWriter(System.out, "UTF-8"); 57 utf8out = new PrintWriter(osw, true); 58 } 59 catch (UnsupportedEncodingException e) 60 { 61 System.out.println(e); 62 } 63 } 64 65 /** open database named filename, using mode */ 66 public boolean openDatabase(String db_filename, int mode) 67 { 68 69 if (db_filename.endsWith(".jdb")) 70 { 71 // remove file extension as JDBM does not expect it 72 db_filename = db_filename.substring(0, db_filename.length() - 4); 73 } 74 75 // Map the mode value into equivalent JDBM 'must_exist' value 76 // currently this is very simple as there is only READ and WRITE 77 // (no WRITER_CREATE) 78 // => assume the database must exist 79 boolean must_exist = true; // default 80 81 if (recman_ != null) 82 { 83 String message = "openDatabase() called when the class already has a database open\n"; 84 message += " Use closeDatabase before opening the next one.\n"; 85 message += " Existing database file: " + db_filename_ + "\n"; 86 message += " New database file: " + db_filename + "\n"; 87 logger.warn(message); 88 // consider closing it automatically? 89 } 90 91 try 92 { 93 // create or open a record manager 94 Properties props = new Properties(); 95 recman_ = RecordManagerFactory.createRecordManager(db_filename, props); 96 97 // load existing table (if exists) otherwise create new one 98 long recid = recman_.getNamedObject(TNAME); 99 100 if (recid != 0) 101 { 102 System.err.println("# Loading existing database table '" + TNAME + "' ..."); 103 hashtable_ = HTree.load(recman_, recid); 104 } 105 else 106 { 107 108 if (must_exist) 109 { 110 recman_.close(); 111 recman_ = null; 112 db_filename_ = null; 113 114 System.err.println("Database table '" + TNAME + "' does not exist."); 115 throw new IOException(); 116 } 117 else 118 { 119 System.err.println("# No database table '" + TNAME + "' to set. Creating new one"); 120 hashtable_ = HTree.createInstance(recman_); 121 recman_.setNamedObject(TNAME, hashtable_.getRecid()); 122 } 123 } 124 } 125 catch (IOException e) 126 { 127 logger.error("couldn't open database " + db_filename); 128 return false; 129 } 130 131 db_filename_ = db_filename; 132 133 return true; 134 } 135 136 /** close the database associated with this wrapper */ 137 public void closeDatabase() 138 { 139 try 140 { 141 if (recman_ != null) 142 { 143 recman_.close(); 144 recman_ = null; 145 db_filename_ = null; 146 } 147 } 148 catch (IOException e) 149 { 150 logger.error("Failed to close JDBM database"); 151 } 152 } 153 154 /** returns the value associated with the key */ 155 public String getValue(String key) 156 { 157 158 String val; 159 160 try 161 { 162 val = (String) hashtable_.get(key); 163 164 recman_.commit(); 165 } 166 catch (IOException e) 167 { 168 logger.error("Failed get key " + key + "from JDBM database"); 169 return null; 170 } 171 172 return val; 173 } 174 175 /** 176 * Sets the given key to the given value in the database 177 */ 178 public boolean setValue(String key, String value) 179 { 180 try 181 { 182 hashtable_.put(key, value); 183 recman_.commit(); 184 } 185 catch (Exception ex) 186 { 187 logger.error("Failed to set " + key + " = " + value + " in the JDBM database"); 188 return false; 189 } 190 return true; 191 } 192 193 /** 194 * Deletes the given key (and corresponding value) from the database 195 */ 196 public boolean deleteKey(String key) 197 { 198 try 199 { 200 hashtable_.remove(key); 201 recman_.commit(); 202 } 203 catch (Exception ex) 204 { 205 logger.error("Failed to delete key " + key + " in the JDBM database"); 206 return false; 207 } 208 return true; 209 } 210 211 /** 212 * returns a string of key-value entries that can be printed for debugging 213 * purposes 214 */ 215 public String displayAllEntries() 216 { 217 218 StringBuffer keys = new StringBuffer(); 219 220 try 221 { 222 FastIterator iter = hashtable_.keys(); 223 String key = (String) iter.next(); 224 225 String nl = System.getProperty("line.separator"); 226 227 while (key != null) 228 { 229 String val = (String) hashtable_.get(key); 230 keys.append("[" + key + "]" + nl); 231 keys.append(val + nl); 232 // 70 hypens 233 keys.append("----------------------------------------------------------------------" + nl); 234 key = (String) iter.next(); 235 } 236 237 recman_.commit(); 238 } 239 catch (IOException e) 240 { 241 logger.error("Failed get all keys and values from JDBM database"); 242 return null; 243 } 244 245 return keys.toString(); 246 } 191 247 } -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java
r23791 r24393 19 19 package org.greenstone.gsdl3.util; 20 20 21 import java.util.Iterator; 22 import java.util.Set; 23 import java.util.Vector; 24 21 25 import org.apache.log4j.*; 22 26 23 27 import org.apache.commons.lang3.StringUtils; 24 28 25 public class SimpleCollectionDatabase implements OID.OIDTranslatable { 26 27 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.SimpleCollectionDatabase.class.getName()); 28 29 /* just read access, many readers can share a database */ 30 public final static int READ = FlatDatabaseWrapper.READ; 31 /* read/write, exclusive access */ 32 public final static int WRITE = FlatDatabaseWrapper.WRITE; 33 34 protected FlatDatabaseWrapper coll_db = null; 35 36 public SimpleCollectionDatabase(String db_type) { 37 38 // Access databaseWrapper through reflection (forName) so code 39 // can be more dynamic as to the database backends that are 40 // supported for this installation of Greenstone 41 42 String dbwrap_name = db_type.toUpperCase() + "Wrapper"; 43 Class dbwrap_class = null; 44 45 try { 46 String full_dbwrap_name = "org.greenstone.gsdl3.util."+dbwrap_name; 47 dbwrap_class = Class.forName(full_dbwrap_name); 48 } 49 catch(ClassNotFoundException e) { 50 try { 51 //try the dbwrap_name alone in case the package name is 52 //already specified 53 dbwrap_class = Class.forName(dbwrap_name); 54 } 55 catch(ClassNotFoundException ae) { 56 logger.error("Couldn't create SimpleCollectionDatabase of type "+db_type); 57 logger.info(ae.getMessage()); 58 } 59 } 60 61 try { 62 this.coll_db = (FlatDatabaseWrapper)dbwrap_class.newInstance(); 63 } 64 catch(Exception e) { 65 logger.error("Failed to call the constructor "+dbwrap_name+"()"); 66 } 67 68 69 } 70 71 public boolean databaseOK() { 72 // Previously failed to open database 73 // Most likely cause is that this installation of Greenstone3 has not 74 // been compiled with support for this database type 75 return coll_db != null; 76 } 77 78 /** open the database filename, with mode mode - uses the FlatDatabaseWrapper modes */ 79 public boolean openDatabase(String filename, int mode){ 80 return this.coll_db.openDatabase(filename, mode); 81 } 82 83 /** close the database */ 84 public void closeDatabase() { 85 this.coll_db.closeDatabase(); 86 } 87 88 /** Returns a DBInfo structure of the key-value pairs associated with a 89 particular main key in the database */ 90 public DBInfo getInfo(String main_key) { 91 // logger.warn("All the entries of the db are:"); 92 // this.coll_db.displayAllEntries(); 93 94 95 if (this.coll_db==null) { 96 // Most likely cause is that this installation of Greenstone3 has not 97 // been compiled with support for this database type 98 return null; 99 } 100 101 String key_info = this.coll_db.getValue(main_key); 102 if (key_info == null || key_info.equals("")) { 103 return null; 104 } 105 106 DBInfo info = new DBInfo(); 107 108 String [] lines = StringUtils.split(key_info, "\n"); 109 String key; 110 String value; 111 for (int i=0; i<lines.length; i++) { 112 logger.debug("line:"+lines[i]); 113 int a = lines[i].indexOf('<'); 114 int b= lines[i].indexOf('>'); 115 if (a==-1 || b==-1) { 116 logger.error("bad format in db"); 117 } 118 else { 119 key=lines[i].substring(a+1, b); 120 value=lines[i].substring(b+1); 121 logger.debug("key="+key+", val="+value); 122 info.addInfo(key, value); 123 124 } 125 } 126 return info; 127 128 } 129 130 /** converts a greenstone OID to internal docnum */ 131 public String OID2Docnum(String OID) { 132 DBInfo info = getInfo(OID); 133 if (info != null) { 134 return info.getInfo("docnum"); 135 } 136 return null; 137 } 138 139 /** converts a greenstone OID to an internal docnum, returning a Long 140 - convenience method*/ 141 public long OID2DocnumLong(String OID) { 142 DBInfo info = getInfo(OID); 143 if (info != null) { 144 long real_num = Long.parseLong(info.getInfo("docnum")); 145 return real_num; 146 } 147 return -1; 148 } 149 150 151 /** converts a docnum to greenstone OID */ 152 public String docnum2OID(String docnum) { 153 DBInfo info = getInfo(docnum); 154 if (info!=null){ 155 String oid = info.getInfo("section"); 156 return oid; 157 } else{ 158 return null; 159 } 160 } 161 162 /** converts a docnum to greenstone OID 163 - convenience method */ 164 public String docnum2OID(long docnum) { 165 return docnum2OID(Long.toString(docnum)); 166 } 167 168 /** converts an external id to greenstone OID */ 169 public String externalId2OID(String extid) { 170 DBInfo info = getInfo(extid); 171 if (info != null) { 172 String oid = info.getInfo("section"); 173 return oid; 174 } 175 return null; 176 } 177 178 /** After OID.translateOID() is through, this method processes OID further 179 * to translate relative oids into proper oids: 180 * .pr (parent), .rt (root) .fc (first child), .lc (last child), 181 * .ns (next sibling), .ps (previous sibling) 182 * .np (next page), .pp (previous page) : links sections in the order that you'd read the document 183 * a suffix is expected to be present so test before using 184 */ 185 public String processOID(String doc_id, String top, String suff, int sibling_num) { 186 DBInfo info = getInfo(doc_id); 187 if (info==null) { 188 logger.info("info is null!!"); 189 return top; 190 } 29 public class SimpleCollectionDatabase implements OID.OIDTranslatable 30 { 31 32 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.SimpleCollectionDatabase.class.getName()); 33 34 /* just read access, many readers can share a database */ 35 public final static int READ = FlatDatabaseWrapper.READ; 36 /* read/write, exclusive access */ 37 public final static int WRITE = FlatDatabaseWrapper.WRITE; 38 39 protected FlatDatabaseWrapper coll_db = null; 40 41 public SimpleCollectionDatabase(String db_type) 42 { 43 44 // Access databaseWrapper through reflection (forName) so code 45 // can be more dynamic as to the database backends that are 46 // supported for this installation of Greenstone 47 48 String dbwrap_name = db_type.toUpperCase() + "Wrapper"; 49 Class dbwrap_class = null; 50 51 try 52 { 53 String full_dbwrap_name = "org.greenstone.gsdl3.util." + dbwrap_name; 54 dbwrap_class = Class.forName(full_dbwrap_name); 55 } 56 catch (ClassNotFoundException e) 57 { 58 try 59 { 60 //try the dbwrap_name alone in case the package name is 61 //already specified 62 dbwrap_class = Class.forName(dbwrap_name); 63 } 64 catch (ClassNotFoundException ae) 65 { 66 logger.error("Couldn't create SimpleCollectionDatabase of type " + db_type); 67 logger.info(ae.getMessage()); 68 } 69 } 70 71 try 72 { 73 this.coll_db = (FlatDatabaseWrapper) dbwrap_class.newInstance(); 74 } 75 catch (Exception e) 76 { 77 logger.error("Failed to call the constructor " + dbwrap_name + "()"); 78 } 79 80 } 81 82 public boolean databaseOK() 83 { 84 // Previously failed to open database 85 // Most likely cause is that this installation of Greenstone3 has not 86 // been compiled with support for this database type 87 return coll_db != null; 88 } 89 90 /** 91 * open the database filename, with mode mode - uses the FlatDatabaseWrapper 92 * modes 93 */ 94 public boolean openDatabase(String filename, int mode) 95 { 96 return this.coll_db.openDatabase(filename, mode); 97 } 98 99 /** close the database */ 100 public void closeDatabase() 101 { 102 this.coll_db.closeDatabase(); 103 } 104 105 /** 106 * Returns a DBInfo structure of the key-value pairs associated with a 107 * particular main key in the database 108 */ 109 public DBInfo getInfo(String main_key) 110 { 111 // logger.warn("All the entries of the db are:"); 112 // this.coll_db.displayAllEntries(); 113 114 if (this.coll_db == null) 115 { 116 // Most likely cause is that this installation of Greenstone3 has not 117 // been compiled with support for this database type 118 return null; 119 } 120 121 String key_info = this.coll_db.getValue(main_key); 122 if (key_info == null || key_info.equals("")) 123 { 124 return null; 125 } 126 127 DBInfo info = new DBInfo(); 128 129 String[] lines = StringUtils.split(key_info, "\n"); 130 String key; 131 String value; 132 for (int i = 0; i < lines.length; i++) 133 { 134 logger.debug("line:" + lines[i]); 135 int a = lines[i].indexOf('<'); 136 int b = lines[i].indexOf('>'); 137 if (a == -1 || b == -1) 138 { 139 logger.error("bad format in db"); 140 } 141 else 142 { 143 key = lines[i].substring(a + 1, b); 144 value = lines[i].substring(b + 1); 145 logger.debug("key=" + key + ", val=" + value); 146 info.addInfo(key, value); 147 } 148 } 149 150 return info; 151 } 191 152 192 String contains = info.getInfo("contains"); 193 if (contains.equals("")) { 194 // something is wrong 195 return top; 196 } 197 contains = StringUtils.replace(contains, "\"", doc_id); 198 String [] children = StringUtils.split(contains, ";"); 199 if (suff.equals("fc")) { 200 return children[0]; 201 } else if (suff.equals("lc")) { 202 return children[children.length-1]; 203 } else { 204 if (suff.equals("ss")) { 205 return children[sibling_num-1]; 206 } 207 // find the position that we are at. 208 int i=0; 209 while (i<children.length) { 210 if (children[i].equals(top)) { 211 break; 212 } 213 i++; 214 } 215 216 if (suff.equals("ns")) { 217 if (i==children.length-1) { 218 return children[i]; 219 } 220 return children[i+1]; 221 } else if (suff.equals("ps")) { 222 if (i==0) { 223 return children[i]; 224 } 225 return children[i-1]; 226 } 227 } 153 public boolean setInfo(String mainKey, DBInfo info) 154 { 155 StringBuilder valueToAdd = new StringBuilder(); 156 Iterator i = info.getKeys().iterator(); 157 while (i.hasNext()) 158 { 159 String currentKey = (String)i.next(); 160 Vector currentValues = (Vector)info.getMultiInfo(currentKey); 161 162 if(currentValues.size() == 0) 163 { 164 valueToAdd.append("<" + currentKey + ">\n"); 165 continue; 166 } 167 168 for(int j = 0; j < currentValues.size(); j++) 169 { 170 valueToAdd.append("<" + currentKey + ">" + currentValues.get(j) + "\n"); 171 } 172 } 173 174 //Remove the final \n 175 if (valueToAdd.length() > 0) 176 { 177 valueToAdd.delete(valueToAdd.length() - 1, valueToAdd.length()); 178 } 179 180 return this.coll_db.setValue(mainKey, valueToAdd.toString()); 181 } 228 182 229 return top; 230 } 183 public String getValue(String key) 184 { 185 return this.coll_db.getValue(key); 186 } 187 188 public boolean setValue(String key, String value) 189 { 190 return this.coll_db.setValue(key, value); 191 } 192 193 public boolean deleteKey(String key) 194 { 195 return this.coll_db.deleteKey(key); 196 } 197 198 /** converts a greenstone OID to internal docnum */ 199 public String OID2Docnum(String OID) 200 { 201 DBInfo info = getInfo(OID); 202 if (info != null) 203 { 204 return info.getInfo("docnum"); 205 } 206 return null; 207 } 208 209 /** 210 * converts a greenstone OID to an internal docnum, returning a Long - 211 * convenience method 212 */ 213 public long OID2DocnumLong(String OID) 214 { 215 DBInfo info = getInfo(OID); 216 if (info != null) 217 { 218 long real_num = Long.parseLong(info.getInfo("docnum")); 219 return real_num; 220 } 221 return -1; 222 } 223 224 /** converts a docnum to greenstone OID */ 225 public String docnum2OID(String docnum) 226 { 227 DBInfo info = getInfo(docnum); 228 if (info != null) 229 { 230 String oid = info.getInfo("section"); 231 return oid; 232 } 233 else 234 { 235 return null; 236 } 237 } 238 239 /** 240 * converts a docnum to greenstone OID - convenience method 241 */ 242 public String docnum2OID(long docnum) 243 { 244 return docnum2OID(Long.toString(docnum)); 245 } 246 247 /** converts an external id to greenstone OID */ 248 public String externalId2OID(String extid) 249 { 250 DBInfo info = getInfo(extid); 251 if (info != null) 252 { 253 String oid = info.getInfo("section"); 254 return oid; 255 } 256 return null; 257 } 258 259 /** 260 * After OID.translateOID() is through, this method processes OID further to 261 * translate relative oids into proper oids: .pr (parent), .rt (root) .fc 262 * (first child), .lc (last child), .ns (next sibling), .ps (previous 263 * sibling) .np (next page), .pp (previous page) : links sections in the 264 * order that you'd read the document a suffix is expected to be present so 265 * test before using 266 */ 267 public String processOID(String doc_id, String top, String suff, int sibling_num) 268 { 269 DBInfo info = getInfo(doc_id); 270 if (info == null) 271 { 272 logger.info("info is null!!"); 273 return top; 274 } 275 276 String contains = info.getInfo("contains"); 277 if (contains.equals("")) 278 { 279 // something is wrong 280 return top; 281 } 282 contains = StringUtils.replace(contains, "\"", doc_id); 283 String[] children = StringUtils.split(contains, ";"); 284 if (suff.equals("fc")) 285 { 286 return children[0]; 287 } 288 else if (suff.equals("lc")) 289 { 290 return children[children.length - 1]; 291 } 292 else 293 { 294 if (suff.equals("ss")) 295 { 296 return children[sibling_num - 1]; 297 } 298 // find the position that we are at. 299 int i = 0; 300 while (i < children.length) 301 { 302 if (children[i].equals(top)) 303 { 304 break; 305 } 306 i++; 307 } 308 309 if (suff.equals("ns")) 310 { 311 if (i == children.length - 1) 312 { 313 return children[i]; 314 } 315 return children[i + 1]; 316 } 317 else if (suff.equals("ps")) 318 { 319 if (i == 0) 320 { 321 return children[i]; 322 } 323 return children[i - 1]; 324 } 325 } 326 327 return top; 328 } 231 329 } -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLTransformer.java
r24361 r24393 177 177 // Use the TransformerFactory to process the stylesheet Source and generate a Transformer. 178 178 Transformer transformer = this.t_factory.newTransformer(new DOMSource(stylesheet)); 179 logger.debug("XMLTransformer transformer is " + transformer);179 logger.error("XMLTransformer transformer is " + transformer); 180 180 transformer.setErrorListener(new TransformErrorListener()); 181 181 if (parameters != null) { -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java
r24219 r24393 138 138 } 139 139 public static String getInterfaceText(String interface_name, String lang, String key, String args_str) { 140 141 key = key.replaceAll("__INTERFACE_NAME__", interface_name); 142 140 143 String [] args = null; 141 144 if (args_str!=null && !args_str.equals("")) {
Note:
See TracChangeset
for help on using the changeset viewer.