Changeset 24393

Show
Ignore:
Timestamp:
12.08.2011 09:57:26 (8 years ago)
Author:
sjm84
Message:

Adding in the server-side code for the Document Maker as well as several other enhancements

Location:
main/trunk/greenstone3/src/java/org/greenstone/gsdl3
Files:
5 added
16 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/Action.java

    r24254 r24393  
    7777    } 
    7878 
    79     protected void extractMetadataNames(Element format, HashSet meta_names) { 
     79    protected void extractMetadataNames(Element format, HashSet meta_names) { 
    8080    //NodeList nodes = format.getElementsByTagNameNS("metadata", "http://www.greenstone.org/configformat"); 
    8181    NodeList metadata_nodes = format.getElementsByTagName("gsf:metadata"); 
     
    9090                metadata.append("all"); 
    9191                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            } 
    9793            if (!select.equals("")) { 
    9894                metadata.append(select); 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/GS2BrowseAction.java

    r24254 r24393  
    272272        Element d = this.doc.createElement(GSXML.DOC_NODE_ELEM); 
    273273        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         } 
    277274        doc_list.appendChild(d); 
    278275        } 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java

    r24361 r24393  
    2323import org.greenstone.gsdl3.service.*; 
    2424 
    25  
    2625// 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;  
     26import org.w3c.dom.Document; 
     27import org.w3c.dom.Node; 
     28import org.w3c.dom.Element; 
     29import org.w3c.dom.NodeList; 
    3130 
    3231import java.io.*; 
     
    4948 
    5049/** 
    51  * Represents a collection in Greenstone. A collection is an extension of 
    52  * a ServiceCluster - 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 *  
    5453 * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a> 
    5554 * @see ModuleInterface 
    5655 */ 
    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, "&lt;", "<"); 
    500             new_config = StringUtils.replace(new_config, "&gt;", ">"); 
    501             new_config = StringUtils.replace(new_config, "&quot;", "\""); 
    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, "&lt;", "<"); 
    617                 new_config = StringUtils.replace(new_config, "&gt;", ">"); 
    618                 new_config = StringUtils.replace(new_config, "&quot;", "\""); 
    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     } 
     56public 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, "&lt;", "<"); 
     565                new_config = StringUtils.replace(new_config, "&gt;", ">"); 
     566                new_config = StringUtils.replace(new_config, "&quot;", "\""); 
     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, "&lt;", "<"); 
     687                    new_config = StringUtils.replace(new_config, "&gt;", ">"); 
     688                    new_config = StringUtils.replace(new_config, "&quot;", "\""); 
     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    } 
    645718 
    646719} 
    647  
    648  
    649  
    650  
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractBrowse.java

    r24254 r24393  
    574574     * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/> 
    575575     */ 
    576     protected Element createDocNode(String node_id, int offset) { 
     576    protected Element createDocNode(String node_id) { 
    577577    Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM); 
    578578    node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
     
    587587    String node_type = getNodeType(node_id, doc_type);   
    588588    node.setAttribute(GSXML.NODE_TYPE_ATT, node_type); 
    589      
    590     // mdoffset information stored in DB determines which of multiple values for 
    591     // a metadata needs to be displayed when a classifier is built on that metadata 
    592     node.setAttribute(GSXML.NODE_MDOFFSET_ATT, Integer.toString(offset)); 
    593589    return node; 
    594590    } 
     
    625621    ArrayList child_ids = getChildrenIds(node_id); 
    626622    if (child_ids==null) return; 
    627      
    628     // get a list of all mdoffsets at this point 
    629     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 length 
    632     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  
    642623    for (int i=0; i< child_ids.size(); i++) { 
    643624        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? 
    645625        Element child_elem; 
    646626        if (isDocumentId(child_id)) { 
    647         child_elem = createDocNode(child_id, child_offset); 
     627        child_elem = createDocNode(child_id); 
    648628        } else { 
    649629        child_elem = createClassifierNode(child_id); 
     
    704684    } 
    705685 
    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  
    711686    /** if id ends in .fc, .pc etc, then translate it to the correct id */ 
    712687    abstract protected String translateId(String node_id); 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractDocumentRetrieve.java

    r24334 r24393  
    241241        Element request_node = (Element) request_nodes.item(i); 
    242242        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 doc 
    245         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 metaname 
    255             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          
    260243        
    261244        boolean is_external_link = false; 
     
    289272        if (!is_external_link){ 
    290273        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); 
    292275            request_node.appendChild(metadata_list); 
    293276        } catch (GSException e) {        
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractGS2DocumentRetrieve.java

    r24254 r24393  
    4141import java.util.Iterator; 
    4242import java.util.ArrayList; 
    43 import java.util.regex.Matcher; 
    44 import java.util.regex.Pattern; 
    4543 
    4644import org.apache.log4j.*; 
     
    198196         
    199197    } 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  
    203198        for (int i=0; i<metadata_names.size(); i++) { 
    204199                String meta_name = (String) metadata_names.get(i); 
    205200        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 match 
    209         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 input       
    212  
    213201        GSXML.addMetadata(this.doc, metadata_list, meta_name, value); 
    214202        } 
     
    329317    protected String getMetadata(String node_id, DBInfo info,  
    330318                 String metadata, String lang) { 
    331     String multiple = "false"; // multiple can now be "true", "false" or "offset<number>". It's no longer a boolean 
     319    boolean multiple = false; 
    332320    String relation = ""; 
    333321    String separator = ", "; 
     
    358346    metadata = metadata.substring(pos+1); 
    359347    // 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;       
    362350        pos = metadata.indexOf(GSConstants.META_RELATION_SEP); 
    363351        if (pos ==-1) { 
     
    411399    StringBuffer result = new StringBuffer(); 
    412400 
    413     if (multiple.equals("false")) { 
     401    if (!multiple) { 
    414402        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 
    425405        Vector values = relation_info.getMultiInfo(metadata); 
    426         if (values != null) { 
     406        if (values != null) { 
    427407        boolean first = true; 
    428408        for (int i=0; i<values.size(); i++) { 
     
    435415        } 
    436416        } 
    437         logger.info(result); 
     417          logger.info(result);  
    438418    } 
    439419    // if not ancestors, then this is all we do 
     
    448428        relation_info = this.coll_db.getInfo(relation_id); 
    449429        if (relation_info == null) return result.toString(); 
    450         if (multiple.equals("false")) { //if (!multiple) 
     430        if (!multiple) { 
    451431        result.insert(0, separator); 
    452432        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  
    175175 
    176176    } 
    177     /** returns a list of the mdoffset values in order for the children, null is  
    178       * 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  
    199177    /** returns the node id of the parent node, null if no parent */ 
    200178    protected String getParentId(String node_id){ 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ServiceRack.java

    r21781 r24393  
    2424 
    2525// 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;  
     26import org.w3c.dom.Node; 
     27import org.w3c.dom.NodeList; 
     28import org.w3c.dom.Element; 
     29import org.w3c.dom.Document; 
    3030import org.xml.sax.InputSource; 
    3131import javax.xml.parsers.*; 
     
    4545/** 
    4646 * 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 
    5352 * processTextQuery(Element request) 
    54  * 
     53 *  
    5554 * @author Katherine Don 
    5655 */ 
    57 public abstract class ServiceRack 
    58     implements ModuleInterface 
     56public abstract class ServiceRack implements ModuleInterface 
    5957{ 
    6058 
    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 
    234237            } 
    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 
    245243            } 
    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    } 
    423504} 
    424  
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DBInfo.java

    r24254 r24393  
    2222import java.util.HashMap; 
    2323import 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 
    2729 */ 
    28 public class DBInfo { 
     30public class DBInfo 
     31{ 
     32    protected HashMap info_map_; 
    2933 
    30     protected HashMap info_map_; 
     34    public DBInfo() 
     35    { 
     36        info_map_ = new HashMap(); 
     37    } 
    3138 
    32     public DBInfo() { 
    33     info_map_ = new HashMap(); 
    34     } 
     39    // methods for keys that can have a single value 
    3540 
    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    } 
    3748 
    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    } 
    4462 
    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); 
    5175    } 
    52     return (String)items.firstElement(); 
    53     } 
    5476 
    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); 
    6185    } 
    62     if(offset >= 0 && offset < items.size()) { 
    63         return (String)items.get(offset); 
    64     } // else 
    65     return (String)items.firstElement(); 
    66     } 
    6786 
     87    /** returns a list of all the keys in the info */ 
     88    public Set getKeys() 
     89    { 
     90        return info_map_.keySet(); 
     91    } 
    6892 
    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 
    7698    } 
    77     v.add(value); 
    78     info_map_.put(key, v); 
    79     } 
    80     /** return a vector of all values associated with a key  
    81      * @return Vector of Strings 
    82      */ 
    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     } 
    9699} 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/FlatDatabaseWrapper.java

    r16797 r24393  
    3737  /** returns the value associated with the key */ 
    3838  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); 
    3945 
    4046  /** returns a string of key-value entries that can be  
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GDBMWrapper.java

    r21912 r24393  
    2828import java.io.File; 
    2929 
    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 
    3233 */ 
    3334 
    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"; 
     35public 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        } 
    78216         
    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        } 
    84240         
    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        } 
    86251         
    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    } 
    218292} 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java

    r24254 r24393  
    11/* 
    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  */ 
     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*/ 
    1919package org.greenstone.gsdl3.util; 
    2020 
     
    2626import org.w3c.dom.Text; 
    2727 
    28  
    2928import javax.xml.transform.TransformerFactory; 
    3029import javax.xml.transform.Transformer; 
     
    4645/** various functions for extracting info out of GS XML */ 
    4746public 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        } 
    300324        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) 
    694656    { 
    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; 
    696661    } 
    697662     
    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         
    785804        if(children != null && children.getLength() > 0) { 
    786805             
     
    789808                if (child.getNodeName().equals(node_name)) { 
    790809                    if (((Element)child).getAttribute(attribute_name).equals(attribute_value)) 
    791                         node_list.addNode(child); 
     810                    node_list.addNode(child); 
    792811                }            
    793812            }            
    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("&gt;"); 
    878       } else if (c == '<') { 
    879         filtered.append("&lt;"); 
    880       } else if (c == '"') { 
    881         filtered.append("&quot;"); 
    882       } else if (c == '&') { 
    883         filtered.append("&amp;"); 
    884       } else if (c == '\'') { 
    885         filtered.append("&apos;"); 
    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("&gt;"); 
     897            } else if (c == '<') { 
     898                filtered.append("&lt;"); 
     899            } else if (c == '"') { 
     900                filtered.append("&quot;"); 
     901            } else if (c == '&') { 
     902                filtered.append("&amp;"); 
     903            } else if (c == '\'') { 
     904                filtered.append("&apos;"); 
     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    } 
    10481065} 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/JDBMWrapper.java

    r22973 r24393  
    3636import jdbm.htree.HTree; 
    3737 
    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   } 
     38public 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    } 
    191247} 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java

    r23791 r24393  
    1919package org.greenstone.gsdl3.util; 
    2020 
     21import java.util.Iterator; 
     22import java.util.Set; 
     23import java.util.Vector; 
     24 
    2125import org.apache.log4j.*; 
    2226 
    2327import org.apache.commons.lang3.StringUtils; 
    2428 
    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     } 
     29public 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    } 
    191152     
    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    } 
    228182     
    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    } 
    231329} 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLTransformer.java

    r24361 r24393  
    177177            // Use the TransformerFactory to process the stylesheet Source and generate a Transformer. 
    178178            Transformer transformer = this.t_factory.newTransformer(new DOMSource(stylesheet)); 
    179             logger.debug("XMLTransformer transformer is " + transformer); 
     179            logger.error("XMLTransformer transformer is " + transformer); 
    180180            transformer.setErrorListener(new TransformErrorListener()); 
    181181            if (parameters != null) { 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java

    r24219 r24393  
    138138    } 
    139139    public static String getInterfaceText(String interface_name, String lang, String key, String args_str) { 
     140     
     141    key = key.replaceAll("__INTERFACE_NAME__", interface_name); 
     142         
    140143    String [] args = null; 
    141144    if (args_str!=null && !args_str.equals("")) {