Changeset 24801 for main/trunk/gli

Show
Ignore:
Timestamp:
08.11.2011 13:45:45 (8 years ago)
Author:
sjm84
Message:

Updating the formatting of these two files so that changes are easier to see

Location:
main/trunk/gli/src/org/greenstone/gatherer
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfigXMLReadWrite.java

    r24425 r24801  
    4242import org.w3c.dom.*; 
    4343 
    44 public class CollectionConfigXMLReadWrite { 
    45  
    46   static final private String PLUGOUT_ELEMENT = "plugout";//used by building flax collections 
    47  
    48   /** ******************************************************************************************************** 
    49       The code from this point below are used for greenstone 3 collection configuration, i.e., read ColletionConfig.xml 
    50       * into the internal DOM tree, and convert the internal DOM tree back to CollectionConfig.xml. 
    51       * 
    52       Methods named 'doXXXX' are for convert collectionConfig.xml into the internal configuration xml structure; 
    53       Methods named 'convertXXXX' are for convert the internal configuration xml structure back to collectionConfig.xml. 
    54       ************************************************************************************************************ */ 
    55      
    56   /**Arguments:  metadataListNode->the 'displayItemList' element in collectionConfig.xml 
    57      name_value->the value of the 'name' attribute of 'index' element; 
    58      att_value->the value of the 'name' attribute of 'displayItem' element 
    59      return:     an ArrayList of the contructed 'CollectionMetadata' elements 
    60   */ 
    61   static private ArrayList doDisplayItemList (Document to, Node displayListNode, String att_value, String name_value) { 
    62     Element toElement = to.getDocumentElement (); 
    63     ArrayList display_item_list = new ArrayList (); 
    64     ArrayList item_list = XMLTools.getNamedElementList ((Element)displayListNode, 
    65                             StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, att_value); 
    66     if (item_list == null) { 
    67       return null; 
    68     } 
    69          
    70     for (int i=0; i<item_list.size (); i++) { 
    71       Element item = (Element)item_list.get (i); 
    72       String text = XMLTools.getNodeText (item); 
    73              
    74       //If there is nothing to display, don't bother creating the element 
    75       if (text == "") { 
    76     continue; 
    77       } 
    78       //get the value in 'lang=value' 
    79       String lang = item.getAttribute (StaticStrings.LANG_STR); 
    80              
    81       Element e = to.createElement (StaticStrings.COLLECTIONMETADATA_ELEMENT); 
    82       e.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    83       e.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_value); 
    84       e.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
    85       XMLTools.setNodeText (e, text); 
    86       display_item_list.add (e); 
    87     } 
    88     return display_item_list; 
    89   } 
    90      
    91   static private ArrayList doMetadataList (Document to, Node metadataListNode, String ele_name, String att_value) { 
    92     Element toElement = to.getDocumentElement (); 
    93     ArrayList metadata_list = new ArrayList (); 
    94          
    95     ArrayList item_list = XMLTools.getNamedElementList ((Element)metadataListNode, 
    96                             StaticStrings.METADATA_STR, StaticStrings.NAME_ATTRIBUTE, att_value); 
    97     if (item_list == null) { 
    98       return null; 
    99     } 
    100          
    101     for (int i=0; i<item_list.size (); i++) { 
    102       Element item = (Element)item_list.get (i); 
    103       String text = XMLTools.getNodeText (item); 
    104              
    105       //If there is nothing to display, don't bother creating the element 
    106       if (text == "") { 
    107     continue; 
    108       } 
    109       //get the value in 'lang=value' 
    110       String lang = item.getAttribute (StaticStrings.LANG_STR); 
    111              
    112       Element element = to.createElement (ele_name); 
    113       element.setAttribute (StaticStrings.NAME_ATTRIBUTE, att_value); 
    114       element.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
    115       element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    116       element.setAttribute (StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR); 
    117       XMLTools.setNodeText (element, text); 
    118              
    119       metadata_list.add (element); 
    120     } 
    121     return metadata_list; 
    122   } 
    123   // 'to' is the internal structure 
    124   static private void doMGIndexes (Document to, Node searchNode) { 
    125     Element toElement = to.getDocumentElement (); 
    126     Element indexes_element = to.createElement (StaticStrings.INDEXES_ELEMENT);//<Indexes> 
    127     indexes_element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    128     indexes_element.setAttribute (StaticStrings.MGPP_ATTRIBUTE, StaticStrings.FALSE_STR); 
    129          
    130     NodeList index_children = ((Element)searchNode).getElementsByTagName (StaticStrings.INDEX_LOW_STR);//index 
    131     int num_nodes = index_children.getLength (); 
    132          
    133     for (int i=0; i<num_nodes; i++) { 
    134       Element e = (Element)index_children.item (i); 
    135       String index_str = e.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    136       String index_str_display = index_str;//used for creating collectionmetadata for this index 
    137       Element index_element = to.createElement (StaticStrings.INDEX_ELEMENT);//<Index> 
    138              
    139       // For mg, it's the 'Old G2.38 and earlier' that use level:source tuplets, but we double check it anyway 
    140       boolean old_index = true; 
    141       if(index_str.indexOf (StaticStrings.COLON_CHARACTER) == -1) { 
    142     // It doesn't contain ':' character 
    143     System.err.println ("Something is wrong! the index should be level:source tuplets."); 
    144     old_index = false; 
    145       } 
    146       else { 
    147     // Handling 'index' element 
    148     index_element.setAttribute (StaticStrings.LEVEL_ATTRIBUTE, 
    149                     index_str.substring (0, index_str.indexOf (StaticStrings.COLON_CHARACTER))); 
    150     index_str = index_str.substring (index_str.indexOf (StaticStrings.COLON_CHARACTER) + 1); 
    151                  
    152     //Each index may have a list of comma-separated strings. 
    153     //split them into 'content' elements in the internal structure 
    154     StringTokenizer content_tokenizer = new StringTokenizer (index_str, StaticStrings.COMMA_CHARACTER); 
    155     //index_str = ""; 
    156     while(content_tokenizer.hasMoreTokens ()) { 
    157       // Replace index_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject. 
    158                      
    159                      
    160       Element content_element = to.createElement (StaticStrings.CONTENT_ELEMENT); 
    161       String content_str = content_tokenizer.nextToken (); 
    162       // Since the contents of indexes have to be certain keywords, or metadata elements, 
    163       //if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace. 
    164       if(content_str.indexOf (StaticStrings.NS_SEP) == -1) { 
    165         if(content_str.equals (StaticStrings.TEXT_STR) || 
    166            (!old_index && content_str.equals (StaticStrings.ALLFIELDS_STR))) { 
    167           // in this case, do nothing 
    168         } 
    169         else { 
    170           content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str; 
    171         } 
    172       } 
    173                      
    174       content_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, content_str); 
    175       index_element.appendChild (content_element); 
    176       content_element = null; 
    177     }   // while ends 
    178                  
    179     indexes_element.appendChild (index_element); 
    180                  
    181     // Handling 'displayItem' elements and Constructing 'collectionmetadata' elements 
    182     // Use the fully qualified index names 
    183     ArrayList collectionmetadata_list = doDisplayItemList (to, e, StaticStrings.NAME_ATTRIBUTE, index_str_display); 
    184     appendArrayList (toElement, collectionmetadata_list); 
    185       } //else ends 
    186     } //for loop ends 
    187     appendProperly (toElement, indexes_element); 
    188          
    189     //***// 
    190     // create another set of <indexes> which will be used when user switches to MGPP/LUCENE 
    191     // i.e. we build a default index set for a start 
    192          
    193     String []index_strs = 
    194       {StaticStrings.TEXT_STR, 
    195        StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.TITLE_ELEMENT, 
    196        StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.SOURCE_ELEMENT}; 
    197           
    198     Element mgpp_indexes = to.createElement (StaticStrings.INDEXES_ELEMENT);//<Indexes> 
    199     mgpp_indexes.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
    200     mgpp_indexes.setAttribute (StaticStrings.MGPP_ATTRIBUTE, StaticStrings.TRUE_STR); 
    201     for (int i=0; i<index_strs.length; i++) { 
    202       Element index_element = to.createElement (StaticStrings.INDEX_ELEMENT);//<Index> 
    203       Element content_element = to.createElement (StaticStrings.CONTENT_ELEMENT); 
    204       content_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, index_strs[i]); 
    205       index_element.appendChild (content_element); 
    206       mgpp_indexes.appendChild (index_element); 
    207               
    208       // Contructing 'collectionmetadata' elements for 'mgpp' indexes 
    209       Element collectionmetadata = to.createElement (StaticStrings.COLLECTIONMETADATA_ELEMENT); 
    210       collectionmetadata.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    211       collectionmetadata.setAttribute (StaticStrings.NAME_ATTRIBUTE, index_strs[i]); 
    212       collectionmetadata.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR); 
    213       if (index_strs[i].indexOf (StaticStrings.NS_SEP) != -1) { 
    214     index_strs[i] = index_strs[i].substring (index_strs[i].indexOf (StaticStrings.NS_SEP) + 1); 
    215       } 
    216       XMLTools.setNodeText (collectionmetadata, index_strs[i]); 
    217               
    218       appendProperly (toElement, collectionmetadata); 
    219               
    220     } 
    221     appendProperly (toElement, mgpp_indexes); 
    222   } 
    223      
    224   //This is actually doing indexes for both mgpp and lucene 
    225   static private void doMGPPIndexes (Document to, Node searchNode) { 
    226     Element toElement = to.getDocumentElement (); 
    227     Element indexes_element = to.createElement (StaticStrings.INDEXES_ELEMENT);//<Indexes> 
    228     indexes_element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    229     indexes_element.setAttribute (StaticStrings.MGPP_ATTRIBUTE, StaticStrings.TRUE_STR); 
    230          
    231     NodeList index_children = ((Element)searchNode).getElementsByTagName (StaticStrings.INDEX_LOW_STR);//index 
    232     int num_nodes = index_children.getLength (); 
    233          
    234     for (int i=0; i<num_nodes; i++) { 
    235              
    236       Element index_element = to.createElement (StaticStrings.INDEX_ELEMENT);//<Index> 
    237       Element e = (Element)index_children.item (i); 
    238       String index_str = e.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    239       String index_str_display = index_str;//for creating collectionmetadata for this index  
    240              
    241       // Handling 'index' element 
    242       // Double check to make sure it's not colon separated style index. 
    243       boolean old_index = false; 
    244       if(index_str.indexOf (StaticStrings.COLON_CHARACTER) != -1) { 
    245     System.err.println ("Something is wrong! the index should NOT be level:source tuplets style."); 
    246     old_index = true; 
    247       } 
    248       //Each index may have a list of comma-separated strings. 
    249       //split them into 'content' elements in the internal structure 
    250       StringTokenizer content_tokenizer = new StringTokenizer (index_str, StaticStrings.COMMA_CHARACTER); 
    251       //index_str = ""; 
    252       while(content_tokenizer.hasMoreTokens ()) { 
    253     // Replace index_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject.              
    254                  
    255     Element content_element = to.createElement (StaticStrings.CONTENT_ELEMENT); 
    256     String content_str = content_tokenizer.nextToken (); 
    257     // Since the contents of indexes have to be certain keywords, or metadata elements, if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace. 
    258     if(content_str.indexOf (StaticStrings.NS_SEP) == -1) { 
    259       if(content_str.equals (StaticStrings.TEXT_STR)) { 
    260         // in this case, do nothing 
    261       } 
    262       else { 
    263         content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str; 
    264       } 
    265     } 
    266     content_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, content_str); 
    267     index_element.appendChild (content_element); 
    268     content_element = null; 
    269       } //while ends 
    270              
    271       indexes_element.appendChild (index_element); 
    272              
    273              
    274       index_element = null; 
    275              
    276       // Handling 'displayItem' element of this 'index' element 
    277       // 'e' is the parent element 'index' of 'displayItem' element 
    278       ArrayList collectionmetadata_list = doDisplayItemList (to, e, StaticStrings.NAME_ATTRIBUTE, index_str_display); 
    279       appendArrayList (toElement, collectionmetadata_list); 
    280              
    281              
    282     } // for loop ends 
    283     toElement.appendChild (indexes_element); 
    284          
    285     // create another set of <indexes> which will be used when user switches to MG 
    286     // i.e. we build a default index set for a start 
    287     Element mg_indexes = to.createElement (StaticStrings.INDEXES_ELEMENT);//<Indexes> 
    288     mg_indexes.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
    289     mg_indexes.setAttribute (StaticStrings.MGPP_ATTRIBUTE, StaticStrings.FALSE_STR); 
    290          
    291     //put the namespace '.ex' as prefix to the indexes 
    292     String []index_strs = 
    293       {StaticStrings.TEXT_STR, 
    294        StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.TITLE_ELEMENT, 
    295        StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.SOURCE_ELEMENT}; 
    296     for (int i=0; i<index_strs.length; i++) { 
    297       Element index_element = to.createElement (StaticStrings.INDEX_ELEMENT);//<Index> 
    298       index_element.setAttribute (StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR); 
    299       Element content_element = to.createElement (StaticStrings.CONTENT_ELEMENT); 
    300       content_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, index_strs[i]); 
    301       index_element.appendChild (content_element); 
    302               
    303       mg_indexes.appendChild (index_element); 
    304               
    305       // Contructing 'collectionmetadata' elements for 'mg' indexes 
    306       Element collectionmetadata = to.createElement (StaticStrings.COLLECTIONMETADATA_ELEMENT); 
    307       collectionmetadata.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    308       String temp = StaticStrings.DOCUMENT_STR.concat (StaticStrings.COLON_CHARACTER).concat (index_strs[i]); 
    309       collectionmetadata.setAttribute (StaticStrings.NAME_ATTRIBUTE, temp); 
    310       collectionmetadata.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR); 
    311       if (index_strs[i].indexOf (StaticStrings.NS_SEP) != -1) { 
    312     index_strs[i] = index_strs[i].substring (index_strs[i].indexOf (StaticStrings.NS_SEP) + 1); 
    313       } 
    314       XMLTools.setNodeText (collectionmetadata, index_strs[i]); 
    315               
    316       appendProperly (toElement, collectionmetadata); 
    317               
    318     } 
    319     toElement.appendChild (mg_indexes); 
    320           
    321   } 
    322      
    323   static private void doDisplayFormat (Document to, Element from) { 
    324     //display element in the xml file 
    325     Element de = (Element)XMLTools.getChildByTagName (from, StaticStrings.DISPLAY_STR); 
    326     if (de == null) { 
    327       return; 
    328     } 
    329     //format element in the display element 
    330     Element fe = (Element)XMLTools.getChildByTagName (de, StaticStrings.FORMAT_STR); 
    331  
    332     to.getDocumentElement ().appendChild (doFormat(to, fe, StaticStrings.DISPLAY_STR)); 
    333   } 
    334  
    335   //construct 'DefaultIndex' element in the internal structure from collectionConfig.xml 
    336   static private void doDefaultIndex (Document to, Node searchNode) { 
    337     Element toElement = to.getDocumentElement (); 
    338     Element default_index_element = to.createElement (StaticStrings.INDEX_DEFAULT_ELEMENT); 
    339     default_index_element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    340          
    341     Element e = (Element)XMLTools.getChildByTagName (searchNode, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE);//defaultIndex 
    342     if (e == null) { 
    343       return; 
    344     } 
    345     String index_str = e.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    346          
    347     boolean old_index = false; 
    348     if(index_str.indexOf (StaticStrings.COLON_CHARACTER) != -1) { 
    349       //The index is 'level:source tuplets' which is for mg. Take out 'level' 
    350       old_index = true; 
    351       default_index_element.setAttribute (StaticStrings.LEVEL_ATTRIBUTE, 
    352                       index_str.substring (0, index_str.indexOf (StaticStrings.COLON_CHARACTER))); 
    353       index_str = index_str.substring (index_str.indexOf (StaticStrings.COLON_CHARACTER) + 1); 
    354     } else { 
    355       default_index_element.setAttribute (StaticStrings.LEVEL_ATTRIBUTE, ""); 
    356     } 
    357          
    358     //Each index may have a list of comma-separated strings. 
    359     //split them into 'content' elements in the internal structure 
    360     StringTokenizer content_tokenizer = new StringTokenizer (index_str, StaticStrings.COMMA_CHARACTER); 
    361     while(content_tokenizer.hasMoreTokens ()) { 
    362       Element content_element = to.createElement (StaticStrings.CONTENT_ELEMENT); 
    363       String content_str = content_tokenizer.nextToken (); 
    364       // Since the contents of indexes have to be certain keywords, or metadata elements, if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace. 
    365       if(content_str.indexOf (StaticStrings.NS_SEP) == -1) { 
    366     if(content_str.equals (StaticStrings.TEXT_STR) || 
    367        (!old_index && content_str.equals (StaticStrings.ALLFIELDS_STR))) { 
    368       // in this case, do nothing 
    369     } 
    370     else { 
    371       content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str; 
    372     } 
    373       } 
    374  
    375       content_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, content_str); 
    376       default_index_element.appendChild (content_element); 
    377       content_element = null; 
    378     } 
    379     appendProperly (toElement, default_index_element); 
    380   } 
    381   // For mg, this method is still called, but make it 'assigned=false' 
    382   static private void doDefaultLevel (Document to, Node searchNode) { 
    383     Element toElement = to.getDocumentElement (); 
    384     Element default_index_option = to.createElement (StaticStrings.INDEXOPTION_DEFAULT_ELEMENT); 
    385     default_index_option.setAttribute (StaticStrings.NAME_STR, StaticStrings.LEVEL_DEFAULT_STR); 
    386          
    387     Element e = (Element)XMLTools.getChildByTagName (searchNode, StaticStrings.LEVEL_DEFAULT_ELEMENT); 
    388     if (e != null) { 
    389       default_index_option.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    390       String level = e.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    391       default_index_option.setAttribute (StaticStrings.VALUE_ATTRIBUTE, level); 
    392     } else { 
    393       //In the case of mg, there's no level! build a default one using 'assigned=false value=document' 
    394       default_index_option.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
    395       default_index_option.setAttribute (StaticStrings.VALUE_ATTRIBUTE, StaticStrings.DOCUMENT_STR); 
    396     } 
    397     appendProperly (toElement, default_index_option); 
    398   } 
    399      
    400   // Transform plugins (pluginListNode) of collectionConfig.xml into the internal structure (i.e. Document to) 
    401   static private void doPlugin (Document to, Node pluginListNode) { 
    402     Element toElement = to.getDocumentElement (); 
    403     NodeList plugin_children = ((Element)pluginListNode).getElementsByTagName (StaticStrings.PLUGIN_STR); 
    404     int plugin_nodes = plugin_children.getLength (); 
    405          
    406     if (plugin_nodes < 1) { 
    407       return; 
    408     } 
    409          
    410     for (int i=0; i<plugin_nodes; i++) { 
    411       Element e = (Element)plugin_children.item (i); 
    412       String str = e.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    413       str = Utility.ensureNewPluginName(str); 
    414       Element plugin_element = to.createElement (StaticStrings.PLUGIN_ELEMENT); 
    415       plugin_element.setAttribute (StaticStrings.TYPE_ATTRIBUTE, str); 
    416              
    417              
    418       NodeList option_children = e.getElementsByTagName (StaticStrings.OPTION_STR); 
    419              
    420       for (int j=0; j<option_children.getLength (); j++) { 
    421     Element el = (Element)option_children.item (j); 
    422     String name_str = el.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    423     if (name_str.startsWith (StaticStrings.MINUS_CHARACTER)) { 
    424       name_str = name_str.substring (1); 
    425     } 
    426     String value_str = el.getAttribute (StaticStrings.VALUE_ATTRIBUTE); 
    427     Element option_element = null; 
    428                  
    429     if (name_str.equals ("") && !value_str.equals ("")) { 
    430       continue; 
    431     } 
    432                  
    433                  
    434     option_element = to.createElement (StaticStrings.OPTION_ELEMENT); 
    435     option_element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    436     if(name_str.equals (StaticStrings.RECPLUG_STR) && value_str.equals (StaticStrings.USE_METADATA_FILES_ARGUMENT)) { 
    437       continue; // ignore this option 
    438     } 
    439                  
    440     if(value_str != null) { 
    441       // Remove any speech marks appended in strings containing whitespace 
    442       if(value_str.startsWith (StaticStrings.SPEECH_CHARACTER) && value_str.endsWith (StaticStrings.SPEECH_CHARACTER)) { 
    443         value_str = value_str.substring (1, value_str.length () - 1); 
    444       } 
    445       if(name_str.equals (StaticStrings.METADATA_STR)) { 
    446         // The metadata argument must be the fully qualified name of a metadata element, so if it doesn't yet have a namespace, append the extracted metadata namespace. 
    447         String[] values = value_str.split (StaticStrings.COMMA_CHARACTER); 
    448         value_str = ""; 
    449         for (int k=0; k<=values.length-1; k++) { 
    450           if (values[k].indexOf (StaticStrings.NS_SEP) == -1) { 
    451         values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k]; 
    452           } 
    453  
    454           if (k < values.length-1) { 
    455         value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER; 
    456                                  
    457           } else { 
    458         value_str = value_str + values[k]; 
    459           } 
    460         } 
    461       } 
    462     } 
    463     if (!name_str.equals ("")) { 
    464       option_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    465     } 
    466     if (!value_str.equals ("")) { 
    467       XMLTools.setNodeText (option_element, value_str); 
    468     } 
    469     plugin_element.appendChild (option_element); 
    470                  
    471       } 
    472              
    473       appendProperly (toElement, plugin_element); 
    474     } 
    475          
    476   } 
    477      
    478   //Handle classifiers 
    479   static private void doClassifier (Document to, Node browseNode) { 
    480     Element toElement = to.getDocumentElement (); 
    481     NodeList classifier_children = ((Element)browseNode).getElementsByTagName (StaticStrings.CLASSIFIER_STR); 
    482     int num_nodes = classifier_children.getLength (); 
    483          
    484     if (num_nodes < 1) { 
    485       return; 
    486     } 
    487          
    488     for (int i=0; i<num_nodes; i++) { 
    489       Element e = (Element)classifier_children.item (i); 
    490       String str = e.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    491       Element classify_element = to.createElement (StaticStrings.CLASSIFY_ELEMENT); 
    492       classify_element.setAttribute (StaticStrings.TYPE_ATTRIBUTE, str); 
    493              
    494       String options_str = ""; 
    495       NodeList option_children = e.getElementsByTagName (StaticStrings.OPTION_STR); 
    496       for (int j=0; j<option_children.getLength (); j++) { 
    497     Element el = (Element)option_children.item (j); 
    498     String name_str = el.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    499     options_str = options_str + ((name_str.equals(""))? "" : (" " + name_str)); 
    500     if (name_str.startsWith (StaticStrings.MINUS_CHARACTER)) { 
    501       name_str = name_str.substring (1); 
    502     } 
    503     String value_str = el.getAttribute (StaticStrings.VALUE_ATTRIBUTE); 
    504     options_str = options_str + ((name_str.equals(""))? "" : (" " + value_str)); 
    505     Element option_element = null; 
    506                  
    507     if (name_str.equals ("") && !value_str.equals ("")) { 
    508       continue; //invalid condition 
    509     } 
    510                  
    511     option_element = to.createElement (StaticStrings.OPTION_ELEMENT); 
    512     option_element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    513                  
    514     if (!name_str.equals ("")) { 
    515       option_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    516     } 
    517                  
    518     if (!value_str.equals ("") && name_str.equals (StaticStrings.METADATA_STR)) { 
    519       // The metadata argument must be the fully qualified name of a metadata element, so if it doesn't yet have a namespace, append the extracted metadata namespace. 
    520       String[] values = value_str.split (StaticStrings.COMMA_CHARACTER); 
    521       value_str = ""; 
    522       for (int k=0; k<=values.length-1; k++) { 
    523         if (values[k].indexOf (StaticStrings.NS_SEP) == -1) { 
    524           values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k]; 
    525         } 
    526         else { 
    527           MetadataElement metadata_element = MetadataTools.getMetadataElementWithName (values[k]); 
    528           if (metadata_element != null) { 
    529         values[k] = metadata_element.getDisplayName (); 
    530           } 
    531         } 
    532         if (k < values.length-1) { 
    533           value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER; 
    534         } else { 
    535           value_str = value_str + values[k]; 
    536         } 
    537       } 
    538     } 
    539                  
    540     if (value_str != null && !value_str.equals ("")) { 
    541       XMLTools.setNodeText (option_element, value_str); 
    542     } 
    543     classify_element.appendChild (option_element); 
    544       } 
    545       //format element for this classifier 
    546       Element format = (Element)XMLTools.getChildByTagName (e, StaticStrings.FORMAT_STR); 
    547       if(format != null) { 
    548     classify_element.appendChild (doFormat(to, format, null)); 
    549       } 
    550       appendProperly (toElement, classify_element); 
    551     } 
    552          
    553     // default format statement for all classifiers 
    554     Element default_classifier_format = (Element)XMLTools.getChildByTagName (browseNode, StaticStrings.FORMAT_STR); 
    555  
    556     to.getDocumentElement ().appendChild (doFormat(to, default_classifier_format, StaticStrings.BROWSE_STR)); 
    557   } 
    558   static private Element doFormat(Document to, Element format, String name_str) { 
    559     Element format_element = to.createElement (StaticStrings.FORMAT_STR); 
    560     if (name_str != null) { 
    561       format_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    562     } 
    563      
    564     // Don't write out an empty format statement of <format/> (i.e. format has no child nodes) 
    565     // as this will end up embedded in another format statement as <format><format/><format /> 
    566     // This doubling up of format stmts will then prevent GLI from opening the collection again. 
    567     if (format != null && format.hasChildNodes()) { // not an empty format statement 
    568       String gsf_text = XMLTools.xmlNodeToStringWithoutIndenting(format); 
    569  
    570       if (gsf_text.startsWith("<") && (gsf_text.indexOf("<") != gsf_text.lastIndexOf("<"))) { 
    571     gsf_text = gsf_text.substring(gsf_text.indexOf("<gsf"), 
    572                       gsf_text.indexOf(StaticStrings.FORMAT_END_TAG)); 
    573       } 
    574        
    575       XMLTools.setNodeText(format_element, gsf_text); 
    576     } 
    577     return format_element; 
    578   } 
    579   // Handling 'subcollection' elements in 'search' element of 'collectionConfig.xml' 
    580   static private void doSubcollection (Document to, Node searchNode) { 
    581     Element toElement = to.getDocumentElement (); 
    582     NodeList sub_children = ((Element)searchNode).getElementsByTagName (StaticStrings.SUBCOLLECTION_STR); 
    583     int sub_nodes = sub_children.getLength (); 
    584          
    585     // There is no subcollection 
    586     if (sub_nodes < 1) { 
    587       return; 
    588     } 
    589          
    590     for (int i=0; i<sub_nodes; i++) { 
    591       Element sub_child = (Element)sub_children.item (i); 
    592       String name_str = sub_child.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    593       String filter_str = sub_child.getAttribute (StaticStrings.FILTER_ATTRIBUTE); 
    594              
    595       // filter_str is in the form '<! (if set)><metadata>/<metadata value>/<flag (if any)>' 
    596              
    597       int pos = filter_str.indexOf (StaticStrings.SEPARATOR_CHARACTER); 
    598       String meta_str = ""; 
    599       String meta_value_str = ""; 
    600       String clude_str = ""; 
    601       String flag_str = ""; 
    602       if (pos == -1) { 
    603                  
    604     meta_str = meta_value_str = filter_str; 
    605     clude_str = StaticStrings.INCLUDE_STR; 
    606       } else { 
    607     clude_str = StaticStrings.INCLUDE_STR; 
    608     if (filter_str.startsWith (StaticStrings.EXCLAMATION_CHARACTER)) { 
    609       clude_str = StaticStrings.EXCLUDE_STR; 
    610       // Peel off "!" 
    611       filter_str = filter_str.substring (StaticStrings.EXCLAMATION_CHARACTER.length ()); 
    612     } 
    613                  
    614     String[] strs = filter_str.split (StaticStrings.SEPARATOR_CHARACTER); 
    615     if (strs[0] != null && strs[0] != "") { 
    616       meta_str = strs[0]; 
    617     } 
    618     if(!meta_str.equals (StaticStrings.FILENAME_STR) && meta_str.indexOf (StaticStrings.NS_SEP) == -1) { 
    619       meta_str = StaticStrings.EXTRACTED_NAMESPACE + meta_str; 
    620     } 
    621                  
    622     if (strs[1] != null && strs[1] != "") { 
    623       meta_value_str = strs[1]; 
    624     } 
    625     if (strs.length > 2) { 
    626       //This means there has been set a flag 
    627       if (strs[2] != null && strs[2] != "") { 
    628         flag_str = strs[2]; 
    629       } 
    630     } 
    631       } 
    632       Element subcollection_element = to.createElement (StaticStrings.SUBCOLLECTION_ELEMENT); 
    633       subcollection_element.setAttribute (StaticStrings.NAME_STR, name_str); 
    634       subcollection_element.setAttribute (StaticStrings.CONTENT_ATTRIBUTE, meta_str); 
    635       subcollection_element.setAttribute (StaticStrings.TYPE_ATTRIBUTE, clude_str); 
    636       if (flag_str != "") { 
    637     subcollection_element.setAttribute (StaticStrings.OPTIONS_ATTRIBUTE, flag_str); 
    638       } 
    639       XMLTools.setNodeText (subcollection_element, meta_value_str); 
    640              
    641       toElement.appendChild (subcollection_element); 
    642     } 
    643   } 
    644   //Handle levels (document, section). In the internal structure, the element is called 'IndexOption' 
    645   static private void doLevel (Document to, Node searchNode) { 
    646     Element toElement = to.getDocumentElement (); 
    647     NodeList level_children = ((Element)searchNode).getElementsByTagName (StaticStrings.LEVEL_ATTRIBUTE); 
    648     int level_nodes = level_children.getLength (); 
    649          
    650     // it's mg, there's no level. So we construct a default 'indexOption' in the internal structure 
    651     if (level_nodes < 1) { 
    652       Element index_option = to.createElement (StaticStrings.INDEXOPTIONS_ELEMENT); 
    653       index_option.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
    654       index_option.setAttribute (StaticStrings.NAME_STR, StaticStrings.LEVELS_STR); 
    655              
    656       Element option_element = to.createElement (StaticStrings.OPTION_ELEMENT); 
    657       option_element.setAttribute (StaticStrings.NAME_STR, StaticStrings.DOCUMENT_STR); 
    658       index_option.appendChild (option_element); 
    659              
    660       appendProperly (toElement, index_option); 
    661              
    662       return; 
    663     } 
    664          
    665     Element index_option = to.createElement (StaticStrings.INDEXOPTIONS_ELEMENT); 
    666     index_option.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    667     index_option.setAttribute (StaticStrings.NAME_STR, StaticStrings.LEVELS_STR); 
    668          
    669     for (int i=0; i<level_nodes; i++) { 
    670       Element level_element = (Element)level_children.item (i); 
    671       String level_str = level_element.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    672       Element option_element = to.createElement (StaticStrings.OPTION_ELEMENT); 
    673       option_element.setAttribute (StaticStrings.NAME_STR, level_str); 
    674       index_option.appendChild (option_element); 
    675              
    676              
    677       // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'level' element 
    678       ArrayList displayItem_list = XMLTools.getNamedElementList (level_element, 
    679                                  StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR); 
    680       if (displayItem_list == null) { 
    681     return ; 
    682       } 
    683       for (int j=0; j<displayItem_list.size (); j++) { 
    684     Element item = (Element)displayItem_list.get (j); 
    685     String text = XMLTools.getNodeText (item); 
    686     String lang = item.getAttribute (StaticStrings.LANG_ATTRIBUTE); 
    687                  
    688     //If there is nothing to display, don't bother creating the element 
    689     if (text == "") { 
    690       continue; 
    691     } 
    692     Element collectionmetadata = to.createElement (StaticStrings.COLLECTIONMETADATA_ELEMENT); 
    693     collectionmetadata.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    694     collectionmetadata.setAttribute (StaticStrings.NAME_ATTRIBUTE, level_str); 
    695     collectionmetadata.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
    696     XMLTools.setNodeText (collectionmetadata, text); 
    697                  
    698     appendProperly (toElement, collectionmetadata); 
    699       } 
    700     } 
    701     appendProperly (toElement, index_option); 
    702   } 
    703   //Handle 'indexSubcollection' element of collectionConfig.xml,  which is called 'SubcollectionIndexes' in the internal structure. These contain the subcollection indexes (i.e. the filter or filter combinations), and displayed words for the filter names. 
    704   static private void doIndexSubcollection (Document to, Node searchNode) { 
    705     Element toElement = to.getDocumentElement (); 
    706     NodeList index_sub_children = ((Element)searchNode).getElementsByTagName (StaticStrings.SUBCOLLECTION_INDEX_ELEMENT); 
    707     int num_nodes = index_sub_children.getLength (); 
    708          
    709     // there is no subcollection index 
    710     if (num_nodes < 1) { 
    711       return; 
    712     } 
    713          
    714     Element subcollection_indexes = to.createElement (StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT); 
    715          
    716     for (int i=0; i<num_nodes; i++) { 
    717       Element index_element = to.createElement (StaticStrings.INDEX_ELEMENT); 
    718       Element index_sub_child = (Element)index_sub_children.item (i); 
    719       String name_str = index_sub_child.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    720              
    721       // name_str is in the form of comma separated strings, each of which is a subcollection filter name 
    722       String[] filters = name_str.split (StaticStrings.COMMA_CHARACTER); 
    723       for (int j=0; j<filters.length; j++) { 
    724                  
    725     Element content_element = to.createElement (StaticStrings.CONTENT_ELEMENT); 
    726     content_element.setAttribute (StaticStrings.NAME_STR, filters[j]); 
    727     index_element.appendChild (content_element); 
    728       } 
    729       subcollection_indexes.appendChild (index_element); 
    730              
    731       // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'indexSubcollection' element 
    732       ArrayList displayItem_list = XMLTools.getNamedElementList (index_sub_child, 
    733                                  StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR); 
    734       if (displayItem_list == null) { 
    735     // there is no display item for this element 
    736     continue; 
    737       } 
    738       for (int j=0; j<displayItem_list.size (); j++) { 
    739     Element item = (Element)displayItem_list.get (j); 
    740     String text = XMLTools.getNodeText (item); 
    741     String lang = item.getAttribute (StaticStrings.LANG_ATTRIBUTE); 
    742                  
    743     //If there is nothing to display, don't bother creating the element 
    744     if (text == "") { 
    745       continue; 
    746     } 
    747     Element collectionmetadata = to.createElement (StaticStrings.COLLECTIONMETADATA_ELEMENT); 
    748     collectionmetadata.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    749     collectionmetadata.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    750     collectionmetadata.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
    751     XMLTools.setNodeText (collectionmetadata, text); 
    752                  
    753     appendProperly (toElement, collectionmetadata); 
    754       } 
    755     } 
    756     appendProperly (toElement, subcollection_indexes); 
    757   } 
    758   //Handle 'indexLanguage' element of collectionConfig.xml,  which is called 'Languages' in the internal structure. These contain the language indexes, and displayed words for those language index names. 
    759   static private void doIndexLanguage (Document to, Node searchNode) { 
    760     Element toElement = to.getDocumentElement (); 
    761     NodeList index_sub_children = ((Element)searchNode).getElementsByTagName (StaticStrings.LANGUAGE_INDEX_ELEMENT); 
    762     int num_nodes = index_sub_children.getLength (); 
    763          
    764     // there is no subcollection index 
    765     if (num_nodes < 1) { 
    766       return; 
    767     } 
    768          
    769     Element language_indexes = to.createElement (StaticStrings.LANGUAGES_ELEMENT); 
    770          
    771     for (int i=0; i<num_nodes; i++) { 
    772       Element language_element = to.createElement (StaticStrings.LANGUAGE_ELEMENT); 
    773       Element index_sub_child = (Element)index_sub_children.item (i); 
    774       String name_str = index_sub_child.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    775       language_element.setAttribute (StaticStrings.NAME_STR, name_str); 
    776       language_indexes.appendChild (language_element); 
    777              
    778       // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'indexLanguage' element 
    779       ArrayList displayItem_list = XMLTools.getNamedElementList (index_sub_child, 
    780                                  StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR); 
    781       if (displayItem_list == null) { 
    782     // there is no display item for this element 
    783     continue; 
    784       } 
    785       for (int j=0; j<displayItem_list.size (); j++) { 
    786     Element item = (Element)displayItem_list.get (j); 
    787     String text = XMLTools.getNodeText (item); 
    788     String lang = item.getAttribute (StaticStrings.LANG_ATTRIBUTE); 
    789                  
    790     //If there is nothing to display, don't bother creating the element 
    791     if (text == "") { 
    792       continue; 
    793     } 
    794     Element collectionmetadata = to.createElement (StaticStrings.COLLECTIONMETADATA_ELEMENT); 
    795     collectionmetadata.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    796     collectionmetadata.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    797     collectionmetadata.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
    798     XMLTools.setNodeText (collectionmetadata, text); 
    799                  
    800     appendProperly (toElement, collectionmetadata); 
    801       } 
    802     } 
    803     toElement.appendChild (language_indexes); 
    804   } 
    805  
    806   // Handling search types 
    807   static private void doSearchType (Document to, Node searchNode) { 
    808     NodeList type_children = ((Element)searchNode).getElementsByTagName (StaticStrings.SEARCHTYPE_ELEMENT); 
    809     int num_types = type_children.getLength(); 
    810     String searchtype_str = ""; 
    811     if (num_types < 1) { 
    812       // not defined yet, add in default 
    813       searchtype_str = "plain,simpleform,advancedform"; 
    814     } 
    815     else { 
    816       for(int i=0; i<num_types; i++) { 
    817     Node e = type_children.item (i); 
    818     String t = ((Element)e).getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    819     if (i>0) { 
    820       searchtype_str += ","; 
    821     } 
    822     searchtype_str += t; 
    823       } 
    824     } 
    825      
    826     // pretend its a format statement 
    827     Element search_type_element = to.createElement (StaticStrings.FORMAT_STR); 
    828     search_type_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT); 
    829     XMLTools.setNodeText(search_type_element, searchtype_str); 
    830     appendProperly (to.getDocumentElement (), search_type_element); 
    831      
    832   } 
    833  
    834   // Handling search format statement 
    835   static private void doSearchFormat (Document to, Node searchNode) { 
    836     // THere is currently just one format element for search. HOwever, need to check for old config files which used to have <format name="searchTypes"> 
    837     NodeList format_children = ((Element)searchNode).getElementsByTagName (StaticStrings.FORMAT_STR); 
    838     int format_nodes = format_children.getLength (); 
    839     if (format_nodes < 1) { 
    840       return; 
    841     } 
    842     Element format = null; 
    843     for(int i=0; i<format_nodes; i++) { 
    844       Node e = format_children.item (i); 
    845       if (e.hasAttributes () == false) { 
    846     //The format element for format statement has no attribute 
    847     format = (Element)e; 
    848       } 
    849     } 
    850     //format statement for search 
    851     if (format != null) {             
    852       (to.getDocumentElement ()).appendChild (doFormat(to, format, StaticStrings.SEARCH_STR)); 
    853     } 
    854   } 
    855   // Handling defaultIndexLanguage and languageMetadata in collectionConfig.xml ('elementNameFrom'); in the internal structure, they are called 'DefaultLanguage' and 'LanguageMetadata' ('elementNameTo') respectively. 
    856   // Converting from collectionConfig.xml to the internal xml structure. 
    857   static private void doLanguageMetadata (Document to, Node searchNode) { 
    858     Element toElement = to.getDocumentElement (); 
    859     String elementNameFrom = StaticStrings.LANGUAGE_METADATA_ELEMENT_STR; 
    860     String elementNameTo = StaticStrings.LANGUAGE_METADATA_ELEMENT; 
    861     Node from_element = XMLTools.getChildByTagName (searchNode, elementNameFrom); 
    862     if (from_element == null) { 
    863       return; // such an element not found 
    864     } 
    865          
    866     Element to_element = to.createElement (elementNameTo); 
    867          
    868     String name_str = ((Element)from_element).getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    869     if (name_str.indexOf (StaticStrings.NS_SEP) == -1) { 
    870       name_str = StaticStrings.EXTRACTED_NAMESPACE + name_str; 
    871     } 
    872     to_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    873     to_element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    874          
    875     toElement.appendChild (to_element); 
    876   } 
    877   static private void doReplaceListRef (Document to, Element from) { 
    878     Element toElement = to.getDocumentElement (); 
    879          
    880     NodeList replace_elements = from.getElementsByTagName(StaticStrings.REPLACELISTREF_STR); 
    881     int num_elems = replace_elements.getLength(); 
    882     if (num_elems < 1) { 
    883       return; 
    884     } 
    885     for (int i=0; i<num_elems; i++) { 
    886       Element to_element = XMLTools.duplicateElement (to, (Element)replace_elements.item(i), true); 
    887       toElement.appendChild (to_element); 
    888     } 
    889   } 
    890   static private void convertReplaceListRef (Document from, Document to) { 
    891     Element toElement = to.getDocumentElement (); 
    892          
    893     NodeList replace_elements = from.getDocumentElement().getElementsByTagName(StaticStrings.REPLACELISTREF_STR); 
    894     int num_elems = replace_elements.getLength(); 
    895     if (num_elems < 1) { 
    896       return; 
    897     } 
    898     for (int i=0; i<num_elems; i++) { 
    899       Element to_element = XMLTools.duplicateElement (to, (Element)replace_elements.item(i), true); 
    900       toElement.appendChild (to_element); 
    901     } 
    902   } 
    903  
    904   /** serviceRackList is currently not editable in GLI - just copy it in from config file and write it out again. */ 
    905   static private void doServiceRackList (Document to, Element from) { 
    906     Element toElement = to.getDocumentElement (); 
    907          
    908     Node srl_element = XMLTools.getChildByTagName (from, StaticStrings.SERVICE_RACK_LIST_ELEMENT); 
    909     if (srl_element == null) { 
    910       return; // such an element not found 
    911     } 
    912          
    913     Element to_element = XMLTools.duplicateElement (to, (Element)srl_element, true); 
    914     toElement.appendChild (to_element); 
    915   } 
    916   static private void convertServiceRackList (Document from, Document to) { 
    917     Element toElement = to.getDocumentElement (); 
    918          
    919     Node srl_element = XMLTools.getChildByTagName (from.getDocumentElement (), StaticStrings.SERVICE_RACK_LIST_ELEMENT); 
    920     if (srl_element == null) { 
    921       return; // such an element not found 
    922     } 
    923          
    924     Element to_element = XMLTools.duplicateElement (to, (Element)srl_element, true); 
    925     toElement.appendChild (to_element); 
    926   } 
    927   static private void doDefaultIndexLanguage (Document to, Node searchNode) { 
    928     Element toElement = to.getDocumentElement (); 
    929     String elementNameFrom = StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT; 
    930     String elementNameTo = StaticStrings.LANGUAGE_DEFAULT_ELEMENT; 
    931     Node from_element = XMLTools.getChildByTagName (searchNode, elementNameFrom); 
    932     if (from_element == null) { 
    933       return; // such an element not found 
    934     } 
    935          
    936     Element to_element = to.createElement (elementNameTo); 
    937          
    938     String name_str = ((Element)from_element).getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    939     to_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    940     to_element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    941          
    942     toElement.appendChild (to_element); 
    943   } 
    944      
    945   //Handle 'indexOption' (i.e. casefold, stem etc). In the internal structure, the element is called 'IndexOption' 
    946   static private void doIndexOption (Document to, Node searchNode) { 
    947     Element toElement = to.getDocumentElement (); 
    948     Node index_option_node = XMLTools.getChildByTagName (searchNode, StaticStrings.INDEXOPTION_STR); 
    949     if (index_option_node == null) { 
    950       return; 
    951     } 
    952     NodeList option_children = ((Element)index_option_node).getElementsByTagName (StaticStrings.OPTION_STR); 
    953     int option_nodes = option_children.getLength (); 
    954          
    955     // for lucene, there is no 'indexOption'. We build a default 'indexOption' and 'assigned=false' in case the user switches to mg or mgpp 
    956     if (option_nodes < 1) { 
    957       Element index_option = to.createElement (StaticStrings.INDEXOPTIONS_ELEMENT); 
    958       index_option.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
    959       index_option.setAttribute (StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR); 
    960       String[] option_str = 
    961     { StaticStrings.CASEFOLD_OPTION_STR, StaticStrings.STEM_OPTION_STR }; 
    962       for (int i=0; i<option_str.length; i++) { 
    963     Element option_element = to.createElement (StaticStrings.OPTION_ELEMENT); 
    964     option_element.setAttribute (StaticStrings.NAME_STR, option_str[i]); 
    965     index_option.appendChild (option_element); 
    966       } 
    967       appendProperly (toElement, index_option); 
    968       return; 
    969     } 
    970          
    971     Element index_option = to.createElement (StaticStrings.INDEXOPTIONS_ELEMENT); 
    972     index_option.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    973     index_option.setAttribute (StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR); 
    974          
    975     for (int i=0; i<option_nodes; i++) { 
    976       String option_str = ((Element)option_children.item (i)).getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    977       Element option_element = to.createElement (StaticStrings.OPTION_ELEMENT); 
    978       option_element.setAttribute (StaticStrings.NAME_STR, option_str); 
    979       index_option.appendChild (option_element); 
    980     } 
    981     appendProperly (toElement, index_option); 
    982   } 
    983      
    984   static private Element doBuildType (Document to, String att_value) { 
    985          
    986     //construct 'BuildType' element 
    987     Element element = to.createElement (StaticStrings.BUILDTYPE_ELEMENT); 
    988     element.setAttribute (StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR); 
    989     element.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR); 
    990     element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    991     element.setAttribute (StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR); 
    992  
    993     XMLTools.setNodeText (element, att_value); 
    994          
    995     return element; 
    996   } 
    997   
    998   static private Element doDatabaseType (Document to, String att_value) { 
    999          
    1000     //construct 'DatabaseType' element 
    1001     Element element = to.createElement (StaticStrings.DATABASETYPE_ELEMENT); 
    1002     element.setAttribute (StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR); 
    1003     element.setAttribute (StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR); 
    1004     element.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    1005     element.setAttribute (StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR); 
    1006  
    1007     XMLTools.setNodeText (element, att_value); 
    1008          
    1009     return element; 
    1010   } 
    1011      
    1012   // Convert 'description', 'smallicon' etc. 
    1013   static private void convertDisplayItemList (Document from, Document to) { 
    1014     Element displayItemList = to.createElement (StaticStrings.DISPLAYITEMLIST_STR); 
    1015     Element destination = to.getDocumentElement (); 
    1016          
    1017     String []att_values = 
    1018       {StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR, 
    1019        StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR, 
    1020        StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR, 
    1021        StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR}; 
    1022           
    1023     String []map_attrs = 
    1024       {StaticStrings.DESCRIPTION_STR, 
    1025        StaticStrings.SMALLICON_STR, 
    1026        StaticStrings.ICON_STR, 
    1027        StaticStrings.NAME_STR}; 
    1028            
    1029     for (int i=0; i<att_values.length; i++) { 
    1030                
    1031       //dOc 
    1032       ArrayList e_list = XMLTools.getNamedElementList (from.getDocumentElement (), 
    1033                                StaticStrings.COLLECTIONMETADATA_ELEMENT, 
    1034                                StaticStrings.NAME_ATTRIBUTE, att_values[i]); 
    1035       // if such elements don't exist, don't bother 
    1036       if (e_list == null) { 
    1037     continue; 
    1038       } 
    1039       for (int j=0; j<e_list.size (); j++) { 
    1040     Element e = (Element)e_list.get (j); 
    1041     if (e.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1042       continue; 
    1043     } 
    1044     String text = XMLTools.getNodeText (e); 
    1045     String lang = e.getAttribute (StaticStrings.LANGUAGE_ATTRIBUTE); 
    1046                    
    1047     Element displayItem = constructElement (StaticStrings.DISPLAYITEM_STR, map_attrs[i], 
    1048                         StaticStrings.LANG_STR, lang, text, to); 
    1049     displayItemList.appendChild (displayItem); 
    1050       } 
    1051                
    1052     } 
    1053     destination.appendChild (displayItemList); 
    1054   } 
    1055   // This method creates a DisplayItem element of the type of 'to' by using the ingredients from the element 'e' 
    1056   static private Element constructDisplayItem (Element e, Document to) { 
    1057     String lang_string = e.getAttribute (StaticStrings.LANGUAGE_ATTRIBUTE); 
    1058     String text = XMLTools.getNodeText (e); 
    1059     Element displayItem = to.createElement (StaticStrings.DISPLAYITEM_STR); 
    1060     displayItem.setAttribute (StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_ATTRIBUTE); 
    1061     displayItem.setAttribute (StaticStrings.LANG_STR, lang_string); 
    1062     XMLTools.setNodeText (displayItem, text); 
    1063     return displayItem; 
    1064   } 
    1065   static private void convertMetadataList (Document from, Document to) { 
    1066     Element metadataList = to.createElement (StaticStrings.METADATALIST_STR); 
    1067     Element destination = to.getDocumentElement (); 
    1068          
    1069     String []ele_names = 
    1070       {StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, 
    1071        StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, 
    1072        StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT}; 
    1073     String []att_names = 
    1074       {StaticStrings.COLLECTIONMETADATA_CREATOR_STR, 
    1075        StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR, 
    1076        StaticStrings.COLLECTIONMETADATA_PUBLIC_STR}; 
    1077     for (int i=0; i<ele_names.length; i++) { 
    1078       Element e = XMLTools.getNamedElement (from.getDocumentElement (), 
    1079                         ele_names[i], StaticStrings.NAME_ATTRIBUTE, att_names[i]); 
    1080       if (e == null) { 
    1081     continue; 
    1082       } 
    1083       String text = XMLTools.getNodeText (e); 
    1084       Element metadata = to.createElement (StaticStrings.METADATA_STR); 
    1085       metadata.setAttribute (StaticStrings.NAME_ATTRIBUTE, att_names[i]); 
    1086       metadata.setAttribute (StaticStrings.LANG_STR, StaticStrings.ENGLISH_LANGUAGE_STR); 
    1087       XMLTools.setNodeText (metadata, text); 
    1088       metadataList.appendChild (metadata); 
    1089     } 
    1090  
    1091     destination.appendChild (metadataList); 
    1092   } 
    1093   // This method creates an element with the name 'element_name' of the type of 'to' by using the other three strings 
    1094   static private Element constructElement (String element_name, String name_value, String lang_att, String lang_value, String text, Document to) { 
    1095     Element e = to.createElement (element_name); 
    1096     e.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    1097     e.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_value); 
    1098     e.setAttribute (lang_att, lang_value); 
    1099     XMLTools.setNodeText (e, text); 
    1100          
    1101     return e; 
    1102   } 
    1103   // Convert classify in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to) 
    1104   static private void convertClassifier (Document from, Document to) { 
    1105     Element browse_element = to.createElement (StaticStrings.BROWSE_STR); 
    1106     NodeList children = from.getDocumentElement ().getElementsByTagName (StaticStrings.CLASSIFY_ELEMENT); 
    1107          
    1108     int num_children = (children == null)? 0 : children.getLength (); 
    1109          
    1110     if (num_children == 0) { 
    1111       return ; 
    1112     } 
    1113          
    1114     for (int i=0; i<num_children; i++) { 
    1115              
    1116       Element child =  (Element)children.item (i); 
    1117       if (child.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1118     continue; 
    1119       } 
    1120       String str = child.getAttribute (StaticStrings.TYPE_ATTRIBUTE); 
    1121       Element classifier_element = to.createElement (StaticStrings.CLASSIFIER_STR); 
    1122       classifier_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, str); 
    1123              
    1124       NodeList option_children = child.getElementsByTagName (StaticStrings.OPTION_ELEMENT); 
    1125       for (int j=0; j<option_children.getLength (); j++) { 
    1126     Element el = (Element)option_children.item (j); 
    1127     if (el.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1128       continue; 
    1129     } 
    1130     String name_str = el.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1131     String value_str = XMLTools.getNodeText (el); 
    1132                  
    1133                  
    1134     if (name_str == null && value_str == null) { 
    1135       continue; 
    1136     } 
    1137     Element option_element = to.createElement (StaticStrings.OPTION_STR); 
    1138     if (name_str != null && name_str.equals (StaticStrings.METADATA_STR)) { 
    1139                      
    1140       // The metadata argument is the fully qualified name of a metadata element, so if it contains a namespace, remove the extracted metadata namespace as the build process doesn't know about it. 
    1141       String[] values = value_str.split (StaticStrings.COMMA_CHARACTER); 
    1142       value_str = ""; 
    1143       for (int k=0; k<=values.length-1; k++) { 
    1144         if(values[k].startsWith (StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) { 
    1145           values[k] = values[k].substring (StaticStrings.EXTRACTED_NAMESPACE.length ()); 
    1146         } 
    1147         else { 
    1148           MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName (values[k]); 
    1149           if (metadata_element != null) { 
    1150         values[k] = metadata_element.getFullName (); 
    1151           } 
    1152         } 
    1153         if (k < values.length-1) { 
    1154           value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER; 
    1155         } else { 
    1156           value_str = value_str + values[k]; 
    1157         } 
    1158       } 
    1159     } 
    1160                  
    1161     if (!name_str.equals ("")) { 
    1162       if (!name_str.startsWith (StaticStrings.MINUS_CHARACTER)) { 
    1163         name_str = StaticStrings.MINUS_CHARACTER + name_str; 
    1164       } 
    1165       option_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    1166     } 
    1167                  
    1168     if (!value_str.equals ("")) { 
    1169       option_element.setAttribute (StaticStrings.VALUE_ATTRIBUTE, value_str); 
    1170     } 
    1171                  
    1172     classifier_element.appendChild (option_element); 
    1173       } 
    1174              
    1175       //format element for this classifier 
    1176       Element e = (Element)XMLTools.getChildByTagName (child, StaticStrings.FORMAT_STR); 
    1177              
    1178       if (e != null) { 
    1179     classifier_element.appendChild (convertFormat(to, e)); 
    1180       } 
    1181       browse_element.appendChild (classifier_element); 
    1182     } 
    1183          
    1184     //convert default classifier format 
    1185     Element e = XMLTools.getNamedElement (from.getDocumentElement (), StaticStrings.FORMAT_STR, 
    1186                       StaticStrings.NAME_ATTRIBUTE,  StaticStrings.BROWSE_STR); 
    1187     browse_element.appendChild (convertFormat(to, e)); 
    1188          
    1189     to.getDocumentElement ().appendChild (browse_element); 
    1190   } 
    1191   static private Element convertFormat(Document to, Element e) { 
    1192     String format_str = XMLTools.getNodeText(e); 
    1193     Element format = to.createElement (StaticStrings.FORMAT_STR); 
    1194     //XMLTools.copyAllChildren (format, e); 
    1195     XMLTools.setNodeText(format, format_str);  
    1196     return format; 
    1197   } 
    1198   //convert format statement for search 
    1199   static private void convertSearchFormat (Document from, Document to) { 
    1200     Element search = (Element)XMLTools.getChildByTagName (to.getDocumentElement (), StaticStrings.SEARCH_STR); 
    1201     Element e = XMLTools.getNamedElement (from.getDocumentElement (), StaticStrings.FORMAT_STR, 
    1202                       StaticStrings.NAME_ATTRIBUTE,  StaticStrings.SEARCH_STR); 
    1203                                                  
    1204     search.appendChild (convertFormat(to, e)); 
    1205          
    1206   } 
    1207   //convert format statement for display of the documents 
    1208   static private void convertDisplayFormat (Document from, Document to) { 
    1209     Element e = XMLTools.getNamedElement (from.getDocumentElement (), StaticStrings.FORMAT_STR, 
    1210                       StaticStrings.NAME_ATTRIBUTE,  StaticStrings.DISPLAY_STR); 
    1211     if (e == null) { 
    1212       return; 
    1213     } 
    1214     Element display = to.createElement (StaticStrings.DISPLAY_STR); 
    1215     display.appendChild (convertFormat(to, e)); 
    1216     to.getDocumentElement ().appendChild (display); 
    1217   } 
    1218   // Convert plugins in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to) 
    1219   static private void convertPlugin (Document from, Document to) { 
    1220     Element import_element = to.createElement (StaticStrings.IMPORT_STR); 
    1221     Element plugin_list_element = to.createElement (StaticStrings.PLUGINLIST_STR); 
    1222          
    1223     NodeList children = from.getDocumentElement ().getElementsByTagName (StaticStrings.PLUGIN_ELEMENT); 
    1224     int num_children = (children == null)? 0 : children.getLength (); 
    1225     if (num_children == 0) { 
    1226       return ; 
    1227     } 
    1228          
    1229     for (int i=0; i<num_children; i++) { 
    1230              
    1231       Element child =  (Element)children.item (i); 
    1232       if (child.getAttribute (StaticStrings.SEPARATOR_ATTRIBUTE).equals (StaticStrings.TRUE_STR)) { 
    1233     continue; 
    1234       } 
    1235       if (child.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1236     continue; 
    1237       } 
    1238              
    1239       String str = child.getAttribute (StaticStrings.TYPE_ATTRIBUTE); 
    1240       Element plugin_element = to.createElement (StaticStrings.PLUGIN_STR); 
    1241       plugin_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, str); 
    1242              
    1243       NodeList option_children = child.getElementsByTagName (StaticStrings.OPTION_ELEMENT); 
    1244       for (int j=0; j<option_children.getLength (); j++) { 
    1245     Element el = (Element)option_children.item (j); 
    1246     if(!el.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.TRUE_STR)) { 
    1247       continue; 
    1248     } 
    1249     String name_str = el.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1250     String value_str = XMLTools.getNodeText (el); 
    1251                  
    1252                  
    1253     if (name_str == null && value_str == null) { 
    1254       continue; 
    1255     } 
    1256     Element option_element = to.createElement (StaticStrings.OPTION_STR); 
    1257     if (name_str != null && name_str.equals (StaticStrings.METADATA_STR)) { 
    1258                      
    1259       // The metadata argument is the fully qualified name of a metadata element, so if it contains a namespace, remove the extracted metadata namespace as the build process doesn't know about it, but ONLY if it is not embedded metadata (e.g. ex.dc.*) 
    1260       String[] values = value_str.split (StaticStrings.COMMA_CHARACTER); 
    1261       value_str = ""; 
    1262       for (int k=0; k<=values.length-1; k++) { 
    1263         if(values[k].startsWith (StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) { 
    1264           values[k] = values[k].substring (StaticStrings.EXTRACTED_NAMESPACE.length ()); 
    1265         } 
    1266  
    1267         if (k < values.length-1) { 
    1268           value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER; 
    1269         } else { 
    1270           value_str = value_str + values[k]; 
    1271         } 
    1272       } 
    1273     } 
    1274                  
    1275     if (!name_str.equals ("")) { 
    1276       if (!name_str.startsWith (StaticStrings.MINUS_CHARACTER)) { 
    1277         name_str = StaticStrings.MINUS_CHARACTER + name_str; 
    1278       } 
    1279       option_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    1280     } 
    1281                  
    1282     if (!value_str.equals ("")) { 
    1283       option_element.setAttribute (StaticStrings.VALUE_ATTRIBUTE, value_str); 
    1284     } 
    1285                  
    1286     plugin_element.appendChild (option_element); 
    1287       }//for loop ends 
    1288              
    1289       plugin_list_element.appendChild (plugin_element); 
    1290     }//for loop ends 
    1291          
    1292     import_element.appendChild (plugin_list_element); 
    1293          
    1294     //do the plugout element (used by building flax collections) 
    1295     Node plugout = XMLTools.getChildByTagNameIndexed (from.getDocumentElement (), PLUGOUT_ELEMENT, 0); 
    1296     if (plugout != null) { 
    1297       Element to_element = XMLTools.duplicateElement (to, (Element)plugout, true); 
    1298       import_element.appendChild (to_element); 
    1299     } 
    1300          
    1301     to.getDocumentElement ().appendChild (import_element); 
    1302   } 
    1303  
    1304   //Handle 'searchType' of collectionConfig.xml. In the internal structure, its also called 'searchType', eg. plain, form 
    1305   static private void convertSearchType (Document from, Document to) { 
    1306     Element e = XMLTools.getNamedElement (from.getDocumentElement (), StaticStrings.FORMAT_STR, 
    1307                       StaticStrings.NAME_ATTRIBUTE,  StaticStrings.SEARCHTYPE_ELEMENT);//searchType 
    1308          
    1309     if (e == null) { 
    1310       return; 
    1311     } 
    1312     String searchtype_str = XMLTools.getNodeText(e);  
    1313     //Get the 'search' element from 'to' 
    1314     Element search = (Element)XMLTools.getChildByTagName (to.getDocumentElement (), StaticStrings.SEARCH_STR); 
    1315  
    1316     String[] types = searchtype_str.split(","); 
    1317     for (int i=0; i<types.length; i++) { 
    1318       Element search_type_element = to.createElement (StaticStrings.SEARCHTYPE_ELEMENT); 
    1319       search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, types[i]); 
    1320       search.appendChild (search_type_element); 
    1321     } 
    1322   } 
    1323      
    1324   static private void convertBuildType (Document from, Document to) { 
    1325     Element e = XMLTools.getNamedElement (from.getDocumentElement (), 
    1326                       StaticStrings.BUILDTYPE_ELEMENT, 
    1327                       StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR); 
    1328     if (e == null) { 
    1329       return; 
    1330     } 
    1331     String indexer = XMLTools.getNodeText (e); 
    1332     Element search = to.createElement (StaticStrings.SEARCH_STR); 
    1333     search.setAttribute (StaticStrings.TYPE_ATTRIBUTE, indexer); 
    1334     to.getDocumentElement ().appendChild (search); 
    1335   } 
    1336   static private void convertDatabaseType (Document from, Document to) { 
    1337     Element e = XMLTools.getNamedElement (from.getDocumentElement (), 
    1338                       StaticStrings.DATABASETYPE_ELEMENT, 
    1339                       StaticStrings.NAME_ATTRIBUTE,  
    1340                       StaticStrings.DATABASETYPE_STR); 
    1341     if (e == null) { 
    1342       return; 
    1343     } 
    1344     String db = XMLTools.getNodeText (e); 
    1345     Element dbtype = to.createElement (StaticStrings.INFODB_STR); 
    1346     dbtype.setAttribute (StaticStrings.TYPE_ATTRIBUTE, db); 
    1347     to.getDocumentElement ().appendChild (dbtype); 
    1348   } 
    1349   static private void convertDefaultIndex (Document from, Document to, Element search) { 
    1350     Element source = from.getDocumentElement (); 
    1351          
    1352     Element default_index_element = (Element)XMLTools.getChildByTagName (source, StaticStrings.INDEX_DEFAULT_ELEMENT); 
    1353     if (default_index_element == null) { 
    1354       return; 
    1355     } 
    1356          
    1357     String indexer = search.getAttribute (StaticStrings.TYPE_ATTRIBUTE); 
    1358     String level_str = default_index_element.getAttribute (StaticStrings.LEVEL_ATTRIBUTE); 
    1359     // Debugging purposes 
    1360     if (level_str.equals ("") && indexer.equals (StaticStrings.MG_STR) ) { 
    1361       System.out.println ("Bug: DefaultIndex should have its level attribute not empty."); 
    1362     } 
    1363          
    1364     NodeList content_elements = default_index_element.getElementsByTagName (StaticStrings.CONTENT_ELEMENT); 
    1365     int content_elements_length = content_elements.getLength (); 
    1366          
    1367     // Don't output anything if no indexes are set 
    1368     if(content_elements_length == 0) { 
    1369       return ;// 
    1370     } 
    1371          
    1372     String index_str = ""; 
    1373          
    1374     if (indexer.equals (StaticStrings.MG_STR)) { 
    1375       //combine level with indexes 
    1376       index_str = level_str + StaticStrings.COLON_CHARACTER; 
    1377     } 
    1378     else { //for mgpp/lucene, just take index 
    1379       //do nothing 
    1380     } 
    1381          
    1382     for(int k = 0; k < content_elements_length; k++) { 
    1383       Element content_element = (Element) content_elements.item (k); 
    1384       if (content_element.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1385     continue; 
    1386       } 
    1387       String name_str = content_element.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1388              
    1389       if(name_str.startsWith (StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) { 
    1390     name_str = name_str.substring (StaticStrings.EXTRACTED_NAMESPACE.length ()); 
    1391       } 
    1392  
    1393       index_str = index_str + name_str; 
    1394              
    1395       // Make it comma separated string 
    1396       if(k < content_elements_length - 1) { 
    1397     index_str = index_str + StaticStrings.COMMA_CHARACTER; 
    1398       } 
    1399       content_element = null; 
    1400     }//for loop ends 
    1401          
    1402          
    1403     Element default_index = to.createElement (StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE); 
    1404     default_index.setAttribute (StaticStrings.NAME_ATTRIBUTE, index_str); 
    1405     search.appendChild (default_index); 
    1406          
    1407   } 
    1408   static private void convertSubcollection (Document from, Document to) { 
    1409     Element source = from.getDocumentElement (); 
    1410     //Get the 'search' element from 'to' which has already been created in 'convertBuildType' 
    1411     Element search = (Element)XMLTools.getChildByTagName (to.getDocumentElement (), StaticStrings.SEARCH_STR); 
    1412          
    1413     // Get the Subcollection element from the internal structure 
    1414     NodeList subcollection_elements = source.getElementsByTagName (StaticStrings.SUBCOLLECTION_ELEMENT); 
    1415     if (subcollection_elements == null) { 
    1416       return; 
    1417     } 
    1418     int subcollection_elements_length = subcollection_elements.getLength (); 
    1419          
    1420     if (subcollection_elements_length == 0) { // no 
    1421       return ; 
    1422     } 
    1423          
    1424     for(int j = 0; j < subcollection_elements_length; j++) { 
    1425              
    1426       Element e = (Element) subcollection_elements.item (j); 
    1427       if (e.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1428     continue; 
    1429       } 
    1430       String content = e.getAttribute (StaticStrings.CONTENT_ATTRIBUTE); 
    1431       String name = e.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1432       String options = e.getAttribute (StaticStrings.OPTIONS_ATTRIBUTE); 
    1433       String type = e.getAttribute (StaticStrings.TYPE_ATTRIBUTE); 
    1434       String text = XMLTools.getNodeText (e); 
    1435              
    1436       String filter = ""; 
    1437       if (type.equals (StaticStrings.EXCLUDE_STR)) { 
    1438     filter = StaticStrings.EXCLAMATION_CHARACTER; 
    1439       } 
    1440              
    1441       if(content.startsWith (StaticStrings.EXTRACTED_NAMESPACE) && content.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) { 
    1442     content = content.substring (StaticStrings.EXTRACTED_NAMESPACE.length ()); 
    1443       } 
    1444       filter = filter + content + StaticStrings.SEPARATOR_CHARACTER + text; 
    1445       if (options != null && options != "") { 
    1446     filter = filter + StaticStrings.SEPARATOR_CHARACTER + options; 
    1447       } 
    1448       Element subcollection = to.createElement (StaticStrings.SUBCOLLECTION_STR); 
    1449       subcollection.setAttribute (StaticStrings.FILTER_ATTRIBUTE, filter); 
    1450       subcollection.setAttribute (StaticStrings.NAME_ATTRIBUTE, name); 
    1451              
    1452       search.appendChild (subcollection); 
    1453     } 
    1454   } 
    1455   static private void convertSubcollectionIndexes (Document from, Document to) { 
    1456     Element source = from.getDocumentElement (); 
    1457     //Get the 'search' element from 'to' which has already been created in 'convertBuildType' 
    1458     Element search = (Element)XMLTools.getChildByTagName (to.getDocumentElement (), StaticStrings.SEARCH_STR); 
    1459          
    1460     // Get the SubcollectionIndexes element from the internal structure 
    1461     Element subcollection_indexes = (Element)XMLTools.getChildByTagName (source, StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT); 
    1462     if (subcollection_indexes == null) { 
    1463       return; 
    1464     } 
    1465     NodeList index_elements = subcollection_indexes.getElementsByTagName (StaticStrings.INDEX_ELEMENT); 
    1466     int index_elements_length = index_elements.getLength (); 
    1467          
    1468     if (index_elements_length == 0) { // no indexes 
    1469       return ; 
    1470     } 
    1471          
    1472     for(int j = 0; j < index_elements_length; j++) { 
    1473       Element index_element = (Element) index_elements.item (j); 
    1474       if (index_element.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1475     continue; 
    1476       } 
    1477              
    1478       Element index = to.createElement (StaticStrings.SUBCOLLECTION_INDEX_ELEMENT); 
    1479              
    1480       String index_value = ""; 
    1481              
    1482       NodeList content_elements = index_element.getElementsByTagName (StaticStrings.CONTENT_ELEMENT); 
    1483       int content_elements_length = content_elements.getLength (); 
    1484              
    1485       for(int k = 0; k < content_elements_length; k++) { 
    1486     Element content_element = (Element) content_elements.item (k); 
    1487     if (content_element.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1488       continue; 
    1489     } 
    1490     String name_str = content_element.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1491     index_value += name_str; 
    1492     // Make it comma separated string 
    1493     if(k < content_elements_length - 1) { 
    1494       index_value += StaticStrings.COMMA_CHARACTER; 
    1495     } 
    1496     content_element = null; 
    1497       }//for loop ends 
    1498              
    1499       index.setAttribute (StaticStrings.NAME_ATTRIBUTE, index_value); 
    1500              
    1501       // Now constructing 'displayItem' element for this 'indexSubcollection' element 
    1502       // from the collectionmetadata element 
    1503       ArrayList collectionmetadata_list = XMLTools.getNamedElementList (source, 
    1504                                     StaticStrings.COLLECTIONMETADATA_ELEMENT, 
    1505                                     StaticStrings.NAME_ATTRIBUTE, index_value); 
    1506              
    1507       if (collectionmetadata_list != null) { 
    1508                  
    1509     for(int k = 0; k < collectionmetadata_list.size (); k++) { 
    1510       Element collectionmetadata = (Element)collectionmetadata_list.get (k); 
    1511       if (collectionmetadata.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1512         continue; 
    1513       } 
    1514       Element displayItem = constructDisplayItem (collectionmetadata, to); 
    1515       index.appendChild (displayItem); 
    1516     } 
    1517       } 
    1518              
    1519       search.appendChild (index); 
    1520              
    1521     } //for loop ends 
    1522   } 
    1523      
    1524   static private void convertLanguages (Document from, Document to) { 
    1525     Element source = from.getDocumentElement (); 
    1526     //Get the 'search' element from 'to' which has already been created in 'convertBuildType' 
    1527     Element search = (Element)XMLTools.getChildByTagName (to.getDocumentElement (), StaticStrings.SEARCH_STR); 
    1528          
    1529     // Get the Languages element from the internal structure 
    1530     Element languages = (Element)XMLTools.getChildByTagName (source, StaticStrings.LANGUAGES_ELEMENT); 
    1531     if (languages == null) { 
    1532       return; 
    1533     } 
    1534     NodeList language_elements = languages.getElementsByTagName (StaticStrings.LANGUAGE_ELEMENT); 
    1535     int language_elements_length = language_elements.getLength (); 
    1536          
    1537     if (language_elements_length == 0) { 
    1538       return ; 
    1539     } 
    1540          
    1541     for(int j = 0; j < language_elements_length; j++) { 
    1542       Element element = (Element) language_elements.item (j); 
    1543       if (element.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1544     continue; 
    1545       } 
    1546              
    1547       // Create indexLanguage element 
    1548       Element index_language = to.createElement (StaticStrings.LANGUAGE_INDEX_ELEMENT); 
    1549              
    1550       String name_str = element.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1551       index_language.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    1552              
    1553       // Now constructing 'displayItem' element for this 'indexLanguage' element 
    1554       // from the collectionmetadata element 
    1555       ArrayList collectionmetadata_list = XMLTools.getNamedElementList (source, 
    1556                                     StaticStrings.COLLECTIONMETADATA_ELEMENT, 
    1557                                     StaticStrings.NAME_ATTRIBUTE, name_str); 
    1558              
    1559       if (collectionmetadata_list != null) { 
    1560                  
    1561     for(int k = 0; k < collectionmetadata_list.size (); k++) { 
    1562       Element collectionmetadata = (Element)collectionmetadata_list.get (k); 
    1563       if (collectionmetadata.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1564         continue; 
    1565       } 
    1566       Element displayItem = constructDisplayItem (collectionmetadata, to); 
    1567       index_language.appendChild (displayItem); 
    1568     } 
    1569       } 
    1570              
    1571       search.appendChild (index_language); 
    1572              
    1573     } //for loop ends 
    1574          
    1575     // Convert DefaultLanguage 
    1576     // Get the DefaultLanguage element from the internal structure 
    1577     Element default_language = (Element)XMLTools.getChildByTagName (source, StaticStrings.LANGUAGE_DEFAULT_ELEMENT); 
    1578     if(default_language != null) { 
    1579       String lang_name = default_language.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1580       Element default_index_language = to.createElement (StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT); 
    1581       default_index_language.setAttribute (StaticStrings.NAME_ATTRIBUTE, lang_name); 
    1582       search.appendChild (default_index_language); 
    1583     } 
    1584     // Convert LanguageMetadata 
    1585     // Get the LanguageMetadata element from the internal structure 
    1586     Element language_metadata = (Element)XMLTools.getChildByTagName (source, StaticStrings.LANGUAGE_METADATA_ELEMENT); 
    1587     if(language_metadata != null) { 
    1588       String meta_name = language_metadata.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1589       Element language_meta = to.createElement (StaticStrings.LANGUAGE_METADATA_ELEMENT_STR); 
    1590       if(meta_name.startsWith (StaticStrings.EXTRACTED_NAMESPACE) && meta_name.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) { 
    1591     meta_name = meta_name.substring (StaticStrings.EXTRACTED_NAMESPACE.length ()); 
    1592       } 
    1593       language_meta.setAttribute (StaticStrings.NAME_ATTRIBUTE, meta_name); 
    1594       search.appendChild (language_meta); 
    1595     } 
    1596   } 
    1597      
    1598   //convert indexes and their displayItems, which go in 'search' element in collectionConfig.xml 
    1599   //parameter 'to' is the document to be saved as collectionConfig.xml 
    1600   //parameter 'from' is the internal xml structure 
    1601   static private void convertIndex (Document from, Document to) { 
    1602     Element source = from.getDocumentElement (); 
    1603     //Get the 'search' element from 'to' which has already been created in 'convertBuildType' 
    1604     Element search = (Element)XMLTools.getChildByTagName (to.getDocumentElement (), StaticStrings.SEARCH_STR); 
    1605          
    1606     //THere are two sets of indexes elements, find the one which is assigned 'true' 
    1607     Element indexes = XMLTools.getNamedElement (source, 
    1608                         StaticStrings.INDEXES_ELEMENT, 
    1609                         StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
    1610     if (indexes == null) { 
    1611       return; 
    1612     } 
    1613     NodeList index_elements = indexes.getElementsByTagName (StaticStrings.INDEX_ELEMENT); 
    1614     int index_elements_length = index_elements.getLength (); 
    1615          
    1616     if (index_elements_length == 0) { // no indexes 
    1617       return ; 
    1618     } 
    1619          
    1620     //find out it's mg or mgpp/lucene 
    1621     String mg = search.getAttribute (StaticStrings.TYPE_ATTRIBUTE); 
    1622     boolean mg_indexer = false; 
    1623     if (mg.equals (StaticStrings.MG_STR)) { 
    1624       mg_indexer = true;//it's mg, then the level is set as attribute of 
    1625     } 
    1626     if (mg_indexer == false) { 
    1627       // It's mgpp. Construct 'level' and 'defaultLevel' elements separately. 
    1628       convertLevels (from, to, search); 
    1629     } 
    1630          
    1631     for(int j = 0; j < index_elements_length; j++) { 
    1632       Element index_element = (Element) index_elements.item (j); 
    1633       if (index_element.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1634     continue; 
    1635       } 
    1636              
    1637       Element index_ele = to.createElement (StaticStrings.INDEX_LOW_STR);//index 
    1638              
    1639       // Used for creating displayItem for this element 'index_ele' further below 
    1640       // full_index_names contain 'ex.' 
    1641       String full_index_name = ""; 
    1642       String level_str = ""; 
    1643              
    1644       StringBuffer index_value = new StringBuffer (); 
    1645       if (mg_indexer == true) { 
    1646     // For mg indexer, there is a 'level' attribute in the index element of the internal structure 
    1647     // But mgpp/lucene don't 
    1648     level_str = index_element.getAttribute (StaticStrings.LEVEL_ATTRIBUTE); 
    1649     if(level_str.length () > 0) { 
    1650       index_value.append (level_str).append (StaticStrings.COLON_CHARACTER); 
    1651       //index_value = index_value.StaticStrings.COLON_CHARACTER; 
    1652     } 
    1653       } 
    1654              
    1655       NodeList content_elements = index_element.getElementsByTagName (StaticStrings.CONTENT_ELEMENT); 
    1656       int content_elements_length = content_elements.getLength (); 
    1657              
    1658       for(int k = 0; k < content_elements_length; k++) { 
    1659     Element content_element = (Element) content_elements.item (k); 
    1660     if (content_element.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1661       continue; 
    1662     } 
    1663     String name_str = content_element.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1664                  
    1665     full_index_name = full_index_name + name_str; 
    1666     if (k < content_elements_length - 1) { 
    1667       full_index_name = full_index_name + StaticStrings.COMMA_CHARACTER; 
    1668     } 
    1669                  
    1670     if(name_str.startsWith (StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) { 
    1671       name_str = name_str.substring (StaticStrings.EXTRACTED_NAMESPACE.length ()); 
    1672     } 
    1673  
    1674     index_value.append (name_str); 
    1675     name_str = null; 
    1676     // Make it comma separated string 
    1677     if(k < content_elements_length - 1) { 
    1678       index_value.append (StaticStrings.COMMA_CHARACTER); 
    1679     } 
    1680     content_element = null; 
    1681       }//for loop ends 
    1682              
    1683       String temp_str = index_value.toString (); 
    1684       index_ele.setAttribute (StaticStrings.NAME_ATTRIBUTE, temp_str); 
    1685              
    1686       // Now constructing 'displayItem' element for this 'index_ele' element 
    1687       // The index names in the collectionmetadata elements in the internal structure are not the names that 
    1688       // are used in the content elements (i.e. ex.Source or dc.Subject and keywords), but the names that are 
    1689       // in the configuration files (i.e. Source or dc.Subject) 
    1690       ArrayList collectionmetadata_list = XMLTools.getNamedElementList (source, 
    1691                                     StaticStrings.COLLECTIONMETADATA_ELEMENT, 
    1692                                     StaticStrings.NAME_ATTRIBUTE, temp_str); 
    1693              
    1694       if (collectionmetadata_list == null) { 
    1695     //try the full name, i.e. with 'ex.' 
    1696     if (mg_indexer == true) { 
    1697       // but first append level info if we are mg 
    1698       full_index_name = level_str+StaticStrings.COLON_CHARACTER+full_index_name; 
    1699     } 
    1700     collectionmetadata_list = XMLTools.getNamedElementList (source, 
    1701                                 StaticStrings.COLLECTIONMETADATA_ELEMENT, 
    1702                                 StaticStrings.NAME_ATTRIBUTE, full_index_name); 
    1703       } 
    1704      
    1705       if (collectionmetadata_list != null) { 
    1706                  
    1707     for(int k = 0; k < collectionmetadata_list.size (); k++) { 
    1708       Element collectionmetadata = (Element)collectionmetadata_list.get (k); 
    1709       if (collectionmetadata.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1710         continue; 
    1711       } 
    1712       Element displayItem = constructDisplayItem (collectionmetadata, to); 
    1713                      
    1714       index_ele.appendChild (displayItem); 
    1715     } 
    1716       } 
    1717              
    1718       search.appendChild (index_ele); 
    1719              
    1720     } //for loop ends 
    1721          
    1722     //Convert default index 
    1723     convertDefaultIndex (from, to, search); 
    1724     convertIndexOptions(from, to, search); 
    1725   } 
    1726   // Convert levels for mgpp/lucene. This method is called by converIndex() when mgpp indexer is detected. 
    1727   static private void convertLevels (Document from, Document to, Element search) { 
    1728     Element source = from.getDocumentElement (); 
    1729     Element index_option = XMLTools.getNamedElement (source, 
    1730                              StaticStrings.INDEXOPTIONS_ELEMENT, 
    1731                              StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVELS_STR); 
    1732     if (index_option == null) { 
    1733       return; 
    1734     } 
    1735     //Debugging purposes 
    1736     if (index_option.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1737       DebugStream.println ("For mgpp, there should be an IndexOption element for levels which is assigned 'true': possible bug."); 
    1738     } 
    1739          
    1740     NodeList option_elements = index_option.getElementsByTagName (StaticStrings.OPTION_ELEMENT); 
    1741     int num_elements = option_elements.getLength (); 
    1742          
    1743     // Don't output anything if no indexes are set 
    1744     if(num_elements == 0) { 
    1745       return ;// 
    1746     } 
    1747          
    1748     for(int k = 0; k < num_elements; k++) { 
    1749       Element e = (Element) option_elements.item (k); 
    1750       String name_str = e.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1751       Element level_element = to.createElement (StaticStrings.LEVEL_ELEMENT); 
    1752       level_element.setAttribute (StaticStrings.NAME_ATTRIBUTE, name_str); 
    1753              
    1754       //Now construct displayItem for this level element from collectionmetadata 
    1755       ArrayList collectionmetadata_list = XMLTools.getNamedElementList (source, 
    1756                                     StaticStrings.COLLECTIONMETADATA_ELEMENT, 
    1757                                     StaticStrings.NAME_ATTRIBUTE, name_str); 
    1758              
    1759       if (collectionmetadata_list != null) { 
    1760                  
    1761     for(int j = 0; j < collectionmetadata_list.size (); j++) { 
    1762       Element collectionmetadata = (Element)collectionmetadata_list.get (j); 
    1763                      
    1764       Element displayItem = constructDisplayItem (collectionmetadata, to); 
    1765       level_element.appendChild (displayItem); 
    1766     } 
    1767       } 
    1768       search.appendChild (level_element); 
    1769     } 
    1770          
    1771     //Convert default level 
    1772     Element default_index_option = XMLTools.getNamedElement (source, 
    1773                                  StaticStrings.INDEXOPTION_DEFAULT_ELEMENT, 
    1774                                  StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVEL_DEFAULT_STR); 
    1775     if (default_index_option == null) { 
    1776       return; 
    1777     } 
    1778     Element default_level = to.createElement (StaticStrings.LEVEL_DEFAULT_ELEMENT); 
    1779     String default_level_str = default_index_option.getAttribute (StaticStrings.VALUE_ATTRIBUTE); 
    1780     default_level.setAttribute (StaticStrings.NAME_ATTRIBUTE, default_level_str); 
    1781     search.appendChild (default_level); 
    1782          
    1783   } 
    1784   // Convert indexoptions for mg/mgpp/lucene. This method is called by convertIndex(). 
    1785   static private void convertIndexOptions (Document from, Document to, Element search) { 
    1786     Element source = from.getDocumentElement (); 
    1787     Element index_option = XMLTools.getNamedElement (source, 
    1788                              StaticStrings.INDEXOPTIONS_ELEMENT, 
    1789                              StaticStrings.NAME_ATTRIBUTE, StaticStrings.INDEXOPTIONS_STR); 
    1790     if (index_option == null) { 
    1791       return; 
    1792     } 
    1793     //Debugging purposes 
    1794     if (index_option.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.FALSE_STR)) { 
    1795       DebugStream.println ("There should be an IndexOption element which is assigned 'true': possible bug."); 
    1796     } 
    1797     Element indexOptionEl = to.createElement(StaticStrings.INDEXOPTION_STR); 
    1798     NodeList option_elements = index_option.getElementsByTagName (StaticStrings.OPTION_ELEMENT); 
    1799     int num_elements = option_elements.getLength ();         
    1800     // Don't output anything if no index 
    1801     if(num_elements == 0) { 
    1802       return ;// 
    1803     } 
    1804     search.appendChild (indexOptionEl); 
    1805          
    1806     for(int k = 0; k < num_elements; k++) { 
    1807       Element e = (Element) option_elements.item (k); 
    1808       String name_att = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
    1809       Element optionEl = to.createElement(StaticStrings.OPTION_STR); 
    1810       optionEl.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_att); 
    1811       indexOptionEl.appendChild(optionEl); 
    1812     } 
    1813             
    1814   } 
    1815   // Append the element son to the element mother in the appropriate position. 
    1816   static public void appendProperly (Element mother, Element son) { 
    1817     if (son == null) 
    1818       return; 
    1819          
    1820     Node reference_node = findInsertionPoint (mother, son); 
    1821     if(reference_node != null) { 
    1822       mother.insertBefore (son, reference_node); 
    1823     } 
    1824     else { 
    1825       mother.appendChild (son); 
    1826     } 
    1827   } 
    1828   /** Find the best insertion position for the given DOM Element 'target_element' in the DOM Element 'document_element'. This should try to match command tag, and if found should then try to group by name or type (eg CollectionMeta), or append to end is no such grouping exists (eg Plugins). Failing a command match it will check against the command order for the best insertion location. 
    1829    * @param target_element the command Element to be inserted 
    1830    * @return the Element which the given command should be inserted before, or null to append to end of list 
    1831    */ 
    1832   static public Node findInsertionPoint (Element document_element, Element target_element) { 
    1833     ///ystem.err.println("Find insertion point: " + target_element.getNodeName()); 
    1834     String target_element_name = target_element.getNodeName (); 
    1835          
    1836     // Try to find commands with the same tag. 
    1837     NodeList matching_elements = document_element.getElementsByTagName (target_element_name); 
    1838     // If we found matching elements, then we have our most likely insertion location, so check within for groupings 
    1839     if(matching_elements.getLength () != 0) { 
    1840       ///ystem.err.println("Found matching elements."); 
    1841       // Only CollectionMeta are grouped. 
    1842       if(target_element_name.equals (StaticStrings.COLLECTIONMETADATA_ELEMENT)) { 
    1843     ///ystem.err.println("Dealing with collection metadata"); 
    1844     // Special case: CollectionMeta can be added at either the start or end of a collection configuration file. However the start position is reserved for special metadata, so if no non-special metadata can be found we must append to the end. 
    1845     // So if the command to be added is special add it immediately after any other special command 
    1846     if(target_element.getAttribute (StaticStrings.SPECIAL_ATTRIBUTE).equals (StaticStrings.TRUE_STR)) { 
    1847       int index = 0; 
    1848       Element matched_element = (Element) matching_elements.item (index); 
    1849       Element sibling_element = (Element) matched_element.getNextSibling (); 
    1850       while(sibling_element.getAttribute (StaticStrings.SPECIAL_ATTRIBUTE).equals (StaticStrings.TRUE_STR)) { 
    1851         index++; 
    1852         matched_element = (Element) matching_elements.item (index); 
    1853         sibling_element = (Element) matched_element.getNextSibling (); 
    1854       } 
    1855       if(sibling_element.getNodeName ().equals (CollectionConfiguration.NEWLINE_ELEMENT)) { 
    1856         Element newline_element = document_element.getOwnerDocument().createElement (CollectionConfiguration.NEWLINE_ELEMENT); 
    1857         document_element.insertBefore (newline_element, sibling_element); 
    1858       } 
    1859       return sibling_element; 
    1860     } 
    1861     // Otherwise try to find a matching 'name' and add after the last one in that group. 
    1862     else { 
    1863       int index = 0; 
    1864       target_element_name = target_element.getAttribute (StaticStrings.NAME_ATTRIBUTE); 
    1865       boolean found = false; 
    1866       // Skip all of the special metadata 
    1867       Element matched_element = (Element) matching_elements.item (index); 
    1868       while(matched_element.getAttribute (StaticStrings.SPECIAL_ATTRIBUTE).equals (StaticStrings.TRUE_STR)) { 
    1869         index++; 
    1870         matched_element = (Element) matching_elements.item (index); 
    1871       } 
    1872       // Begin search 
    1873       while(!found && matched_element != null) { 
    1874         if(matched_element.getAttribute (StaticStrings.NAME_ATTRIBUTE).equals (target_element_name)) { 
    1875           found = true; 
    1876         } 
    1877         else { 
    1878           index++; 
    1879           matched_element = (Element) matching_elements.item (index); 
    1880         } 
    1881       } 
    1882       // If we found a match, we need to continue checking until we find the last name match. 
    1883       if(found) { 
    1884         index++; 
    1885         Element previous_sibling = matched_element; 
    1886         Element sibling_element = (Element) matching_elements.item (index); 
    1887         while(sibling_element != null && sibling_element.getAttribute (StaticStrings.NAME_ATTRIBUTE).equals (target_element_name)) { 
    1888           previous_sibling = sibling_element; 
    1889           index++; 
    1890           sibling_element = (Element) matching_elements.item (index); 
    1891         } 
    1892         // Previous sibling now holds the command immediately before where we want to add, so find its next sibling and add to that. In this one case we can ignore new lines! 
    1893         return previous_sibling.getNextSibling (); 
    1894       } 
    1895       // If not found we just add after last metadata element 
    1896       else { 
    1897         Element last_element = (Element) matching_elements.item (matching_elements.getLength () - 1); 
    1898         return last_element.getNextSibling (); 
    1899       } 
    1900     } 
    1901                  
    1902       } 
    1903       else { 
    1904     ///ystem.err.println("Not dealing with collection meta."); 
    1905     Element matched_element = (Element) matching_elements.item (matching_elements.getLength () - 1); 
    1906     // One final quick test. If the matched element is immediately followed by a NewLine command, then we insert another NewLine after the matched command, then return the NewLine instead (thus the about to be inserted command will be placed between the two NewLines) 
    1907     Node sibling_element = matched_element.getNextSibling (); 
    1908     if(sibling_element != null && sibling_element.getNodeName ().equals (CollectionConfiguration.NEWLINE_ELEMENT)) { 
    1909       Element newline_element = document_element.getOwnerDocument().createElement (CollectionConfiguration.NEWLINE_ELEMENT); 
    1910       document_element.insertBefore (newline_element, sibling_element); 
    1911     } 
    1912     return sibling_element; // Note that this may be null 
    1913       } 
    1914     } 
    1915     ///ystem.err.println("No matching elements found."); 
    1916     // Locate where this command is in the ordering 
    1917     int command_index = -1; 
    1918     for(int i = 0; command_index == -1 && i < CollectionConfiguration.COMMAND_ORDER.length; i++) { 
    1919       if(CollectionConfiguration.COMMAND_ORDER[i].equals (target_element_name)) { 
    1920     command_index = i; 
    1921       } 
    1922     } 
    1923     ///ystem.err.println("Command index is: " + command_index); 
    1924     // Now move forward, checking for existing elements in each of the preceeding command orders. 
    1925     int preceeding_index = command_index - 1; 
    1926     ///ystem.err.println("Searching before the target command."); 
    1927     while(preceeding_index >= 0) { 
    1928       matching_elements = document_element.getElementsByTagName (CollectionConfiguration.COMMAND_ORDER[preceeding_index]); 
    1929       // If we've found a match 
    1930       if(matching_elements.getLength () > 0) { 
    1931     // We add after the last element 
    1932     Element matched_element = (Element) matching_elements.item (matching_elements.getLength () - 1); 
    1933     // One final quick test. If the matched element is immediately followed by a NewLine command, then we insert another NewLine after the matched command, then return the NewLine instead (thus the about to be inserted command will be placed between the two NewLines) 
    1934     Node sibling_element = matched_element.getNextSibling (); 
    1935     if(sibling_element != null && sibling_element.getNodeName ().equals (CollectionConfiguration.NEWLINE_ELEMENT)) { 
    1936       Element newline_element = document_element.getOwnerDocument().createElement (CollectionConfiguration.NEWLINE_ELEMENT); 
    1937       document_element.insertBefore (newline_element, sibling_element); 
    1938     } 
    1939     return sibling_element; // Note that this may be null 
    1940       } 
    1941       preceeding_index--; 
    1942     } 
    1943     // If all that fails, we now move backwards through the commands 
    1944     int susceeding_index = command_index + 1; 
    1945     ///ystem.err.println("Searching after the target command."); 
    1946     while(susceeding_index < CollectionConfiguration.COMMAND_ORDER.length) { 
    1947       matching_elements = document_element.getElementsByTagName (CollectionConfiguration.COMMAND_ORDER[susceeding_index]); 
    1948       // If we've found a match 
    1949       if(matching_elements.getLength () > 0) { 
    1950     // We add before the first element 
    1951     Element matched_element = (Element) matching_elements.item (0); 
    1952     // One final quick test. If the matched element is immediately preceeded by a NewLine command, then we insert another NewLine before the matched command, then return this new NewLine instead (thus the about to be inserted command will be placed between the two NewLines) 
    1953     Node sibling_element = matched_element.getPreviousSibling (); 
    1954     if(sibling_element != null && sibling_element.getNodeName ().equals (CollectionConfiguration.NEWLINE_ELEMENT)) { 
    1955       Element newline_element = document_element.getOwnerDocument().createElement (CollectionConfiguration.NEWLINE_ELEMENT); 
    1956       document_element.insertBefore (newline_element, sibling_element); 
    1957     } 
    1958     return sibling_element; // Note that this may be null 
    1959       } 
    1960       susceeding_index++; 
    1961     } 
    1962     // Well. Apparently there are no other commands in this collection configuration. So append away... 
    1963     return null; 
    1964   } 
    1965   // From collectionConfig.xml to internal structure:add 'ex.' namespace (if none). 
    1966   // From internal structure to collectionConfig.xml:always peel off 'ex.' namespace (if any), except for format statement 
    1967   //This method parses 'xml_file_doc' into 'dOc' 
    1968   static public void parse(File xml_file, Document dOc) { 
    1969          
    1970     Document xml_file_doc = XMLTools.parseXMLFile (xml_file); 
    1971     Element fromElement = xml_file_doc.getDocumentElement (); 
    1972     Element toElement = dOc.getDocumentElement (); 
    1973          
    1974     // It's deliberately set that 'creator', 'maintainer', and 'public' are only in English (as they are just names). 
    1975     // So the following ArrayList have only one element. 
    1976     Node metadataListNode = XMLTools.getChildByTagNameIndexed (fromElement, StaticStrings.METADATALIST_STR, 0); 
    1977     if (metadataListNode != null) { 
    1978       ArrayList creator = doMetadataList (dOc, metadataListNode, StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, 
    1979                       StaticStrings.COLLECTIONMETADATA_CREATOR_STR); 
    1980       ArrayList maintainer = doMetadataList (dOc, metadataListNode, 
    1981                          StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, 
    1982                          StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR); 
    1983       ArrayList is_public = doMetadataList (dOc, metadataListNode, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT, 
    1984                         StaticStrings.COLLECTIONMETADATA_PUBLIC_STR); 
    1985              
    1986       appendArrayList (toElement, creator); 
    1987       appendArrayList (toElement, maintainer); 
    1988       appendArrayList (toElement, is_public); 
    1989     } 
    1990  
    1991     Node databaseNode = XMLTools.getChildByTagNameIndexed (fromElement, StaticStrings.INFODB_STR, 0); 
    1992     String databasetype_value = "gdbm"; 
    1993     if(databaseNode != null) { 
    1994     databasetype_value = ((Element)databaseNode).getAttribute (StaticStrings.TYPE_ATTRIBUTE);//might be gdbm|jdbm|sqlite OR not yet set (in which case it should default to gdbm) 
    1995     } 
    1996      
    1997     Element databasetype = doDatabaseType(dOc, databasetype_value); 
    1998     appendProperly (toElement, databasetype); 
    1999          
    2000     Node searchNode = XMLTools.getChildByTagNameIndexed (fromElement, StaticStrings.SEARCH_STR, 0); 
    2001     String buildtype_value = ((Element)searchNode).getAttribute (StaticStrings.TYPE_ATTRIBUTE);//might be mg|mgpp|lucene 
    2002     Element buildtype = doBuildType (dOc, buildtype_value); 
    2003     appendProperly (toElement, buildtype); 
    2004          
    2005          
    2006     Node importNode = XMLTools.getChildByTagNameIndexed (fromElement, StaticStrings.IMPORT_STR, 0); 
    2007     if (importNode == null) { 
    2008       System.out.println ("There is no content in the 'import' block."); 
    2009     } 
    2010     if (importNode != null) { 
    2011       //do plugin list nodes 
    2012       Node pluginListNode = XMLTools.getChildByTagNameIndexed ((Element)importNode, StaticStrings.PLUGINLIST_STR, 0);            
    2013       if (pluginListNode == null) { 
    2014     System.out.println ("There is no pluginlist set."); 
    2015       } 
    2016       if (pluginListNode != null) { 
    2017                  
    2018     doPlugin (dOc, pluginListNode); 
    2019       } 
    2020              
    2021       //do the plugout element (used by building flax collections) 
    2022       Node plugout = XMLTools.getChildByTagNameIndexed ((Element)importNode, PLUGOUT_ELEMENT, 0); 
    2023       if (plugout != null) { 
    2024     Element to_element = XMLTools.duplicateElement (dOc, (Element)plugout, true); 
    2025     toElement.appendChild (to_element); 
    2026       } 
    2027     } 
    2028          
    2029     Node browseNode = XMLTools.getChildByTagNameIndexed (fromElement, StaticStrings.BROWSE_STR, 0); 
    2030     if (browseNode != null) { 
    2031       if (browseNode == null) { 
    2032     System.out.println ("There is no classifier."); 
    2033       } 
    2034       doClassifier (dOc, browseNode); 
    2035     } 
    2036          
    2037     Node displayItemListNode = XMLTools.getChildByTagNameIndexed (fromElement, StaticStrings.DISPLAYITEMLIST_STR, 0); 
    2038     if (displayItemListNode != null) { 
    2039       ArrayList description = doDisplayItemList (dOc, displayItemListNode, StaticStrings.DESCRIPTION_STR, 
    2040                          StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR); 
    2041       ArrayList smallicon = doDisplayItemList (dOc, displayItemListNode, StaticStrings.SMALLICON_STR, 
    2042                            StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR); 
    2043       ArrayList icon = doDisplayItemList (dOc, displayItemListNode, StaticStrings.ICON_STR, 
    2044                       StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR); 
    2045       ArrayList name = doDisplayItemList (dOc, displayItemListNode, StaticStrings.NAME_STR, 
    2046                       StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR); 
    2047              
    2048       appendArrayList (toElement, description); 
    2049       appendArrayList (toElement, smallicon); 
    2050       appendArrayList (toElement, icon); 
    2051       appendArrayList (toElement, name); 
    2052     } 
    2053          
    2054     if (buildtype_value.equalsIgnoreCase ("mg")) { 
    2055       doMGIndexes (dOc, searchNode); 
    2056     } 
    2057     else { 
    2058       doMGPPIndexes (dOc, searchNode); 
    2059     } 
    2060          
    2061     doDefaultIndex (dOc, searchNode); 
    2062     doDefaultLevel (dOc, searchNode); 
    2063     doLevel (dOc, searchNode); 
    2064     doIndexOption (dOc, searchNode); 
    2065     doSubcollection (dOc, searchNode); 
    2066     doIndexSubcollection (dOc, searchNode); 
    2067     doIndexLanguage (dOc, searchNode); 
    2068     doDefaultIndexLanguage (dOc, searchNode); 
    2069     doLanguageMetadata (dOc, searchNode); 
    2070     doSearchType (dOc, searchNode); 
    2071     doSearchFormat (dOc, searchNode); 
    2072     doDisplayFormat (dOc, fromElement); 
    2073     doReplaceListRef (dOc, fromElement); 
    2074     doServiceRackList (dOc, fromElement); 
    2075          
    2076   } 
    2077      
    2078      
    2079   static public String generateStringVersion(Document doc) { 
    2080     return XMLTools.xmlNodeToString(doc); 
    2081   } 
    2082    
    2083   static public void save (File collect_config_xml_file, Document doc) { 
    2084          
    2085     Document collection_config_xml_document = convertInternalToCollectionConfig (doc); 
    2086     String[] nonEscapingTagNames = {StaticStrings.FORMAT_STR}; 
    2087     XMLTools.writeXMLFile (collect_config_xml_file, collection_config_xml_document, nonEscapingTagNames); 
    2088         
    2089   } 
    2090  
    2091   //Convert the internal XML DOM tree (dOc) into that of collectionConfig.xml (skeleton) 
    2092   static private Document convertInternalToCollectionConfig (Document dOc) { 
    2093     //first parse an empty skeleton of xml config file 
    2094     //The aim is to convert the internal structure into this skeleton 
    2095     Document skeleton = XMLTools.parseXMLFile ("xml/CollectionConfig.xml", true); 
    2096     //Element internal = dOc.getDocumentElement(); 
    2097     convertMetadataList (dOc, skeleton); 
    2098     convertDisplayItemList (dOc, skeleton); 
    2099     convertBuildType (dOc, skeleton); 
    2100     convertDatabaseType (dOc, skeleton); 
    2101     convertIndex (dOc, skeleton); 
    2102     convertPlugin (dOc, skeleton);//also do the plugout element 
    2103     convertClassifier (dOc, skeleton); 
    2104     convertSubcollectionIndexes (dOc, skeleton); 
    2105     convertLanguages (dOc, skeleton); 
    2106     convertSubcollection (dOc, skeleton); 
    2107     convertSearchType (dOc, skeleton); 
    2108     convertSearchFormat (dOc, skeleton); 
    2109     convertDisplayFormat (dOc, skeleton); 
    2110     convertReplaceListRef (dOc, skeleton); 
    2111     convertServiceRackList(dOc, skeleton); 
    2112  
    2113     return skeleton; 
    2114   } 
    2115  
    2116   // Append the elements, which are of Element type, in 'list' to Element 'to' 
    2117   static private void appendArrayList (Element to, ArrayList list) { 
    2118     if (list == null) return; 
    2119          
    2120     for (int i=0; i<list.size (); i++) { 
    2121       appendProperly (to, (Element)list.get (i)); 
    2122     } 
    2123   } 
    2124  
    2125  
    2126    
     44public class CollectionConfigXMLReadWrite 
     45{ 
     46 
     47    static final private String PLUGOUT_ELEMENT = "plugout";//used by building flax collections 
     48 
     49    /** 
     50     * ************************************************************************* 
     51     * ******************************* The code from this point below are used 
     52     * for greenstone 3 collection configuration, i.e., read ColletionConfig.xml 
     53     * into the internal DOM tree, and convert the internal DOM tree back to 
     54     * CollectionConfig.xml. 
     55     *  
     56     * Methods named 'doXXXX' are for convert collectionConfig.xml into the 
     57     * internal configuration xml structure; Methods named 'convertXXXX' are for 
     58     * convert the internal configuration xml structure back to 
     59     * collectionConfig.xml. 
     60     ************************************************************************************************************ */ 
     61 
     62    /** 
     63     * Arguments: metadataListNode->the 'displayItemList' element in 
     64     * collectionConfig.xml name_value->the value of the 'name' attribute of 
     65     * 'index' element; att_value->the value of the 'name' attribute of 
     66     * 'displayItem' element return: an ArrayList of the contructed 
     67     * 'CollectionMetadata' elements 
     68     */ 
     69    static private ArrayList doDisplayItemList(Document to, Node displayListNode, String att_value, String name_value) 
     70    { 
     71        Element toElement = to.getDocumentElement(); 
     72        ArrayList display_item_list = new ArrayList(); 
     73        ArrayList item_list = XMLTools.getNamedElementList((Element) displayListNode, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, att_value); 
     74        if (item_list == null) 
     75        { 
     76            return null; 
     77        } 
     78 
     79        for (int i = 0; i < item_list.size(); i++) 
     80        { 
     81            Element item = (Element) item_list.get(i); 
     82            String text = XMLTools.getNodeText(item); 
     83 
     84            //If there is nothing to display, don't bother creating the element 
     85            if (text == "") 
     86            { 
     87                continue; 
     88            } 
     89            //get the value in 'lang=value' 
     90            String lang = item.getAttribute(StaticStrings.LANG_STR); 
     91 
     92            Element e = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT); 
     93            e.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     94            e.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_value); 
     95            e.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
     96            XMLTools.setNodeText(e, text); 
     97            display_item_list.add(e); 
     98        } 
     99        return display_item_list; 
     100    } 
     101 
     102    static private ArrayList doMetadataList(Document to, Node metadataListNode, String ele_name, String att_value) 
     103    { 
     104        Element toElement = to.getDocumentElement(); 
     105        ArrayList metadata_list = new ArrayList(); 
     106 
     107        ArrayList item_list = XMLTools.getNamedElementList((Element) metadataListNode, StaticStrings.METADATA_STR, StaticStrings.NAME_ATTRIBUTE, att_value); 
     108        if (item_list == null) 
     109        { 
     110            return null; 
     111        } 
     112 
     113        for (int i = 0; i < item_list.size(); i++) 
     114        { 
     115            Element item = (Element) item_list.get(i); 
     116            String text = XMLTools.getNodeText(item); 
     117 
     118            //If there is nothing to display, don't bother creating the element 
     119            if (text == "") 
     120            { 
     121                continue; 
     122            } 
     123            //get the value in 'lang=value' 
     124            String lang = item.getAttribute(StaticStrings.LANG_STR); 
     125 
     126            Element element = to.createElement(ele_name); 
     127            element.setAttribute(StaticStrings.NAME_ATTRIBUTE, att_value); 
     128            element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
     129            element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     130            element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR); 
     131            XMLTools.setNodeText(element, text); 
     132 
     133            metadata_list.add(element); 
     134        } 
     135        return metadata_list; 
     136    } 
     137 
     138    // 'to' is the internal structure 
     139    static private void doMGIndexes(Document to, Node searchNode) 
     140    { 
     141        Element toElement = to.getDocumentElement(); 
     142        Element indexes_element = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes> 
     143        indexes_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     144        indexes_element.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.FALSE_STR); 
     145 
     146        NodeList index_children = ((Element) searchNode).getElementsByTagName(StaticStrings.INDEX_LOW_STR);//index 
     147        int num_nodes = index_children.getLength(); 
     148 
     149        for (int i = 0; i < num_nodes; i++) 
     150        { 
     151            Element e = (Element) index_children.item(i); 
     152            String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     153            String index_str_display = index_str;//used for creating collectionmetadata for this index 
     154            Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index> 
     155 
     156            // For mg, it's the 'Old G2.38 and earlier' that use level:source tuplets, but we double check it anyway 
     157            boolean old_index = true; 
     158            if (index_str.indexOf(StaticStrings.COLON_CHARACTER) == -1) 
     159            { 
     160                // It doesn't contain ':' character 
     161                System.err.println("Something is wrong! the index should be level:source tuplets."); 
     162                old_index = false; 
     163            } 
     164            else 
     165            { 
     166                // Handling 'index' element 
     167                index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER))); 
     168                index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1); 
     169 
     170                //Each index may have a list of comma-separated strings. 
     171                //split them into 'content' elements in the internal structure 
     172                StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER); 
     173                //index_str = ""; 
     174                while (content_tokenizer.hasMoreTokens()) 
     175                { 
     176                    // Replace index_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject. 
     177 
     178                    Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT); 
     179                    String content_str = content_tokenizer.nextToken(); 
     180                    // Since the contents of indexes have to be certain keywords, or metadata elements, 
     181                    //if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace. 
     182                    if (content_str.indexOf(StaticStrings.NS_SEP) == -1) 
     183                    { 
     184                        if (content_str.equals(StaticStrings.TEXT_STR) || (!old_index && content_str.equals(StaticStrings.ALLFIELDS_STR))) 
     185                        { 
     186                            // in this case, do nothing 
     187                        } 
     188                        else 
     189                        { 
     190                            content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str; 
     191                        } 
     192                    } 
     193 
     194                    content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str); 
     195                    index_element.appendChild(content_element); 
     196                    content_element = null; 
     197                } // while ends 
     198 
     199                indexes_element.appendChild(index_element); 
     200 
     201                // Handling 'displayItem' elements and Constructing 'collectionmetadata' elements 
     202                // Use the fully qualified index names 
     203                ArrayList collectionmetadata_list = doDisplayItemList(to, e, StaticStrings.NAME_ATTRIBUTE, index_str_display); 
     204                appendArrayList(toElement, collectionmetadata_list); 
     205            } //else ends 
     206        } //for loop ends 
     207        appendProperly(toElement, indexes_element); 
     208 
     209        //***// 
     210        // create another set of <indexes> which will be used when user switches to MGPP/LUCENE 
     211        // i.e. we build a default index set for a start 
     212 
     213        String[] index_strs = { StaticStrings.TEXT_STR, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.TITLE_ELEMENT, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.SOURCE_ELEMENT }; 
     214 
     215        Element mgpp_indexes = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes> 
     216        mgpp_indexes.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
     217        mgpp_indexes.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.TRUE_STR); 
     218        for (int i = 0; i < index_strs.length; i++) 
     219        { 
     220            Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index> 
     221            Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT); 
     222            content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_strs[i]); 
     223            index_element.appendChild(content_element); 
     224            mgpp_indexes.appendChild(index_element); 
     225 
     226            // Contructing 'collectionmetadata' elements for 'mgpp' indexes 
     227            Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT); 
     228            collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     229            collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_strs[i]); 
     230            collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR); 
     231            if (index_strs[i].indexOf(StaticStrings.NS_SEP) != -1) 
     232            { 
     233                index_strs[i] = index_strs[i].substring(index_strs[i].indexOf(StaticStrings.NS_SEP) + 1); 
     234            } 
     235            XMLTools.setNodeText(collectionmetadata, index_strs[i]); 
     236 
     237            appendProperly(toElement, collectionmetadata); 
     238 
     239        } 
     240        appendProperly(toElement, mgpp_indexes); 
     241    } 
     242 
     243    //This is actually doing indexes for both mgpp and lucene 
     244    static private void doMGPPIndexes(Document to, Node searchNode) 
     245    { 
     246        Element toElement = to.getDocumentElement(); 
     247        Element indexes_element = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes> 
     248        indexes_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     249        indexes_element.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.TRUE_STR); 
     250 
     251        NodeList index_children = ((Element) searchNode).getElementsByTagName(StaticStrings.INDEX_LOW_STR);//index 
     252        int num_nodes = index_children.getLength(); 
     253 
     254        for (int i = 0; i < num_nodes; i++) 
     255        { 
     256 
     257            Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index> 
     258            Element e = (Element) index_children.item(i); 
     259            String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     260            String index_str_display = index_str;//for creating collectionmetadata for this index  
     261 
     262            // Handling 'index' element 
     263            // Double check to make sure it's not colon separated style index. 
     264            boolean old_index = false; 
     265            if (index_str.indexOf(StaticStrings.COLON_CHARACTER) != -1) 
     266            { 
     267                System.err.println("Something is wrong! the index should NOT be level:source tuplets style."); 
     268                old_index = true; 
     269            } 
     270            //Each index may have a list of comma-separated strings. 
     271            //split them into 'content' elements in the internal structure 
     272            StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER); 
     273            //index_str = ""; 
     274            while (content_tokenizer.hasMoreTokens()) 
     275            { 
     276                // Replace index_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject.              
     277 
     278                Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT); 
     279                String content_str = content_tokenizer.nextToken(); 
     280                // Since the contents of indexes have to be certain keywords, or metadata elements, if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace. 
     281                if (content_str.indexOf(StaticStrings.NS_SEP) == -1) 
     282                { 
     283                    if (content_str.equals(StaticStrings.TEXT_STR)) 
     284                    { 
     285                        // in this case, do nothing 
     286                    } 
     287                    else 
     288                    { 
     289                        content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str; 
     290                    } 
     291                } 
     292                content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str); 
     293                index_element.appendChild(content_element); 
     294                content_element = null; 
     295            } //while ends 
     296 
     297            indexes_element.appendChild(index_element); 
     298 
     299            index_element = null; 
     300 
     301            // Handling 'displayItem' element of this 'index' element 
     302            // 'e' is the parent element 'index' of 'displayItem' element 
     303            ArrayList collectionmetadata_list = doDisplayItemList(to, e, StaticStrings.NAME_ATTRIBUTE, index_str_display); 
     304            appendArrayList(toElement, collectionmetadata_list); 
     305 
     306        } // for loop ends 
     307        toElement.appendChild(indexes_element); 
     308 
     309        // create another set of <indexes> which will be used when user switches to MG 
     310        // i.e. we build a default index set for a start 
     311        Element mg_indexes = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes> 
     312        mg_indexes.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
     313        mg_indexes.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.FALSE_STR); 
     314 
     315        //put the namespace '.ex' as prefix to the indexes 
     316        String[] index_strs = { StaticStrings.TEXT_STR, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.TITLE_ELEMENT, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.SOURCE_ELEMENT }; 
     317        for (int i = 0; i < index_strs.length; i++) 
     318        { 
     319            Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index> 
     320            index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR); 
     321            Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT); 
     322            content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_strs[i]); 
     323            index_element.appendChild(content_element); 
     324 
     325            mg_indexes.appendChild(index_element); 
     326 
     327            // Contructing 'collectionmetadata' elements for 'mg' indexes 
     328            Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT); 
     329            collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     330            String temp = StaticStrings.DOCUMENT_STR.concat(StaticStrings.COLON_CHARACTER).concat(index_strs[i]); 
     331            collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, temp); 
     332            collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR); 
     333            if (index_strs[i].indexOf(StaticStrings.NS_SEP) != -1) 
     334            { 
     335                index_strs[i] = index_strs[i].substring(index_strs[i].indexOf(StaticStrings.NS_SEP) + 1); 
     336            } 
     337            XMLTools.setNodeText(collectionmetadata, index_strs[i]); 
     338 
     339            appendProperly(toElement, collectionmetadata); 
     340 
     341        } 
     342        toElement.appendChild(mg_indexes); 
     343 
     344    } 
     345 
     346    static private void doDisplayFormat(Document to, Element from) 
     347    { 
     348        //display element in the xml file 
     349        Element de = (Element) XMLTools.getChildByTagName(from, StaticStrings.DISPLAY_STR); 
     350        if (de == null) 
     351        { 
     352            return; 
     353        } 
     354        //format element in the display element 
     355        Element fe = (Element) XMLTools.getChildByTagName(de, StaticStrings.FORMAT_STR); 
     356 
     357        to.getDocumentElement().appendChild(doFormat(to, fe, StaticStrings.DISPLAY_STR)); 
     358    } 
     359 
     360    //construct 'DefaultIndex' element in the internal structure from collectionConfig.xml 
     361    static private void doDefaultIndex(Document to, Node searchNode) 
     362    { 
     363        Element toElement = to.getDocumentElement(); 
     364        Element default_index_element = to.createElement(StaticStrings.INDEX_DEFAULT_ELEMENT); 
     365        default_index_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     366 
     367        Element e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE);//defaultIndex 
     368        if (e == null) 
     369        { 
     370            return; 
     371        } 
     372        String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     373 
     374        boolean old_index = false; 
     375        if (index_str.indexOf(StaticStrings.COLON_CHARACTER) != -1) 
     376        { 
     377            //The index is 'level:source tuplets' which is for mg. Take out 'level' 
     378            old_index = true; 
     379            default_index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER))); 
     380            index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1); 
     381        } 
     382        else 
     383        { 
     384            default_index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, ""); 
     385        } 
     386 
     387        //Each index may have a list of comma-separated strings. 
     388        //split them into 'content' elements in the internal structure 
     389        StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER); 
     390        while (content_tokenizer.hasMoreTokens()) 
     391        { 
     392            Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT); 
     393            String content_str = content_tokenizer.nextToken(); 
     394            // Since the contents of indexes have to be certain keywords, or metadata elements, if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace. 
     395            if (content_str.indexOf(StaticStrings.NS_SEP) == -1) 
     396            { 
     397                if (content_str.equals(StaticStrings.TEXT_STR) || (!old_index && content_str.equals(StaticStrings.ALLFIELDS_STR))) 
     398                { 
     399                    // in this case, do nothing 
     400                } 
     401                else 
     402                { 
     403                    content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str; 
     404                } 
     405            } 
     406 
     407            content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str); 
     408            default_index_element.appendChild(content_element); 
     409            content_element = null; 
     410        } 
     411        appendProperly(toElement, default_index_element); 
     412    } 
     413 
     414    // For mg, this method is still called, but make it 'assigned=false' 
     415    static private void doDefaultLevel(Document to, Node searchNode) 
     416    { 
     417        Element toElement = to.getDocumentElement(); 
     418        Element default_index_option = to.createElement(StaticStrings.INDEXOPTION_DEFAULT_ELEMENT); 
     419        default_index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVEL_DEFAULT_STR); 
     420 
     421        Element e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.LEVEL_DEFAULT_ELEMENT); 
     422        if (e != null) 
     423        { 
     424            default_index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     425            String level = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     426            default_index_option.setAttribute(StaticStrings.VALUE_ATTRIBUTE, level); 
     427        } 
     428        else 
     429        { 
     430            //In the case of mg, there's no level! build a default one using 'assigned=false value=document' 
     431            default_index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
     432            default_index_option.setAttribute(StaticStrings.VALUE_ATTRIBUTE, StaticStrings.DOCUMENT_STR); 
     433        } 
     434        appendProperly(toElement, default_index_option); 
     435    } 
     436 
     437    // Transform plugins (pluginListNode) of collectionConfig.xml into the internal structure (i.e. Document to) 
     438    static private void doPlugin(Document to, Node pluginListNode) 
     439    { 
     440        Element toElement = to.getDocumentElement(); 
     441        NodeList plugin_children = ((Element) pluginListNode).getElementsByTagName(StaticStrings.PLUGIN_STR); 
     442        int plugin_nodes = plugin_children.getLength(); 
     443 
     444        if (plugin_nodes < 1) 
     445        { 
     446            return; 
     447        } 
     448 
     449        for (int i = 0; i < plugin_nodes; i++) 
     450        { 
     451            Element e = (Element) plugin_children.item(i); 
     452            String str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     453            str = Utility.ensureNewPluginName(str); 
     454            Element plugin_element = to.createElement(StaticStrings.PLUGIN_ELEMENT); 
     455            plugin_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, str); 
     456 
     457            NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR); 
     458 
     459            for (int j = 0; j < option_children.getLength(); j++) 
     460            { 
     461                Element el = (Element) option_children.item(j); 
     462                String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     463                if (name_str.startsWith(StaticStrings.MINUS_CHARACTER)) 
     464                { 
     465                    name_str = name_str.substring(1); 
     466                } 
     467                String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE); 
     468                Element option_element = null; 
     469 
     470                if (name_str.equals("") && !value_str.equals("")) 
     471                { 
     472                    continue; 
     473                } 
     474 
     475                option_element = to.createElement(StaticStrings.OPTION_ELEMENT); 
     476                option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     477                if (name_str.equals(StaticStrings.RECPLUG_STR) && value_str.equals(StaticStrings.USE_METADATA_FILES_ARGUMENT)) 
     478                { 
     479                    continue; // ignore this option 
     480                } 
     481 
     482                if (value_str != null) 
     483                { 
     484                    // Remove any speech marks appended in strings containing whitespace 
     485                    if (value_str.startsWith(StaticStrings.SPEECH_CHARACTER) && value_str.endsWith(StaticStrings.SPEECH_CHARACTER)) 
     486                    { 
     487                        value_str = value_str.substring(1, value_str.length() - 1); 
     488                    } 
     489                    if (name_str.equals(StaticStrings.METADATA_STR)) 
     490                    { 
     491                        // The metadata argument must be the fully qualified name of a metadata element, so if it doesn't yet have a namespace, append the extracted metadata namespace. 
     492                        String[] values = value_str.split(StaticStrings.COMMA_CHARACTER); 
     493                        value_str = ""; 
     494                        for (int k = 0; k <= values.length - 1; k++) 
     495                        { 
     496                            if (values[k].indexOf(StaticStrings.NS_SEP) == -1) 
     497                            { 
     498                                values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k]; 
     499                            } 
     500 
     501                            if (k < values.length - 1) 
     502                            { 
     503                                value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER; 
     504 
     505                            } 
     506                            else 
     507                            { 
     508                                value_str = value_str + values[k]; 
     509                            } 
     510                        } 
     511                    } 
     512                } 
     513                if (!name_str.equals("")) 
     514                { 
     515                    option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     516                } 
     517                if (!value_str.equals("")) 
     518                { 
     519                    XMLTools.setNodeText(option_element, value_str); 
     520                } 
     521                plugin_element.appendChild(option_element); 
     522 
     523            } 
     524 
     525            appendProperly(toElement, plugin_element); 
     526        } 
     527 
     528    } 
     529 
     530    //Handle classifiers 
     531    static private void doClassifier(Document to, Node browseNode) 
     532    { 
     533        Element toElement = to.getDocumentElement(); 
     534        NodeList classifier_children = ((Element) browseNode).getElementsByTagName(StaticStrings.CLASSIFIER_STR); 
     535        int num_nodes = classifier_children.getLength(); 
     536 
     537        if (num_nodes < 1) 
     538        { 
     539            return; 
     540        } 
     541 
     542        for (int i = 0; i < num_nodes; i++) 
     543        { 
     544            Element e = (Element) classifier_children.item(i); 
     545            String str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     546            Element classify_element = to.createElement(StaticStrings.CLASSIFY_ELEMENT); 
     547            classify_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, str); 
     548 
     549            String options_str = ""; 
     550            NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR); 
     551            for (int j = 0; j < option_children.getLength(); j++) 
     552            { 
     553                Element el = (Element) option_children.item(j); 
     554                String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     555                options_str = options_str + ((name_str.equals("")) ? "" : (" " + name_str)); 
     556                if (name_str.startsWith(StaticStrings.MINUS_CHARACTER)) 
     557                { 
     558                    name_str = name_str.substring(1); 
     559                } 
     560                String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE); 
     561                options_str = options_str + ((name_str.equals("")) ? "" : (" " + value_str)); 
     562                Element option_element = null; 
     563 
     564                if (name_str.equals("") && !value_str.equals("")) 
     565                { 
     566                    continue; //invalid condition 
     567                } 
     568 
     569                option_element = to.createElement(StaticStrings.OPTION_ELEMENT); 
     570                option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     571 
     572                if (!name_str.equals("")) 
     573                { 
     574                    option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     575                } 
     576 
     577                if (!value_str.equals("") && name_str.equals(StaticStrings.METADATA_STR)) 
     578                { 
     579                    // The metadata argument must be the fully qualified name of a metadata element, so if it doesn't yet have a namespace, append the extracted metadata namespace. 
     580                    String[] values = value_str.split(StaticStrings.COMMA_CHARACTER); 
     581                    value_str = ""; 
     582                    for (int k = 0; k <= values.length - 1; k++) 
     583                    { 
     584                        if (values[k].indexOf(StaticStrings.NS_SEP) == -1) 
     585                        { 
     586                            values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k]; 
     587                        } 
     588                        else 
     589                        { 
     590                            MetadataElement metadata_element = MetadataTools.getMetadataElementWithName(values[k]); 
     591                            if (metadata_element != null) 
     592                            { 
     593                                values[k] = metadata_element.getDisplayName(); 
     594                            } 
     595                        } 
     596                        if (k < values.length - 1) 
     597                        { 
     598                            value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER; 
     599                        } 
     600                        else 
     601                        { 
     602                            value_str = value_str + values[k]; 
     603                        } 
     604                    } 
     605                } 
     606 
     607                if (value_str != null && !value_str.equals("")) 
     608                { 
     609                    XMLTools.setNodeText(option_element, value_str); 
     610                } 
     611                classify_element.appendChild(option_element); 
     612            } 
     613            //format element for this classifier 
     614            Element format = (Element) XMLTools.getChildByTagName(e, StaticStrings.FORMAT_STR); 
     615            if (format != null) 
     616            { 
     617                classify_element.appendChild(doFormat(to, format, null)); 
     618            } 
     619            appendProperly(toElement, classify_element); 
     620        } 
     621 
     622        // default format statement for all classifiers 
     623        Element default_classifier_format = (Element) XMLTools.getChildByTagName(browseNode, StaticStrings.FORMAT_STR); 
     624 
     625        to.getDocumentElement().appendChild(doFormat(to, default_classifier_format, StaticStrings.BROWSE_STR)); 
     626    } 
     627 
     628    static private Element doFormat(Document to, Element format, String name_str) 
     629    { 
     630        Element format_element = to.createElement(StaticStrings.FORMAT_STR); 
     631        if (name_str != null) 
     632        { 
     633            format_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     634        } 
     635 
     636        // Don't write out an empty format statement of <format/> (i.e. format has no child nodes) 
     637        // as this will end up embedded in another format statement as <format><format/><format /> 
     638        // This doubling up of format stmts will then prevent GLI from opening the collection again. 
     639        if (format != null && format.hasChildNodes()) 
     640        { // not an empty format statement 
     641            String gsf_text = XMLTools.xmlNodeToStringWithoutIndenting(format); 
     642 
     643            if (gsf_text.startsWith("<") && (gsf_text.indexOf("<") != gsf_text.lastIndexOf("<"))) 
     644            { 
     645                gsf_text = gsf_text.substring(gsf_text.indexOf("<gsf"), gsf_text.indexOf(StaticStrings.FORMAT_END_TAG)); 
     646            } 
     647 
     648            XMLTools.setNodeText(format_element, gsf_text); 
     649        } 
     650        return format_element; 
     651    } 
     652 
     653    // Handling 'subcollection' elements in 'search' element of 'collectionConfig.xml' 
     654    static private void doSubcollection(Document to, Node searchNode) 
     655    { 
     656        Element toElement = to.getDocumentElement(); 
     657        NodeList sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SUBCOLLECTION_STR); 
     658        int sub_nodes = sub_children.getLength(); 
     659 
     660        // There is no subcollection 
     661        if (sub_nodes < 1) 
     662        { 
     663            return; 
     664        } 
     665 
     666        for (int i = 0; i < sub_nodes; i++) 
     667        { 
     668            Element sub_child = (Element) sub_children.item(i); 
     669            String name_str = sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     670            String filter_str = sub_child.getAttribute(StaticStrings.FILTER_ATTRIBUTE); 
     671 
     672            // filter_str is in the form '<! (if set)><metadata>/<metadata value>/<flag (if any)>' 
     673 
     674            int pos = filter_str.indexOf(StaticStrings.SEPARATOR_CHARACTER); 
     675            String meta_str = ""; 
     676            String meta_value_str = ""; 
     677            String clude_str = ""; 
     678            String flag_str = ""; 
     679            if (pos == -1) 
     680            { 
     681 
     682                meta_str = meta_value_str = filter_str; 
     683                clude_str = StaticStrings.INCLUDE_STR; 
     684            } 
     685            else 
     686            { 
     687                clude_str = StaticStrings.INCLUDE_STR; 
     688                if (filter_str.startsWith(StaticStrings.EXCLAMATION_CHARACTER)) 
     689                { 
     690                    clude_str = StaticStrings.EXCLUDE_STR; 
     691                    // Peel off "!" 
     692                    filter_str = filter_str.substring(StaticStrings.EXCLAMATION_CHARACTER.length()); 
     693                } 
     694 
     695                String[] strs = filter_str.split(StaticStrings.SEPARATOR_CHARACTER); 
     696                if (strs[0] != null && strs[0] != "") 
     697                { 
     698                    meta_str = strs[0]; 
     699                } 
     700                if (!meta_str.equals(StaticStrings.FILENAME_STR) && meta_str.indexOf(StaticStrings.NS_SEP) == -1) 
     701                { 
     702                    meta_str = StaticStrings.EXTRACTED_NAMESPACE + meta_str; 
     703                } 
     704 
     705                if (strs[1] != null && strs[1] != "") 
     706                { 
     707                    meta_value_str = strs[1]; 
     708                } 
     709                if (strs.length > 2) 
     710                { 
     711                    //This means there has been set a flag 
     712                    if (strs[2] != null && strs[2] != "") 
     713                    { 
     714                        flag_str = strs[2]; 
     715                    } 
     716                } 
     717            } 
     718            Element subcollection_element = to.createElement(StaticStrings.SUBCOLLECTION_ELEMENT); 
     719            subcollection_element.setAttribute(StaticStrings.NAME_STR, name_str); 
     720            subcollection_element.setAttribute(StaticStrings.CONTENT_ATTRIBUTE, meta_str); 
     721            subcollection_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, clude_str); 
     722            if (flag_str != "") 
     723            { 
     724                subcollection_element.setAttribute(StaticStrings.OPTIONS_ATTRIBUTE, flag_str); 
     725            } 
     726            XMLTools.setNodeText(subcollection_element, meta_value_str); 
     727 
     728            toElement.appendChild(subcollection_element); 
     729        } 
     730    } 
     731 
     732    //Handle levels (document, section). In the internal structure, the element is called 'IndexOption' 
     733    static private void doLevel(Document to, Node searchNode) 
     734    { 
     735        Element toElement = to.getDocumentElement(); 
     736        NodeList level_children = ((Element) searchNode).getElementsByTagName(StaticStrings.LEVEL_ATTRIBUTE); 
     737        int level_nodes = level_children.getLength(); 
     738 
     739        // it's mg, there's no level. So we construct a default 'indexOption' in the internal structure 
     740        if (level_nodes < 1) 
     741        { 
     742            Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT); 
     743            index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
     744            index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVELS_STR); 
     745 
     746            Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT); 
     747            option_element.setAttribute(StaticStrings.NAME_STR, StaticStrings.DOCUMENT_STR); 
     748            index_option.appendChild(option_element); 
     749 
     750            appendProperly(toElement, index_option); 
     751 
     752            return; 
     753        } 
     754 
     755        Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT); 
     756        index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     757        index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVELS_STR); 
     758 
     759        for (int i = 0; i < level_nodes; i++) 
     760        { 
     761            Element level_element = (Element) level_children.item(i); 
     762            String level_str = level_element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     763            Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT); 
     764            option_element.setAttribute(StaticStrings.NAME_STR, level_str); 
     765            index_option.appendChild(option_element); 
     766 
     767            // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'level' element 
     768            ArrayList displayItem_list = XMLTools.getNamedElementList(level_element, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR); 
     769            if (displayItem_list == null) 
     770            { 
     771                return; 
     772            } 
     773            for (int j = 0; j < displayItem_list.size(); j++) 
     774            { 
     775                Element item = (Element) displayItem_list.get(j); 
     776                String text = XMLTools.getNodeText(item); 
     777                String lang = item.getAttribute(StaticStrings.LANG_ATTRIBUTE); 
     778 
     779                //If there is nothing to display, don't bother creating the element 
     780                if (text == "") 
     781                { 
     782                    continue; 
     783                } 
     784                Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT); 
     785                collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     786                collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, level_str); 
     787                collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
     788                XMLTools.setNodeText(collectionmetadata, text); 
     789 
     790                appendProperly(toElement, collectionmetadata); 
     791            } 
     792        } 
     793        appendProperly(toElement, index_option); 
     794    } 
     795 
     796    //Handle 'indexSubcollection' element of collectionConfig.xml,  which is called 'SubcollectionIndexes' in the internal structure. These contain the subcollection indexes (i.e. the filter or filter combinations), and displayed words for the filter names. 
     797    static private void doIndexSubcollection(Document to, Node searchNode) 
     798    { 
     799        Element toElement = to.getDocumentElement(); 
     800        NodeList index_sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SUBCOLLECTION_INDEX_ELEMENT); 
     801        int num_nodes = index_sub_children.getLength(); 
     802 
     803        // there is no subcollection index 
     804        if (num_nodes < 1) 
     805        { 
     806            return; 
     807        } 
     808 
     809        Element subcollection_indexes = to.createElement(StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT); 
     810 
     811        for (int i = 0; i < num_nodes; i++) 
     812        { 
     813            Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT); 
     814            Element index_sub_child = (Element) index_sub_children.item(i); 
     815            String name_str = index_sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     816 
     817            // name_str is in the form of comma separated strings, each of which is a subcollection filter name 
     818            String[] filters = name_str.split(StaticStrings.COMMA_CHARACTER); 
     819            for (int j = 0; j < filters.length; j++) 
     820            { 
     821 
     822                Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT); 
     823                content_element.setAttribute(StaticStrings.NAME_STR, filters[j]); 
     824                index_element.appendChild(content_element); 
     825            } 
     826            subcollection_indexes.appendChild(index_element); 
     827 
     828            // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'indexSubcollection' element 
     829            ArrayList displayItem_list = XMLTools.getNamedElementList(index_sub_child, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR); 
     830            if (displayItem_list == null) 
     831            { 
     832                // there is no display item for this element 
     833                continue; 
     834            } 
     835            for (int j = 0; j < displayItem_list.size(); j++) 
     836            { 
     837                Element item = (Element) displayItem_list.get(j); 
     838                String text = XMLTools.getNodeText(item); 
     839                String lang = item.getAttribute(StaticStrings.LANG_ATTRIBUTE); 
     840 
     841                //If there is nothing to display, don't bother creating the element 
     842                if (text == "") 
     843                { 
     844                    continue; 
     845                } 
     846                Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT); 
     847                collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     848                collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     849                collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
     850                XMLTools.setNodeText(collectionmetadata, text); 
     851 
     852                appendProperly(toElement, collectionmetadata); 
     853            } 
     854        } 
     855        appendProperly(toElement, subcollection_indexes); 
     856    } 
     857 
     858    //Handle 'indexLanguage' element of collectionConfig.xml,  which is called 'Languages' in the internal structure. These contain the language indexes, and displayed words for those language index names. 
     859    static private void doIndexLanguage(Document to, Node searchNode) 
     860    { 
     861        Element toElement = to.getDocumentElement(); 
     862        NodeList index_sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.LANGUAGE_INDEX_ELEMENT); 
     863        int num_nodes = index_sub_children.getLength(); 
     864 
     865        // there is no subcollection index 
     866        if (num_nodes < 1) 
     867        { 
     868            return; 
     869        } 
     870 
     871        Element language_indexes = to.createElement(StaticStrings.LANGUAGES_ELEMENT); 
     872 
     873        for (int i = 0; i < num_nodes; i++) 
     874        { 
     875            Element language_element = to.createElement(StaticStrings.LANGUAGE_ELEMENT); 
     876            Element index_sub_child = (Element) index_sub_children.item(i); 
     877            String name_str = index_sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     878            language_element.setAttribute(StaticStrings.NAME_STR, name_str); 
     879            language_indexes.appendChild(language_element); 
     880 
     881            // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'indexLanguage' element 
     882            ArrayList displayItem_list = XMLTools.getNamedElementList(index_sub_child, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR); 
     883            if (displayItem_list == null) 
     884            { 
     885                // there is no display item for this element 
     886                continue; 
     887            } 
     888            for (int j = 0; j < displayItem_list.size(); j++) 
     889            { 
     890                Element item = (Element) displayItem_list.get(j); 
     891                String text = XMLTools.getNodeText(item); 
     892                String lang = item.getAttribute(StaticStrings.LANG_ATTRIBUTE); 
     893 
     894                //If there is nothing to display, don't bother creating the element 
     895                if (text == "") 
     896                { 
     897                    continue; 
     898                } 
     899                Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT); 
     900                collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     901                collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     902                collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang); 
     903                XMLTools.setNodeText(collectionmetadata, text); 
     904 
     905                appendProperly(toElement, collectionmetadata); 
     906            } 
     907        } 
     908        toElement.appendChild(language_indexes); 
     909    } 
     910 
     911    // Handling search types 
     912    static private void doSearchType(Document to, Node searchNode) 
     913    { 
     914        NodeList type_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SEARCHTYPE_ELEMENT); 
     915        int num_types = type_children.getLength(); 
     916        String searchtype_str = ""; 
     917        if (num_types < 1) 
     918        { 
     919            // not defined yet, add in default 
     920            searchtype_str = "plain,simpleform,advancedform"; 
     921        } 
     922        else 
     923        { 
     924            for (int i = 0; i < num_types; i++) 
     925            { 
     926                Node e = type_children.item(i); 
     927                String t = ((Element) e).getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     928                if (i > 0) 
     929                { 
     930                    searchtype_str += ","; 
     931                } 
     932                searchtype_str += t; 
     933            } 
     934        } 
     935 
     936        // pretend its a format statement 
     937        Element search_type_element = to.createElement(StaticStrings.FORMAT_STR); 
     938        search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT); 
     939        XMLTools.setNodeText(search_type_element, searchtype_str); 
     940        appendProperly(to.getDocumentElement(), search_type_element); 
     941 
     942    } 
     943 
     944    // Handling search format statement 
     945    static private void doSearchFormat(Document to, Node searchNode) 
     946    { 
     947        // THere is currently just one format element for search. HOwever, need to check for old config files which used to have <format name="searchTypes"> 
     948        NodeList format_children = ((Element) searchNode).getElementsByTagName(StaticStrings.FORMAT_STR); 
     949        int format_nodes = format_children.getLength(); 
     950        if (format_nodes < 1) 
     951        { 
     952            return; 
     953        } 
     954        Element format = null; 
     955        for (int i = 0; i < format_nodes; i++) 
     956        { 
     957            Node e = format_children.item(i); 
     958            if (e.hasAttributes() == false) 
     959            { 
     960                //The format element for format statement has no attribute 
     961                format = (Element) e; 
     962            } 
     963        } 
     964        //format statement for search 
     965        if (format != null) 
     966        { 
     967            (to.getDocumentElement()).appendChild(doFormat(to, format, StaticStrings.SEARCH_STR)); 
     968        } 
     969    } 
     970 
     971    // Handling defaultIndexLanguage and languageMetadata in collectionConfig.xml ('elementNameFrom'); in the internal structure, they are called 'DefaultLanguage' and 'LanguageMetadata' ('elementNameTo') respectively. 
     972    // Converting from collectionConfig.xml to the internal xml structure. 
     973    static private void doLanguageMetadata(Document to, Node searchNode) 
     974    { 
     975        Element toElement = to.getDocumentElement(); 
     976        String elementNameFrom = StaticStrings.LANGUAGE_METADATA_ELEMENT_STR; 
     977        String elementNameTo = StaticStrings.LANGUAGE_METADATA_ELEMENT; 
     978        Node from_element = XMLTools.getChildByTagName(searchNode, elementNameFrom); 
     979        if (from_element == null) 
     980        { 
     981            return; // such an element not found 
     982        } 
     983 
     984        Element to_element = to.createElement(elementNameTo); 
     985 
     986        String name_str = ((Element) from_element).getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     987        if (name_str.indexOf(StaticStrings.NS_SEP) == -1) 
     988        { 
     989            name_str = StaticStrings.EXTRACTED_NAMESPACE + name_str; 
     990        } 
     991        to_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     992        to_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     993 
     994        toElement.appendChild(to_element); 
     995    } 
     996 
     997    static private void doReplaceListRef(Document to, Element from) 
     998    { 
     999        Element toElement = to.getDocumentElement(); 
     1000 
     1001        NodeList replace_elements = from.getElementsByTagName(StaticStrings.REPLACELISTREF_STR); 
     1002        int num_elems = replace_elements.getLength(); 
     1003        if (num_elems < 1) 
     1004        { 
     1005            return; 
     1006        } 
     1007        for (int i = 0; i < num_elems; i++) 
     1008        { 
     1009            Element to_element = XMLTools.duplicateElement(to, (Element) replace_elements.item(i), true); 
     1010            toElement.appendChild(to_element); 
     1011        } 
     1012    } 
     1013 
     1014    static private void convertReplaceListRef(Document from, Document to) 
     1015    { 
     1016        Element toElement = to.getDocumentElement(); 
     1017 
     1018        NodeList replace_elements = from.getDocumentElement().getElementsByTagName(StaticStrings.REPLACELISTREF_STR); 
     1019        int num_elems = replace_elements.getLength(); 
     1020        if (num_elems < 1) 
     1021        { 
     1022            return; 
     1023        } 
     1024        for (int i = 0; i < num_elems; i++) 
     1025        { 
     1026            Element to_element = XMLTools.duplicateElement(to, (Element) replace_elements.item(i), true); 
     1027            toElement.appendChild(to_element); 
     1028        } 
     1029    } 
     1030 
     1031    /** 
     1032     * serviceRackList is currently not editable in GLI - just copy it in from 
     1033     * config file and write it out again. 
     1034     */ 
     1035    static private void doServiceRackList(Document to, Element from) 
     1036    { 
     1037        Element toElement = to.getDocumentElement(); 
     1038 
     1039        Node srl_element = XMLTools.getChildByTagName(from, StaticStrings.SERVICE_RACK_LIST_ELEMENT); 
     1040        if (srl_element == null) 
     1041        { 
     1042            return; // such an element not found 
     1043        } 
     1044 
     1045        Element to_element = XMLTools.duplicateElement(to, (Element) srl_element, true); 
     1046        toElement.appendChild(to_element); 
     1047    } 
     1048 
     1049    static private void convertServiceRackList(Document from, Document to) 
     1050    { 
     1051        Element toElement = to.getDocumentElement(); 
     1052 
     1053        Node srl_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.SERVICE_RACK_LIST_ELEMENT); 
     1054        if (srl_element == null) 
     1055        { 
     1056            return; // such an element not found 
     1057        } 
     1058 
     1059        Element to_element = XMLTools.duplicateElement(to, (Element) srl_element, true); 
     1060        toElement.appendChild(to_element); 
     1061    } 
     1062 
     1063    static private void doDefaultIndexLanguage(Document to, Node searchNode) 
     1064    { 
     1065        Element toElement = to.getDocumentElement(); 
     1066        String elementNameFrom = StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT; 
     1067        String elementNameTo = StaticStrings.LANGUAGE_DEFAULT_ELEMENT; 
     1068        Node from_element = XMLTools.getChildByTagName(searchNode, elementNameFrom); 
     1069        if (from_element == null) 
     1070        { 
     1071            return; // such an element not found 
     1072        } 
     1073 
     1074        Element to_element = to.createElement(elementNameTo); 
     1075 
     1076        String name_str = ((Element) from_element).getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1077        to_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     1078        to_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     1079 
     1080        toElement.appendChild(to_element); 
     1081    } 
     1082 
     1083    //Handle 'indexOption' (i.e. casefold, stem etc). In the internal structure, the element is called 'IndexOption' 
     1084    static private void doIndexOption(Document to, Node searchNode) 
     1085    { 
     1086        Element toElement = to.getDocumentElement(); 
     1087        Node index_option_node = XMLTools.getChildByTagName(searchNode, StaticStrings.INDEXOPTION_STR); 
     1088        if (index_option_node == null) 
     1089        { 
     1090            return; 
     1091        } 
     1092        NodeList option_children = ((Element) index_option_node).getElementsByTagName(StaticStrings.OPTION_STR); 
     1093        int option_nodes = option_children.getLength(); 
     1094 
     1095        // for lucene, there is no 'indexOption'. We build a default 'indexOption' and 'assigned=false' in case the user switches to mg or mgpp 
     1096        if (option_nodes < 1) 
     1097        { 
     1098            Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT); 
     1099            index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 
     1100            index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR); 
     1101            String[] option_str = { StaticStrings.CASEFOLD_OPTION_STR, StaticStrings.STEM_OPTION_STR }; 
     1102            for (int i = 0; i < option_str.length; i++) 
     1103            { 
     1104                Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT); 
     1105                option_element.setAttribute(StaticStrings.NAME_STR, option_str[i]); 
     1106                index_option.appendChild(option_element); 
     1107            } 
     1108            appendProperly(toElement, index_option); 
     1109            return; 
     1110        } 
     1111 
     1112        Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT); 
     1113        index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     1114        index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR); 
     1115 
     1116        for (int i = 0; i < option_nodes; i++) 
     1117        { 
     1118            String option_str = ((Element) option_children.item(i)).getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1119            Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT); 
     1120            option_element.setAttribute(StaticStrings.NAME_STR, option_str); 
     1121            index_option.appendChild(option_element); 
     1122        } 
     1123        appendProperly(toElement, index_option); 
     1124    } 
     1125 
     1126    static private Element doBuildType(Document to, String att_value) 
     1127    { 
     1128 
     1129        //construct 'BuildType' element 
     1130        Element element = to.createElement(StaticStrings.BUILDTYPE_ELEMENT); 
     1131        element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR); 
     1132        element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR); 
     1133        element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     1134        element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR); 
     1135 
     1136        XMLTools.setNodeText(element, att_value); 
     1137 
     1138        return element; 
     1139    } 
     1140 
     1141    static private Element doDatabaseType(Document to, String att_value) 
     1142    { 
     1143 
     1144        //construct 'DatabaseType' element 
     1145        Element element = to.createElement(StaticStrings.DATABASETYPE_ELEMENT); 
     1146        element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR); 
     1147        element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR); 
     1148        element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     1149        element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR); 
     1150 
     1151        XMLTools.setNodeText(element, att_value); 
     1152 
     1153        return element; 
     1154    } 
     1155 
     1156    // Convert 'description', 'smallicon' etc. 
     1157    static private void convertDisplayItemList(Document from, Document to) 
     1158    { 
     1159        Element displayItemList = to.createElement(StaticStrings.DISPLAYITEMLIST_STR); 
     1160        Element destination = to.getDocumentElement(); 
     1161 
     1162        String[] att_values = { StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR, StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR, StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR, StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR }; 
     1163 
     1164        String[] map_attrs = { StaticStrings.DESCRIPTION_STR, StaticStrings.SMALLICON_STR, StaticStrings.ICON_STR, StaticStrings.NAME_STR }; 
     1165 
     1166        for (int i = 0; i < att_values.length; i++) 
     1167        { 
     1168 
     1169            //dOc 
     1170            ArrayList e_list = XMLTools.getNamedElementList(from.getDocumentElement(), StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, att_values[i]); 
     1171            // if such elements don't exist, don't bother 
     1172            if (e_list == null) 
     1173            { 
     1174                continue; 
     1175            } 
     1176            for (int j = 0; j < e_list.size(); j++) 
     1177            { 
     1178                Element e = (Element) e_list.get(j); 
     1179                if (e.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1180                { 
     1181                    continue; 
     1182                } 
     1183                String text = XMLTools.getNodeText(e); 
     1184                String lang = e.getAttribute(StaticStrings.LANGUAGE_ATTRIBUTE); 
     1185 
     1186                Element displayItem = constructElement(StaticStrings.DISPLAYITEM_STR, map_attrs[i], StaticStrings.LANG_STR, lang, text, to); 
     1187                displayItemList.appendChild(displayItem); 
     1188            } 
     1189 
     1190        } 
     1191        destination.appendChild(displayItemList); 
     1192    } 
     1193 
     1194    // This method creates a DisplayItem element of the type of 'to' by using the ingredients from the element 'e' 
     1195    static private Element constructDisplayItem(Element e, Document to) 
     1196    { 
     1197        String lang_string = e.getAttribute(StaticStrings.LANGUAGE_ATTRIBUTE); 
     1198        String text = XMLTools.getNodeText(e); 
     1199        Element displayItem = to.createElement(StaticStrings.DISPLAYITEM_STR); 
     1200        displayItem.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_ATTRIBUTE); 
     1201        displayItem.setAttribute(StaticStrings.LANG_STR, lang_string); 
     1202        XMLTools.setNodeText(displayItem, text); 
     1203        return displayItem; 
     1204    } 
     1205 
     1206    static private void convertMetadataList(Document from, Document to) 
     1207    { 
     1208        Element metadataList = to.createElement(StaticStrings.METADATALIST_STR); 
     1209        Element destination = to.getDocumentElement(); 
     1210 
     1211        String[] ele_names = { StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT }; 
     1212        String[] att_names = { StaticStrings.COLLECTIONMETADATA_CREATOR_STR, StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR, StaticStrings.COLLECTIONMETADATA_PUBLIC_STR }; 
     1213        for (int i = 0; i < ele_names.length; i++) 
     1214        { 
     1215            Element e = XMLTools.getNamedElement(from.getDocumentElement(), ele_names[i], StaticStrings.NAME_ATTRIBUTE, att_names[i]); 
     1216            if (e == null) 
     1217            { 
     1218                continue; 
     1219            } 
     1220            String text = XMLTools.getNodeText(e); 
     1221            Element metadata = to.createElement(StaticStrings.METADATA_STR); 
     1222            metadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, att_names[i]); 
     1223            metadata.setAttribute(StaticStrings.LANG_STR, StaticStrings.ENGLISH_LANGUAGE_STR); 
     1224            XMLTools.setNodeText(metadata, text); 
     1225            metadataList.appendChild(metadata); 
     1226        } 
     1227 
     1228        destination.appendChild(metadataList); 
     1229    } 
     1230 
     1231    // This method creates an element with the name 'element_name' of the type of 'to' by using the other three strings 
     1232    static private Element constructElement(String element_name, String name_value, String lang_att, String lang_value, String text, Document to) 
     1233    { 
     1234        Element e = to.createElement(element_name); 
     1235        e.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     1236        e.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_value); 
     1237        e.setAttribute(lang_att, lang_value); 
     1238        XMLTools.setNodeText(e, text); 
     1239 
     1240        return e; 
     1241    } 
     1242 
     1243    // Convert classify in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to) 
     1244    static private void convertClassifier(Document from, Document to) 
     1245    { 
     1246        Element browse_element = to.createElement(StaticStrings.BROWSE_STR); 
     1247        NodeList children = from.getDocumentElement().getElementsByTagName(StaticStrings.CLASSIFY_ELEMENT); 
     1248 
     1249        int num_children = (children == null) ? 0 : children.getLength(); 
     1250 
     1251        if (num_children == 0) 
     1252        { 
     1253            return; 
     1254        } 
     1255 
     1256        for (int i = 0; i < num_children; i++) 
     1257        { 
     1258 
     1259            Element child = (Element) children.item(i); 
     1260            if (child.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1261            { 
     1262                continue; 
     1263            } 
     1264            String str = child.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 
     1265            Element classifier_element = to.createElement(StaticStrings.CLASSIFIER_STR); 
     1266            classifier_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, str); 
     1267 
     1268            NodeList option_children = child.getElementsByTagName(StaticStrings.OPTION_ELEMENT); 
     1269            for (int j = 0; j < option_children.getLength(); j++) 
     1270            { 
     1271                Element el = (Element) option_children.item(j); 
     1272                if (el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1273                { 
     1274                    continue; 
     1275                } 
     1276                String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1277                String value_str = XMLTools.getNodeText(el); 
     1278 
     1279                if (name_str == null && value_str == null) 
     1280                { 
     1281                    continue; 
     1282                } 
     1283                Element option_element = to.createElement(StaticStrings.OPTION_STR); 
     1284                if (name_str != null && name_str.equals(StaticStrings.METADATA_STR)) 
     1285                { 
     1286 
     1287                    // The metadata argument is the fully qualified name of a metadata element, so if it contains a namespace, remove the extracted metadata namespace as the build process doesn't know about it. 
     1288                    String[] values = value_str.split(StaticStrings.COMMA_CHARACTER); 
     1289                    value_str = ""; 
     1290                    for (int k = 0; k <= values.length - 1; k++) 
     1291                    { 
     1292                        if (values[k].startsWith(StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) 
     1293                        { 
     1294                            values[k] = values[k].substring(StaticStrings.EXTRACTED_NAMESPACE.length()); 
     1295                        } 
     1296                        else 
     1297                        { 
     1298                            MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(values[k]); 
     1299                            if (metadata_element != null) 
     1300                            { 
     1301                                values[k] = metadata_element.getFullName(); 
     1302                            } 
     1303                        } 
     1304                        if (k < values.length - 1) 
     1305                        { 
     1306                            value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER; 
     1307                        } 
     1308                        else 
     1309                        { 
     1310                            value_str = value_str + values[k]; 
     1311                        } 
     1312                    } 
     1313                } 
     1314 
     1315                if (!name_str.equals("")) 
     1316                { 
     1317                    if (!name_str.startsWith(StaticStrings.MINUS_CHARACTER)) 
     1318                    { 
     1319                        name_str = StaticStrings.MINUS_CHARACTER + name_str; 
     1320                    } 
     1321                    option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     1322                } 
     1323 
     1324                if (!value_str.equals("")) 
     1325                { 
     1326                    option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str); 
     1327                } 
     1328 
     1329                classifier_element.appendChild(option_element); 
     1330            } 
     1331 
     1332            //format element for this classifier 
     1333            Element e = (Element) XMLTools.getChildByTagName(child, StaticStrings.FORMAT_STR); 
     1334 
     1335            if (e != null) 
     1336            { 
     1337                classifier_element.appendChild(convertFormat(to, e)); 
     1338            } 
     1339            browse_element.appendChild(classifier_element); 
     1340        } 
     1341 
     1342        //convert default classifier format 
     1343        Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.BROWSE_STR); 
     1344        browse_element.appendChild(convertFormat(to, e)); 
     1345 
     1346        to.getDocumentElement().appendChild(browse_element); 
     1347    } 
     1348 
     1349    static private Element convertFormat(Document to, Element e) 
     1350    { 
     1351        String format_str = XMLTools.getNodeText(e); 
     1352        Element format = to.createElement(StaticStrings.FORMAT_STR); 
     1353        //XMLTools.copyAllChildren (format, e); 
     1354        XMLTools.setNodeText(format, format_str); 
     1355        return format; 
     1356    } 
     1357 
     1358    //convert format statement for search 
     1359    static private void convertSearchFormat(Document from, Document to) 
     1360    { 
     1361        Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR); 
     1362        Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCH_STR); 
     1363 
     1364        search.appendChild(convertFormat(to, e)); 
     1365 
     1366    } 
     1367 
     1368    //convert format statement for display of the documents 
     1369    static private void convertDisplayFormat(Document from, Document to) 
     1370    { 
     1371        Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.DISPLAY_STR); 
     1372        if (e == null) 
     1373        { 
     1374            return; 
     1375        } 
     1376        Element display = to.createElement(StaticStrings.DISPLAY_STR); 
     1377        display.appendChild(convertFormat(to, e)); 
     1378        to.getDocumentElement().appendChild(display); 
     1379    } 
     1380 
     1381    // Convert plugins in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to) 
     1382    static private void convertPlugin(Document from, Document to) 
     1383    { 
     1384        Element import_element = to.createElement(StaticStrings.IMPORT_STR); 
     1385        Element plugin_list_element = to.createElement(StaticStrings.PLUGINLIST_STR); 
     1386 
     1387        NodeList children = from.getDocumentElement().getElementsByTagName(StaticStrings.PLUGIN_ELEMENT); 
     1388        int num_children = (children == null) ? 0 : children.getLength(); 
     1389        if (num_children == 0) 
     1390        { 
     1391            return; 
     1392        } 
     1393 
     1394        for (int i = 0; i < num_children; i++) 
     1395        { 
     1396 
     1397            Element child = (Element) children.item(i); 
     1398            if (child.getAttribute(StaticStrings.SEPARATOR_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) 
     1399            { 
     1400                continue; 
     1401            } 
     1402            if (child.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1403            { 
     1404                continue; 
     1405            } 
     1406 
     1407            String str = child.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 
     1408            Element plugin_element = to.createElement(StaticStrings.PLUGIN_STR); 
     1409            plugin_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, str); 
     1410 
     1411            NodeList option_children = child.getElementsByTagName(StaticStrings.OPTION_ELEMENT); 
     1412            for (int j = 0; j < option_children.getLength(); j++) 
     1413            { 
     1414                Element el = (Element) option_children.item(j); 
     1415                if (!el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) 
     1416                { 
     1417                    continue; 
     1418                } 
     1419                String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1420                String value_str = XMLTools.getNodeText(el); 
     1421 
     1422                if (name_str == null && value_str == null) 
     1423                { 
     1424                    continue; 
     1425                } 
     1426                Element option_element = to.createElement(StaticStrings.OPTION_STR); 
     1427                if (name_str != null && name_str.equals(StaticStrings.METADATA_STR)) 
     1428                { 
     1429 
     1430                    // The metadata argument is the fully qualified name of a metadata element, so if it contains a namespace, remove the extracted metadata namespace as the build process doesn't know about it, but ONLY if it is not embedded metadata (e.g. ex.dc.*) 
     1431                    String[] values = value_str.split(StaticStrings.COMMA_CHARACTER); 
     1432                    value_str = ""; 
     1433                    for (int k = 0; k <= values.length - 1; k++) 
     1434                    { 
     1435                        if (values[k].startsWith(StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) 
     1436                        { 
     1437                            values[k] = values[k].substring(StaticStrings.EXTRACTED_NAMESPACE.length()); 
     1438                        } 
     1439 
     1440                        if (k < values.length - 1) 
     1441                        { 
     1442                            value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER; 
     1443                        } 
     1444                        else 
     1445                        { 
     1446                            value_str = value_str + values[k]; 
     1447                        } 
     1448                    } 
     1449                } 
     1450 
     1451                if (!name_str.equals("")) 
     1452                { 
     1453                    if (!name_str.startsWith(StaticStrings.MINUS_CHARACTER)) 
     1454                    { 
     1455                        name_str = StaticStrings.MINUS_CHARACTER + name_str; 
     1456                    } 
     1457                    option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     1458                } 
     1459 
     1460                if (!value_str.equals("")) 
     1461                { 
     1462                    option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str); 
     1463                } 
     1464 
     1465                plugin_element.appendChild(option_element); 
     1466            }//for loop ends 
     1467 
     1468            plugin_list_element.appendChild(plugin_element); 
     1469        }//for loop ends 
     1470 
     1471        import_element.appendChild(plugin_list_element); 
     1472 
     1473        //do the plugout element (used by building flax collections) 
     1474        Node plugout = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), PLUGOUT_ELEMENT, 0); 
     1475        if (plugout != null) 
     1476        { 
     1477            Element to_element = XMLTools.duplicateElement(to, (Element) plugout, true); 
     1478            import_element.appendChild(to_element); 
     1479        } 
     1480 
     1481        to.getDocumentElement().appendChild(import_element); 
     1482    } 
     1483 
     1484    //Handle 'searchType' of collectionConfig.xml. In the internal structure, its also called 'searchType', eg. plain, form 
     1485    static private void convertSearchType(Document from, Document to) 
     1486    { 
     1487        Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT);//searchType 
     1488 
     1489        if (e == null) 
     1490        { 
     1491            return; 
     1492        } 
     1493        String searchtype_str = XMLTools.getNodeText(e); 
     1494        //Get the 'search' element from 'to' 
     1495        Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR); 
     1496 
     1497        String[] types = searchtype_str.split(","); 
     1498        for (int i = 0; i < types.length; i++) 
     1499        { 
     1500            Element search_type_element = to.createElement(StaticStrings.SEARCHTYPE_ELEMENT); 
     1501            search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, types[i]); 
     1502            search.appendChild(search_type_element); 
     1503        } 
     1504    } 
     1505 
     1506    static private void convertBuildType(Document from, Document to) 
     1507    { 
     1508        Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.BUILDTYPE_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR); 
     1509        if (e == null) 
     1510        { 
     1511            return; 
     1512        } 
     1513        String indexer = XMLTools.getNodeText(e); 
     1514        Element search = to.createElement(StaticStrings.SEARCH_STR); 
     1515        search.setAttribute(StaticStrings.TYPE_ATTRIBUTE, indexer); 
     1516        to.getDocumentElement().appendChild(search); 
     1517    } 
     1518 
     1519    static private void convertDatabaseType(Document from, Document to) 
     1520    { 
     1521        Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.DATABASETYPE_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR); 
     1522        if (e == null) 
     1523        { 
     1524            return; 
     1525        } 
     1526        String db = XMLTools.getNodeText(e); 
     1527        Element dbtype = to.createElement(StaticStrings.INFODB_STR); 
     1528        dbtype.setAttribute(StaticStrings.TYPE_ATTRIBUTE, db); 
     1529        to.getDocumentElement().appendChild(dbtype); 
     1530    } 
     1531 
     1532    static private void convertDefaultIndex(Document from, Document to, Element search) 
     1533    { 
     1534        Element source = from.getDocumentElement(); 
     1535 
     1536        Element default_index_element = (Element) XMLTools.getChildByTagName(source, StaticStrings.INDEX_DEFAULT_ELEMENT); 
     1537        if (default_index_element == null) 
     1538        { 
     1539            return; 
     1540        } 
     1541 
     1542        String indexer = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 
     1543        String level_str = default_index_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE); 
     1544        // Debugging purposes 
     1545        if (level_str.equals("") && indexer.equals(StaticStrings.MG_STR)) 
     1546        { 
     1547            System.out.println("Bug: DefaultIndex should have its level attribute not empty."); 
     1548        } 
     1549 
     1550        NodeList content_elements = default_index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT); 
     1551        int content_elements_length = content_elements.getLength(); 
     1552 
     1553        // Don't output anything if no indexes are set 
     1554        if (content_elements_length == 0) 
     1555        { 
     1556            return;// 
     1557        } 
     1558 
     1559        String index_str = ""; 
     1560 
     1561        if (indexer.equals(StaticStrings.MG_STR)) 
     1562        { 
     1563            //combine level with indexes 
     1564            index_str = level_str + StaticStrings.COLON_CHARACTER; 
     1565        } 
     1566        else 
     1567        { //for mgpp/lucene, just take index 
     1568            //do nothing 
     1569        } 
     1570 
     1571        for (int k = 0; k < content_elements_length; k++) 
     1572        { 
     1573            Element content_element = (Element) content_elements.item(k); 
     1574            if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1575            { 
     1576                continue; 
     1577            } 
     1578            String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1579 
     1580            if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) 
     1581            { 
     1582                name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length()); 
     1583            } 
     1584 
     1585            index_str = index_str + name_str; 
     1586 
     1587            // Make it comma separated string 
     1588            if (k < content_elements_length - 1) 
     1589            { 
     1590                index_str = index_str + StaticStrings.COMMA_CHARACTER; 
     1591            } 
     1592            content_element = null; 
     1593        }//for loop ends 
     1594 
     1595        Element default_index = to.createElement(StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE); 
     1596        default_index.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_str); 
     1597        search.appendChild(default_index); 
     1598 
     1599    } 
     1600 
     1601    static private void convertSubcollection(Document from, Document to) 
     1602    { 
     1603        Element source = from.getDocumentElement(); 
     1604        //Get the 'search' element from 'to' which has already been created in 'convertBuildType' 
     1605        Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR); 
     1606 
     1607        // Get the Subcollection element from the internal structure 
     1608        NodeList subcollection_elements = source.getElementsByTagName(StaticStrings.SUBCOLLECTION_ELEMENT); 
     1609        if (subcollection_elements == null) 
     1610        { 
     1611            return; 
     1612        } 
     1613        int subcollection_elements_length = subcollection_elements.getLength(); 
     1614 
     1615        if (subcollection_elements_length == 0) 
     1616        { // no 
     1617            return; 
     1618        } 
     1619 
     1620        for (int j = 0; j < subcollection_elements_length; j++) 
     1621        { 
     1622 
     1623            Element e = (Element) subcollection_elements.item(j); 
     1624            if (e.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1625            { 
     1626                continue; 
     1627            } 
     1628            String content = e.getAttribute(StaticStrings.CONTENT_ATTRIBUTE); 
     1629            String name = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1630            String options = e.getAttribute(StaticStrings.OPTIONS_ATTRIBUTE); 
     1631            String type = e.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 
     1632            String text = XMLTools.getNodeText(e); 
     1633 
     1634            String filter = ""; 
     1635            if (type.equals(StaticStrings.EXCLUDE_STR)) 
     1636            { 
     1637                filter = StaticStrings.EXCLAMATION_CHARACTER; 
     1638            } 
     1639 
     1640            if (content.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && content.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) 
     1641            { 
     1642                content = content.substring(StaticStrings.EXTRACTED_NAMESPACE.length()); 
     1643            } 
     1644            filter = filter + content + StaticStrings.SEPARATOR_CHARACTER + text; 
     1645            if (options != null && options != "") 
     1646            { 
     1647                filter = filter + StaticStrings.SEPARATOR_CHARACTER + options; 
     1648            } 
     1649            Element subcollection = to.createElement(StaticStrings.SUBCOLLECTION_STR); 
     1650            subcollection.setAttribute(StaticStrings.FILTER_ATTRIBUTE, filter); 
     1651            subcollection.setAttribute(StaticStrings.NAME_ATTRIBUTE, name); 
     1652 
     1653            search.appendChild(subcollection); 
     1654        } 
     1655    } 
     1656 
     1657    static private void convertSubcollectionIndexes(Document from, Document to) 
     1658    { 
     1659        Element source = from.getDocumentElement(); 
     1660        //Get the 'search' element from 'to' which has already been created in 'convertBuildType' 
     1661        Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR); 
     1662 
     1663        // Get the SubcollectionIndexes element from the internal structure 
     1664        Element subcollection_indexes = (Element) XMLTools.getChildByTagName(source, StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT); 
     1665        if (subcollection_indexes == null) 
     1666        { 
     1667            return; 
     1668        } 
     1669        NodeList index_elements = subcollection_indexes.getElementsByTagName(StaticStrings.INDEX_ELEMENT); 
     1670        int index_elements_length = index_elements.getLength(); 
     1671 
     1672        if (index_elements_length == 0) 
     1673        { // no indexes 
     1674            return; 
     1675        } 
     1676 
     1677        for (int j = 0; j < index_elements_length; j++) 
     1678        { 
     1679            Element index_element = (Element) index_elements.item(j); 
     1680            if (index_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1681            { 
     1682                continue; 
     1683            } 
     1684 
     1685            Element index = to.createElement(StaticStrings.SUBCOLLECTION_INDEX_ELEMENT); 
     1686 
     1687            String index_value = ""; 
     1688 
     1689            NodeList content_elements = index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT); 
     1690            int content_elements_length = content_elements.getLength(); 
     1691 
     1692            for (int k = 0; k < content_elements_length; k++) 
     1693            { 
     1694                Element content_element = (Element) content_elements.item(k); 
     1695                if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1696                { 
     1697                    continue; 
     1698                } 
     1699                String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1700                index_value += name_str; 
     1701                // Make it comma separated string 
     1702                if (k < content_elements_length - 1) 
     1703                { 
     1704                    index_value += StaticStrings.COMMA_CHARACTER; 
     1705                } 
     1706                content_element = null; 
     1707            }//for loop ends 
     1708 
     1709            index.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_value); 
     1710 
     1711            // Now constructing 'displayItem' element for this 'indexSubcollection' element 
     1712            // from the collectionmetadata element 
     1713            ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, index_value); 
     1714 
     1715            if (collectionmetadata_list != null) 
     1716            { 
     1717 
     1718                for (int k = 0; k < collectionmetadata_list.size(); k++) 
     1719                { 
     1720                    Element collectionmetadata = (Element) collectionmetadata_list.get(k); 
     1721                    if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1722                    { 
     1723                        continue; 
     1724                    } 
     1725                    Element displayItem = constructDisplayItem(collectionmetadata, to); 
     1726                    index.appendChild(displayItem); 
     1727                } 
     1728            } 
     1729 
     1730            search.appendChild(index); 
     1731 
     1732        } //for loop ends 
     1733    } 
     1734 
     1735    static private void convertLanguages(Document from, Document to) 
     1736    { 
     1737        Element source = from.getDocumentElement(); 
     1738        //Get the 'search' element from 'to' which has already been created in 'convertBuildType' 
     1739        Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR); 
     1740 
     1741        // Get the Languages element from the internal structure 
     1742        Element languages = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGES_ELEMENT); 
     1743        if (languages == null) 
     1744        { 
     1745            return; 
     1746        } 
     1747        NodeList language_elements = languages.getElementsByTagName(StaticStrings.LANGUAGE_ELEMENT); 
     1748        int language_elements_length = language_elements.getLength(); 
     1749 
     1750        if (language_elements_length == 0) 
     1751        { 
     1752            return; 
     1753        } 
     1754 
     1755        for (int j = 0; j < language_elements_length; j++) 
     1756        { 
     1757            Element element = (Element) language_elements.item(j); 
     1758            if (element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1759            { 
     1760                continue; 
     1761            } 
     1762 
     1763            // Create indexLanguage element 
     1764            Element index_language = to.createElement(StaticStrings.LANGUAGE_INDEX_ELEMENT); 
     1765 
     1766            String name_str = element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1767            index_language.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     1768 
     1769            // Now constructing 'displayItem' element for this 'indexLanguage' element 
     1770            // from the collectionmetadata element 
     1771            ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, name_str); 
     1772 
     1773            if (collectionmetadata_list != null) 
     1774            { 
     1775 
     1776                for (int k = 0; k < collectionmetadata_list.size(); k++) 
     1777                { 
     1778                    Element collectionmetadata = (Element) collectionmetadata_list.get(k); 
     1779                    if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1780                    { 
     1781                        continue; 
     1782                    } 
     1783                    Element displayItem = constructDisplayItem(collectionmetadata, to); 
     1784                    index_language.appendChild(displayItem); 
     1785                } 
     1786            } 
     1787 
     1788            search.appendChild(index_language); 
     1789 
     1790        } //for loop ends 
     1791 
     1792        // Convert DefaultLanguage 
     1793        // Get the DefaultLanguage element from the internal structure 
     1794        Element default_language = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGE_DEFAULT_ELEMENT); 
     1795        if (default_language != null) 
     1796        { 
     1797            String lang_name = default_language.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1798            Element default_index_language = to.createElement(StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT); 
     1799            default_index_language.setAttribute(StaticStrings.NAME_ATTRIBUTE, lang_name); 
     1800            search.appendChild(default_index_language); 
     1801        } 
     1802        // Convert LanguageMetadata 
     1803        // Get the LanguageMetadata element from the internal structure 
     1804        Element language_metadata = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGE_METADATA_ELEMENT); 
     1805        if (language_metadata != null) 
     1806        { 
     1807            String meta_name = language_metadata.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1808            Element language_meta = to.createElement(StaticStrings.LANGUAGE_METADATA_ELEMENT_STR); 
     1809            if (meta_name.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && meta_name.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) 
     1810            { 
     1811                meta_name = meta_name.substring(StaticStrings.EXTRACTED_NAMESPACE.length()); 
     1812            } 
     1813            language_meta.setAttribute(StaticStrings.NAME_ATTRIBUTE, meta_name); 
     1814            search.appendChild(language_meta); 
     1815        } 
     1816    } 
     1817 
     1818    //convert indexes and their displayItems, which go in 'search' element in collectionConfig.xml 
     1819    //parameter 'to' is the document to be saved as collectionConfig.xml 
     1820    //parameter 'from' is the internal xml structure 
     1821    static private void convertIndex(Document from, Document to) 
     1822    { 
     1823        Element source = from.getDocumentElement(); 
     1824        //Get the 'search' element from 'to' which has already been created in 'convertBuildType' 
     1825        Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR); 
     1826 
     1827        //THere are two sets of indexes elements, find the one which is assigned 'true' 
     1828        Element indexes = XMLTools.getNamedElement(source, StaticStrings.INDEXES_ELEMENT, StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 
     1829        if (indexes == null) 
     1830        { 
     1831            return; 
     1832        } 
     1833        NodeList index_elements = indexes.getElementsByTagName(StaticStrings.INDEX_ELEMENT); 
     1834        int index_elements_length = index_elements.getLength(); 
     1835 
     1836        if (index_elements_length == 0) 
     1837        { // no indexes 
     1838            return; 
     1839        } 
     1840 
     1841        //find out it's mg or mgpp/lucene 
     1842        String mg = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 
     1843        boolean mg_indexer = false; 
     1844        if (mg.equals(StaticStrings.MG_STR)) 
     1845        { 
     1846            mg_indexer = true;//it's mg, then the level is set as attribute of 
     1847        } 
     1848        if (mg_indexer == false) 
     1849        { 
     1850            // It's mgpp. Construct 'level' and 'defaultLevel' elements separately. 
     1851            convertLevels(from, to, search); 
     1852        } 
     1853 
     1854        for (int j = 0; j < index_elements_length; j++) 
     1855        { 
     1856            Element index_element = (Element) index_elements.item(j); 
     1857            if (index_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1858            { 
     1859                continue; 
     1860            } 
     1861 
     1862            Element index_ele = to.createElement(StaticStrings.INDEX_LOW_STR);//index 
     1863 
     1864            // Used for creating displayItem for this element 'index_ele' further below 
     1865            // full_index_names contain 'ex.' 
     1866            String full_index_name = ""; 
     1867            String level_str = ""; 
     1868 
     1869            StringBuffer index_value = new StringBuffer(); 
     1870            if (mg_indexer == true) 
     1871            { 
     1872                // For mg indexer, there is a 'level' attribute in the index element of the internal structure 
     1873                // But mgpp/lucene don't 
     1874                level_str = index_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE); 
     1875                if (level_str.length() > 0) 
     1876                { 
     1877                    index_value.append(level_str).append(StaticStrings.COLON_CHARACTER); 
     1878                    //index_value = index_value.StaticStrings.COLON_CHARACTER; 
     1879                } 
     1880            } 
     1881 
     1882            NodeList content_elements = index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT); 
     1883            int content_elements_length = content_elements.getLength(); 
     1884 
     1885            for (int k = 0; k < content_elements_length; k++) 
     1886            { 
     1887                Element content_element = (Element) content_elements.item(k); 
     1888                if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1889                { 
     1890                    continue; 
     1891                } 
     1892                String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1893 
     1894                full_index_name = full_index_name + name_str; 
     1895                if (k < content_elements_length - 1) 
     1896                { 
     1897                    full_index_name = full_index_name + StaticStrings.COMMA_CHARACTER; 
     1898                } 
     1899 
     1900                if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) 
     1901                { 
     1902                    name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length()); 
     1903                } 
     1904 
     1905                index_value.append(name_str); 
     1906                name_str = null; 
     1907                // Make it comma separated string 
     1908                if (k < content_elements_length - 1) 
     1909                { 
     1910                    index_value.append(StaticStrings.COMMA_CHARACTER); 
     1911                } 
     1912                content_element = null; 
     1913            }//for loop ends 
     1914 
     1915            String temp_str = index_value.toString(); 
     1916            index_ele.setAttribute(StaticStrings.NAME_ATTRIBUTE, temp_str); 
     1917 
     1918            // Now constructing 'displayItem' element for this 'index_ele' element 
     1919            // The index names in the collectionmetadata elements in the internal structure are not the names that 
     1920            // are used in the content elements (i.e. ex.Source or dc.Subject and keywords), but the names that are 
     1921            // in the configuration files (i.e. Source or dc.Subject) 
     1922            ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, temp_str); 
     1923 
     1924            if (collectionmetadata_list == null) 
     1925            { 
     1926                //try the full name, i.e. with 'ex.' 
     1927                if (mg_indexer == true) 
     1928                { 
     1929                    // but first append level info if we are mg 
     1930                    full_index_name = level_str + StaticStrings.COLON_CHARACTER + full_index_name; 
     1931                } 
     1932                collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, full_index_name); 
     1933            } 
     1934 
     1935            if (collectionmetadata_list != null) 
     1936            { 
     1937 
     1938                for (int k = 0; k < collectionmetadata_list.size(); k++) 
     1939                { 
     1940                    Element collectionmetadata = (Element) collectionmetadata_list.get(k); 
     1941                    if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1942                    { 
     1943                        continue; 
     1944                    } 
     1945                    Element displayItem = constructDisplayItem(collectionmetadata, to); 
     1946 
     1947                    index_ele.appendChild(displayItem); 
     1948                } 
     1949            } 
     1950 
     1951            search.appendChild(index_ele); 
     1952 
     1953        } //for loop ends 
     1954 
     1955        //Convert default index 
     1956        convertDefaultIndex(from, to, search); 
     1957        convertIndexOptions(from, to, search); 
     1958    } 
     1959 
     1960    // Convert levels for mgpp/lucene. This method is called by converIndex() when mgpp indexer is detected. 
     1961    static private void convertLevels(Document from, Document to, Element search) 
     1962    { 
     1963        Element source = from.getDocumentElement(); 
     1964        Element index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTIONS_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVELS_STR); 
     1965        if (index_option == null) 
     1966        { 
     1967            return; 
     1968        } 
     1969        //Debugging purposes 
     1970        if (index_option.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     1971        { 
     1972            DebugStream.println("For mgpp, there should be an IndexOption element for levels which is assigned 'true': possible bug."); 
     1973        } 
     1974 
     1975        NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT); 
     1976        int num_elements = option_elements.getLength(); 
     1977 
     1978        // Don't output anything if no indexes are set 
     1979        if (num_elements == 0) 
     1980        { 
     1981            return;// 
     1982        } 
     1983 
     1984        for (int k = 0; k < num_elements; k++) 
     1985        { 
     1986            Element e = (Element) option_elements.item(k); 
     1987            String name_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     1988            Element level_element = to.createElement(StaticStrings.LEVEL_ELEMENT); 
     1989            level_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str); 
     1990 
     1991            //Now construct displayItem for this level element from collectionmetadata 
     1992            ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, name_str); 
     1993 
     1994            if (collectionmetadata_list != null) 
     1995            { 
     1996 
     1997                for (int j = 0; j < collectionmetadata_list.size(); j++) 
     1998                { 
     1999                    Element collectionmetadata = (Element) collectionmetadata_list.get(j); 
     2000 
     2001                    Element displayItem = constructDisplayItem(collectionmetadata, to); 
     2002                    level_element.appendChild(displayItem); 
     2003                } 
     2004            } 
     2005            search.appendChild(level_element); 
     2006        } 
     2007 
     2008        //Convert default level 
     2009        Element default_index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTION_DEFAULT_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVEL_DEFAULT_STR); 
     2010        if (default_index_option == null) 
     2011        { 
     2012            return; 
     2013        } 
     2014        Element default_level = to.createElement(StaticStrings.LEVEL_DEFAULT_ELEMENT); 
     2015        String default_level_str = default_index_option.getAttribute(StaticStrings.VALUE_ATTRIBUTE); 
     2016        default_level.setAttribute(StaticStrings.NAME_ATTRIBUTE, default_level_str); 
     2017        search.appendChild(default_level); 
     2018 
     2019    } 
     2020 
     2021    // Convert indexoptions for mg/mgpp/lucene. This method is called by convertIndex(). 
     2022    static private void convertIndexOptions(Document from, Document to, Element search) 
     2023    { 
     2024        Element source = from.getDocumentElement(); 
     2025        Element index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTIONS_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.INDEXOPTIONS_STR); 
     2026        if (index_option == null) 
     2027        { 
     2028            return; 
     2029        } 
     2030        //Debugging purposes 
     2031        if (index_option.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) 
     2032        { 
     2033            DebugStream.println("There should be an IndexOption element which is assigned 'true': possible bug."); 
     2034        } 
     2035        Element indexOptionEl = to.createElement(StaticStrings.INDEXOPTION_STR); 
     2036        NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT); 
     2037        int num_elements = option_elements.getLength(); 
     2038        // Don't output anything if no index 
     2039        if (num_elements == 0) 
     2040        { 
     2041            return;// 
     2042        } 
     2043        search.appendChild(indexOptionEl); 
     2044 
     2045        for (int k = 0; k < num_elements; k++) 
     2046        { 
     2047            Element e = (Element) option_elements.item(k); 
     2048            String name_att = e.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     2049            Element optionEl = to.createElement(StaticStrings.OPTION_STR); 
     2050            optionEl.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_att); 
     2051            indexOptionEl.appendChild(optionEl); 
     2052        } 
     2053 
     2054    } 
     2055 
     2056    // Append the element son to the element mother in the appropriate position. 
     2057    static public void appendProperly(Element mother, Element son) 
     2058    { 
     2059        if (son == null) 
     2060            return; 
     2061 
     2062        Node reference_node = findInsertionPoint(mother, son); 
     2063        if (reference_node != null) 
     2064        { 
     2065            mother.insertBefore(son, reference_node); 
     2066        } 
     2067        else 
     2068        { 
     2069            mother.appendChild(son); 
     2070        } 
     2071    } 
     2072 
     2073    /** 
     2074     * Find the best insertion position for the given DOM Element 
     2075     * 'target_element' in the DOM Element 'document_element'. This should try 
     2076     * to match command tag, and if found should then try to group by name or 
     2077     * type (eg CollectionMeta), or append to end is no such grouping exists (eg 
     2078     * Plugins). Failing a command match it will check against the command order 
     2079     * for the best insertion location. 
     2080     *  
     2081     * @param target_element 
     2082     *            the command Element to be inserted 
     2083     * @return the Element which the given command should be inserted before, or 
     2084     *         null to append to end of list 
     2085     */ 
     2086    static public Node findInsertionPoint(Element document_element, Element target_element) 
     2087    { 
     2088        ///ystem.err.println("Find insertion point: " + target_element.getNodeName()); 
     2089        String target_element_name = target_element.getNodeName(); 
     2090 
     2091        // Try to find commands with the same tag. 
     2092        NodeList matching_elements = document_element.getElementsByTagName(target_element_name); 
     2093        // If we found matching elements, then we have our most likely insertion location, so check within for groupings 
     2094        if (matching_elements.getLength() != 0) 
     2095        { 
     2096            ///ystem.err.println("Found matching elements."); 
     2097            // Only CollectionMeta are grouped. 
     2098            if (target_element_name.equals(StaticStrings.COLLECTIONMETADATA_ELEMENT)) 
     2099            { 
     2100                ///ystem.err.println("Dealing with collection metadata"); 
     2101                // Special case: CollectionMeta can be added at either the start or end of a collection configuration file. However the start position is reserved for special metadata, so if no non-special metadata can be found we must append to the end. 
     2102                // So if the command to be added is special add it immediately after any other special command 
     2103                if (target_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) 
     2104                { 
     2105                    int index = 0; 
     2106                    Element matched_element = (Element) matching_elements.item(index); 
     2107                    Element sibling_element = (Element) matched_element.getNextSibling(); 
     2108                    while (sibling_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) 
     2109                    { 
     2110                        index++; 
     2111                        matched_element = (Element) matching_elements.item(index); 
     2112                        sibling_element = (Element) matched_element.getNextSibling(); 
     2113                    } 
     2114                    if (sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) 
     2115                    { 
     2116                        Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT); 
     2117                        document_element.insertBefore(newline_element, sibling_element); 
     2118                    } 
     2119                    return sibling_element; 
     2120                } 
     2121                // Otherwise try to find a matching 'name' and add after the last one in that group. 
     2122                else 
     2123                { 
     2124                    int index = 0; 
     2125                    target_element_name = target_element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 
     2126                    boolean found = false; 
     2127                    // Skip all of the special metadata 
     2128                    Element matched_element = (Element) matching_elements.item(index); 
     2129                    while (matched_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) 
     2130                    { 
     2131                        index++; 
     2132                        matched_element = (Element) matching_elements.item(index); 
     2133                    } 
     2134                    // Begin search 
     2135                    while (!found && matched_element != null) 
     2136                    { 
     2137                        if (matched_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(target_element_name)) 
     2138                        { 
     2139                            found = true; 
     2140                        } 
     2141                        else 
     2142                        { 
     2143                            index++; 
     2144                            matched_element = (Element) matching_elements.item(index); 
     2145                        } 
     2146                    } 
     2147                    // If we found a match, we need to continue checking until we find the last name match. 
     2148                    if (found) 
     2149                    { 
     2150                        index++; 
     2151                        Element previous_sibling = matched_element; 
     2152                        Element sibling_element = (Element) matching_elements.item(index); 
     2153                        while (sibling_element != null && sibling_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(target_element_name)) 
     2154                        { 
     2155                            previous_sibling = sibling_element; 
     2156                            index++; 
     2157                            sibling_element = (Element) matching_elements.item(index); 
     2158                        } 
     2159                        // Previous sibling now holds the command immediately before where we want to add, so find its next sibling and add to that. In this one case we can ignore new lines! 
     2160                        return previous_sibling.getNextSibling(); 
     2161                    } 
     2162                    // If not found we just add after last metadata element 
     2163                    else 
     2164                    { 
     2165                        Element last_element = (Element) matching_elements.item(matching_elements.getLength() - 1); 
     2166                        return last_element.getNextSibling(); 
     2167                    } 
     2168                } 
     2169 
     2170            } 
     2171            else 
     2172            { 
     2173                ///ystem.err.println("Not dealing with collection meta."); 
     2174                Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1); 
     2175                // One final quick test. If the matched element is immediately followed by a NewLine command, then we insert another NewLine after the matched command, then return the NewLine instead (thus the about to be inserted command will be placed between the two NewLines) 
     2176                Node sibling_element = matched_element.getNextSibling(); 
     2177                if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) 
     2178                { 
     2179                    Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT); 
     2180                    document_element.insertBefore(newline_element, sibling_element); 
     2181                } 
     2182                return sibling_element; // Note that this may be null 
     2183            } 
     2184        } 
     2185        ///ystem.err.println("No matching elements found."); 
     2186        // Locate where this command is in the ordering 
     2187        int command_index = -1; 
     2188        for (int i = 0; command_index == -1 && i < CollectionConfiguration.COMMAND_ORDER.length; i++) 
     2189        { 
     2190            if (CollectionConfiguration.COMMAND_ORDER[i].equals(target_element_name)) 
     2191            { 
     2192                command_index = i; 
     2193            } 
     2194        } 
     2195        ///ystem.err.println("Command index is: " + command_index); 
     2196        // Now move forward, checking for existing elements in each of the preceeding command orders. 
     2197        int preceeding_index = command_index - 1; 
     2198        ///ystem.err.println("Searching before the target command."); 
     2199        while (preceeding_index >= 0) 
     2200        { 
     2201            matching_elements = document_element.getElementsByTagName(CollectionConfiguration.COMMAND_ORDER[preceeding_index]); 
     2202            // If we've found a match 
     2203            if (matching_elements.getLength() > 0) 
     2204            { 
     2205                // We add after the last element 
     2206                Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1); 
     2207                // One final quick test. If the matched element is immediately followed by a NewLine command, then we insert another NewLine after the matched command, then return the NewLine instead (thus the about to be inserted command will be placed between the two NewLines) 
     2208                Node sibling_element = matched_element.getNextSibling(); 
     2209                if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) 
     2210                { 
     2211                    Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT); 
     2212                    document_element.insertBefore(newline_element, sibling_element); 
     2213                } 
     2214                return sibling_element; // Note that this may be null 
     2215            } 
     2216            preceeding_index--; 
     2217        } 
     2218        // If all that fails, we now move backwards through the commands 
     2219        int susceeding_index = command_index + 1; 
     2220        ///ystem.err.println("Searching after the target command."); 
     2221        while (susceeding_index < CollectionConfiguration.COMMAND_ORDER.length) 
     2222        { 
     2223            matching_elements = document_element.getElementsByTagName(CollectionConfiguration.COMMAND_ORDER[susceeding_index]); 
     2224            // If we've found a match 
     2225            if (matching_elements.getLength() > 0) 
     2226            { 
     2227                // We add before the first element 
     2228                Element matched_element = (Element) matching_elements.item(0); 
     2229                // One final quick test. If the matched element is immediately preceeded by a NewLine command, then we insert another NewLine before the matched command, then return this new NewLine instead (thus the about to be inserted command will be placed between the two NewLines) 
     2230                Node sibling_element = matched_element.getPreviousSibling(); 
     2231                if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) 
     2232                { 
     2233                    Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT); 
     2234                    document_element.insertBefore(newline_element, sibling_element); 
     2235                } 
     2236                return sibling_element; // Note that this may be null 
     2237            } 
     2238            susceeding_index++; 
     2239        } 
     2240        // Well. Apparently there are no other commands in this collection configuration. So append away... 
     2241        return null; 
     2242    } 
     2243 
     2244    // From collectionConfig.xml to internal structure:add 'ex.' namespace (if none). 
     2245    // From internal structure to collectionConfig.xml:always peel off 'ex.' namespace (if any), except for format statement 
     2246    //This method parses 'xml_file_doc' into 'dOc' 
     2247    static public void parse(File xml_file, Document dOc) 
     2248    { 
     2249 
     2250        Document xml_file_doc = XMLTools.parseXMLFile(xml_file); 
     2251        Element fromElement = xml_file_doc.getDocumentElement(); 
     2252        Element toElement = dOc.getDocumentElement(); 
     2253 
     2254        // It's deliberately set that 'creator', 'maintainer', and 'public' are only in English (as they are just names). 
     2255        // So the following ArrayList have only one element. 
     2256        Node metadataListNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.METADATALIST_STR, 0); 
     2257        if (metadataListNode != null) 
     2258        { 
     2259            ArrayList creator = doMetadataList(dOc, metadataListNode, StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_CREATOR_STR); 
     2260            ArrayList maintainer = doMetadataList(dOc, metadataListNode, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR); 
     2261            ArrayList is_public = doMetadataList(dOc, metadataListNode, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_STR); 
     2262 
     2263            appendArrayList(toElement, creator); 
     2264            appendArrayList(toElement, maintainer); 
     2265            appendArrayList(toElement, is_public); 
     2266        } 
     2267 
     2268        Node databaseNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.INFODB_STR, 0); 
     2269        String databasetype_value = "gdbm"; 
     2270        if (databaseNode != null) 
     2271        { 
     2272            databasetype_value = ((Element) databaseNode).getAttribute(StaticStrings.TYPE_ATTRIBUTE);//might be gdbm|jdbm|sqlite OR not yet set (in which case it should default to gdbm) 
     2273        } 
     2274 
     2275        Element databasetype = doDatabaseType(dOc, databasetype_value); 
     2276        appendProperly(toElement, databasetype); 
     2277 
     2278        Node searchNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.SEARCH_STR, 0); 
     2279        String buildtype_value = ((Element) searchNode).getAttribute(StaticStrings.TYPE_ATTRIBUTE);//might be mg|mgpp|lucene 
     2280        Element buildtype = doBuildType(dOc, buildtype_value); 
     2281        appendProperly(toElement, buildtype); 
     2282 
     2283        Node importNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.IMPORT_STR, 0); 
     2284        if (importNode == null) 
     2285        { 
     2286            System.out.println("There is no content in the 'import' block."); 
     2287        } 
     2288        if (importNode != null) 
     2289        { 
     2290            //do plugin list nodes 
     2291            Node pluginListNode = XMLTools.getChildByTagNameIndexed((Element) importNode, StaticStrings.PLUGINLIST_STR, 0); 
     2292            if (pluginListNode == null) 
     2293            { 
     2294                System.out.println("There is no pluginlist set."); 
     2295            } 
     2296            if (pluginListNode != null) 
     2297            { 
     2298 
     2299                doPlugin(dOc, pluginListNode); 
     2300            } 
     2301 
     2302            //do the plugout element (used by building flax collections) 
     2303            Node plugout = XMLTools.getChildByTagNameIndexed((Element) importNode, PLUGOUT_ELEMENT, 0); 
     2304            if (plugout != null) 
     2305            { 
     2306                Element to_element = XMLTools.duplicateElement(dOc, (Element) plugout, true); 
     2307                toElement.appendChild(to_element); 
     2308            } 
     2309        } 
     2310 
     2311        Node browseNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.BROWSE_STR, 0); 
     2312        if (browseNode != null) 
     2313        { 
     2314            if (browseNode == null) 
     2315            { 
     2316                System.out.println("There is no classifier."); 
     2317            } 
     2318            doClassifier(dOc, browseNode); 
     2319        } 
     2320 
     2321        Node displayItemListNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.DISPLAYITEMLIST_STR, 0); 
     2322        if (displayItemListNode != null) 
     2323        { 
     2324            ArrayList description = doDisplayItemList(dOc, displayItemListNode, StaticStrings.DESCRIPTION_STR, StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR); 
     2325            ArrayList smallicon = doDisplayItemList(dOc, displayItemListNode, StaticStrings.SMALLICON_STR, StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR); 
     2326            ArrayList icon = doDisplayItemList(dOc, displayItemListNode, StaticStrings.ICON_STR, StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR); 
     2327            ArrayList name = doDisplayItemList(dOc, displayItemListNode, StaticStrings.NAME_STR, StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR); 
     2328 
     2329            appendArrayList(toElement, description); 
     2330            appendArrayList(toElement, smallicon); 
     2331            appendArrayList(toElement, icon); 
     2332            appendArrayList(toElement, name); 
     2333        } 
     2334 
     2335        if (buildtype_value.equalsIgnoreCase("mg")) 
     2336        { 
     2337            doMGIndexes(dOc, searchNode); 
     2338        } 
     2339        else 
     2340        { 
     2341            doMGPPIndexes(dOc, searchNode); 
     2342        } 
     2343 
     2344        doDefaultIndex(dOc, searchNode); 
     2345        doDefaultLevel(dOc, searchNode); 
     2346        doLevel(dOc, searchNode); 
     2347        doIndexOption(dOc, searchNode); 
     2348        doSubcollection(dOc, searchNode); 
     2349        doIndexSubcollection(dOc, searchNode); 
     2350        doIndexLanguage(dOc, searchNode); 
     2351        doDefaultIndexLanguage(dOc, searchNode); 
     2352        doLanguageMetadata(dOc, searchNode); 
     2353        doSearchType(dOc, searchNode); 
     2354        doSearchFormat(dOc, searchNode); 
     2355        doDisplayFormat(dOc, fromElement); 
     2356        doReplaceListRef(dOc, fromElement); 
     2357        doServiceRackList(dOc, fromElement); 
     2358 
     2359    } 
     2360 
     2361    static public String generateStringVersion(Document doc) 
     2362    { 
     2363        return XMLTools.xmlNodeToString(doc); 
     2364    } 
     2365 
     2366    static public void save(File collect_config_xml_file, Document doc) 
     2367    { 
     2368 
     2369        Document collection_config_xml_document = convertInternalToCollectionConfig(doc); 
     2370        String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR }; 
     2371        XMLTools.writeXMLFile(collect_config_xml_file, collection_config_xml_document, nonEscapingTagNames); 
     2372 
     2373    } 
     2374 
     2375    //Convert the internal XML DOM tree (dOc) into that of collectionConfig.xml (skeleton) 
     2376    static private Document convertInternalToCollectionConfig(Document dOc) 
     2377    { 
     2378        //first parse an empty skeleton of xml config file 
     2379        //The aim is to convert the internal structure into this skeleton 
     2380        Document skeleton = XMLTools.parseXMLFile("xml/CollectionConfig.xml", true); 
     2381        //Element internal = dOc.getDocumentElement(); 
     2382        convertMetadataList(dOc, skeleton); 
     2383        convertDisplayItemList(dOc, skeleton); 
     2384        convertBuildType(dOc, skeleton); 
     2385        convertDatabaseType(dOc, skeleton); 
     2386        convertIndex(dOc, skeleton); 
     2387        convertPlugin(dOc, skeleton);//also do the plugout element 
     2388        convertClassifier(dOc, skeleton); 
     2389        convertSubcollectionIndexes(dOc, skeleton); 
     2390        convertLanguages(dOc, skeleton); 
     2391        convertSubcollection(dOc, skeleton); 
     2392        convertSearchType(dOc, skeleton); 
     2393        convertSearchFormat(dOc, skeleton); 
     2394        convertDisplayFormat(dOc, skeleton); 
     2395        convertReplaceListRef(dOc, skeleton); 
     2396        convertServiceRackList(dOc, skeleton); 
     2397 
     2398        return skeleton; 
     2399    } 
     2400 
     2401    // Append the elements, which are of Element type, in 'list' to Element 'to' 
     2402    static private void appendArrayList(Element to, ArrayList list) 
     2403    { 
     2404        if (list == null) 
     2405            return; 
     2406 
     2407        for (int i = 0; i < list.size(); i++) 
     2408        { 
     2409            appendProperly(to, (Element) list.get(i)); 
     2410        } 
     2411    } 
     2412 
    21272413} 
  • main/trunk/gli/src/org/greenstone/gatherer/util/XMLTools.java

    r21548 r24801  
    11package org.greenstone.gatherer.util; 
    2  
    32 
    43import java.io.*; 
     
    2928 
    3029/** This class is a static class containing useful XML functions */ 
    31 public class XMLTools { 
    32     /** extracts the text out of a node */ 
    33     public static Node getNodeTextNode (Element param) { 
    34         param.normalize (); 
    35         Node n = param.getFirstChild (); 
    36         while (n!=null && n.getNodeType () !=Node.TEXT_NODE) { 
    37             n=n.getNextSibling (); 
    38         } 
    39         return n; 
    40     } 
    41      
    42     /** extracts the text out of a node */ 
    43     public static String getNodeText (Element param) { 
    44         Node text_node = getNodeTextNode (param); 
    45         if (text_node == null) { 
    46             return ""; 
    47         } 
    48         return text_node.getNodeValue (); 
    49     } 
    50     public static void setNodeText (Element elem, String text) { 
    51         Node old_text_node = getNodeTextNode (elem); 
    52         if (old_text_node != null) { 
    53             elem.removeChild (old_text_node); 
    54         } 
    55         Text t = elem.getOwnerDocument ().createTextNode (text); 
    56         elem.appendChild (t); 
    57     } 
    58     /** returns the (first) child element with the given name */ 
    59     public static Node getChildByTagName (Node n, String name) { 
    60          
    61         Node child = n.getFirstChild (); 
    62         while (child!=null) { 
    63             if (child.getNodeName ().equals (name)) { 
    64                 return child; 
    65             } 
    66             child = child.getNextSibling (); 
    67         } 
    68         return null; //not found 
    69     } 
    70      
    71     /** returns the (nth) child element with the given name 
    72      * index numbers start at 0 */ 
    73     public static Node getChildByTagNameIndexed (Node n, String name, int index) { 
    74         if (index == -1) { 
    75             return getChildByTagName (n, name); 
    76         } 
    77         int count = 0; 
    78         Node child = n.getFirstChild (); 
    79         while (child!=null) { 
    80             if (child.getNodeName ().equals (name)) { 
    81                 if (count == index) { 
    82                     return child; 
    83                 } else { 
    84                     count++; 
    85                 } 
    86             } 
    87             child = child.getNextSibling (); 
    88         } 
    89         return null; //not found 
    90     } 
    91      
    92     /** returns the element parent/node_name[@attribute_name='attribute_value'] 
    93      */ 
    94     public static Element getNamedElement (Element parent, String node_name, 
    95     String attribute_name, 
    96     String attribute_value) { 
    97          
    98         NodeList children = parent.getChildNodes (); 
    99         for (int i=0; i<children.getLength (); i++) { 
    100             Node child = children.item (i); 
    101             //logger.debug("getnamed elem, node nmae="+child.getNodeName()); 
    102             if (child.getNodeName ().equals (node_name)) { 
    103                 if (((Element)child).getAttribute (attribute_name).equals (attribute_value)) 
    104                     return (Element)child; 
    105             } 
    106         } 
    107         // not found 
    108         return null; 
    109     } 
    110     /** returns a list of elements parent/node_name[@attribute_name='attribute_value'] 
    111      */ 
    112     public static ArrayList getNamedElementList (Element parent, String node_name, 
    113     String attribute_name, 
    114     String attribute_value) { 
    115         ArrayList elements = new ArrayList (); 
    116         NodeList children = parent.getChildNodes (); 
    117         for (int i=0; i<children.getLength (); i++) { 
    118             //System.out.println("getNamedElementList"); 
    119             Node child = children.item (i); 
    120             //logger.debug("getnamed elem, node nmae="+child.getNodeName()); 
    121             if (child.getNodeName ().equals (node_name)) { 
    122                 if (((Element)child).getAttribute (attribute_name).equals (attribute_value)) 
    123                     elements.add ((Element)child); 
    124             } 
    125         } 
    126         // not found 
    127         if (elements.size () == 0) { 
    128             elements = null; 
    129         } 
    130         return elements; 
    131     } 
    132     public static void copyAllChildren (Element to, Element from) { 
    133          
    134         Document to_doc = to.getOwnerDocument (); 
    135         Node child = from.getFirstChild (); 
    136         while (child != null) { 
    137             to.appendChild (to_doc.importNode (child, true)); 
    138             child = child.getNextSibling (); 
    139         } 
    140     } 
    141     /** Duplicates an element */ 
    142     public static Element duplicateElement (Document owner, Element element, boolean with_attributes) { 
    143         return duplicateElementNS (owner, element, null, with_attributes); 
    144     } 
    145      
    146     /** Duplicates an element */ 
    147     public static Element duplicateElementNS (Document owner, 
    148     Element element, 
    149     String namespace_uri, 
    150     boolean with_attributes) { 
    151         Element duplicate; 
    152         if (namespace_uri == null) { 
    153             duplicate = owner.createElement (element.getTagName ()); 
    154         } else { 
    155             duplicate = owner.createElementNS (namespace_uri, element.getTagName ()); 
    156         } 
    157         // Copy element attributes 
    158         if (with_attributes) { 
    159             NamedNodeMap attributes = element.getAttributes (); 
    160             for (int i = 0; i < attributes.getLength (); i++) { 
    161                 Node attribute = attributes.item (i); 
    162                 duplicate.setAttribute (attribute.getNodeName (), attribute.getNodeValue ()); 
    163             } 
    164         } 
    165          
    166         // Copy element children 
    167         NodeList children = element.getChildNodes (); 
    168         for (int i = 0; i < children.getLength (); i++) { 
    169             Node child = children.item (i); 
    170             duplicate.appendChild (owner.importNode (child, true)); 
    171         } 
    172          
    173         return duplicate; 
    174     } 
    175      
    176      
    177     /** Remove all of the child nodes from a certain node. */ 
    178     static final public void clear (Node node) { 
    179         while (node.hasChildNodes ()) { 
    180             node.removeChild (node.getFirstChild ()); 
    181         } 
    182     } 
    183      
    184      
    185     static public ArrayList getChildElementsByTagName (Element parent_element, String element_name) { 
    186         ArrayList child_elements = new ArrayList (); 
    187          
    188         NodeList children_nodelist = parent_element.getChildNodes (); 
    189         for (int i = 0; i < children_nodelist.getLength (); i++) { 
    190             Node child_node = children_nodelist.item (i); 
    191             if (child_node.getNodeType () == Node.ELEMENT_NODE && child_node.getNodeName ().equals (element_name)) { 
    192                 child_elements.add (child_node); 
    193             } 
    194         } 
    195          
    196         return child_elements; 
    197     } 
    198      
    199      
    200     static public String getElementTextValue (Element element) { 
    201         // Find the first text node child 
    202         NodeList children_nodelist = element.getChildNodes (); 
    203         for (int i = 0; i < children_nodelist.getLength (); i++) { 
    204             Node child_node = children_nodelist.item (i); 
    205             if (child_node.getNodeType () == Node.TEXT_NODE) { 
    206                 return child_node.getNodeValue (); 
    207             } 
    208         } 
    209          
    210         // None found 
    211         return ""; 
    212     } 
    213      
    214      
    215     /** Method to retrieve the value of a given node. 
    216      * @param element The <strong>Element</strong> whose value we wish to find. 
    217      * Soon to be deprecated! 
    218      */ 
    219     static final public String getValue (Node element) { 
    220         if (element == null) { 
    221             return ""; 
    222         } 
    223         // If we've been given a subject node first retrieve its value node. 
    224         if(element.getNodeName ().equals ("Subject")) { 
    225             element = getNodeFromNamed (element, "Value"); 
    226         } 
    227         // If we've got a value node, then reconstruct the text. Remember that DOM will split text over 256 characters into several text nodes 
    228         if(element != null && element.hasChildNodes ()) { 
    229             StringBuffer text_buffer = new StringBuffer (); 
    230             NodeList text_nodes = element.getChildNodes (); 
    231             for(int i = 0; i < text_nodes.getLength (); i++) { 
    232                 Node possible_text = text_nodes.item (i); 
    233                 if(possible_text.getNodeName ().equals (StaticStrings.TEXT_NODE)) { 
    234                     text_buffer.append (possible_text.getNodeValue ()); 
    235                 } 
    236             } 
    237             return text_buffer.toString (); 
    238         } 
    239         return ""; 
    240     } 
    241      
    242      
    243     /** Method to retrieve from the node given, a certain child node with the specified name. 
    244      * @param parent The <strong>Node</strong> whose children should be searched. 
    245      * @param name The required nodes name as a <strong>String</strong>. 
    246      * @return The requested <strong>Node</strong> if it is found, <i>null</i> otherwise. 
    247      * Soon to be deprecated! 
    248      */ 
    249     static final public Node getNodeFromNamed (Node parent, String name) { 
    250         Node child = null; 
    251         for(Node i = parent.getFirstChild (); i != null && child == null; 
    252         i = i.getNextSibling ()) { 
    253             if(i.getNodeName ().equals (name)) { 
    254                 child = i; 
    255             } 
    256         } 
    257         return child; 
    258     } 
    259      
    260     static final public String WELLFORMED= "well-formed !"; 
    261     static final public String NOTWELLFORMED= "not well-formed"; 
    262     static final private String HEADER = "<?xml version='1.0' encoding='UTF-8'?><collectionConfig xmlns:gsf='http://www.greenstone.org/greenstone3/schema/ConfigFormat' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"; 
    263     static final private String FOOTER = "</collectionConfig>"; 
    264         
    265 public static String parse (String xml_str) { 
    266         String validation_msg = WELLFORMED; 
    267         xml_str = HEADER + xml_str + FOOTER; 
    268         try { 
    269             SAXParserFactory factory = SAXParserFactory.newInstance (); 
    270             factory.setNamespaceAware (true); 
    271             //factory.setValidating (true); 
    272             SAXParser parser = factory.newSAXParser (); 
    273             InputSource iSource = new InputSource ( new StringReader ( xml_str ) ); 
    274 //              parser.parse (iSource, new DefaultHandler ()); 
    275              
    276             org.xml.sax.XMLReader reader = parser.getXMLReader (); 
    277             reader.setContentHandler(new DefaultHandler()); 
    278             reader.setErrorHandler(new DefaultHandler()); 
    279             reader.parse(iSource); 
    280         } catch (FactoryConfigurationError e) { 
    281             validation_msg = "unable to get a document builder factory"; 
    282         } catch (ParserConfigurationException e) { 
    283             validation_msg = "unable to configure parser"; 
    284         } catch (SAXParseException e) { 
    285             validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage (); 
    286         } catch (SAXException e) { 
    287             validation_msg += " Fatal error: " + e.toString (); 
    288         } catch (IOException e) { 
    289             validation_msg = "Unable to read the input, i/o error"; 
    290         } 
    291          
    292         return validation_msg; 
    293     } 
    294 //In this method, the parsed string xml_str is not wrapped by the header and footer strings. 
    295 public static String parseDOM (String xml_str) { 
    296         String validation_msg = WELLFORMED; 
    297          
    298         try { 
    299             SAXParserFactory factory = SAXParserFactory.newInstance (); 
    300             factory.setNamespaceAware (true); 
    301             //factory.setValidating (true); 
    302             SAXParser parser = factory.newSAXParser (); 
    303             InputSource iSource = new InputSource ( new StringReader ( xml_str ) ); 
    304 //              parser.parse (iSource, new DefaultHandler ()); 
    305              
    306             org.xml.sax.XMLReader reader = parser.getXMLReader (); 
    307             reader.setContentHandler(new DefaultHandler()); 
    308             reader.setErrorHandler(new DefaultHandler()); 
    309             reader.parse(iSource); 
    310         } catch (FactoryConfigurationError e) { 
    311             validation_msg = "unable to get a document builder factory"; 
    312         } catch (ParserConfigurationException e) { 
    313             validation_msg = "unable to configure parser"; 
    314         } catch (SAXParseException e) { 
    315             validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage (); 
    316         } catch (SAXException e) { 
    317             validation_msg += " " + e.toString (); 
    318         } catch (IOException e) { 
    319             validation_msg = "Unable to read the input, i/o error"; 
    320         } 
    321          
    322         return validation_msg; 
    323     } 
    324  
    325 public static String parse (File xml_file) { 
    326         String validation_msg = WELLFORMED; 
    327  
    328         try { 
    329             SAXParserFactory factory = SAXParserFactory.newInstance (); 
    330             factory.setNamespaceAware (true); 
    331             //factory.setValidating (true); 
    332             SAXParser parser = factory.newSAXParser (); 
    333             FileReader r = new FileReader(xml_file); 
    334             InputSource iSource = new InputSource(r); 
    335             XMLReader reader = parser.getXMLReader (); 
    336             reader.setContentHandler(new DefaultHandler()); 
    337             reader.setErrorHandler(new DefaultHandler()); 
    338             reader.parse(iSource); 
    339         } catch (FactoryConfigurationError e) { 
    340             validation_msg = "unable to get a document builder factory"; 
    341         } catch (ParserConfigurationException e) { 
    342             validation_msg = "unable to configure parser"; 
    343         } catch (SAXParseException e) { 
    344             validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage (); 
    345         } catch (SAXException e) { 
    346             validation_msg += " Fatal error: " + e.toString (); 
    347         } catch (IOException e) { 
    348             validation_msg = "Unable to read the input, i/o error"; 
    349         } 
    350          
    351         return validation_msg; 
    352     }     
    353     /** Returns a string of the location. */ 
    354     private static String getLocationString(SAXParseException ex) { 
    355         StringBuffer str = new StringBuffer(); 
    356  
    357         String systemId = ex.getSystemId(); 
    358         if (systemId != null) { 
    359             int index = systemId.lastIndexOf('/'); 
    360             if (index != -1) 
    361                 systemId = systemId.substring(index + 1); 
    362             str.append(systemId); 
    363         } 
    364         str.append("(line "); 
    365         str.append(ex.getLineNumber()-1); 
    366         str.append(", column "); 
    367         str.append(ex.getColumnNumber()); 
    368         str.append("): "); 
    369  
    370         return str.toString(); 
    371  
    372     } // getLocationString(SAXParseException):String 
    373  
    374  
    375     /** Parse an XML document from a given file path */ 
    376     static public Document parseXMLFile (String xml_file_path, boolean use_class_loader) { 
    377         if (use_class_loader == true) { 
    378             InputStream is = JarTools.getResourceAsStream ("/" + xml_file_path); 
    379             if (is != null) { 
    380                 return parseXML (is); 
    381             } 
    382         } 
    383          
    384         // Try the file outside the classes directory 
    385         return parseXMLFile (new File (xml_file_path)); 
    386     } 
    387      
    388      
    389     /** Parse an XML document from a given file */ 
    390     static public Document parseXMLFile (File xml_file) { 
    391         // No file? No point trying! 
    392         if (xml_file.exists () == false) { 
    393             return null; 
    394         } 
    395          
    396         try { 
    397             return parseXML (new FileInputStream (xml_file)); 
    398         } 
    399         catch (Exception exception) { 
    400             DebugStream.printStackTrace (exception); 
    401             return null; 
    402         } 
    403     } 
    404      
    405      
    406     /** Parse an XML document from a given input stream */ 
    407     static public Document parseXML (InputStream xml_input_stream) { 
    408         Document document = null; 
    409          
    410         try { 
    411             InputStreamReader isr = new InputStreamReader (xml_input_stream, "UTF-8"); 
    412             document = parseXML(isr); 
    413             isr.close (); 
    414             xml_input_stream.close (); 
    415         } 
    416         catch (Exception exception) { 
    417             DebugStream.printStackTrace (exception); 
    418         } 
    419          
    420         return document; 
    421     } 
    422      
    423      
    424     /** Parse an XML document from a given reader */ 
    425     static public Document parseXML (Reader xml_reader) { 
    426         Document document = null; 
    427  
    428     // If debugging, the following will store the XML contents to be parsed,  
    429     // which can then be inspected upon encountering a SAXException (need to run GLI with -debug on) 
    430     String xmlContents = ""; 
    431  
    432     try { 
    433         Reader reader = null; 
    434  
    435         // (1) By default, GLI will remove any contents preceeding (and invalidating)  
    436         // the XML and present these lines separately to the user 
    437         if(!DebugStream.isDebuggingEnabled()) { 
    438         try { 
    439                 reader = new BufferedReader( new RemoveContentBeforeRootElementXMLReader(xml_reader) ); 
    440             } catch ( Exception e ) { 
    441                 System.err.println( "Exception while wrapping the reader in parseXML(Reader)" ); 
    442                 e.printStackTrace(); 
    443             } 
    444         }  
    445  
    446         // (2) If we are running GLI in debug mode: 
    447         // In case parsing exceptions are thrown (SAX Exceptions), we want to get some 
    448         // idea of where things went wrong. This will print the "XML" contents to either 
    449         // system.out (if debugging is off) or to the DebugStream otherwise. 
    450         // We need to read the XML twice to know the line where things went wrong, so 
    451         // do the additional reading only if we're debugging  
    452         else { 
    453             StringBuffer buf = new StringBuffer(); 
    454             char[] buffer = new char[500]; 
    455             int numCharsRead = xml_reader.read(buffer, 0, buffer.length);  
    456             while(numCharsRead != -1) { 
    457                 buf.append(buffer, 0, numCharsRead); 
    458                 numCharsRead = xml_reader.read(buffer, 0, buffer.length);  
    459             } 
    460             xmlContents = buf.toString(); 
    461             xml_reader.close(); // closing the old Reader 
    462             xml_reader = null; 
    463             buffer = null; 
    464             buf = null; 
    465             // we need a Reader to parse the same contents as the Reader that was just closed 
    466             reader = new BufferedReader(new StringReader(xmlContents)); 
    467         //System.err.println("xmlContents:\n" + xmlContents); 
    468         } 
    469          
    470         // (2) The actual XML parsing 
    471         InputSource isc       = new InputSource (reader); 
    472         DOMParser parser      = new DOMParser (); 
    473         parser.setFeature ("http://xml.org/sax/features/validation", false); 
    474         parser.setFeature ("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 
    475         // May or may not be ignored, the documentation for Xerces is contradictory. If it works then parsing -should- be faster. 
    476         parser.setFeature ("http://apache.org/xml/features/dom/defer-node-expansion", true); 
    477         parser.setFeature ("http://apache.org/xml/features/dom/include-ignorable-whitespace", false); 
    478         parser.parse (isc); 
    479         document = parser.getDocument (); 
    480          
    481     } catch(SAXParseException e) { 
    482         showXMLParseFailureLine(e, xmlContents); 
    483     } catch (SAXException exception) { 
    484         System.err.println ("SAX exception: " + exception.getMessage ()); 
    485         if(DebugStream.isDebuggingEnabled()) { 
    486         DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"  
    487                     + xmlContents + "\n************END\n"); 
    488         // Exit to let the user view the erroneous line/xml before it goes past the screen buffer? 
    489         DebugStream.println("Debug mode: Exiting the program as there was trouble parsing the XML...");  
    490         System.exit(-1); 
    491         }  
    492         // else, not running in debug mode, so don't exit after exception   
    493         System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents that could not be parsed."); 
    494         DebugStream.printStackTrace (exception); 
    495         } 
    496         catch (Exception exception) { 
    497             DebugStream.printStackTrace (exception); 
    498         } 
    499          
    500         return document; 
    501     } 
    502  
    503     /** Displays the line (string) where the SAXParseException occurred, given a String of the  
    504      * entire xml that was being parsed and the SAXParseException object that was caught.  
    505      * The messages are printed to DebugStream, so run GLI/FLI with -debug to view this output.  
    506      * @param xmlContents is the entire xml that was being parsed when the exception occurred 
    507      * @param e is the SAXParseException object that was thrown upon parsing the xmlContents. 
    508      */ 
    509     public static void showXMLParseFailureLine(SAXParseException e, String xmlContents) { 
    510      
    511         // There should be no characters at all that preceed the <?xml>... bit.  
    512         // The first check is for starting spaces: 
    513         if(xmlContents.startsWith("\n") || xmlContents.startsWith(" ") || xmlContents.startsWith("\t")) { 
    514             DebugStream.println("ERROR: illegal start of XML. Space/tab/newline should not preceed xml declaration.\n"); 
    515             DebugStream.println("xmlContents (length is " + xmlContents.length() + "):\n" + xmlContents); 
    516             return; // nothing more to do, first error identified 
    517         } 
    518      
    519         // the actual line (String literal) where parsing failed and the SAXParseException occurred. 
    520         String line = ""; 
    521         int linenumber = e.getLineNumber(); 
    522         DebugStream.print("\n****SAXParseException on LINE NUMBER: " + linenumber); 
    523         if(DebugStream.isDebuggingEnabled()) { 
    524             if(linenumber != -1) {  
    525         String[] lines = xmlContents.split("\n"); 
    526         if (lines.length > 0) { 
    527             DebugStream.println(" (number of lines: " + lines.length + ")"); 
    528             if(lines.length >= linenumber) { 
    529             line = lines[linenumber-1]; 
    530             } else { // error is past the last line 
    531             line = "Error is past the last line (" + lines.length + "): " + lines[lines.length-1];           
    532             } 
    533         } else { 
    534             DebugStream.print("\n"); 
    535         } 
    536         lines = null; 
    537  
    538                 DebugStream.println("The parsing error occurred on this line:\n***********START\n" + line + "\n***********END"); 
    539                 DebugStream.println("SAXParseException message: " + e.getMessage() + "\n"); 
    540  
    541         // Uncomment if you want to print out the entire contents of the XML doc: 
    542         //DebugStream.println("\n\nThis was the XML:\n*********START\n"  
    543         //  + xmlContents + "\n************END\n"); 
    544             } else { // no particular line number, print out all the xml so debugger can inspect it 
    545                 DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"  
    546                     + xmlContents + "\n************END\n"); 
    547             } 
    548             // Exit to let the user view the erroneous line/xml before it goes past the screen buffer? 
    549             DebugStream.println("\nDebug mode: Exiting the program as there was trouble parsing the XML...");  
    550             System.exit(-1); 
    551         } else { // not running in debug mode 
    552             System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents/line that could not be parsed."); 
    553         } 
    554     } 
    555  
    556      
    557     static public StringBuffer readXMLStream (InputStream input_stream) { 
    558         StringBuffer xml = new StringBuffer (""); 
    559          
    560         try { 
    561             InputStreamReader isr = new InputStreamReader (input_stream, "UTF-8"); 
    562             BufferedReader buffered_in = new BufferedReader (isr); 
    563              
    564             String line = ""; 
    565             boolean xml_content = false; 
    566             while((line = buffered_in.readLine ()) != null) { 
    567                 if(xml_content) { 
    568                     xml.append (line); 
    569                     xml.append ("\n"); 
    570                 } 
    571                 else if(line.trim ().startsWith ("<?xml")) { 
    572                     xml_content = true; 
    573                     xml.append (line); 
    574                     xml.append ("\n"); 
    575                 } 
    576             } 
    577             buffered_in = null; 
    578         } 
    579         catch (Exception error) { 
    580             System.err.println ("Failed when trying to parse XML stream"); 
    581             error.printStackTrace (); 
    582         } 
    583          
    584         return xml; 
    585     } 
    586      
    587      
    588     /** Removes characters that are invalid in XML (see http://www.w3.org/TR/2000/REC-xml-20001006#charsets) */ 
    589     static public String removeInvalidCharacters (String text) { 
    590         char[] safe_characters = new char[text.length ()]; 
    591         int j = 0; 
    592          
    593         char[] raw_characters = new char[text.length ()]; 
    594         text.getChars (0, text.length (), raw_characters, 0); 
    595         for (int i = 0; i < raw_characters.length; i++) { 
    596             char character = raw_characters[i]; 
    597             if ((character >= 0x20 && character <= 0xD7FF) || character == 0x09 || character == 0x0A || character == 0x0D || (character >= 0xE000 && character <= 0xFFFD) || (character >= 0x10000 && character <= 0x10FFFF)) { 
    598                 safe_characters[j] = character; 
    599                 j++; 
    600             } 
    601         } 
    602          
    603         return new String (safe_characters, 0, j); 
    604     } 
    605      
    606      
    607     static public void setElementTextValue (Element element, String text) { 
    608         // Remove all text node children 
    609         NodeList children_nodelist = element.getChildNodes (); 
    610         for (int i = children_nodelist.getLength () - 1; i >= 0; i--) { 
    611             Node child_node = children_nodelist.item (i); 
    612             if (child_node.getNodeType () == Node.TEXT_NODE) { 
    613                 element.removeChild (child_node); 
    614             } 
    615         } 
    616          
    617         // Add a new text node 
    618         if (text != null) { 
    619             element.appendChild (element.getOwnerDocument ().createTextNode (text)); 
    620         } 
    621     } 
    622      
    623      
    624     /** Set the #text node value of some element. 
    625      * @param element the Element whose value we wish to set 
    626      * @param value the new value for the element as a String 
    627      * Soon to be deprecated! 
    628      */ 
    629     static final public void setValue (Element element, String value) { 
    630         // Remove any existing child node(s) 
    631         clear (element); 
    632         // Add new text node. 
    633         if (value != null) { 
    634             element.appendChild (element.getOwnerDocument ().createTextNode (value)); 
    635         } 
    636     } 
    637      
    638     /** Write an XML document to a given file with the text node of the specified element unescaped*/ 
    639     static public void writeXMLFile (File xml_file, Document document, String[] nonEscapingTagNames) { 
    640         try { 
    641             OutputStream os = new FileOutputStream (xml_file); 
    642             // Create an output format for our document. 
    643             OutputFormat f = new OutputFormat (document); 
    644             f.setEncoding ("UTF-8"); 
    645             f.setIndenting (true); 
    646             f.setLineWidth (0); // Why isn't this working! 
    647             f.setPreserveSpace (false); 
    648             if (nonEscapingTagNames != null) { 
    649           f.setNonEscapingElements (nonEscapingTagNames); 
    650         } 
    651             // Create the necessary writer stream for serialization. 
    652             OutputStreamWriter osw = new OutputStreamWriter (os, "UTF-8"); 
    653             Writer w               = new BufferedWriter (osw); 
    654             // Generate a new serializer from the above. 
    655             XMLSerializer s        = new XMLSerializer (w, f); 
    656             s.asDOMSerializer (); 
    657             // Finally serialize the document to file. 
    658             s.serialize (document); 
    659             // And close. 
    660             os.close (); 
    661         } 
    662         catch (Exception exception) { 
    663             DebugStream.printStackTrace (exception); 
    664         } 
    665     } 
    666      
    667     /** Write an XML document to a given file */ 
    668     static public void writeXMLFile (File xml_file, Document document) { 
    669       writeXMLFile(xml_file, document, null); 
    670     } 
    671  
    672     public static void printXMLNode (Node e) { 
    673         printXMLNode (e, 0) ; 
    674     } 
    675      
    676     public static void printXMLNode (Node e, int depth) { //recursive method call using DOM API... 
    677          
    678         for (int i=0 ; i<depth ; i++) 
    679             System.out.print (' ') ; 
    680          
    681         if (e.getNodeType () == Node.TEXT_NODE){ 
    682             //System.out.println("text") ; 
    683             if (e.getNodeValue () != "") { 
    684                 System.out.println (e.getNodeValue ()) ; 
    685             } 
    686             return ; 
    687         } 
    688          
    689         System.out.print ('<'); 
    690         System.out.print (e.getNodeName ()); 
    691         NamedNodeMap attrs = e.getAttributes (); 
    692         if (attrs != null) { 
    693             for (int i = 0; i < attrs.getLength (); i++) { 
    694                 Node attr = attrs.item (i); 
    695                 System.out.print (' '); 
    696                 System.out.print (attr.getNodeName ()); 
    697                 System.out.print ("=\""); 
    698                 System.out.print (attr.getNodeValue ()); 
    699                 System.out.print ('"'); 
    700             } 
    701         } 
    702         NodeList children = e.getChildNodes (); 
    703          
    704         if (children == null || children.getLength () == 0) 
    705             System.out.println ("/>") ; 
    706         else { 
    707              
    708             System.out.println ('>') ; 
    709              
    710             int len = children.getLength (); 
    711             for (int i = 0; i < len; i++) { 
    712                 printXMLNode (children.item (i), depth + 1); 
    713             } 
    714              
    715             for (int i=0 ; i<depth ; i++) 
    716                 System.out.print (' ') ; 
    717              
    718             System.out.println ("</" + e.getNodeName () + ">"); 
    719         } 
    720          
    721     } 
    722     public static String xmlNodeToString (Node e){ 
    723         StringBuffer sb = new StringBuffer (""); 
    724         xmlNodeToString (sb,e,0); 
    725         return sb.toString (); 
    726     } 
    727      
    728     private static void xmlNodeToString (StringBuffer sb, Node e, int depth){ 
    729          
    730         for (int i=0 ; i<depth ; i++) 
    731             sb.append (' ') ; 
    732          
    733         if (e.getNodeType () == Node.TEXT_NODE){ 
    734             if (e.getNodeValue () != "") { 
    735                 sb.append (e.getNodeValue ()) ; 
    736             } 
    737             return ; 
    738         } 
    739          
    740         sb.append ('<'); 
    741         sb.append (e.getNodeName ()); 
    742         NamedNodeMap attrs = e.getAttributes (); 
    743         if (attrs != null) { 
    744             for (int i = 0; i < attrs.getLength (); i++) { 
    745                 Node attr = attrs.item (i); 
    746                 sb.append (' '); 
    747                 sb.append (attr.getNodeName ()); 
    748                 sb.append ("=\""); 
    749                 sb.append (attr.getNodeValue ()); 
    750                 sb.append ('"'); 
    751             } 
    752         } 
    753         NodeList children = e.getChildNodes (); 
    754          
    755         if (children == null || children.getLength () == 0) 
    756             sb.append ("/>\n") ; 
    757         else { 
    758              
    759             sb.append (">\n") ; 
    760              
    761             int len = children.getLength (); 
    762             for (int i = 0; i < len; i++) { 
    763                 xmlNodeToString (sb,children.item (i), depth + 1); 
    764             } 
    765              
    766             for (int i=0 ; i<depth ; i++) 
    767                 sb.append (' ') ; 
    768              
    769             sb.append ("</" + e.getNodeName () + ">\n"); 
    770         } 
    771          
    772          
    773     } 
    774  
    775   public static String xmlNodeToStringWithoutIndenting (Node e) { 
    776     StringBuffer sb = new StringBuffer (""); 
    777     xmlNodeToStringWithoutNewline(sb, e, -1); 
    778     return sb.toString(); 
    779   } 
    780     public static String xmlNodeToStringWithoutNewline (Node e){ 
    781         StringBuffer sb = new StringBuffer (""); 
    782         xmlNodeToStringWithoutNewline (sb,e,0); 
    783         return sb.toString (); 
    784     } 
    785      
    786     private static void xmlNodeToStringWithoutNewline (StringBuffer sb, Node e, int depth){ 
    787          
    788         for (int i=0 ; i<depth ; i++) 
    789             sb.append (' ') ; 
    790        
    791         if (e.getNodeType () == Node.TEXT_NODE){ 
    792             if (e.getNodeValue () != "") { 
    793                 sb.append (e.getNodeValue ()) ; 
    794             } 
    795             return ; 
    796         } 
    797          
    798         sb.append ('<'); 
    799         sb.append (e.getNodeName ()); 
    800         NamedNodeMap attrs = e.getAttributes (); 
    801         if (attrs != null) { 
    802             for (int i = 0; i < attrs.getLength (); i++) { 
    803                 Node attr = attrs.item (i); 
    804                 sb.append (' '); 
    805                 sb.append (attr.getNodeName ()); 
    806                 sb.append ("=\""); 
    807                 sb.append (attr.getNodeValue ()); 
    808                 sb.append ('"'); 
    809             } 
    810         } 
    811         NodeList children = e.getChildNodes (); 
    812          
    813         if (children == null || children.getLength () == 0) 
    814             sb.append ("/>") ; 
    815         else { 
    816              
    817             sb.append (">") ; 
    818              
    819             int len = children.getLength (); 
    820             for (int i = 0; i < len; i++) { 
    821           if (depth >= 0) { 
    822                 xmlNodeToStringWithoutNewline (sb,children.item (i), depth + 1); 
    823           } else { 
    824         xmlNodeToStringWithoutNewline (sb,children.item (i), depth); 
    825           } 
    826             } 
    827              
    828             for (int i=0 ; i<depth ; i++) 
    829                 sb.append (' ') ; 
    830              
    831             sb.append ("</" + e.getNodeName () + ">"); 
    832         } 
    833     } 
     30public class XMLTools 
     31{ 
     32    /** extracts the text out of a node */ 
     33    public static Node getNodeTextNode(Element param) 
     34    { 
     35        param.normalize(); 
     36        Node n = param.getFirstChild(); 
     37        while (n != null && n.getNodeType() != Node.TEXT_NODE) 
     38        { 
     39            n = n.getNextSibling(); 
     40        } 
     41        return n; 
     42    } 
     43 
     44    /** extracts the text out of a node */ 
     45    public static String getNodeText(Element param) 
     46    { 
     47        Node text_node = getNodeTextNode(param); 
     48        if (text_node == null) 
     49        { 
     50            return ""; 
     51        } 
     52        return text_node.getNodeValue(); 
     53    } 
     54 
     55    public static void setNodeText(Element elem, String text) 
     56    { 
     57        Node old_text_node = getNodeTextNode(elem); 
     58        if (old_text_node != null) 
     59        { 
     60            elem.removeChild(old_text_node); 
     61        } 
     62        Text t = elem.getOwnerDocument().createTextNode(text); 
     63        elem.appendChild(t); 
     64    } 
     65 
     66    /** returns the (first) child element with the given name */ 
     67    public static Node getChildByTagName(Node n, String name) 
     68    { 
     69 
     70        Node child = n.getFirstChild(); 
     71        while (child != null) 
     72        { 
     73            if (child.getNodeName().equals(name)) 
     74            { 
     75                return child; 
     76            } 
     77            child = child.getNextSibling(); 
     78        } 
     79        return null; //not found 
     80    } 
     81 
     82    /** 
     83     * returns the (nth) child element with the given name index numbers start 
     84     * at 0 
     85     */ 
     86    public static Node getChildByTagNameIndexed(Node n, String name, int index) 
     87    { 
     88        if (index == -1) 
     89        { 
     90            return getChildByTagName(n, name); 
     91        } 
     92        int count = 0; 
     93        Node child = n.getFirstChild(); 
     94        while (child != null) 
     95        { 
     96            if (child.getNodeName().equals(name)) 
     97            { 
     98                if (count == index) 
     99                { 
     100                    return child; 
     101                } 
     102                else 
     103                { 
     104                    count++; 
     105                } 
     106            } 
     107            child = child.getNextSibling(); 
     108        } 
     109        return null; //not found 
     110    } 
     111 
     112    /** 
     113     * returns the element parent/node_name[@attribute_name='attribute_value'] 
     114     */ 
     115    public static Element getNamedElement(Element parent, String node_name, String attribute_name, String attribute_value) 
     116    { 
     117 
     118        NodeList children = parent.getChildNodes(); 
     119        for (int i = 0; i < children.getLength(); i++) 
     120        { 
     121            Node child = children.item(i); 
     122            //logger.debug("getnamed elem, node nmae="+child.getNodeName()); 
     123            if (child.getNodeName().equals(node_name)) 
     124            { 
     125                if (((Element) child).getAttribute(attribute_name).equals(attribute_value)) 
     126                    return (Element) child; 
     127            } 
     128        } 
     129        // not found 
     130        return null; 
     131    } 
     132 
     133    /** 
     134     * returns a list of elements 
     135     * parent/node_name[@attribute_name='attribute_value'] 
     136     */ 
     137    public static ArrayList getNamedElementList(Element parent, String node_name, String attribute_name, String attribute_value) 
     138    { 
     139        ArrayList elements = new ArrayList(); 
     140        NodeList children = parent.getChildNodes(); 
     141        for (int i = 0; i < children.getLength(); i++) 
     142        { 
     143            //System.out.println("getNamedElementList"); 
     144            Node child = children.item(i); 
     145            //logger.debug("getnamed elem, node nmae="+child.getNodeName()); 
     146            if (child.getNodeName().equals(node_name)) 
     147            { 
     148                if (((Element) child).getAttribute(attribute_name).equals(attribute_value)) 
     149                    elements.add((Element) child); 
     150            } 
     151        } 
     152        // not found 
     153        if (elements.size() == 0) 
     154        { 
     155            elements = null; 
     156        } 
     157        return elements; 
     158    } 
     159 
     160    public static void copyAllChildren(Element to, Element from) 
     161    { 
     162 
     163        Document to_doc = to.getOwnerDocument(); 
     164        Node child = from.getFirstChild(); 
     165        while (child != null) 
     166        { 
     167            to.appendChild(to_doc.importNode(child, true)); 
     168            child = child.getNextSibling(); 
     169        } 
     170    } 
     171 
     172    /** Duplicates an element */ 
     173    public static Element duplicateElement(Document owner, Element element, boolean with_attributes) 
     174    { 
     175        return duplicateElementNS(owner, element, null, with_attributes); 
     176    } 
     177 
     178    /** Duplicates an element */ 
     179    public static Element duplicateElementNS(Document owner, Element element, String namespace_uri, boolean with_attributes) 
     180    { 
     181        Element duplicate; 
     182        if (namespace_uri == null) 
     183        { 
     184            duplicate = owner.createElement(element.getTagName()); 
     185        } 
     186        else 
     187        { 
     188            duplicate = owner.createElementNS(namespace_uri, element.getTagName()); 
     189        } 
     190        // Copy element attributes 
     191        if (with_attributes) 
     192        { 
     193            NamedNodeMap attributes = element.getAttributes(); 
     194            for (int i = 0; i < attributes.getLength(); i++) 
     195            { 
     196                Node attribute = attributes.item(i); 
     197                duplicate.setAttribute(attribute.getNodeName(), attribute.getNodeValue()); 
     198            } 
     199        } 
     200 
     201        // Copy element children 
     202        NodeList children = element.getChildNodes(); 
     203        for (int i = 0; i < children.getLength(); i++) 
     204        { 
     205            Node child = children.item(i); 
     206            duplicate.appendChild(owner.importNode(child, true)); 
     207        } 
     208 
     209        return duplicate; 
     210    } 
     211 
     212    /** Remove all of the child nodes from a certain node. */ 
     213    static final public void clear(Node node) 
     214    { 
     215        while (node.hasChildNodes()) 
     216        { 
     217            node.removeChild(node.getFirstChild()); 
     218        } 
     219    } 
     220 
     221    static public ArrayList getChildElementsByTagName(Element parent_element, String element_name) 
     222    { 
     223        ArrayList child_elements = new ArrayList(); 
     224 
     225        NodeList children_nodelist = parent_element.getChildNodes(); 
     226        for (int i = 0; i < children_nodelist.getLength(); i++) 
     227        { 
     228            Node child_node = children_nodelist.item(i); 
     229            if (child_node.getNodeType() == Node.ELEMENT_NODE && child_node.getNodeName().equals(element_name)) 
     230            { 
     231                child_elements.add(child_node); 
     232            } 
     233        } 
     234 
     235        return child_elements; 
     236    } 
     237 
     238    static public String getElementTextValue(Element element) 
     239    { 
     240        // Find the first text node child 
     241        NodeList children_nodelist = element.getChildNodes(); 
     242        for (int i = 0; i < children_nodelist.getLength(); i++) 
     243        { 
     244            Node child_node = children_nodelist.item(i); 
     245            if (child_node.getNodeType() == Node.TEXT_NODE) 
     246            { 
     247                return child_node.getNodeValue(); 
     248            } 
     249        } 
     250 
     251        // None found 
     252        return ""; 
     253    } 
     254 
     255    /** 
     256     * Method to retrieve the value of a given node. 
     257     *  
     258     * @param element 
     259     *            The <strong>Element</strong> whose value we wish to find. Soon 
     260     *            to be deprecated! 
     261     */ 
     262    static final public String getValue(Node element) 
     263    { 
     264        if (element == null) 
     265        { 
     266            return ""; 
     267        } 
     268        // If we've been given a subject node first retrieve its value node. 
     269        if (element.getNodeName().equals("Subject")) 
     270        { 
     271            element = getNodeFromNamed(element, "Value"); 
     272        } 
     273        // If we've got a value node, then reconstruct the text. Remember that DOM will split text over 256 characters into several text nodes 
     274        if (element != null && element.hasChildNodes()) 
     275        { 
     276            StringBuffer text_buffer = new StringBuffer(); 
     277            NodeList text_nodes = element.getChildNodes(); 
     278            for (int i = 0; i < text_nodes.getLength(); i++) 
     279            { 
     280                Node possible_text = text_nodes.item(i); 
     281                if (possible_text.getNodeName().equals(StaticStrings.TEXT_NODE)) 
     282                { 
     283                    text_buffer.append(possible_text.getNodeValue()); 
     284                } 
     285            } 
     286            return text_buffer.toString(); 
     287        } 
     288        return ""; 
     289    } 
     290 
     291    /** 
     292     * Method to retrieve from the node given, a certain child node with the 
     293     * specified name. 
     294     *  
     295     * @param parent 
     296     *            The <strong>Node</strong> whose children should be searched. 
     297     * @param name 
     298     *            The required nodes name as a <strong>String</strong>. 
     299     * @return The requested <strong>Node</strong> if it is found, <i>null</i> 
     300     *         otherwise. Soon to be deprecated! 
     301     */ 
     302    static final public Node getNodeFromNamed(Node parent, String name) 
     303    { 
     304        Node child = null; 
     305        for (Node i = parent.getFirstChild(); i != null && child == null; i = i.getNextSibling()) 
     306        { 
     307            if (i.getNodeName().equals(name)) 
     308            { 
     309                child = i; 
     310            } 
     311        } 
     312        return child; 
     313    } 
     314 
     315    static final public String WELLFORMED = "well-formed !"; 
     316    static final public String NOTWELLFORMED = "not well-formed"; 
     317    static final private String HEADER = "<?xml version='1.0' encoding='UTF-8'?><collectionConfig xmlns:gsf='http://www.greenstone.org/greenstone3/schema/ConfigFormat' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"; 
     318    static final private String FOOTER = "</collectionConfig>"; 
     319 
     320    public static String parse(String xml_str) 
     321    { 
     322        String validation_msg = WELLFORMED; 
     323        xml_str = HEADER + xml_str + FOOTER; 
     324        try 
     325        { 
     326            SAXParserFactory factory = SAXParserFactory.newInstance(); 
     327            factory.setNamespaceAware(true); 
     328            //factory.setValidating (true); 
     329            SAXParser parser = factory.newSAXParser(); 
     330            InputSource iSource = new InputSource(new StringReader(xml_str)); 
     331            //              parser.parse (iSource, new DefaultHandler ()); 
     332 
     333            org.xml.sax.XMLReader reader = parser.getXMLReader(); 
     334            reader.setContentHandler(new DefaultHandler()); 
     335            reader.setErrorHandler(new DefaultHandler()); 
     336            reader.parse(iSource); 
     337        } 
     338        catch (FactoryConfigurationError e) 
     339        { 
     340            validation_msg = "unable to get a document builder factory"; 
     341        } 
     342        catch (ParserConfigurationException e) 
     343        { 
     344            validation_msg = "unable to configure parser"; 
     345        } 
     346        catch (SAXParseException e) 
     347        { 
     348            validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage(); 
     349        } 
     350        catch (SAXException e) 
     351        { 
     352            validation_msg += " Fatal error: " + e.toString(); 
     353        } 
     354        catch (IOException e) 
     355        { 
     356            validation_msg = "Unable to read the input, i/o error"; 
     357        } 
     358 
     359        return validation_msg; 
     360    } 
     361 
     362    //In this method, the parsed string xml_str is not wrapped by the header and footer strings. 
     363    public static String parseDOM(String xml_str) 
     364    { 
     365        String validation_msg = WELLFORMED; 
     366 
     367        try 
     368        { 
     369            SAXParserFactory factory = SAXParserFactory.newInstance(); 
     370            factory.setNamespaceAware(true); 
     371            //factory.setValidating (true); 
     372            SAXParser parser = factory.newSAXParser(); 
     373            InputSource iSource = new InputSource(new StringReader(xml_str)); 
     374            //              parser.parse (iSource, new DefaultHandler ()); 
     375 
     376            org.xml.sax.XMLReader reader = parser.getXMLReader(); 
     377            reader.setContentHandler(new DefaultHandler()); 
     378            reader.setErrorHandler(new DefaultHandler()); 
     379            reader.parse(iSource); 
     380        } 
     381        catch (FactoryConfigurationError e) 
     382        { 
     383            validation_msg = "unable to get a document builder factory"; 
     384        } 
     385        catch (ParserConfigurationException e) 
     386        { 
     387            validation_msg = "unable to configure parser"; 
     388        } 
     389        catch (SAXParseException e) 
     390        { 
     391            validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage(); 
     392        } 
     393        catch (SAXException e) 
     394        { 
     395            validation_msg += " " + e.toString(); 
     396        } 
     397        catch (IOException e) 
     398        { 
     399            validation_msg = "Unable to read the input, i/o error"; 
     400        } 
     401 
     402        return validation_msg; 
     403    } 
     404 
     405    public static String parse(File xml_file) 
     406    { 
     407        String validation_msg = WELLFORMED; 
     408 
     409        try 
     410        { 
     411            SAXParserFactory factory = SAXParserFactory.newInstance(); 
     412            factory.setNamespaceAware(true); 
     413            //factory.setValidating (true); 
     414            SAXParser parser = factory.newSAXParser(); 
     415            FileReader r = new FileReader(xml_file); 
     416            InputSource iSource = new InputSource(r); 
     417            XMLReader reader = parser.getXMLReader(); 
     418            reader.setContentHandler(new DefaultHandler()); 
     419            reader.setErrorHandler(new DefaultHandler()); 
     420            reader.parse(iSource); 
     421        } 
     422        catch (FactoryConfigurationError e) 
     423        { 
     424            validation_msg = "unable to get a document builder factory"; 
     425        } 
     426        catch (ParserConfigurationException e) 
     427        { 
     428            validation_msg = "unable to configure parser"; 
     429        } 
     430        catch (SAXParseException e) 
     431        { 
     432            validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage(); 
     433        } 
     434        catch (SAXException e) 
     435        { 
     436            validation_msg += " Fatal error: " + e.toString(); 
     437        } 
     438        catch (IOException e) 
     439        { 
     440            validation_msg = "Unable to read the input, i/o error"; 
     441        } 
     442 
     443        return validation_msg; 
     444    } 
     445 
     446    /** Returns a string of the location. */ 
     447    private static String getLocationString(SAXParseException ex) 
     448    { 
     449        StringBuffer str = new StringBuffer(); 
     450 
     451        String systemId = ex.getSystemId(); 
     452        if (systemId != null) 
     453        { 
     454            int index = systemId.lastIndexOf('/'); 
     455            if (index != -1) 
     456                systemId = systemId.substring(index + 1); 
     457            str.append(systemId); 
     458        } 
     459        str.append("(line "); 
     460        str.append(ex.getLineNumber() - 1); 
     461        str.append(", column "); 
     462        str.append(ex.getColumnNumber()); 
     463        str.append("): "); 
     464 
     465        return str.toString(); 
     466 
     467    } // getLocationString(SAXParseException):String 
     468 
     469    /** Parse an XML document from a given file path */ 
     470    static public Document parseXMLFile(String xml_file_path, boolean use_class_loader) 
     471    { 
     472        if (use_class_loader == true) 
     473        { 
     474            InputStream is = JarTools.getResourceAsStream("/" + xml_file_path); 
     475            if (is != null) 
     476            { 
     477                return parseXML(is); 
     478            } 
     479        } 
     480 
     481        // Try the file outside the classes directory 
     482        return parseXMLFile(new File(xml_file_path)); 
     483    } 
     484 
     485    /** Parse an XML document from a given file */ 
     486    static public Document parseXMLFile(File xml_file) 
     487    { 
     488        // No file? No point trying! 
     489        if (xml_file.exists() == false) 
     490        { 
     491            return null; 
     492        } 
     493 
     494        try 
     495        { 
     496            return parseXML(new FileInputStream(xml_file)); 
     497        } 
     498        catch (Exception exception) 
     499        { 
     500            DebugStream.printStackTrace(exception); 
     501            return null; 
     502        } 
     503    } 
     504 
     505    /** Parse an XML document from a given input stream */ 
     506    static public Document parseXML(InputStream xml_input_stream) 
     507    { 
     508        Document document = null; 
     509 
     510        try 
     511        { 
     512            InputStreamReader isr = new InputStreamReader(xml_input_stream, "UTF-8"); 
     513            document = parseXML(isr); 
     514            isr.close(); 
     515            xml_input_stream.close(); 
     516        } 
     517        catch (Exception exception) 
     518        { 
     519            DebugStream.printStackTrace(exception); 
     520        } 
     521 
     522        return document; 
     523    } 
     524 
     525    /** Parse an XML document from a given reader */ 
     526    static public Document parseXML(Reader xml_reader) 
     527    { 
     528        Document document = null; 
     529 
     530        // If debugging, the following will store the XML contents to be parsed,  
     531        // which can then be inspected upon encountering a SAXException (need to run GLI with -debug on) 
     532        String xmlContents = ""; 
     533 
     534        try 
     535        { 
     536            Reader reader = null; 
     537 
     538            // (1) By default, GLI will remove any contents preceeding (and invalidating)  
     539            // the XML and present these lines separately to the user 
     540            if (!DebugStream.isDebuggingEnabled()) 
     541            { 
     542                try 
     543                { 
     544                    reader = new BufferedReader(new RemoveContentBeforeRootElementXMLReader(xml_reader)); 
     545                } 
     546                catch (Exception e) 
     547                { 
     548                    System.err.println("Exception while wrapping the reader in parseXML(Reader)"); 
     549                    e.printStackTrace(); 
     550                } 
     551