Changeset 36305


Ignore:
Timestamp:
2022-07-22T11:33:52+12:00 (3 weeks ago)
Author:
kjdon
Message:

major overhaul of this file. Tidied, reordered functions to make it easier to use, tried to get rid of as much duplicated code as possible, indented, etc. Sorry, will be impossible to see what changes I have made through svn diff.

File:
1 edited

Legend:

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

    r36263 r36305  
    5454{
    5555
    56     // a list of all known top level elements
    57   static final private String known_element_names_array[] = { StaticStrings.SECURITY_STR, StaticStrings.METADATALIST_STR, StaticStrings.DISPLAYITEMLIST_STR, StaticStrings.FORMAT_STR, StaticStrings.SEARCH_STR, StaticStrings.INFODB_STR, StaticStrings.BROWSE_STR, StaticStrings.IMPORT_STR,
    58   /*StaticStrings.IMPORT_OPTION_STR, StaticStrings.BUILD_OPTION_STR,*/
    59   StaticStrings.DISPLAY_STR, StaticStrings.REPLACELISTREF_STR, StaticStrings.REPLACELIST_STR, StaticStrings.SERVICE_RACK_LIST_ELEMENT };
    60     static final private Set known_element_names = new HashSet(Arrays.asList(known_element_names_array));
    61 
    62     /**
    63      * *************************************************************************
    64      * ******************************* The code in this file is used for
    65      * greenstone 3 collection configuration, i.e., read ColletionConfig.xml
    66      * into the internal DOM tree, and convert the internal DOM tree back to
    67      * CollectionConfig.xml.
    68      *
    69      * Methods named 'doXXXX' are for convert collectionConfig.xml into the
    70      * internal configuration xml structure; Methods named 'convertXXXX' are for
    71      * convert the internal configuration xml structure back to
    72      * collectionConfig.xml.
    73      ************************************************************************************************************ */
    74 
    75     static private ArrayList getMatchingSearchMetaElements(Element source, String meta_name, String meta_type) {
    76     return XMLTools.getNamedElementList(source, StaticStrings.SEARCHMETADATA_ELEMENT, new String[]{StaticStrings.NAME_ATTRIBUTE, StaticStrings.TYPE_ATTRIBUTE}, new String[]{ meta_name, meta_type});
    77 
    78     }
    79     /**
    80      * Arguments:
    81          * * metadataListNode->the 'displayItemList' element in
    82      * collectionConfig.xml, or any other element that contains displayItems, eg <index>
    83          * * name_value->the value of the 'name' attribute of
    84      * the new collectionmeta element;
    85          * * att_value->the value of the 'name' attribute of
    86      * 'displayItem' element - we only process the displayItems whose name attribute == att_value. apart from the top level displayItemList where we have collectiondescription etc, this will be 'name'
    87          * * return: an ArrayList of the contructed
    88      * 'CollectionMetadata' elements
    89      */
    90   static private ArrayList doDisplayItemList(Document to, Node displayListNode, String att_value, String name_value) {
    91     return doDisplayItemList(to, displayListNode, att_value, name_value, null);
    92   }
    93 
    94   static private ArrayList doDisplayItemList(Document to, Node displayListNode, String att_value, String name_value, String type)
    95     {
    96         Element toElement = to.getDocumentElement();
    97         ArrayList display_item_list = new ArrayList();
    98         ArrayList item_list = XMLTools.getNamedElementList((Element) displayListNode, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, att_value);
    99         if (item_list == null)
     56    // a list of all known top level elements; importOption and buildOPtion are commented out here as they are currently handled by unknown code
     57    // /*StaticStrings.IMPORT_OPTION_STR, StaticStrings.BUILD_OPTION_STR,*/
     58    static final private String known_element_names_array[] = { StaticStrings.SECURITY_STR, StaticStrings.METADATALIST_STR, StaticStrings.DISPLAYITEMLIST_STR, StaticStrings.FORMAT_STR, StaticStrings.SEARCH_STR, StaticStrings.INFODB_STR, StaticStrings.BROWSE_STR, StaticStrings.IMPORT_STR, StaticStrings.DISPLAY_STR, StaticStrings.REPLACELISTREF_STR, StaticStrings.REPLACELIST_STR, StaticStrings.SERVICE_RACK_LIST_ELEMENT };
     59    static final private Set known_element_names = new HashSet(Arrays.asList(known_element_names_array));
     60
     61    /**
     62     * *************************************************************************
     63     * ******************************* The code in this file is used for
     64     * greenstone 3 collection configuration, i.e., read ColletionConfig.xml
     65     * into the internal DOM tree, and convert the internal DOM tree back to
     66     * CollectionConfig.xml.
     67     *
     68     * The main methods are save - save internal DOM out to config file, and
     69     * parse - read in the config file into the internal DOM tree.
     70     *
     71     * Methods named 'doXXXX' are for converting collectionConfig.xml into
     72     * the internal configuration xml structure;
     73     * Methods named 'convertXXXX' are for
     74     * converting the internal configuration xml structure back to
     75     * collectionConfig.xml.
     76     ************************************************************************************************************ */
     77
     78    /** Generates a String version of the internal XML document */
     79    static public String generateStringVersion(Document doc)
     80    {
     81    return XMLTools.xmlNodeToString(doc);
     82    }
     83
     84
     85    // From collectionConfig.xml to internal structure:add 'ex.' namespace (if none).
     86    // From internal structure to collectionConfig.xml:always peel off 'ex.' namespace (if any), except for format statement
     87
     88    //This method parses 'xml_file_doc' into 'dOc'
     89    static public void parse(File xml_file, Document dOc)
     90    {
     91
     92    Document xml_file_doc = XMLTools.parseXMLFile(xml_file);
     93    Element fromElement = xml_file_doc.getDocumentElement();
     94    Element toElement = dOc.getDocumentElement();
     95
     96    // security element.
     97    doSecurity(dOc, fromElement);
     98
     99    // metadataList - creator, maintainer, public, plus any custom metadata
     100    doMetadataList(dOc, fromElement);
     101
     102    // top level display items
     103    doDisplayItemList(dOc, fromElement);
     104
     105    // global format
     106    doGlobalFormat(dOc, fromElement);
     107    // infodb type
     108    doDatabaseType(dOc, fromElement);
     109
     110    // searching. <search> index, level, subcolls etc
     111    Node searchNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.SEARCH_STR, 0);
     112    // return buildtype here as we use it later
     113    String buildtype = doBuildType(dOc, (Element)searchNode);
     114    if (buildtype.equalsIgnoreCase("mg")) {
     115       
     116        doIndexes(dOc, searchNode, true);
     117    }
     118    else {
     119       
     120        doIndexes(dOc, searchNode, false);
     121    }
     122
     123    if(buildtype.equalsIgnoreCase("solr") || buildtype.equalsIgnoreCase("lucene")) {
     124        doSorts(dOc, searchNode);
     125        doDefaultSort(dOc, searchNode);
     126        if (buildtype.equalsIgnoreCase("solr")) {
     127        doFacets(dOc, searchNode);
     128        }
     129        // lucene will only have sort elements
     130    }
     131
     132    doDefaultIndex(dOc, searchNode);
     133    doDefaultLevel(dOc, searchNode);
     134    doLevel(dOc, searchNode);
     135    doIndexOption(dOc, searchNode);
     136    doSubcollection(dOc, searchNode);
     137    doIndexSubcollection(dOc, searchNode);
     138    doIndexLanguage(dOc, searchNode);
     139    doDefaultIndexLanguage(dOc, searchNode);
     140    doLanguageMetadata(dOc, searchNode);
     141    doSearchType(dOc, searchNode);
     142    doSearchFormat(dOc, searchNode);
     143
     144    // importing
     145    Node importNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.IMPORT_STR, 0);
     146    if (importNode == null) {
     147       
     148        System.out.println("There is no 'import' element.");
     149    } else {
     150
     151        // plugins + plugout
     152        doPluginsAndPlugout(dOc, importNode);
     153
     154    }
     155
     156    // import and build options are handled by unknown code at present,
     157    // as can't be used in gli
     158
     159    // browsing
     160
     161    Node browseNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.BROWSE_STR, 0);
     162    if (browseNode == null) {
     163       
     164        System.out.println("There is no browse element.");
     165    } else {
     166        doClassifiers(dOc, browseNode);
     167    }
     168
     169    // <display> - currently just has a format element?
     170
     171    doDisplayFormat(dOc, fromElement);
     172
     173    // lesser top level elements
     174    doReplaceListRef(dOc, fromElement);
     175    doReplaceList(dOc, fromElement);
     176    doServiceRackList(dOc, fromElement);
     177
     178    // handle everything else
     179    doUnknownElements(dOc, fromElement);
     180
     181    }
     182
     183    /** Saves the internal XML document out to the collectionConfig file */
     184    static public void save(File collect_config_xml_file, Document doc)
     185    {
     186    Document collection_config_xml_document = convertInternalToCollectionConfig(doc);
     187    String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR, StaticStrings.DISPLAYITEM_STR };
     188    XMLTools.writeXMLFile(collect_config_xml_file, collection_config_xml_document, nonEscapingTagNames);
     189    }
     190
     191
     192    //Convert the internal XML DOM tree (dOc) into that of collectionConfig.xml (skeleton)
     193    static private Document convertInternalToCollectionConfig(Document dOc)
     194    {
     195    //first parse an empty skeleton of xml config file
     196    //The aim is to convert the internal structure into this skeleton
     197    // This skeleton just has the CollectionConfig element and nothing else
     198    Document skeleton = XMLTools.parseXMLFile("xml/CollectionConfig.xml", true);
     199    convertSecurity(dOc, skeleton);
     200    convertMetadataList(dOc, skeleton);
     201    convertDisplayItemList(dOc, skeleton);
     202    convertGlobalFormat(dOc, skeleton);
     203    convertBuildType(dOc, skeleton); // creates the search elem
     204    Element search = (Element) XMLTools.getChildByTagName(skeleton.getDocumentElement(), StaticStrings.SEARCH_STR);
     205    String buildtype = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
     206
     207    if (buildtype.equals(StaticStrings.MG_STR)) {
     208        // for mg, levels are included in index definition
     209        convertIndexes(dOc, skeleton, search, true);
     210        //Convert default index
     211        convertDefaultIndex(dOc, skeleton, search, true);
     212
     213    } else {
     214        convertIndexes(dOc, skeleton, search, false);
     215        //Convert default index
     216        convertDefaultIndex(dOc, skeleton, search, false);
     217        // do the levels
     218        convertLevels(dOc, skeleton, search);
     219        convertDefaultLevel(dOc, skeleton, search);
     220           
     221    }
     222    // sortfields
     223    if (buildtype.equals(StaticStrings.LUCENE_STR) || buildtype.equals(StaticStrings.SOLR_STR)) {
     224        convertSorts(dOc, skeleton, search);
     225        convertDefaultSort(dOc, skeleton, search);
     226           
     227    }
     228    // facet fields
     229    if (buildtype.equals(StaticStrings.SOLR_STR)) {
     230        convertFacets(dOc, skeleton, search);
     231           
     232    }
     233
     234    convertIndexOptions(dOc, skeleton, search);
     235    convertSubcollectionIndexes(dOc, skeleton, search);
     236    convertLanguages(dOc, skeleton, search);
     237    convertSubcollection(dOc, skeleton, search);
     238    convertSearchType(dOc, skeleton, search);
     239    convertSearchFormat(dOc, skeleton, search);
     240
     241    convertDatabaseType(dOc, skeleton);
     242    convertPluginsAndPlugout(dOc, skeleton);// creates import/pluginList/plugin* + plugout if present (flax)
     243    convertClassifier(dOc, skeleton); //creates browse/classifier*
     244    convertDisplayFormat(dOc, skeleton);
     245    convertReplaceListRef(dOc, skeleton);
     246    convertReplaceList(dOc, skeleton);
     247    convertServiceRackList(dOc, skeleton);
     248    convertUnknownElements(dOc, skeleton); // try to catch everything GLI doesn't know about
     249
     250    return skeleton;
     251    }
     252    ///////////////////////////////
     253    // Security
     254    //////////////////////////////
     255
     256    /** Copy security element from config file to internal DOM */
     257    static private void doSecurity(Document to, Element from) {
     258    Node securityNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.SECURITY_STR,0);
     259    if (securityNode != null) {
     260        Element new_security = XMLTools.duplicateElement(to, (Element) securityNode, true);
     261        to.getDocumentElement().appendChild(new_security);
     262    }
     263    }
     264
     265    /** Write out security element from internal DOM to config file */
     266    static private void convertSecurity(Document from, Document to)
     267    {
     268    Node security = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), StaticStrings.SECURITY_STR, 0);
     269    if (security != null)
     270        {
     271        Element to_element = XMLTools.duplicateElement(to, (Element) security, true);
     272        to.getDocumentElement().appendChild(to_element);
     273       
     274        }
     275    }
     276
     277
     278    ///////////////////////////////////////////////////////
     279    // metadataList - includes creator, maintainer, public
     280    ///////////////////////////////////////////////////////
     281
     282    /** handle metadataList from config file. creator, maintainer, public get their own special elements in internal DOM, the rest just get copied to a metadataList, unused by GLI */
     283    static private void doMetadataList(Document to, Element from)
     284    {
     285    Element toElement = to.getDocumentElement();
     286    Element new_metadataList = to.createElement(StaticStrings.METADATALIST_STR);
     287
     288    Node metadataListNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.METADATALIST_STR, 0);
     289    if (metadataListNode == null) {
     290        return;
     291    }
     292    NodeList metas = ((Element)metadataListNode).getElementsByTagName(StaticStrings.METADATA_STR);
     293    int num_children = (metas == null) ? 0: metas.getLength();
     294    if (num_children == 0) {
     295        return;
     296    }
     297    boolean has_meta = false;
     298    for (int i=0; i < num_children; i++) {
     299        Element m = (Element) metas.item(i);
     300
     301        String name = m.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     302        if (name.equals(StaticStrings.COLLECTIONMETADATA_CREATOR_STR)) {
     303        // creator
     304        doSpecialMetadata(to, m, StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT);
     305        } else if (name.equals(StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR)) {
     306        // maintainer
     307        doSpecialMetadata(to, m, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT);
     308        } else if (name.equals(StaticStrings.COLLECTIONMETADATA_PUBLIC_STR)) {
     309        // public
     310        doSpecialMetadata(to, m, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT);
     311        } else {
     312        // custom metadata - we just store it in the metadataList
     313        Element new_m = XMLTools.duplicateElement(to, m, true);
     314        new_metadataList.appendChild(new_m);
     315        has_meta = true;
     316        }
     317    }
     318    if (has_meta) {
     319        toElement.appendChild(new_metadataList);
     320    }
     321    }
     322
     323    /** convert a special metadata element into internal DOM element */
     324    static private void doSpecialMetadata(Document to, Element meta, String new_element_name) {
     325    String text = XMLTools.getNodeText(meta);
     326
     327    //If there is nothing to display, don't bother creating the element
     328    if (text.equals("")) return;
     329       
     330    Element new_element = to.createElement(new_element_name);
     331    new_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, meta.getAttribute(StaticStrings.NAME_ATTRIBUTE));
     332    new_element.setAttribute(StaticStrings.LANG_ATTRIBUTE, meta.getAttribute(StaticStrings.LANG_ATTRIBUTE));
     333    new_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     334    new_element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
     335    XMLTools.setNodeText(new_element, text);
     336    to.getDocumentElement().appendChild(new_element);
     337    } // doMetadataList
     338
     339    /** output metadataList to config file. Comprises any custom metadata stored in metadataList in internal DOM, plus creator, maintainer, public elements converted back to metadataList */
     340    static private void convertMetadataList(Document from, Document to)
     341    {
     342    // if we have existing metadataList (not used by GLI, just copied over)
     343    // then we use that otherwise we create a new one
     344    Node existing_metadataList = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), StaticStrings.METADATALIST_STR, 0);
     345    Element metadataList;
     346    if (existing_metadataList != null) {
     347        metadataList = XMLTools.duplicateElement(to, (Element)existing_metadataList, true);
     348    } else {
     349        metadataList = to.createElement(StaticStrings.METADATALIST_STR);
     350    }
     351
     352    to.getDocumentElement().appendChild(metadataList);
     353
     354    // creator, maintainer, public are stored differently in internal DOM, but
     355    // go into the metadataList for the config file
     356
     357    String[] ele_names = { StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT };
     358    String[] att_names = { StaticStrings.COLLECTIONMETADATA_CREATOR_STR, StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR, StaticStrings.COLLECTIONMETADATA_PUBLIC_STR };
     359    for (int i = 0; i < ele_names.length; i++) {
     360       
     361        Element e = XMLTools.getNamedElement(from.getDocumentElement(), ele_names[i], StaticStrings.NAME_ATTRIBUTE, att_names[i]);
     362        if (e == null)
    100363        {
    101             return null;
     364            continue;
    102365        }
    103 
    104         for (int i = 0; i < item_list.size(); i++)
    105         {
    106             Element item = (Element) item_list.get(i);
    107             boolean isCollDescr = name_value.equals(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
    108 
    109             // Sadly, XMLTools.getNodeText(item) returns empty for any HTML in displayItem
    110             // so we have to do it the hard way
    111             // We can't take a shortcut like format statements, which also need to keep their
    112             // tags intact in collConfig.xml, because we know in advance the format tag name
    113             // Can't guess at what html tag names the user uses, and there may be several at
    114             // the same level inside collDescription (e.g. multiple paragraphs)
    115             String text = isCollDescr ? preserveHTMLInDescriptionDisplayItem(item)
    116                 : XMLTools.getNodeText(item); // else as before for all other displayItems
    117 
     366        String text = XMLTools.getNodeText(e);
     367        Element metadata = to.createElement(StaticStrings.METADATA_STR);
     368        metadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, att_names[i]);
     369        metadata.setAttribute(StaticStrings.LANG_STR, StaticStrings.ENGLISH_LANGUAGE_STR);
     370        XMLTools.setNodeText(metadata, text);
     371        metadataList.appendChild(metadata);
     372    }
     373       
     374    }// convertMetadataList
     375
     376
     377    ////////////////////////////////////////////////
     378    // display items (top level)
     379    ///////////////////////////////////////////////
     380
     381    /** processes the top level displayItemList, and adds them all as
     382    CollectionMeta to the internal doc. */
     383    static private void doDisplayItemList(Document to, Element from) {
     384    Element toElement = to.getDocumentElement();
     385    Node displayItemListNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.DISPLAYITEMLIST_STR, 0);
     386    if (displayItemListNode == null) {
     387        return;
     388    }
     389    NodeList displayItems = ((Element)displayItemListNode).getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
     390    for (int i=0; i<displayItems.getLength(); i++) {
     391        Element item = (Element) displayItems.item(i);
     392        String name = item.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     393        String internal_name = name; // unless mentioned below
     394        if (name.equals(StaticStrings.NAME_STR)) {
     395        internal_name = StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR;
     396        } else if (name.equals(StaticStrings.DESCRIPTION_STR)) {
     397        internal_name = StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR;
     398        } else if (name.equals(StaticStrings.ICON_STR)) {
     399        internal_name = StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR;
     400        } else if (name.equals(StaticStrings.SMALLICON_STR)) {
     401        internal_name = StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR;
     402        }
     403
     404        Element coll_meta = processSingleDisplayItem(to, item, internal_name, null);
     405        if (coll_meta != null) {
     406        toElement.appendChild(coll_meta);
     407        }
     408    }
     409
     410
     411    }
     412
     413
     414    // create a displayItemList for config file, from CollectionMetadata
     415    static private void convertDisplayItemList(Document from, Document to)
     416    {
     417    Element displayItemList = to.createElement(StaticStrings.DISPLAYITEMLIST_STR);
     418    Element destination = to.getDocumentElement();
     419
     420    // certain special collectionmeta elements should have different names
     421    // as displayItems in the collectionConfig.xml than they do in memory
     422    Map attributeMap = new HashMap(4);
     423    attributeMap.put(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR, StaticStrings.DESCRIPTION_STR);
     424    attributeMap.put(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR, StaticStrings.NAME_STR);
     425    attributeMap.put(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR, StaticStrings.SMALLICON_STR);
     426    attributeMap.put(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR, StaticStrings.ICON_STR);
     427
     428    NodeList e_list = from.getDocumentElement().getElementsByTagName(StaticStrings.COLLECTIONMETADATA_ELEMENT);
     429    // if such elements don't exist, don't bother
     430    if (e_list != null) {
     431       
     432
     433        for (int j = 0; j < e_list.getLength(); j++) {
     434           
     435        Element e = (Element) e_list.item(j);
     436        if (e.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) {
     437               
     438            continue;
     439        }
     440
     441        String name_value = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     442        String name_mapping = (String) attributeMap.get(name_value);
     443        if (name_mapping != null) {             
     444            name_value = name_mapping;
     445        }
     446        Element displayItem  = constructDisplayItem(e, to, name_value);
     447               
     448        displayItemList.appendChild(displayItem);
     449        }
     450
     451    }
     452    destination.appendChild(displayItemList);
     453    }
     454
     455    //////////////////////////////////////////////
     456    // global (top level) format
     457    /////////////////////////////////////////////
     458
     459    static private void doGlobalFormat(Document to, Element from)
     460    {
     461    // look for a top level format element
     462    Element fe = (Element) XMLTools.getChildByTagName(from, StaticStrings.FORMAT_STR);
     463    to.getDocumentElement().appendChild(doFormat(to, fe, StaticStrings.GLOBAL_STR));
     464    }
     465
     466    // convert global format statement
     467    static private void convertGlobalFormat(Document from, Document to)
     468    {
     469    Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.GLOBAL_STR);
     470
     471    to.getDocumentElement().appendChild(convertFormat(to, e));
     472
     473    }
     474
     475
     476    ////////////////////////////////////////////////
     477    // database type = infodb type
     478    ////////////////////////////////////////////////
     479
     480    static private void doDatabaseType(Document to, Element from) {
     481
     482    Node databaseNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.INFODB_STR, 0);
     483    String databasetype_value = "gdbm";
     484    if (databaseNode != null) {
     485       
     486        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)
     487    }
     488   
     489    Element element = to.createElement(StaticStrings.DATABASETYPE_ELEMENT);
     490    element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR);
     491    element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR);
     492    element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     493    element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
     494   
     495    XMLTools.setNodeText(element, databasetype_value);
     496
     497    appendProperly(to.getDocumentElement(), element);
     498
     499    }
     500    static private void convertDatabaseType(Document from, Document to)
     501    {
     502    Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.DATABASETYPE_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR);
     503    if (e == null) {
     504       
     505        return;
     506    }
     507    String db = XMLTools.getNodeText(e);
     508    Element dbtype = to.createElement(StaticStrings.INFODB_STR);
     509    dbtype.setAttribute(StaticStrings.TYPE_ATTRIBUTE, db);
     510    to.getDocumentElement().appendChild(dbtype);
     511    }
     512
     513    // search *************************************************************
     514
     515    ///////////////////////////////////////////////////
     516    // build type
     517    //////////////////////////////////////////////////
     518
     519    static private String doBuildType(Document to, Element searchNode)
     520    {
     521
     522    String buildtype = ((Element) searchNode).getAttribute(StaticStrings.TYPE_ATTRIBUTE);//might be mg|mgpp|lucene|solr
     523
     524
     525
     526    //construct 'BuildType' element
     527    Element element = to.createElement(StaticStrings.BUILDTYPE_ELEMENT);
     528    element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR);
     529    element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR);
     530    element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     531    element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
     532
     533    XMLTools.setNodeText(element, buildtype);
     534    appendProperly(to.getDocumentElement(), element);
     535    return buildtype;
     536    }
     537
     538    /** This uses the buildtype element in internal DOM, and creates the search element in the config file output, with type set to the indexer type */
     539    static private void convertBuildType(Document from, Document to)
     540    {
     541    Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.BUILDTYPE_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR);
     542    if (e == null)
     543        {
     544        return;
     545        }
     546    String indexer = XMLTools.getNodeText(e);
     547    Element search = to.createElement(StaticStrings.SEARCH_STR);
     548    search.setAttribute(StaticStrings.TYPE_ATTRIBUTE, indexer);
     549    to.getDocumentElement().appendChild(search);
     550    }
     551
     552
     553
     554
     555    /////////////////////////////////////////////
     556    // indexes
     557    ////////////////////////////////////////////
     558
     559    /**This converts indexes and their displayItems - set is_mg_index to true if dealing with mg, as that has slightly different format to the rest. */
     560    static private void doIndexes(Document to, Node searchNode, boolean is_mg_index)
     561    {
     562    doBaseSearchPartInternal(to, searchNode, StaticStrings.INDEXES_ELEMENT, StaticStrings.INDEX_ELEMENT, StaticStrings.INDEX_LOW_STR, SearchMeta.TYPE_INDEX, is_mg_index);
     563    Element toElement = to.getDocumentElement();
     564    Element indexes_element = (Element) XMLTools.getChildByTagName(toElement, StaticStrings.INDEXES_ELEMENT);
     565    indexes_element.setAttribute(StaticStrings.MGPP_ATTRIBUTE, (is_mg_index? StaticStrings.FALSE_STR:StaticStrings.TRUE_STR));
     566
     567
     568    boolean creating_mg_index = !is_mg_index;
     569    // create another set of <indexes> which will be used when user switches to/from MG
     570    // i.e. we build a default index set for a start
     571    Element other_indexes = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes>
     572    other_indexes.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
     573    other_indexes.setAttribute(StaticStrings.MGPP_ATTRIBUTE, (creating_mg_index? StaticStrings.FALSE_STR:StaticStrings.TRUE_STR));
     574
     575    //put the namespace '.ex' as prefix to the indexes
     576    String[] index_strs = { StaticStrings.TEXT_STR, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.TITLE_ELEMENT, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.SOURCE_ELEMENT };
     577    for (int i = 0; i < index_strs.length; i++) {
     578       
     579        Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index>
     580        if (creating_mg_index) {
     581        index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
     582        }
     583        Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
     584        content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_strs[i]);
     585        index_element.appendChild(content_element);
     586
     587        other_indexes.appendChild(index_element);
     588
     589    } // foreach fake index
     590    toElement.appendChild(other_indexes);
     591
     592    } // doIndexes
     593
     594
     595    //construct 'DefaultIndex' element in the internal structure from collectionConfig.xml
     596    // TODO
     597
     598    static private void doDefaultIndex(Document to, Node searchNode)
     599    {
     600    Element toElement = to.getDocumentElement();
     601    Element default_index_element = to.createElement(StaticStrings.INDEX_DEFAULT_ELEMENT);
     602    default_index_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     603
     604    Element e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE);//defaultIndex
     605    if (e == null) {
     606       
     607        return;
     608    }
     609    String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     610
     611    boolean old_index = false;
     612    if (index_str.indexOf(StaticStrings.COLON_CHARACTER) != -1) {
     613       
     614        //The index is 'level:source tuplets' which is for mg. Take out 'level'
     615        old_index = true;
     616        default_index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER)));
     617        index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
     618    }
     619    else {
     620       
     621        default_index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, "");
     622    }
     623
     624    //Each index may have a list of comma-separated strings.
     625    //split them into 'content' elements in the internal structure
     626    StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
     627    while (content_tokenizer.hasMoreTokens()) {
     628       
     629        Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
     630        String content_str = content_tokenizer.nextToken();
     631        // 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.
     632        if (content_str.indexOf(StaticStrings.NS_SEP) == -1) {
     633           
     634        if (content_str.equals(StaticStrings.TEXT_STR) || (!old_index && content_str.equals(StaticStrings.ALLFIELDS_STR))) {
     635               
     636            // in this case, do nothing
     637        }
     638        else {
    118639           
    119             //If there is nothing to display, don't bother creating the element
    120             // Either lang or key should be set. If key set, no textnode.
    121             // if lang set, should have textnode. Check if it's meaningful
    122             if (item.hasAttribute(StaticStrings.LANG_STR) && text.equals(""))
    123             {
    124                 continue;
    125             }       
    126 
    127             // get the value in 'lang=langcode' or 'key=keyname'
    128             // We can have either a key attribute (with optional dictionary attribute, else dictionary is implicit)
    129             // OR we can have a lang attr, with the nodetext containing the actual display string.
    130             String lang = item.getAttribute(StaticStrings.LANG_STR);
    131             String key = item.getAttribute(StaticStrings.KEY_ATTRIBUTE);
    132 
    133             Element e;
    134             if (type ==null) {
    135                 e = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT);
    136             } else {
    137                 e = to.createElement(StaticStrings.SEARCHMETADATA_ELEMENT);
    138             }
    139             e.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    140             e.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_value);
    141 
    142                         if (type != null) {
    143                           e.setAttribute(StaticStrings.TYPE_ATTRIBUTE, type);
    144                         }
    145             if(!lang.equals("")) {
    146                 e.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
    147                 text = text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
    148                 XMLTools.setNodeText(e, text);
    149                
    150             }
    151 
    152             if(!key.equals("")) {
    153                 e.setAttribute(StaticStrings.KEY_ATTRIBUTE, key);
    154                 String dictionary = item.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
    155                 if(!dictionary.equals("")) {
    156                 e.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary);
    157                 }
    158             }
    159 
    160             display_item_list.add(e);
     640            content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
    161641        }
    162         return display_item_list;
    163     } // doDisplayItemList
    164 
    165     static private ArrayList doMetadataList(Document to, Node metadataListNode, String ele_name, String att_value)
    166     {
    167         Element toElement = to.getDocumentElement();
    168         ArrayList metadata_list = new ArrayList();
    169 
    170         ArrayList item_list = XMLTools.getNamedElementList((Element) metadataListNode, StaticStrings.METADATA_STR, StaticStrings.NAME_ATTRIBUTE, att_value);
    171         if (item_list == null)
    172         {
    173             return null;
    174         }
    175 
    176         for (int i = 0; i < item_list.size(); i++)
    177         {
    178             Element item = (Element) item_list.get(i);
    179             String text = XMLTools.getNodeText(item);
    180 
    181             //If there is nothing to display, don't bother creating the element
    182             if (text.equals(""))
    183             {
    184                 continue;
    185             }
    186             //get the value in 'lang=value'
    187             String lang = item.getAttribute(StaticStrings.LANG_STR);
    188 
    189             Element element = to.createElement(ele_name);
    190             element.setAttribute(StaticStrings.NAME_ATTRIBUTE, att_value);
    191             element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
    192             element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    193             element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
    194             XMLTools.setNodeText(element, text);
    195 
    196             metadata_list.add(element);
    197         }
    198         return metadata_list;
    199     } // doMetadataList
    200 
    201     // 'to' is the internal structure
    202     static private void doMGIndexes(Document to, Node searchNode)
    203     {
    204         Element toElement = to.getDocumentElement();
    205         Element indexes_element = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes>
    206         indexes_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    207         indexes_element.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.FALSE_STR);
    208 
    209         NodeList index_children = ((Element) searchNode).getElementsByTagName(StaticStrings.INDEX_LOW_STR);//index
    210         int num_nodes = index_children.getLength();
    211 
    212         for (int i = 0; i < num_nodes; i++)
    213         {
    214             Element e = (Element) index_children.item(i);
    215             String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    216             String index_str_display = index_str;//used for creating collectionmetadata for this index
    217             Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index>
    218 
    219             if (index_str.indexOf(StaticStrings.COLON_CHARACTER) == -1)
    220             {
    221                 // It doesn't contain ':' character
    222                 System.err.println("Something is wrong! the index should be level:source tuplets.");
    223                 // assume document level
    224                 index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
    225             }
    226             else
    227             {
    228                 // Handling 'index' element
    229                 index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER)));
    230 
    231                 index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
    232             }
    233             //Each index may have a list of comma-separated strings.
    234             //split them into 'content' elements in the internal structure
    235             StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
    236             //index_str = "";
    237             while (content_tokenizer.hasMoreTokens())
    238             {
    239                 // Replace index_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject.
    240 
    241                 Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
    242                 String content_str = content_tokenizer.nextToken();
    243                 // Since the contents of indexes have to be certain keywords, or metadata elements,
    244                 //if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace.
    245                 if (content_str.indexOf(StaticStrings.NS_SEP) == -1 && !(content_str.equals(StaticStrings.TEXT_STR)))
    246                 {
    247                     content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
    248 
    249                 }
    250 
    251                 content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
    252                 index_element.appendChild(content_element);
    253                 content_element = null;
    254             } // while ends
    255 
    256             indexes_element.appendChild(index_element);
    257 
    258             // Handling 'displayItem' elements and Constructing 'collectionmetadata' elements
    259             // Use the fully qualified index names
    260             ArrayList collectionmetadata_list = doDisplayItemList(to, e, StaticStrings.NAME_STR, index_str_display, SearchMeta.TYPE_INDEX); // todo should be name_str???
    261             appendArrayList(toElement, collectionmetadata_list);
    262         } //for loop ends
    263         appendProperly(toElement, indexes_element);
    264 
    265         //***//
    266         // create another set of <indexes> which will be used when user switches to MGPP/LUCENE
    267         // i.e. we build a default index set for a start
    268 
    269         String[] index_strs = { StaticStrings.TEXT_STR, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.TITLE_ELEMENT, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.SOURCE_ELEMENT };
    270 
    271         Element mgpp_indexes = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes>
    272         mgpp_indexes.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
    273         mgpp_indexes.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.TRUE_STR);
    274         for (int i = 0; i < index_strs.length; i++)
    275         {
    276             Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index>
    277             Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
    278             content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_strs[i]);
    279             index_element.appendChild(content_element);
    280             mgpp_indexes.appendChild(index_element);
    281 
    282             // Contructing 'collectionmetadata' elements for 'mgpp' indexes
    283             Element collectionmetadata = to.createElement(StaticStrings.SEARCHMETADATA_ELEMENT);
    284             collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    285             collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_strs[i]);
    286             collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR);
    287                         collectionmetadata.setAttribute("type", SearchMeta.TYPE_INDEX);
    288             if (index_strs[i].indexOf(StaticStrings.NS_SEP) != -1)
    289             {
    290                 index_strs[i] = index_strs[i].substring(index_strs[i].indexOf(StaticStrings.NS_SEP) + 1);
    291             }
    292             XMLTools.setNodeText(collectionmetadata, index_strs[i]);
    293 
    294             appendProperly(toElement, collectionmetadata);
    295 
    296         }
    297         appendProperly(toElement, mgpp_indexes);
    298     }
    299 
    300     static private void doBaseIndexInternal(Document to, Node searchNode, String new_indexes_str, String new_index_str, String existing_index_str) {
    301 
    302     Element toElement = to.getDocumentElement();
    303     Element indexes_element = to.createElement(new_indexes_str);//<Indexes> // INDEXES_ELEMENT
    304     indexes_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    305     //indexes_element.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.TRUE_STR);
    306 
    307     NodeList index_children = ((Element) searchNode).getElementsByTagName(existing_index_str);//index INDEx_LOW_STR
    308     int num_nodes = index_children.getLength();
    309    
    310     for (int i = 0; i < num_nodes; i++)
    311         {
    312 
    313         Element index_element = to.createElement(new_index_str);//<Index> INDEX_ELEMENT
    314         Element e = (Element) index_children.item(i);
    315         String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    316         String index_str_display = index_str;//for creating collectionmetadata for this index
    317        
    318         // look for options inside the index, eg
    319         // <option name="solrfieldtype" value="text_ja" />
    320         String options_str = "";
    321         NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR);
    322         if(option_children != null) {
    323             for (int j = 0; j < option_children.getLength(); j++) {
    324             Element el = (Element) option_children.item(j);
    325            
    326             String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    327             options_str = options_str + ((name_str.equals("")) ? "" : (" " + name_str));
    328            
    329             String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
    330             options_str = options_str + ((name_str.equals("")) ? "" : (" " + value_str));
    331            
    332             if (name_str.equals("") && !value_str.equals(""))
    333                 {
    334                 continue; //invalid condition
    335                 }
    336            
    337             Element option_element = null;
    338             option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
    339             option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    340            
    341             if (!name_str.equals(""))
    342                 {
    343                 option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    344                 }
    345             if (value_str != null && !value_str.equals(""))
    346                 {
    347                 XMLTools.setNodeText(option_element, value_str);
    348                 }
    349             index_element.appendChild(option_element);
    350             }
    351         }
    352 
    353         // Handling 'index' element
    354         // Double check to make sure it's not colon separated style index.
    355         if (index_str.indexOf(StaticStrings.COLON_CHARACTER) != -1)
    356             {
    357             System.err.println("Something is wrong! the "+existing_index_str+" should NOT be level:source tuplets style.");
    358             index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
    359            
    360             }
    361         //Each index may have a list of comma-separated strings.
    362         //split them into 'content' elements in the internal structure
    363         StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
    364         while (content_tokenizer.hasMoreTokens())
    365             {
    366             // Replace index_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject.             
    367            
    368             Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
    369             String content_str = content_tokenizer.nextToken();
    370             // 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.
    371             if (content_str.indexOf(StaticStrings.NS_SEP) == -1 && !(content_str.equals(StaticStrings.TEXT_STR) || content_str.equals(StaticStrings.ALLFIELDS_STR) || content_str.equals(StaticStrings.NONE_STR) || content_str.equals(StaticStrings.RANK_STR)))
    372                 {
    373                 content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
    374                 }
    375             content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
    376             index_element.appendChild(content_element);
    377             content_element = null;
    378             } //while ends
    379 
    380         indexes_element.appendChild(index_element);
    381        
    382         index_element = null;
    383 
    384         // Handling 'displayItem' element of this 'index' element
    385         // 'e' is the parent element 'index' of 'displayItem' element
    386         ArrayList collectionmetadata_list = doDisplayItemList(to, e, StaticStrings.NAME_ATTRIBUTE, index_str_display, existing_index_str);
    387         appendArrayList(toElement, collectionmetadata_list);
    388        
    389         } // for loop ends
    390     toElement.appendChild(indexes_element);
    391     //return toElement;
    392 
    393     } // doBaseIndexInternal
    394     //This is actually doing indexes for both mgpp and lucene
    395     static private void doMGPPIndexes(Document to, Node searchNode)
    396     {
    397          doBaseIndexInternal(to, searchNode, StaticStrings.INDEXES_ELEMENT, StaticStrings.INDEX_ELEMENT, StaticStrings.INDEX_LOW_STR);
    398          Element toElement = to.getDocumentElement();
    399          Element indexes_element = (Element) XMLTools.getChildByTagName(toElement, StaticStrings.INDEXES_ELEMENT);
    400         indexes_element.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.TRUE_STR);
    401 
    402         // Element toElement = to.getDocumentElement();
    403         // Element indexes_element = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes>
    404         // indexes_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    405         // indexes_element.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.TRUE_STR);
    406 
    407         // NodeList index_children = ((Element) searchNode).getElementsByTagName(StaticStrings.INDEX_LOW_STR);//index
    408         // int num_nodes = index_children.getLength();
    409 
    410         // for (int i = 0; i < num_nodes; i++)
    411         // {
    412 
    413         //  Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index>
    414         //  Element e = (Element) index_children.item(i);
    415         //  String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    416         //  String index_str_display = index_str;//for creating collectionmetadata for this index
    417 
    418         //  // look for options inside the index, eg
    419         //  // <option name="solrfieldtype" value="text_ja" />
    420         //  String options_str = "";
    421         //  NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR);
    422         //  if(option_children != null) {
    423         //     for (int j = 0; j < option_children.getLength(); j++) {
    424         //      Element el = (Element) option_children.item(j);
    425 
    426         //      String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    427         //      options_str = options_str + ((name_str.equals("")) ? "" : (" " + name_str));
    428 
    429         //      String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
    430         //      options_str = options_str + ((name_str.equals("")) ? "" : (" " + value_str));
    431 
    432         //      if (name_str.equals("") && !value_str.equals(""))
    433         //      {
    434         //          continue; //invalid condition
    435         //      }
    436 
    437         //      Element option_element = null;
    438         //      option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
    439         //      option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    440 
    441         //      if (!name_str.equals(""))
    442         //      {
    443         //          option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    444         //      }
    445         //      if (value_str != null && !value_str.equals(""))
    446         //      {
    447         //          XMLTools.setNodeText(option_element, value_str);
    448         //      }
    449         //      index_element.appendChild(option_element);
    450         //     }
    451         //  }
    452 
    453         //  // Handling 'index' element
    454         //  // Double check to make sure it's not colon separated style index.
    455         //  if (index_str.indexOf(StaticStrings.COLON_CHARACTER) != -1)
    456         //  {
    457         //      System.err.println("Something is wrong! the index should NOT be level:source tuplets style.");
    458         //      index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
    459 
    460         //  }
    461         //  //Each index may have a list of comma-separated strings.
    462         //  //split them into 'content' elements in the internal structure
    463         //  StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
    464         //  while (content_tokenizer.hasMoreTokens())
    465         //  {
    466         //      // Replace index_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject.             
    467 
    468         //      Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
    469         //      String content_str = content_tokenizer.nextToken();
    470         //      // 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.
    471         //      if (content_str.indexOf(StaticStrings.NS_SEP) == -1 && !(content_str.equals(StaticStrings.TEXT_STR) || content_str.equals(StaticStrings.ALLFIELDS_STR)))
    472         //      {
    473         //          content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
    474         //      }
    475         //      content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
    476         //      index_element.appendChild(content_element);
    477         //      content_element = null;
    478         //  } //while ends
    479 
    480         //  indexes_element.appendChild(index_element);
    481 
    482         //  index_element = null;
    483 
    484         //  // Handling 'displayItem' element of this 'index' element
    485         //  // 'e' is the parent element 'index' of 'displayItem' element
    486         //  ArrayList collectionmetadata_list = doDisplayItemList(to, e, StaticStrings.NAME_ATTRIBUTE, index_str_display);
    487         //  appendArrayList(toElement, collectionmetadata_list);
    488 
    489         // } // for loop ends
    490         // toElement.appendChild(indexes_element);
    491 
    492         // create another set of <indexes> which will be used when user switches to MG
    493         // i.e. we build a default index set for a start
    494         Element mg_indexes = to.createElement(StaticStrings.INDEXES_ELEMENT);//<Indexes>
    495         mg_indexes.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
    496         mg_indexes.setAttribute(StaticStrings.MGPP_ATTRIBUTE, StaticStrings.FALSE_STR);
    497 
    498         //put the namespace '.ex' as prefix to the indexes
    499         String[] index_strs = { StaticStrings.TEXT_STR, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.TITLE_ELEMENT, StaticStrings.EXTRACTED_NAMESPACE + StaticStrings.SOURCE_ELEMENT };
    500         for (int i = 0; i < index_strs.length; i++)
    501         {
    502             Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index>
    503             index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
    504             Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
    505             content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_strs[i]);
    506             index_element.appendChild(content_element);
    507 
    508             mg_indexes.appendChild(index_element);
    509 
    510             // Contructing 'collectionmetadata' elements for 'mg' indexes
    511             Element collectionmetadata = to.createElement(StaticStrings.SEARCHMETADATA_ELEMENT);
    512             collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    513                         collectionmetadata.setAttribute("type", SearchMeta.TYPE_INDEX);
    514             String temp = StaticStrings.DOCUMENT_STR.concat(StaticStrings.COLON_CHARACTER).concat(index_strs[i]);
    515             collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, temp);
    516             collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR);
    517             if (index_strs[i].indexOf(StaticStrings.NS_SEP) != -1)
    518             {
    519                 index_strs[i] = index_strs[i].substring(index_strs[i].indexOf(StaticStrings.NS_SEP) + 1);
    520             }
    521             XMLTools.setNodeText(collectionmetadata, index_strs[i]);
    522 
    523             appendProperly(toElement, collectionmetadata);
    524 
    525         }
    526         toElement.appendChild(mg_indexes);
    527 
    528     } // doMGPPIndexes
     642        }
     643
     644        content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
     645        default_index_element.appendChild(content_element);
     646        content_element = null;
     647    }
     648    appendProperly(toElement, default_index_element);
     649    } //doDefaultIndex
     650
     651    static private void convertIndexes(Document from, Document to, Element search, boolean is_mg_index) {
     652
     653    convertBaseSearchPartInternal(from, to, search, StaticStrings.INDEXES_ELEMENT, StaticStrings.INDEX_ELEMENT, StaticStrings.INDEX_LOW_STR, SearchMeta.TYPE_INDEX, is_mg_index);
     654    }
     655    static private void convertDefaultIndex(Document from, Document to, Element search, boolean is_mg_index) {
     656    convertBaseDefaultSearchPartInternal(from, to, search, StaticStrings.INDEX_DEFAULT_ELEMENT, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE, is_mg_index);
     657    }
     658   
     659
     660
     661    ////////////////////////////////////////////////////////
     662    // sortfields and facets
     663    ////////////////////////////////////////////////////////
    529664
    530665    static private void doSorts(Document to, Node searchNode) {
    531     doBaseIndexInternal(to, searchNode, StaticStrings.SORTS_ELEMENT, StaticStrings.SORT_ELEMENT, StaticStrings.SORT_LOW_STR);
    532     }
    533     // static private void doSortsOld(Document to, Node searchNode)
    534     // {
    535     //     Element toElement = to.getDocumentElement();
    536     //     NodeList sort_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SORT_LOW_STR);
    537     //     int num_nodes = sort_children.getLength();
    538    
    539     //     // there are no sort fields
    540     //     if (num_nodes < 1)
    541     //         {
    542     //      return;
    543     //         }
    544    
    545     //     Element sorts = to.createElement(StaticStrings.SORTS_ELEMENT);
    546 
    547     //     for (int i = 0; i < num_nodes; i++)
    548     //         {
    549     //      Element sort_element = to.createElement(StaticStrings.SORT_ELEMENT);
    550     //      Element sort_child = (Element) sort_children.item(i);
    551     //      String name_str = sort_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    552     //      sort_element.setAttribute(StaticStrings.NAME_STR, name_str);
    553     //      sorts.appendChild(sort_element);
    554 
    555     //      // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'sort' element
    556     //      ArrayList displayItem_list = XMLTools.getNamedElementList(sort_child, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR);
    557     //      if (displayItem_list == null)
    558     //          {
    559     //          // there is no display item for this element
    560     //          continue;
    561     //          }
    562     //      for (int j = 0; j < displayItem_list.size(); j++)
    563     //          {
    564     //          Element item = (Element) displayItem_list.get(j);
    565     //          String text = XMLTools.getNodeText(item);
    566     //          //If there is nothing to display, don't bother creating the element
    567     //          // Either lang or key should be set. If key set, no textnode.
    568     //          // if lang set, should have textnode. Check if it's meaningful
    569     //          if (item.hasAttribute(StaticStrings.LANG_STR) && text.equals(""))
    570     //              {
    571     //              continue;
    572     //              }
    573            
    574     //          // get the value in 'lang=langcode' or 'key=keyname'
    575     //          // We can have either a key attribute (with optional dictionary attribute, else dictionary is implicit)
    576     //          // OR we can have a lang attr, with the nodetext containing the actual display strin.g
    577     //          String lang = item.getAttribute(StaticStrings.LANG_ATTRIBUTE);
    578     //          String key = item.getAttribute(StaticStrings.KEY_ATTRIBUTE);
    579            
    580            
    581     //          Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT);
    582     //          collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    583     //          collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    584     //          collectionmetadata.setAttribute("type", "sort");
    585     //          if(!lang.equals("")) {
    586     //              collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
    587     //              XMLTools.setNodeText(collectionmetadata, text);
    588     //          }
    589     //          if(!key.equals("")) {
    590     //              collectionmetadata.setAttribute(StaticStrings.KEY_ATTRIBUTE, key);
    591     //              String dictionary = item.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
    592     //              if(!dictionary.equals("")) {
    593     //              collectionmetadata.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary);
    594     //              }
    595     //          }
    596            
    597     //          appendProperly(toElement, collectionmetadata);
    598     //          }
    599     //         }
    600     //     toElement.appendChild(sorts);
    601     //     }
     666    doBaseSearchPartInternal(to, searchNode, StaticStrings.SORTS_ELEMENT, StaticStrings.SORT_ELEMENT, StaticStrings.SORT_LOW_STR, SearchMeta.TYPE_SORT, false);
     667    }
     668    static private void convertSorts(Document from, Document to, Element search) {
     669    convertBaseSearchPartInternal(from, to, search, StaticStrings.SORTS_ELEMENT, StaticStrings.SORT_ELEMENT, StaticStrings.SORT_LOW_STR, SearchMeta.TYPE_SORT, false);
     670    }
    602671
    603672    // TODO
     
    617686    appendProperly(toElement, default_sort);
    618687    }
     688    static private void convertDefaultSort(Document from, Document to, Element search) {
     689    // todo - should this be combined with index? or write own code?
     690    convertBaseDefaultSearchPartInternal(from, to, search, StaticStrings.SORT_DEFAULT_ELEMENT, StaticStrings.SORT_DEFAULT_ELEMENT, false);
     691    }
    619692    static private void doFacets(Document to, Node searchNode) {
    620     doBaseIndexInternal(to, searchNode, StaticStrings.FACETS_ELEMENT, StaticStrings.FACET_ELEMENT, StaticStrings.FACET_LOW_STR);
    621     }
    622 
    623    
    624     // static private void doFacetsOld(Document to, Node searchNode)
    625     // {
    626     //     Element toElement = to.getDocumentElement();
    627     //     NodeList facet_children = ((Element) searchNode).getElementsByTagName(StaticStrings.FACET_LOW_STR);
    628     //     int num_nodes = facet_children.getLength();
     693    doBaseSearchPartInternal(to, searchNode, StaticStrings.FACETS_ELEMENT, StaticStrings.FACET_ELEMENT, StaticStrings.FACET_LOW_STR, SearchMeta.TYPE_FACET, false);
     694    }
     695    static private void convertFacets(Document from, Document to, Element search) {
     696    convertBaseSearchPartInternal(from, to, search, StaticStrings.FACETS_ELEMENT, StaticStrings.FACET_ELEMENT, StaticStrings.FACET_LOW_STR, SearchMeta.TYPE_FACET, false);
     697    }
     698    //////////////////////////////////////////////////
     699    // levels
     700    /////////////////////////////////////////////////
     701
     702
     703    //Handle levels (document, section). In the internal structure, the element is called 'IndexOption'
     704    static private void doLevel(Document to, Node searchNode)
     705    {
     706    Element toElement = to.getDocumentElement();
     707    NodeList level_children = ((Element) searchNode).getElementsByTagName(StaticStrings.LEVEL_ATTRIBUTE);
     708    int level_nodes = level_children.getLength();
     709
     710    // it's mg, there's no level. So we construct a default 'indexOption' in the internal structure
     711    if (level_nodes < 1)
     712        {
     713        Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
     714        index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
     715        index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVELS_STR);
     716
     717        Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
     718        option_element.setAttribute(StaticStrings.NAME_STR, StaticStrings.DOCUMENT_STR);
     719        index_option.appendChild(option_element);
     720
     721        appendProperly(toElement, index_option);
     722
     723        return;
     724        }
     725
     726    Element index_options = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
     727    index_options.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     728    index_options.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVELS_STR);
     729
     730    for (int i = 0; i < level_nodes; i++)
     731        {
     732        Element level_element = (Element) level_children.item(i);
     733        String level_str = level_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     734        Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
     735        option_element.setAttribute(StaticStrings.NAME_STR, level_str);
     736        index_options.appendChild(option_element);
     737
     738        // Contructing 'searchmetadata' elements from the 'displayItem' of this 'level' element
     739        doSearchDisplayItems(to, level_element, level_str, SearchMeta.TYPE_LEVEL);
     740        //ArrayList searchmetadata_list = doDisplayItemListForType(to, level_element, StaticStrings.NAME_STR, level_str, SearchMeta.TYPE_LEVEL);
     741        //appendArrayList(toElement, searchmetadata_list);
     742        }
     743    appendProperly(toElement, index_options);
     744    } // doLevel
     745
     746    // For mg, this method is still called, but make it 'assigned=false'
     747    static private void doDefaultLevel(Document to, Node searchNode)
     748    {
     749    Element toElement = to.getDocumentElement();
     750    Element default_index_option = to.createElement(StaticStrings.INDEXOPTION_DEFAULT_ELEMENT);
     751    default_index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVEL_DEFAULT_STR);
     752
     753    Element e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.LEVEL_DEFAULT_ELEMENT);
     754    if (e != null) {
     755       
     756        default_index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     757        String level = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     758        default_index_option.setAttribute(StaticStrings.VALUE_ATTRIBUTE, level);
     759    }
     760    else {
     761       
     762        //In the case of mg, there's no level! build a default one using 'assigned=false value=document'
     763        default_index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
     764        default_index_option.setAttribute(StaticStrings.VALUE_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
     765    }
     766    appendProperly(toElement, default_index_option);
     767    }
     768
     769    // Convert levels for mgpp/lucene. This method is called by converIndex() when mgpp indexer is detected.
     770    static private void convertLevels(Document from, Document to, Element search)
     771    {
     772    Element source = from.getDocumentElement();
     773    Element index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTIONS_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVELS_STR);
     774    if (index_option == null)
     775        {
     776        return;
     777        }
     778    //Debugging purposes
     779    if (index_option.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
     780        {
     781        DebugStream.println("For mgpp, there should be an IndexOption element for levels which is assigned 'true': possible bug.");
     782        }
     783
     784    NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
     785    int num_elements = option_elements.getLength();
     786
     787    // Don't output anything if no indexes are set
     788    if (num_elements == 0)
     789        {
     790        return;//
     791        }
     792
     793    for (int k = 0; k < num_elements; k++)
     794        {
     795        Element e = (Element) option_elements.item(k);
     796        String name_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     797        Element level_element = to.createElement(StaticStrings.LEVEL_ELEMENT);
     798        level_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     799
     800        //Now construct displayItem for this level element from searchmetadata
     801        // ** here
     802        ArrayList searchmetadata_list = getMatchingSearchMetaElements(source, name_str, SearchMeta.TYPE_LEVEL);
     803        //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.SEARCHMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, name_str);
     804
     805        if (searchmetadata_list != null)
     806            {
     807
     808            for (int j = 0; j < searchmetadata_list.size(); j++)
     809                {
     810                Element searchmetadata = (Element) searchmetadata_list.get(j);
     811
     812                Element displayItem = constructDisplayItem(searchmetadata, to);
     813                level_element.appendChild(displayItem);
     814                }
     815            }
     816        search.appendChild(level_element);
     817        }
     818    }
     819    static private void convertDefaultLevel(Document from, Document to, Element search) {
     820    Element source = from.getDocumentElement();
     821    Element default_index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTION_DEFAULT_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVEL_DEFAULT_STR);
     822    if (default_index_option == null)
     823        {
     824        return;
     825        }
     826    Element default_level = to.createElement(StaticStrings.LEVEL_DEFAULT_ELEMENT);
     827    String default_level_str = default_index_option.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
     828    default_level.setAttribute(StaticStrings.NAME_ATTRIBUTE, default_level_str);
     829    search.appendChild(default_level);
    629830   
    630     //     // there are no facet fields
    631     //     if (num_nodes < 1)
    632     //         {
    633     //      return;
    634     //         }
    635    
    636     //     Element facets = to.createElement(StaticStrings.FACETS_ELEMENT);
    637 
    638     //     for (int i = 0; i < num_nodes; i++)
    639     //         {
    640     //      Element facet_element = to.createElement(StaticStrings.FACET_ELEMENT);
    641     //      Element facet_child = (Element) facet_children.item(i);
    642     //      String name_str = facet_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    643     //      facet_element.setAttribute(StaticStrings.NAME_STR, name_str);
    644     //      facets.appendChild(facet_element);
    645 
    646     //      // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'facet' element
    647     //      ArrayList displayItem_list = XMLTools.getNamedElementList(facet_child, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR);
    648     //      if (displayItem_list == null)
    649     //          {
    650     //          // there is no display item for this element
    651     //          continue;
    652     //          }
    653     //      for (int j = 0; j < displayItem_list.size(); j++)
    654     //          {
    655     //          Element item = (Element) displayItem_list.get(j);
    656     //          String text = XMLTools.getNodeText(item);
    657     //          //If there is nothing to display, don't bother creating the element
    658     //          // Either lang or key should be set. If key set, no textnode.
    659     //          // if lang set, should have textnode. Check if it's meaningful
    660     //          if (item.hasAttribute(StaticStrings.LANG_STR) && text.equals(""))
    661     //              {
    662     //              continue;
    663     //              }
     831    }
     832
     833    ////////////////////////////////////////////////
     834    // index options
     835    /////////////////////////////////////////////////
     836
     837    //Handle 'indexOption' (i.e. casefold, stem etc). In the internal structure, the element is called 'IndexOption'
     838    static private void doIndexOption(Document to, Node searchNode)
     839    {
     840    Element toElement = to.getDocumentElement();
     841    //Node index_option_node = XMLTools.getChildByTagName(searchNode, StaticStrings.INDEXOPTION_STR);
     842    //if (index_option_node == null)
     843    //{
     844    //  return;
     845    //}
     846    //NodeList option_children = ((Element) index_option_node).getElementsByTagName(StaticStrings.OPTION_STR);
     847    NodeList option_children = ((Element) searchNode).getElementsByTagName(StaticStrings.INDEXOPTION_STR);
     848    int num_options = option_children.getLength();
     849
     850    // for lucene, there is no 'indexOption'. We build a default 'indexOption' and 'assigned=false' in case the user switches to mg or mgpp
     851    if (num_options < 1)
     852        {
     853        Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
     854        index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
     855        index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR);
     856        String[] option_str = { StaticStrings.CASEFOLD_OPTION_STR, StaticStrings.STEM_OPTION_STR };
     857        for (int i = 0; i < option_str.length; i++)
     858            {
     859            Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
     860            option_element.setAttribute(StaticStrings.NAME_STR, option_str[i]);
     861            index_option.appendChild(option_element);
     862            }
     863        appendProperly(toElement, index_option);
     864        return;
     865        }
     866
     867    Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
     868    index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     869    index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR);
     870
     871    for (int i = 0; i < num_options; i++)
     872        {
     873        String option_str = ((Element) option_children.item(i)).getAttribute(StaticStrings.NAME_ATTRIBUTE);
     874        Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
     875        option_element.setAttribute(StaticStrings.NAME_STR, option_str);
     876        index_option.appendChild(option_element);
     877        }
     878    appendProperly(toElement, index_option);
     879    }
     880
     881
     882    // Convert indexoptions for mg/mgpp/lucene. This method is called by convertIndex().
     883    static private void convertIndexOptions(Document from, Document to, Element search)
     884    {
     885    Element source = from.getDocumentElement();
     886    Element index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTIONS_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.INDEXOPTIONS_STR);
     887    if (index_option == null)
     888        {
     889        return;
     890        }
     891    //Debugging purposes
     892    if (index_option.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) {
     893       
     894        DebugStream.println("There should be an IndexOption element which is assigned 'true': possible bug.");
     895
     896        // for lucene and solr collections, don't write out stemming, casefolding and accentfolding indexOptions
     897        // since they are not meant to be editable: stemming and casefolding are always on in lucene
     898        String buildtype_value = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE); //might be mg|mgpp|lucene|solr
     899        if(buildtype_value.equalsIgnoreCase("solr") || buildtype_value.equalsIgnoreCase("lucene")) {
     900        return;
     901        }
     902    }
     903    //Element indexOptionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
     904    NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
     905    int num_elements = option_elements.getLength();
     906    // Don't output anything if no index
     907    if (num_elements == 0)
     908        {
     909        return;//
     910        }
     911    //search.appendChild(indexOptionEl);
     912
     913    for (int k = 0; k < num_elements; k++)
     914        {
     915        Element e = (Element) option_elements.item(k);
     916        String name_att = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     917        Element optionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
     918        optionEl.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_att);
     919        // default value?? on/off
     920        //indexOptionEl.appendChild(optionEl);
     921        search.appendChild(optionEl);
     922        }
     923
     924    }
     925
     926    //////////////////////////////////////////
     927    // subcollections
     928    //////////////////////////////////////////
     929
     930    // Handling 'subcollection' elements in 'search' element of 'collectionConfig.xml'
     931    static private void doSubcollection(Document to, Node searchNode)
     932    {
     933    Element toElement = to.getDocumentElement();
     934    NodeList sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SUBCOLLECTION_STR);
     935    int sub_nodes = sub_children.getLength();
     936
     937    // There is no subcollection
     938    if (sub_nodes < 1)
     939        {
     940        return;
     941        }
     942
     943    for (int i = 0; i < sub_nodes; i++)
     944        {
     945        Element sub_child = (Element) sub_children.item(i);
     946        String name_str = sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     947        String filter_str = sub_child.getAttribute(StaticStrings.FILTER_ATTRIBUTE);
     948
     949        // filter_str is in the form '<! (if set)><metadata>/<metadata value>/<flag (if any)>'
     950
     951        int pos = filter_str.indexOf(StaticStrings.SEPARATOR_CHARACTER);
     952        String meta_str = "";
     953        String meta_value_str = "";
     954        String clude_str = "";
     955        String flag_str = "";
     956        if (pos == -1)
     957            {
     958
     959            meta_str = meta_value_str = filter_str;
     960            clude_str = StaticStrings.INCLUDE_STR;
     961            }
     962        else
     963            {
     964            clude_str = StaticStrings.INCLUDE_STR;
     965            if (filter_str.startsWith(StaticStrings.EXCLAMATION_CHARACTER))
     966                {
     967                clude_str = StaticStrings.EXCLUDE_STR;
     968                // Peel off "!"
     969                filter_str = filter_str.substring(StaticStrings.EXCLAMATION_CHARACTER.length());
     970                }
     971
     972            String[] strs = filter_str.split(StaticStrings.SEPARATOR_CHARACTER);
     973            if (strs[0] != null && strs[0] != "")
     974                {
     975                meta_str = strs[0];
     976                }
     977            if (!meta_str.equals(StaticStrings.FILENAME_STR) && meta_str.indexOf(StaticStrings.NS_SEP) == -1)
     978                {
     979                meta_str = StaticStrings.EXTRACTED_NAMESPACE + meta_str;
     980                }
     981
     982            if (strs[1] != null && strs[1] != "")
     983                {
     984                meta_value_str = strs[1];
     985                }
     986            if (strs.length > 2)
     987                {
     988                //This means there has been set a flag
     989                if (strs[2] != null && strs[2] != "")
     990                    {
     991                    flag_str = strs[2];
     992                    }
     993                }
     994            }
     995        Element subcollection_element = to.createElement(StaticStrings.SUBCOLLECTION_ELEMENT);
     996        subcollection_element.setAttribute(StaticStrings.NAME_STR, name_str);
     997        subcollection_element.setAttribute(StaticStrings.CONTENT_ATTRIBUTE, meta_str);
     998        subcollection_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, clude_str);
     999        if (flag_str != "")
     1000            {
     1001            subcollection_element.setAttribute(StaticStrings.OPTIONS_ATTRIBUTE, flag_str);
     1002            }
     1003        XMLTools.setNodeText(subcollection_element, meta_value_str);
     1004
     1005        toElement.appendChild(subcollection_element);
     1006        }
     1007    } // doSubCollection
     1008
     1009
     1010    static private void convertSubcollection(Document from, Document to, Element search)
     1011    {
     1012    Element source = from.getDocumentElement();
     1013    //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
     1014    //Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
     1015
     1016    // Get the Subcollection element from the internal structure
     1017    NodeList subcollection_elements = source.getElementsByTagName(StaticStrings.SUBCOLLECTION_ELEMENT);
     1018    if (subcollection_elements == null)
     1019        {
     1020        return;
     1021        }
     1022    int subcollection_elements_length = subcollection_elements.getLength();
     1023
     1024    if (subcollection_elements_length == 0)
     1025        { // no
     1026        return;
     1027        }
     1028
     1029    for (int j = 0; j < subcollection_elements_length; j++)
     1030        {
     1031
     1032        Element e = (Element) subcollection_elements.item(j);
     1033        if (e.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
     1034            {
     1035            continue;
     1036            }
     1037        String content = e.getAttribute(StaticStrings.CONTENT_ATTRIBUTE);
     1038        String name = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1039        String options = e.getAttribute(StaticStrings.OPTIONS_ATTRIBUTE);
     1040        String type = e.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
     1041        String text = XMLTools.getNodeText(e);
     1042
     1043        String filter = "";
     1044        if (type.equals(StaticStrings.EXCLUDE_STR))
     1045            {
     1046            filter = StaticStrings.EXCLAMATION_CHARACTER;
     1047            }
     1048
     1049        if (content.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && content.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
     1050            {
     1051            content = content.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
     1052            }
     1053        filter = filter + content + StaticStrings.SEPARATOR_CHARACTER + text;
     1054        if (options != null && options != "")
     1055            {
     1056            filter = filter + StaticStrings.SEPARATOR_CHARACTER + options;
     1057            }
     1058        Element subcollection = to.createElement(StaticStrings.SUBCOLLECTION_STR);
     1059        subcollection.setAttribute(StaticStrings.FILTER_ATTRIBUTE, filter);
     1060        subcollection.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
     1061
     1062        search.appendChild(subcollection);
     1063        }
     1064    }
     1065
     1066    //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.
     1067    static private void doIndexSubcollection(Document to, Node searchNode)
     1068    {
     1069    Element toElement = to.getDocumentElement();
     1070    NodeList index_sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SUBCOLLECTION_INDEX_ELEMENT);
     1071    int num_nodes = index_sub_children.getLength();
     1072
     1073    // there is no subcollection index
     1074    if (num_nodes < 1)
     1075        {
     1076        return;
     1077        }
     1078
     1079    Element subcollection_indexes = to.createElement(StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT);
     1080
     1081    for (int i = 0; i < num_nodes; i++)
     1082        {
     1083        Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);
     1084        Element index_sub_child = (Element) index_sub_children.item(i);
     1085        String name_str = index_sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1086
     1087        // name_str is in the form of comma separated strings, each of which is a subcollection filter name
     1088        String[] filters = name_str.split(StaticStrings.COMMA_CHARACTER);
     1089        for (int j = 0; j < filters.length; j++)
     1090            {
     1091
     1092            Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
     1093            content_element.setAttribute(StaticStrings.NAME_STR, filters[j]);
     1094            index_element.appendChild(content_element);
     1095            }
     1096        subcollection_indexes.appendChild(index_element);
     1097
     1098        // Contructing 'searchmetadata' elements from the 'displayItem' of this 'indexSubcollection' element
     1099        doSearchDisplayItems(to, index_sub_child, name_str, SearchMeta.TYPE_PARTITION);
     1100        //ArrayList searchmetadata_list = doDisplayItemListForType(to, index_sub_child, StaticStrings.NAME_STR, name_str, SearchMeta.TYPE_PARTITION); // todo should be name_str???
     1101        //appendArrayList(toElement, searchmetadata_list);
     1102        }
     1103    appendProperly(toElement, subcollection_indexes);
     1104    } // doIndexSubCollection
     1105
     1106    static private void convertSubcollectionIndexes(Document from, Document to, Element search)
     1107    {
     1108    Element source = from.getDocumentElement();
     1109    //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
     1110    //Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
     1111
     1112    // Get the SubcollectionIndexes element from the internal structure
     1113    Element subcollection_indexes = (Element) XMLTools.getChildByTagName(source, StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT);
     1114    if (subcollection_indexes == null)
     1115        {
     1116        return;
     1117        }
     1118    NodeList index_elements = subcollection_indexes.getElementsByTagName(StaticStrings.INDEX_ELEMENT);
     1119    int index_elements_length = index_elements.getLength();
     1120
     1121    if (index_elements_length == 0)
     1122        { // no indexes
     1123        return;
     1124        }
     1125
     1126    for (int j = 0; j < index_elements_length; j++)
     1127        {
     1128        Element index_element = (Element) index_elements.item(j);
     1129        if (index_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
     1130            {
     1131            continue;
     1132            }
     1133
     1134        Element index = to.createElement(StaticStrings.SUBCOLLECTION_INDEX_ELEMENT);
     1135
     1136        String index_value = "";
     1137
     1138        NodeList content_elements = index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
     1139        int content_elements_length = content_elements.getLength();
     1140
     1141        for (int k = 0; k < content_elements_length; k++)
     1142            {
     1143            Element content_element = (Element) content_elements.item(k);
     1144            if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
     1145                {
     1146                continue;
     1147                }
     1148            String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1149            index_value += name_str;
     1150            // Make it comma separated string
     1151            if (k < content_elements_length - 1)
     1152                {
     1153                index_value += StaticStrings.COMMA_CHARACTER;
     1154                }
     1155            content_element = null;
     1156            }//for loop ends
     1157
     1158        index.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_value);
     1159
     1160        // Now constructing 'displayItem' element for this 'indexSubcollection' element
     1161        // from the searchmetadata element
     1162        // *** here
     1163        ArrayList searchmetadata_list = getMatchingSearchMetaElements(source, index_value, SearchMeta.TYPE_PARTITION);
     1164        //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, index_value);
     1165
     1166        if (searchmetadata_list != null)
     1167            {
     1168
     1169            for (int k = 0; k < searchmetadata_list.size(); k++)
     1170                {
     1171                Element searchmetadata = (Element) searchmetadata_list.get(k);
     1172                if (searchmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
     1173                    {
     1174                    continue;
     1175                    }
     1176                Element displayItem = constructDisplayItem(searchmetadata, to);
     1177                index.appendChild(displayItem);
     1178                }
     1179            }
     1180
     1181        search.appendChild(index);
     1182
     1183        } //for loop ends
     1184    }
     1185
     1186    ///////////////////////////////////////////////
     1187    // language partitions
     1188    //////////////////////////////////////////////
     1189
     1190    //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.
     1191    static private void doIndexLanguage(Document to, Node searchNode)
     1192    {
     1193    Element toElement = to.getDocumentElement();
     1194    NodeList index_sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.LANGUAGE_INDEX_ELEMENT);
     1195    int num_nodes = index_sub_children.getLength();
     1196
     1197    // there is no subcollection index
     1198    if (num_nodes < 1)
     1199        {
     1200        return;
     1201        }
     1202
     1203    Element language_indexes = to.createElement(StaticStrings.LANGUAGES_ELEMENT);
     1204
     1205    for (int i = 0; i < num_nodes; i++)
     1206        {
     1207        Element language_element = to.createElement(StaticStrings.LANGUAGE_ELEMENT);
     1208        Element index_sub_child = (Element) index_sub_children.item(i);
     1209        String name_str = index_sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1210        language_element.setAttribute(StaticStrings.NAME_STR, name_str);
     1211        language_indexes.appendChild(language_element);
     1212
     1213        // Contructing 'searchmetadata' elements from the 'displayItem' of this 'indexLanguage' element
     1214        doSearchDisplayItems(to, index_sub_child, name_str, SearchMeta.TYPE_LANGUAGE);
     1215        }
     1216    toElement.appendChild(language_indexes);
     1217    } //doIndexLanguage
     1218
     1219
     1220    static private void doDefaultIndexLanguage(Document to, Node searchNode)
     1221    {
     1222    Element toElement = to.getDocumentElement();
     1223    String elementNameFrom = StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT;
     1224    String elementNameTo = StaticStrings.LANGUAGE_DEFAULT_ELEMENT;
     1225    Node from_element = XMLTools.getChildByTagName(searchNode, elementNameFrom);
     1226    if (from_element == null) return;
     1227
     1228    Element to_element = to.createElement(elementNameTo);
     1229
     1230    String name_str = ((Element) from_element).getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1231    to_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     1232    to_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     1233
     1234    toElement.appendChild(to_element);
     1235    }
     1236
     1237    // Handling <languageMetadata> in collectionConfig.xml ('elementNameFrom'); in the internal structure, it is called 'LanguageMetadata' ('elementNameTo').
     1238    // Converting from collectionConfig.xml to the internal xml structure.
     1239    static private void doLanguageMetadata(Document to, Node searchNode)
     1240    {
     1241    Element toElement = to.getDocumentElement();
     1242    String elementNameFrom = StaticStrings.LANGUAGE_METADATA_ELEMENT_STR;
     1243    String elementNameTo = StaticStrings.LANGUAGE_METADATA_ELEMENT;
     1244    Node from_element = XMLTools.getChildByTagName(searchNode, elementNameFrom);
     1245    if (from_element == null) return;
     1246
     1247    Element to_element = to.createElement(elementNameTo);
     1248
     1249    String name_str = ((Element) from_element).getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1250    if (name_str.indexOf(StaticStrings.NS_SEP) == -1) {
     1251       
     1252        name_str = StaticStrings.EXTRACTED_NAMESPACE + name_str;
     1253    }
     1254    to_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     1255    to_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     1256
     1257    toElement.appendChild(to_element);
     1258    }
     1259
     1260    /** language partitions - convert from internal DOM to config file,
     1261    does <language>, <defaultLanguage>, <languageMetadata> plus the <displayItem>s inside <language>
     1262    */
     1263    static private void convertLanguages(Document from, Document to, Element search)
     1264    {
     1265    Element source = from.getDocumentElement();
     1266
     1267    // Get the Languages element from the internal structure
     1268    Element languages = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGES_ELEMENT);
     1269    if (languages == null) return;
     1270
     1271    NodeList language_elements = languages.getElementsByTagName(StaticStrings.LANGUAGE_ELEMENT);
     1272    int language_elements_length = language_elements.getLength();
     1273
     1274    if (language_elements_length == 0) return;
     1275
     1276    for (int j = 0; j < language_elements_length; j++) {
     1277       
     1278        Element element = (Element) language_elements.item(j);
     1279        if (element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
     1280
     1281        // Create indexLanguage element
     1282        Element index_language = to.createElement(StaticStrings.LANGUAGE_INDEX_ELEMENT);
     1283
     1284        String name_str = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1285        index_language.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     1286
     1287        // Now constructing 'displayItem' element for this 'indexLanguage' element
     1288        // from the searchmetadata element
     1289
     1290        ArrayList searchmetadata_list = getMatchingSearchMetaElements(source, name_str, SearchMeta.TYPE_LANGUAGE);
     1291
     1292        if (searchmetadata_list != null) {
     1293        for (int k = 0; k < searchmetadata_list.size(); k++) {
     1294               
     1295            Element searchmetadata = (Element) searchmetadata_list.get(k);
     1296            if (searchmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
    6641297           
    665     //          // get the value in 'lang=langcode' or 'key=keyname'
    666     //          // We can have either a key attribute (with optional dictionary attribute, else dictionary is implicit)
    667     //          // OR we can have a lang attr, with the nodetext containing the actual display strin.g
    668     //          String lang = item.getAttribute(StaticStrings.LANG_ATTRIBUTE);
    669     //          String key = item.getAttribute(StaticStrings.KEY_ATTRIBUTE);
     1298            Element displayItem = constructDisplayItem(searchmetadata, to);
     1299            index_language.appendChild(displayItem);
     1300        }
     1301        }
     1302
     1303        search.appendChild(index_language);
     1304
     1305    } //for loop ends
     1306
     1307    // Convert DefaultLanguage
     1308    // Get the DefaultLanguage element from the internal structure
     1309    Element default_language = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGE_DEFAULT_ELEMENT);
     1310    if (default_language != null) {
     1311       
     1312        String lang_name = default_language.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1313        Element default_index_language = to.createElement(StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT);
     1314        default_index_language.setAttribute(StaticStrings.NAME_ATTRIBUTE, lang_name);
     1315        search.appendChild(default_index_language);
     1316    }
     1317    // Convert LanguageMetadata
     1318    // Get the LanguageMetadata element from the internal structure
     1319    Element language_metadata = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGE_METADATA_ELEMENT);
     1320    if (language_metadata != null) {
     1321       
     1322        String meta_name = language_metadata.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1323        Element language_meta = to.createElement(StaticStrings.LANGUAGE_METADATA_ELEMENT_STR);
     1324        if (meta_name.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && meta_name.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) {
     1325       
     1326        meta_name = meta_name.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
     1327        }
     1328        language_meta.setAttribute(StaticStrings.NAME_ATTRIBUTE, meta_name);
     1329        search.appendChild(language_meta);
     1330    }
     1331    }
     1332
     1333    ////////////////////////////////////////////////
     1334    // search types
     1335    //////////////////////////////////////////////////
     1336
     1337    // Handling search types
     1338    static private void doSearchType(Document to, Node searchNode)
     1339    {
     1340    NodeList type_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SEARCHTYPE_ELEMENT);
     1341    int num_types = type_children.getLength();
     1342    String searchtype_str = "";
     1343    if (num_types < 1) {
     1344       
     1345        // not defined yet, add in default
     1346        searchtype_str = "plain,simpleform,advancedform";
     1347    }
     1348    else {
     1349       
     1350        for (int i = 0; i < num_types; i++) {
     1351           
     1352        Node e = type_children.item(i);
     1353        String t = ((Element) e).getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1354        if (i > 0) {
     1355               
     1356            searchtype_str += ",";
     1357        }
     1358        searchtype_str += t;
     1359        }
     1360    }
     1361    searchtype_str = searchtype_str.trim();
     1362
     1363    // pretend its a format statement
     1364    Element search_type_element = to.createElement(StaticStrings.FORMAT_STR);
     1365    search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT);
     1366    XMLTools.setNodeText(search_type_element, searchtype_str);
     1367    appendProperly(to.getDocumentElement(), search_type_element);
     1368
     1369    }
     1370
     1371
     1372    //Handle 'searchType' of collectionConfig.xml. In the internal structure, its also called 'searchType', eg. plain, form
     1373    static private void convertSearchType(Document from, Document to, Element search)
     1374    {
     1375    Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT);//searchType
     1376
     1377    if (e == null) return;
     1378
     1379    String searchtype_str = XMLTools.getNodeText(e).trim();
     1380
     1381    String[] types = searchtype_str.split(",");
     1382    for (int i = 0; i < types.length; i++) {
     1383       
     1384        Element search_type_element = to.createElement(StaticStrings.SEARCHTYPE_ELEMENT);
     1385        search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, types[i]);
     1386        search.appendChild(search_type_element);
     1387    }
     1388    }
     1389
     1390    /////////////////////////////////////////////
     1391    // search format
     1392    ///////////////////////////////////////////////
     1393
     1394
     1395    // Handling search format statement
     1396    static private void doSearchFormat(Document to, Node searchNode)
     1397    {
     1398    // THere is currently just one format element for search. HOwever, need to check for old config files which used to have <format name="searchTypes">
     1399    NodeList format_children = ((Element) searchNode).getElementsByTagName(StaticStrings.FORMAT_STR);
     1400    int format_nodes = format_children.getLength();
     1401    if (format_nodes < 1) return;
     1402
     1403    Element format = null;
     1404    for (int i = 0; i < format_nodes; i++) {
     1405       
     1406        Node e = format_children.item(i);
     1407        if (e.hasAttributes() == false) {
     1408           
     1409        //The format element for format statement has no attribute
     1410        format = (Element) e;
     1411        }
     1412    }
     1413    //format statement for search
     1414    if (format != null) {
     1415       
     1416        (to.getDocumentElement()).appendChild(doFormat(to, format, StaticStrings.SEARCH_STR));
     1417    }
     1418    }
     1419
     1420    //convert format statement for search
     1421    static private void convertSearchFormat(Document from, Document to, Element search)
     1422    {
     1423    Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCH_STR);
     1424
     1425    search.appendChild(convertFormat(to, e));
     1426
     1427    }
     1428
     1429    ///////////////////////////////////////////
     1430    // plugins
     1431    ///////////////////////////////////////////
     1432
     1433    // Transform plugins (pluginListNode) of collectionConfig.xml into the internal structure (i.e. Document to)
     1434    static private void doPluginsAndPlugout(Document to, Node importNode)
     1435    {
     1436    Element toElement = to.getDocumentElement();
     1437    Node pluginListNode = XMLTools.getChildByTagNameIndexed((Element) importNode, StaticStrings.PLUGINLIST_STR, 0);
     1438    if (pluginListNode == null) {
     1439           
     1440        System.out.println("There is no pluginlist set.");
    6701441           
    671            
    672     //          Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT);
    673     //          collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    674     //          collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    675            
    676     //          if(!lang.equals("")) {
    677     //              collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
    678     //              XMLTools.setNodeText(collectionmetadata, text);
    679     //          }
    680     //          if(!key.equals("")) {
    681     //              collectionmetadata.setAttribute(StaticStrings.KEY_ATTRIBUTE, key);
    682     //              String dictionary = item.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
    683     //              if(!dictionary.equals("")) {
    684     //              collectionmetadata.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary);
    685     //              }
    686     //          }
    687            
    688     //          appendProperly(toElement, collectionmetadata);
    689     //          }
    690     //         }
    691     //     toElement.appendChild(facets);
    692     // }
    693 
    694 
    695 
    696     static private void doGlobalFormat(Document to, Element from)
    697     {
    698         // look for a top level format element
    699         Element fe = (Element) XMLTools.getChildByTagName(from, StaticStrings.FORMAT_STR);
    700         to.getDocumentElement().appendChild(doFormat(to, fe, StaticStrings.GLOBAL_STR));
    701     }
    702 
    703     static private void doDisplayFormat(Document to, Element from)
    704     {
    705         //display element in the xml file
    706         Element de = (Element) XMLTools.getChildByTagName(from, StaticStrings.DISPLAY_STR);
    707         if (de == null)
    708         {
    709             return;
    710         }
    711         //format element in the display element
    712         Element fe = (Element) XMLTools.getChildByTagName(de, StaticStrings.FORMAT_STR);
    713 
    714         to.getDocumentElement().appendChild(doFormat(to, fe, StaticStrings.DISPLAY_STR));
    715     }
    716 
    717     //construct 'DefaultIndex' element in the internal structure from collectionConfig.xml
    718     static private void doDefaultIndex(Document to, Node searchNode)
    719     {
    720         Element toElement = to.getDocumentElement();
    721         Element default_index_element = to.createElement(StaticStrings.INDEX_DEFAULT_ELEMENT);
    722         default_index_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    723 
    724         Element e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE);//defaultIndex
    725         if (e == null)
    726         {
    727             return;
    728         }
    729         String index_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    730 
    731         boolean old_index = false;
    732         if (index_str.indexOf(StaticStrings.COLON_CHARACTER) != -1)
    733         {
    734             //The index is 'level:source tuplets' which is for mg. Take out 'level'
    735             old_index = true;
    736             default_index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER)));
    737             index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
    738         }
    739         else
    740         {
    741             default_index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, "");
    742         }
    743 
    744         //Each index may have a list of comma-separated strings.
    745         //split them into 'content' elements in the internal structure
    746         StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
    747         while (content_tokenizer.hasMoreTokens())
    748         {
    749             Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
    750             String content_str = content_tokenizer.nextToken();
    751             // 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.
    752             if (content_str.indexOf(StaticStrings.NS_SEP) == -1)
    753             {
    754                 if (content_str.equals(StaticStrings.TEXT_STR) || (!old_index && content_str.equals(StaticStrings.ALLFIELDS_STR)))
    755                 {
    756                     // in this case, do nothing
    757                 }
    758                 else
    759                 {
    760                     content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
    761                 }
    762             }
    763 
    764             content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
    765             default_index_element.appendChild(content_element);
    766             content_element = null;
    767         }
    768         appendProperly(toElement, default_index_element);
    769     } //doDefaultIndex
    770 
    771     // For mg, this method is still called, but make it 'assigned=false'
    772     static private void doDefaultLevel(Document to, Node searchNode)
    773     {
    774         Element toElement = to.getDocumentElement();
    775         Element default_index_option = to.createElement(StaticStrings.INDEXOPTION_DEFAULT_ELEMENT);
    776         default_index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVEL_DEFAULT_STR);
    777 
    778         Element e = (Element) XMLTools.getChildByTagName(searchNode, StaticStrings.LEVEL_DEFAULT_ELEMENT);
    779         if (e != null)
    780         {
    781             default_index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    782             String level = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    783             default_index_option.setAttribute(StaticStrings.VALUE_ATTRIBUTE, level);
    784         }
    785         else
    786         {
    787             //In the case of mg, there's no level! build a default one using 'assigned=false value=document'
    788             default_index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
    789             default_index_option.setAttribute(StaticStrings.VALUE_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
    790         }
    791         appendProperly(toElement, default_index_option);
    792     }
    793 
    794     // Transform plugins (pluginListNode) of collectionConfig.xml into the internal structure (i.e. Document to)
    795     static private void doPlugins(Document to, Node pluginListNode)
    796     {
    797         Element toElement = to.getDocumentElement();
    798         NodeList plugin_children = ((Element) pluginListNode).getElementsByTagName(StaticStrings.PLUGIN_STR);
    799         int plugin_nodes = plugin_children.getLength();
    800 
    801         if (plugin_nodes < 1)
    802         {
    803             return;
    804         }
    805 
     1442    } else {
     1443        NodeList plugin_children = ((Element) pluginListNode).getElementsByTagName(StaticStrings.PLUGIN_STR);
     1444        int plugin_nodes = plugin_children.getLength();
     1445
     1446        if (plugin_nodes >= 1) {
    8061447        for (int i = 0; i < plugin_nodes; i++)
    807         {
     1448            {
    8081449            Element e = (Element) plugin_children.item(i);
    8091450            String str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     
    8151456
    8161457            for (int j = 0; j < option_children.getLength(); j++)
    817             {
     1458                {
    8181459                Element el = (Element) option_children.item(j);
    8191460                String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    8201461                if (name_str.startsWith(StaticStrings.MINUS_CHARACTER))
    821                 {
     1462                    {
    8221463                    name_str = name_str.substring(1);
    823                 }
     1464                    }
    8241465                String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
    8251466                Element option_element = null;
    8261467
    8271468                if (name_str.equals("") && !value_str.equals(""))
    828                 {
     1469                    {
    8291470                    continue;
    830                 }
     1471                    }
    8311472
    8321473                option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
    8331474                option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    8341475                if (name_str.equals(StaticStrings.RECPLUG_STR) && value_str.equals(StaticStrings.USE_METADATA_FILES_ARGUMENT))
    835                 {
     1476                    {
    8361477                    continue; // ignore this option
    837                 }
     1478                    }
    8381479
    8391480                if (value_str != null)
    840                 {
     1481                    {
    8411482                    // Remove any speech marks appended in strings containing whitespace
    8421483                    if (value_str.startsWith(StaticStrings.SPEECH_CHARACTER) && value_str.endsWith(StaticStrings.SPEECH_CHARACTER))
    843                     {
     1484                        {
    8441485                        value_str = value_str.substring(1, value_str.length() - 1);
    845                     }
     1486                        }
    8461487                    if (name_str.equals(StaticStrings.METADATA_STR))
    847                     {
     1488                        {
    8481489                        // 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.
    8491490                        String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
    8501491                        value_str = "";
    8511492                        for (int k = 0; k <= values.length - 1; k++)
    852                         {
     1493                            {
    8531494                            if (values[k].indexOf(StaticStrings.NS_SEP) == -1)
    854                             {
     1495                                {
    8551496                                values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k];
    856                             }
     1497                                }
    8571498
    8581499                            if (k < values.length - 1)
    859                             {
     1500                                {
    8601501                                value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
    8611502
    862                             }
     1503                                }
    8631504                            else
    864                             {
     1505                                {
    8651506                                value_str = value_str + values[k];
    866                             }
    867                         }
    868                     }
     1507                                }
     1508                            }
     1509                        }
     1510                    }
     1511                if (!name_str.equals(""))
     1512                    {
     1513                    option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     1514                    }
     1515                if (!value_str.equals(""))
     1516                    {
     1517                    XMLTools.setNodeText(option_element, value_str);
     1518                    }
     1519                plugin_element.appendChild(option_element);
     1520
     1521                }
     1522
     1523            appendProperly(toElement, plugin_element);
     1524            }
     1525        } // if we had plugin nodes
     1526    }// else plguins not null
     1527   
     1528    // do the plugout element if there is one (flax)
     1529    Node plugout = XMLTools.getChildByTagNameIndexed((Element) importNode, StaticStrings.PLUGOUT_ELEMENT, 0);
     1530    if (plugout != null)
     1531        {
     1532        Element to_element = XMLTools.duplicateElement(to, (Element) plugout, true);
     1533        toElement.appendChild(to_element);
     1534        }
     1535       
     1536       
     1537    }
     1538
     1539
     1540    // Convert plugins in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to)
     1541    static private void convertPluginsAndPlugout(Document from, Document to)
     1542    {
     1543    Element import_element = to.createElement(StaticStrings.IMPORT_STR);
     1544    Element plugin_list_element = to.createElement(StaticStrings.PLUGINLIST_STR);
     1545
     1546    NodeList children = from.getDocumentElement().getElementsByTagName(StaticStrings.PLUGIN_ELEMENT);
     1547    int num_children = (children == null) ? 0 : children.getLength();
     1548    if (num_children == 0)
     1549        {
     1550        return;
     1551        }
     1552
     1553    for (int i = 0; i < num_children; i++)
     1554        {
     1555
     1556        Element child = (Element) children.item(i);
     1557        if (child.getAttribute(StaticStrings.SEPARATOR_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
     1558            {
     1559            continue;
     1560            }
     1561        if (child.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
     1562            {
     1563            continue;
     1564            }
     1565
     1566        String str = child.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
     1567        Element plugin_element = to.createElement(StaticStrings.PLUGIN_STR);
     1568        plugin_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, str);
     1569
     1570        NodeList option_children = child.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
     1571        for (int j = 0; j < option_children.getLength(); j++)
     1572            {
     1573            Element el = (Element) option_children.item(j);
     1574            if (!el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
     1575                {
     1576                continue;
     1577                }
     1578            String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1579            String value_str = XMLTools.getNodeText(el);
     1580
     1581            if (name_str == null && value_str == null)
     1582                {
     1583                continue;
     1584                }
     1585            Element option_element = to.createElement(StaticStrings.OPTION_STR);
     1586            if (name_str != null && name_str.equals(StaticStrings.METADATA_STR))
     1587                {
     1588
     1589                // 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.*)
     1590                String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
     1591                value_str = "";
     1592                for (int k = 0; k <= values.length - 1; k++)
     1593                    {
     1594                    if (values[k].startsWith(StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
     1595                        {
     1596                        values[k] = values[k].substring(StaticStrings.EXTRACTED_NAMESPACE.length());
     1597                        }
     1598
     1599                    if (k < values.length - 1)
     1600                        {
     1601                        value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
     1602                        }
     1603                    else
     1604                        {
     1605                        value_str = value_str + values[k];
     1606                        }
     1607                    }
     1608                }
     1609
     1610            if (!name_str.equals(""))
     1611                {
     1612                if (!name_str.startsWith(StaticStrings.MINUS_CHARACTER))
     1613                    {
     1614                    name_str = StaticStrings.MINUS_CHARACTER + name_str;
     1615                    }
     1616                option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     1617                }
     1618
     1619            if (!value_str.equals(""))
     1620                {
     1621                option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);
     1622                }
     1623
     1624            plugin_element.appendChild(option_element);
     1625            }//for loop ends
     1626
     1627        plugin_list_element.appendChild(plugin_element);
     1628        }//for loop ends
     1629
     1630    import_element.appendChild(plugin_list_element);
     1631
     1632    //do the plugout element (used by building flax collections)
     1633    Node plugout = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), StaticStrings.PLUGOUT_ELEMENT, 0);
     1634    if (plugout != null)
     1635        {
     1636        Element to_element = XMLTools.duplicateElement(to, (Element) plugout, true);
     1637        import_element.appendChild(to_element);
     1638        }
     1639
     1640    to.getDocumentElement().appendChild(import_element);
     1641    } // convertPlugins
     1642
     1643
     1644    // Browse**********************************************************
     1645
     1646    ////////////////////////////////////////////////////
     1647    // classifiers
     1648    ////////////////////////////////////////////////////
     1649
     1650
     1651    //Handle classifiers
     1652    static private void doClassifiers(Document to, Node browseNode)
     1653    {
     1654    Element toElement = to.getDocumentElement();
     1655    NodeList classifier_children = ((Element) browseNode).getElementsByTagName(StaticStrings.CLASSIFIER_STR);
     1656    int num_nodes = classifier_children.getLength();
     1657
     1658    if (num_nodes < 1)
     1659        {
     1660        return;
     1661        }
     1662
     1663    for (int i = 0; i < num_nodes; i++)
     1664        {
     1665        Element e = (Element) classifier_children.item(i);
     1666        String str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1667        Element classify_element = to.createElement(StaticStrings.CLASSIFY_ELEMENT);
     1668        classify_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, str);
     1669
     1670        String options_str = "";
     1671        NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR);
     1672        for (int j = 0; j < option_children.getLength(); j++)
     1673            {
     1674            Element el = (Element) option_children.item(j);
     1675            String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1676            options_str = options_str + ((name_str.equals("")) ? "" : (" " + name_str));
     1677            if (name_str.startsWith(StaticStrings.MINUS_CHARACTER))
     1678                {
     1679                name_str = name_str.substring(1);
     1680                }
     1681            String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
     1682            options_str = options_str + ((name_str.equals("")) ? "" : (" " + value_str));
     1683            Element option_element = null;
     1684
     1685            if (name_str.equals("") && !value_str.equals(""))
     1686                {
     1687                continue; //invalid condition
     1688                }
     1689
     1690            option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
     1691            option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     1692
     1693            if (!name_str.equals(""))
     1694                {
     1695                option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     1696                }
     1697
     1698            if (!value_str.equals("") && name_str.equals(StaticStrings.METADATA_STR))
     1699                {
     1700                // 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.
     1701                String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
     1702                value_str = "";
     1703                for (int k = 0; k <= values.length - 1; k++)
     1704                    {
     1705                    if (values[k].indexOf(StaticStrings.NS_SEP) == -1)
     1706                        {
     1707                        values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k];
     1708                        }
     1709                    else
     1710                        {
     1711                        MetadataElement metadata_element = MetadataTools.getMetadataElementWithName(values[k]);
     1712                        if (metadata_element != null)
     1713                            {
     1714                            values[k] = metadata_element.getDisplayName();
     1715                            }
     1716                        }
     1717                    if (k < values.length - 1)
     1718                        {
     1719                        value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
     1720                        }
     1721                    else
     1722                        {
     1723                        value_str = value_str + values[k];
     1724                        }
     1725                    }
     1726                }
     1727
     1728            if (value_str != null && !value_str.equals(""))
     1729                {
     1730                XMLTools.setNodeText(option_element, value_str);
     1731                }
     1732            classify_element.appendChild(option_element);
     1733
     1734            } // for each option
     1735           
     1736        //format element for this classifier
     1737        Element format = (Element) XMLTools.getChildByTagName(e, StaticStrings.FORMAT_STR);
     1738        if (format != null)
     1739            {
     1740            classify_element.appendChild(doFormat(to, format, null));
     1741            }
     1742
     1743        // Handling 'displayItem' element of this 'classifier' element - for now, just copy in and out so they don't get deleted
     1744        NodeList di_children = e.getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
     1745           
     1746        XMLTools.duplicateElementList(to, classify_element, di_children, true);
     1747                       
     1748        appendProperly(toElement, classify_element);
     1749        }
     1750
     1751    // default format statement for all classifiers
     1752    Element default_classifier_format = (Element) XMLTools.getChildByTagName(browseNode, StaticStrings.FORMAT_STR);
     1753
     1754    to.getDocumentElement().appendChild(doFormat(to, default_classifier_format, StaticStrings.BROWSE_STR));
     1755    } // doClassifiers
     1756
     1757    // Convert classify in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to)
     1758    static private void convertClassifier(Document from, Document to)
     1759    {
     1760    Element browse_element = to.createElement(StaticStrings.BROWSE_STR);
     1761    NodeList children = from.getDocumentElement().getElementsByTagName(StaticStrings.CLASSIFY_ELEMENT);
     1762
     1763    int num_children = (children == null) ? 0 : children.getLength();
     1764
     1765    if (num_children == 0) return;
     1766
     1767    for (int i = 0; i < num_children; i++)
     1768        {
     1769
     1770        Element child = (Element) children.item(i);
     1771        if (child.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
     1772
     1773        String str = child.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
     1774        Element classifier_element = to.createElement(StaticStrings.CLASSIFIER_STR);
     1775        classifier_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, str);
     1776
     1777        NodeList option_children = child.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
     1778        for (int j = 0; j < option_children.getLength(); j++)
     1779            {
     1780            Element el = (Element) option_children.item(j);
     1781            if (el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
     1782
     1783            String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     1784            String value_str = XMLTools.getNodeText(el);
     1785
     1786            if (name_str == null && value_str == null) continue;
     1787
     1788            Element option_element = to.createElement(StaticStrings.OPTION_STR);
     1789            if (name_str != null && name_str.equals(StaticStrings.METADATA_STR))
     1790                {
     1791
     1792                // 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.
     1793                String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
     1794                value_str = "";
     1795                for (int k = 0; k <= values.length - 1; k++)
     1796                    {
     1797                    if (values[k].startsWith(StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
     1798                        {
     1799                        values[k] = values[k].substring(StaticStrings.EXTRACTED_NAMESPACE.length());
     1800                        }
     1801                    else
     1802                        {
     1803                        MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(values[k]);
     1804                        if (metadata_element != null)
     1805                            {
     1806                            values[k] = metadata_element.getFullName();
     1807                            }
     1808                        }
     1809                    if (k < values.length - 1)
     1810                        {
     1811                        value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
     1812                        }
     1813                    else
     1814                        {
     1815                        value_str = value_str + values[k];
     1816                        }
     1817                    }
     1818                }
     1819
     1820            if (!name_str.equals(""))
     1821                {
     1822                if (!name_str.startsWith(StaticStrings.MINUS_CHARACTER))
     1823                    {
     1824                    name_str = StaticStrings.MINUS_CHARACTER + name_str;
     1825                    }
     1826                option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     1827                }
     1828
     1829            if (!value_str.equals(""))
     1830                {
     1831                option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);
     1832                }
     1833
     1834            classifier_element.appendChild(option_element);
     1835            }
     1836
     1837        //format element for this classifier
     1838        Element e = (Element) XMLTools.getChildByTagName(child, StaticStrings.FORMAT_STR);
     1839
     1840        if (e != null)
     1841            {
     1842            classifier_element.appendChild(convertFormat(to, e));
     1843            }
     1844
     1845        // Handling 'displayItem' element of this 'classifier' element - for now, just copy in and out so they don't get deleted
     1846        NodeList di_children = child.getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
     1847           
     1848        XMLTools.duplicateElementList(to, classifier_element, di_children, true);
     1849        browse_element.appendChild(classifier_element);
     1850        }
     1851
     1852    //convert default classifier format
     1853    Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.BROWSE_STR);
     1854    browse_element.appendChild(convertFormat(to, e));
     1855
     1856    to.getDocumentElement().appendChild(browse_element);
     1857    } // convertClassifier
     1858
     1859    // Display ********************************************************
     1860
     1861    static private void doDisplayFormat(Document to, Element from)
     1862    {
     1863    //display element in the xml file
     1864    Element de = (Element) XMLTools.getChildByTagName(from, StaticStrings.DISPLAY_STR);
     1865    if (de == null) return;
     1866
     1867    //format element in the display element
     1868    Element fe = (Element) XMLTools.getChildByTagName(de, StaticStrings.FORMAT_STR);
     1869
     1870    to.getDocumentElement().appendChild(doFormat(to, fe, StaticStrings.DISPLAY_STR));
     1871    }
     1872
     1873    //convert format statement for display of the documents
     1874    static private void convertDisplayFormat(Document from, Document to)
     1875    {
     1876    Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.DISPLAY_STR);
     1877    if (e == null) return;
     1878
     1879    Element display = to.createElement(StaticStrings.DISPLAY_STR);
     1880    display.appendChild(convertFormat(to, e));
     1881    to.getDocumentElement().appendChild(display);
     1882    }
     1883
     1884
     1885
     1886    // Other top level elements *****************************************
     1887
     1888
     1889    ////////////////////////////////////////////////////
     1890    // replaceList and replaceListRef
     1891    ///////////////////////////////////////////////////
     1892
     1893    /*
     1894     * replacelist currently not editable in GLI, just copy it in and back out
     1895     * again
     1896     */
     1897    static private void doReplaceList(Document to, Element from)
     1898    {
     1899    Element toElement = to.getDocumentElement();
     1900
     1901    Node rl_element = XMLTools.getChildByTagName(from, StaticStrings.REPLACELIST_STR);
     1902    if (rl_element == null) return;
     1903
     1904    Element to_element = XMLTools.duplicateElement(to, (Element) rl_element, true);
     1905    toElement.appendChild(to_element);
     1906    }
     1907
     1908    static private void convertReplaceList(Document from, Document to)
     1909    {
     1910    Element toElement = to.getDocumentElement();
     1911
     1912    Node rl_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.REPLACELIST_STR);
     1913    if (rl_element == null) return;
     1914
     1915    Element to_element = XMLTools.duplicateElement(to, (Element) rl_element, true);
     1916    toElement.appendChild(to_element);
     1917    }
     1918
     1919    static private void doReplaceListRef(Document to, Element from)
     1920    {
     1921    Element toElement = to.getDocumentElement();
     1922
     1923    NodeList replace_elements = from.getElementsByTagName(StaticStrings.REPLACELISTREF_STR);
     1924    XMLTools.duplicateElementList(to, toElement, replace_elements, true);
     1925    }
     1926
     1927
     1928    static private void convertReplaceListRef(Document from, Document to)
     1929    {
     1930    Element toElement = to.getDocumentElement();
     1931
     1932    NodeList replace_elements = from.getDocumentElement().getElementsByTagName(StaticStrings.REPLACELISTREF_STR);
     1933    XMLTools.duplicateElementList(to, toElement, replace_elements, true);
     1934    }
     1935
     1936    ///////////////////////////////////////////////
     1937    // service racks
     1938    ////////////////////////////////////////////////
     1939
     1940    /**
     1941     * serviceRackList is currently not editable in GLI - just copy it in from
     1942     * config file and write it out again.
     1943     */
     1944    static private void doServiceRackList(Document to, Element from)
     1945    {
     1946    Element toElement = to.getDocumentElement();
     1947
     1948    Node srl_element = XMLTools.getChildByTagName(from, StaticStrings.SERVICE_RACK_LIST_ELEMENT);
     1949    if (srl_element == null) return;
     1950
     1951    Element to_element = XMLTools.duplicateElement(to, (Element) srl_element, true);
     1952    toElement.appendChild(to_element);
     1953    }
     1954
     1955    static private void convertServiceRackList(Document from, Document to)
     1956    {
     1957    Element toElement = to.getDocumentElement();
     1958
     1959    Node srl_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.SERVICE_RACK_LIST_ELEMENT);
     1960    if (srl_element == null) return;
     1961
     1962    Element to_element = XMLTools.duplicateElement(to, (Element) srl_element, true);
     1963    toElement.appendChild(to_element);
     1964    }
     1965
     1966
     1967    ////////////////////////////////////////////////////
     1968    // Unknown elements
     1969    //////////////////////////////////////////////////////
     1970
     1971    // handle top level elements which GLI knows nothing about
     1972    // we store them internally in a Unknown element for easy access when
     1973    // we write them out.
     1974    static private void doUnknownElements(Document to, Element from)
     1975    {
     1976    Element toElement = to.getDocumentElement();
     1977    Element unknownElement = to.createElement(StaticStrings.UNKNOWN_ELEMENT);
     1978    toElement.appendChild(unknownElement);
     1979
     1980    Node child = from.getFirstChild();
     1981    while (child != null)
     1982        {
     1983        if (child.getNodeType() == Node.ELEMENT_NODE && !known_element_names.contains(child.getNodeName()))
     1984            {
     1985            unknownElement.appendChild(XMLTools.duplicateElement(to, (Element) child, true));
     1986            }
     1987        child = child.getNextSibling();
     1988        }
     1989
     1990    }
     1991
     1992    // just copy all children of Unknown element into output doc.
     1993    static private void convertUnknownElements(Document from, Document to)
     1994    {
     1995
     1996    Element toElement = to.getDocumentElement();
     1997    Node unknown_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.UNKNOWN_ELEMENT);
     1998
     1999    Node child = unknown_element.getFirstChild();
     2000    while (child != null)
     2001        {
     2002        Element to_element = XMLTools.duplicateElement(to, (Element) child, true);
     2003        toElement.appendChild(to_element);
     2004
     2005        child = child.getNextSibling();
     2006        }
     2007
     2008    }
     2009
     2010
     2011    //****************************************************************************
     2012
     2013    ///////////////////////////////////////////////////
     2014    // Helper functions
     2015    /////////////////////////////////////////////////
     2016
     2017
     2018    // /////////////////////////////////////////////
     2019    // base code for index/sort/facet
     2020    ///////////////////////////////////////////////
     2021
     2022    static private void doBaseSearchPartInternal(Document to, Node searchNode, String new_parts_str, String new_part_str, String existing_part_str, String type, boolean is_mg_index) {
     2023
     2024    Element toElement = to.getDocumentElement();
     2025    Element parts_element = to.createElement(new_parts_str);//<Indexes> / <Facets> / <Sorts>
     2026    parts_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     2027
     2028    NodeList part_children = ((Element) searchNode).getElementsByTagName(existing_part_str);//index/facet/sort
     2029    int num_nodes = part_children.getLength();
     2030   
     2031    for (int i = 0; i < num_nodes; i++)
     2032        {
     2033
     2034        Element part_element = to.createElement(new_part_str);//<Index> INDEX_ELEMENT
     2035        Element e = (Element) part_children.item(i);
     2036        String part_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     2037        String part_str_display = part_str;//for creating searchmetadata for this index
     2038        if (!is_mg_index) {
     2039            // look for options inside the index, eg
     2040            // <option name="solrfieldtype" value="text_ja" />
     2041            String options_str = "";
     2042            NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR);
     2043            if(option_children != null) {
     2044            for (int j = 0; j < option_children.getLength(); j++) {
     2045                Element el = (Element) option_children.item(j);
     2046           
     2047                String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     2048                options_str = options_str + ((name_str.equals("")) ? "" : (" " + name_str));
     2049           
     2050                String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
     2051                options_str = options_str + ((name_str.equals("")) ? "" : (" " + value_str));
     2052           
     2053                if (name_str.equals("") && !value_str.equals(""))
     2054                {
     2055                    continue; //invalid condition
    8692056                }
    870                 if (!name_str.equals(""))
     2057           
     2058                Element option_element = null;
     2059                option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
     2060                option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     2061           
     2062                if (!name_str.equals(""))
    8712063                {
    872                     option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     2064                    option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    8732065                }
    874                 if (!value_str.equals(""))
     2066                if (value_str != null && !value_str.equals(""))
    8752067                {
    876                     XMLTools.setNodeText(option_element, value_str);
     2068                    XMLTools.setNodeText(option_element, value_str);
    8772069                }
    878                 plugin_element.appendChild(option_element);
    879 
     2070                part_element.appendChild(option_element);
    8802071            }
    881 
    882             appendProperly(toElement, plugin_element);
     2072            }
    8832073        }
    8842074
    885     }
    886 
    887     //Handle classifiers
    888     static private void doClassifiers(Document to, Node browseNode)
    889     {
    890         Element toElement = to.getDocumentElement();
    891         NodeList classifier_children = ((Element) browseNode).getElementsByTagName(StaticStrings.CLASSIFIER_STR);
    892         int num_nodes = classifier_children.getLength();
    893 
    894         if (num_nodes < 1)
    895         {
    896             return;
     2075        // Handling 'index' element
     2076        // Double check colon separated style
     2077        int colon_index = part_str.indexOf(StaticStrings.COLON_CHARACTER);
     2078        if (!is_mg_index && colon_index != -1 )   {
     2079            System.err.println("Something is wrong! the "+existing_part_str+" should NOT be level:source tuplets style.");
     2080            part_str = part_str.substring(colon_index + 1);
     2081           
    8972082        }
    898 
    899         for (int i = 0; i < num_nodes; i++)
    900         {
    901             Element e = (Element) classifier_children.item(i);
    902             String str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    903             Element classify_element = to.createElement(StaticStrings.CLASSIFY_ELEMENT);
    904             classify_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, str);
    905 
    906             String options_str = "";
    907             NodeList option_children = e.getElementsByTagName(StaticStrings.OPTION_STR);
    908             for (int j = 0; j < option_children.getLength(); j++)
    909             {
    910                 Element el = (Element) option_children.item(j);
    911                 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    912                 options_str = options_str + ((name_str.equals("")) ? "" : (" " + name_str));
    913                 if (name_str.startsWith(StaticStrings.MINUS_CHARACTER))
    914                 {
    915                     name_str = name_str.substring(1);
    916                 }
    917                 String value_str = el.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
    918                 options_str = options_str + ((name_str.equals("")) ? "" : (" " + value_str));
    919                 Element option_element = null;
    920 
    921                 if (name_str.equals("") && !value_str.equals(""))
    922                 {
    923                     continue; //invalid condition
    924                 }
    925 
    926                 option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
    927                 option_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    928 
    929                 if (!name_str.equals(""))
    930                 {
    931                     option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    932                 }
    933 
    934                 if (!value_str.equals("") && name_str.equals(StaticStrings.METADATA_STR))
    935                 {
    936                     // 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.
    937                     String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
    938                     value_str = "";
    939                     for (int k = 0; k <= values.length - 1; k++)
    940                     {
    941                         if (values[k].indexOf(StaticStrings.NS_SEP) == -1)
    942                         {
    943                             values[k] = StaticStrings.EXTRACTED_NAMESPACE + values[k];
    944                         }
    945                         else
    946                         {
    947                             MetadataElement metadata_element = MetadataTools.getMetadataElementWithName(values[k]);
    948                             if (metadata_element != null)
    949                             {
    950                                 values[k] = metadata_element.getDisplayName();
    951                             }
    952                         }
    953                         if (k < values.length - 1)
    954                         {
    955                             value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
    956                         }
    957                         else
    958                         {
    959                             value_str = value_str + values[k];
    960                         }
    961                     }
    962                 }
    963 
    964                 if (value_str != null && !value_str.equals(""))
    965                 {
    966                     XMLTools.setNodeText(option_element, value_str);
    967                 }
    968                 classify_element.appendChild(option_element);
    969 
    970             } // for each option
     2083        if (is_mg_index) {
     2084            if (colon_index == -1) {
     2085           
     2086            // MG, and it doesn't contain ':' character
     2087            System.err.println("Something is wrong! the index should be level:source tuplets.");
     2088            // assume document level
     2089            part_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
     2090            }
     2091            else {
     2092            part_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, part_str.substring(0, colon_index));
    9712093           
    972             //format element for this classifier
    973             Element format = (Element) XMLTools.getChildByTagName(e, StaticStrings.FORMAT_STR);
    974             if (format != null)
    975             {
    976                 classify_element.appendChild(doFormat(to, format, null));
     2094            part_str = part_str.substring(part_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
     2095            }
     2096        }
     2097        //Each index/sort/facet may have a list of comma-separated strings.
     2098        //split them into 'content' elements in the internal structure
     2099        StringTokenizer content_tokenizer = new StringTokenizer(part_str, StaticStrings.COMMA_CHARACTER);
     2100        while (content_tokenizer.hasMoreTokens())
     2101            {
     2102            // Replace part_str to be qualified name, eg. dc.Subject and keywords insread of dc.Subject.             
     2103           
     2104            Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
     2105            String content_str = content_tokenizer.nextToken();
     2106            // Since the contents of parts 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.
     2107            if (content_str.indexOf(StaticStrings.NS_SEP) == -1 && !(content_str.equals(StaticStrings.TEXT_STR) || content_str.equals(StaticStrings.ALLFIELDS_STR) || content_str.equals(StaticStrings.NONE_STR) || content_str.equals(StaticStrings.RANK_STR)))
     2108                {
     2109                content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
     2110                }
     2111            content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
     2112            part_element.appendChild(content_element);
     2113            content_element = null;
     2114            } //while ends
     2115
     2116        parts_element.appendChild(part_element);
     2117       
     2118        part_element = null;
     2119
     2120        // Handling 'displayItem' element of this 'index' element
     2121        // 'e' is the parent element 'index' of 'displayItem' element
     2122        doSearchDisplayItems(to, e, part_str_display, type);
     2123       
     2124        } // for loop ends
     2125    toElement.appendChild(parts_element);
     2126    //return toElement;
     2127
     2128    } // doBaseSearchPartInternal
     2129
     2130    // this code is used for indexes, sortfields, facets
     2131    // internal_parts_str = Indexes/Sorts/Facets - internal doc
     2132    // internal_part_str = Index/Sort/Facet - internal doc
     2133    // output_part_str = index/sortfield/facet - what goes in collectionConfig
     2134
     2135    private static void convertBaseSearchPartInternal(Document from, Document to, Element search, String internal_parts_str, String internal_part_str, String output_part_str, String searchmeta_type, boolean is_mg_index)
     2136    {
     2137   
     2138    Element source = from.getDocumentElement();
     2139    Element parts= XMLTools.getNamedElement(source, internal_parts_str, StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     2140    if (parts == null) return;
     2141
     2142    NodeList part_elements = parts.getElementsByTagName(internal_part_str);
     2143    int part_elements_length = part_elements.getLength();
     2144   
     2145    if (part_elements_length == 0) return;
     2146
     2147    for (int j = 0; j < part_elements_length; j++) {
     2148       
     2149        Element part_element = (Element) part_elements.item(j);
     2150        if (part_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
     2151     
     2152        Element part_ele = to.createElement(output_part_str);//part
     2153     
     2154        // Used for creating displayItem for this element 'part_ele' further below
     2155        // full_part_names contain 'ex.'
     2156        String full_part_name = ""; //why this string and below strin buffer??
     2157        String level_str = "";
     2158     
     2159        StringBuffer part_value = new StringBuffer();
     2160        if (is_mg_index) {
     2161        level_str = part_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE);
     2162        part_value.append(level_str).append(StaticStrings.COLON_CHARACTER);
     2163        full_part_name = level_str + StaticStrings.COLON_CHARACTER;
     2164        }
     2165
     2166        NodeList content_elements = part_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
     2167        int content_elements_length = content_elements.getLength();
     2168     
     2169        for (int k = 0; k < content_elements_length; k++) {
     2170           
     2171        Element content_element = (Element) content_elements.item(k);
     2172        if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
     2173
     2174        String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     2175       
     2176        full_part_name = full_part_name + name_str;
     2177        if (k < content_elements_length - 1) {
     2178               
     2179            full_part_name = full_part_name + StaticStrings.COMMA_CHARACTER;
     2180        }
     2181       
     2182        if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) {
     2183               
     2184            name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
     2185        }
     2186       
     2187        part_value.append(name_str);
     2188        name_str = null;
     2189        // Make it comma separated string
     2190        if (k < content_elements_length - 1) {
     2191               
     2192            part_value.append(StaticStrings.COMMA_CHARACTER);
     2193        }
     2194        content_element = null;
     2195        } //k for loop ends
     2196
     2197        // ok to here
     2198        String temp_str = part_value.toString();
     2199        part_ele.setAttribute(StaticStrings.NAME_ATTRIBUTE, temp_str);
     2200     
     2201        // Now constructing 'displayItem' element for this 'part_ele' element
     2202        // The part names in the searchmetadata elements in the internal structure are not the names that
     2203        // are used in the content elements (i.e. ex.Source or dc.Subject and keywords), but the names that are
     2204        // in the configuration files (i.e. Source or dc.Subject)
     2205        ArrayList searchmetadata_list = getMatchingSearchMetaElements(source, temp_str, searchmeta_type);
     2206   
     2207        if (searchmetadata_list == null) {
     2208           
     2209        //try the full name, i.e. with 'ex.'
     2210        searchmetadata_list = getMatchingSearchMetaElements(source, full_part_name, searchmeta_type);
     2211        }
     2212     
     2213        if (searchmetadata_list != null) {
     2214           
     2215       
     2216        for (int k = 0; k < searchmetadata_list.size(); k++) {
     2217               
     2218            Element searchmetadata = (Element) searchmetadata_list.get(k);
     2219            if (searchmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
     2220
     2221            Element displayItem = constructDisplayItem(searchmetadata, to);
     2222         
     2223            part_ele.appendChild(displayItem);
     2224        }
     2225        }
     2226   
     2227        if (!is_mg_index) {
     2228        // deal with any <option name='' value=''> children of this part
     2229        // e.g. <option name='solrfieldtype' value='text_es'>
     2230        NodeList option_children = part_element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
     2231        for (int k = 0; k < option_children.getLength(); k++) {
     2232           
     2233            Element el = (Element) option_children.item(k);
     2234            if (el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
     2235
     2236            String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     2237            String value_str = XMLTools.getNodeText(el);
     2238         
     2239            if (name_str == null && value_str == null) continue;
     2240            Element option_element = to.createElement(StaticStrings.OPTION_STR);
     2241            if (!name_str.equals("")) {
     2242            option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     2243            }
     2244            if (!value_str.equals("")) { // or no value attribute without name attribute?
     2245            option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);     
     2246            }
     2247            part_ele.appendChild(option_element);
     2248        } // for each option
     2249        }
     2250        search.appendChild(part_ele);
     2251     
     2252    } //for loop ends
     2253
     2254    } // convertBaseSearchPartInternal
     2255
     2256    // find searchMetas (which become display items) matching meta_name and meta_type
     2257    static private ArrayList getMatchingSearchMetaElements(Element source, String meta_name, String meta_type) {
     2258    return XMLTools.getNamedElementList(source, StaticStrings.SEARCHMETADATA_ELEMENT, new String[]{StaticStrings.NAME_ATTRIBUTE, StaticStrings.TYPE_ATTRIBUTE}, new String[]{ meta_name, meta_type});
     2259
     2260    }
     2261
     2262    //
     2263    static private void convertBaseDefaultSearchPartInternal(Document from, Document to, Element search, String internal_default_part_str, String output_default_part_str, boolean is_mg_index)
     2264    {
     2265    Element source = from.getDocumentElement();
     2266
     2267    Element default_part_element = (Element) XMLTools.getChildByTagName(source, internal_default_part_str);
     2268    if (default_part_element == null)
     2269        {
     2270        return;
     2271        }
     2272
     2273    String level_str = "";
     2274    if (is_mg_index) {
     2275        level_str = default_part_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE);
     2276        // Debugging purposes
     2277        if (level_str.equals("")) {
     2278       
     2279        System.out.println("Bug: DefaultIndex should have its level attribute not empty. Setting it to document");
     2280        level_str = StaticStrings.DOCUMENT_STR;
     2281        }
     2282    }
     2283    NodeList content_elements = default_part_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
     2284    int content_elements_length = content_elements.getLength();
     2285
     2286    // Don't output anything if no parts are set
     2287    if (content_elements_length == 0) return;
     2288
     2289    String part_str = "";
     2290
     2291    if (is_mg_index) {
     2292   
     2293        //combine level with indexes
     2294        part_str = level_str + StaticStrings.COLON_CHARACTER;
     2295    }
     2296
     2297    for (int k = 0; k < content_elements_length; k++) {
     2298       
     2299        Element content_element = (Element) content_elements.item(k);
     2300        if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR)) continue;
     2301
     2302        String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     2303
     2304        if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) {
     2305           
     2306        name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
     2307        }
     2308
     2309        part_str = part_str + name_str;
     2310
     2311        // Make it comma separated string
     2312        if (k < content_elements_length - 1) {
     2313           
     2314        part_str = part_str + StaticStrings.COMMA_CHARACTER;
     2315        }
     2316        content_element = null;
     2317    }//for loop ends
     2318   
     2319    Element default_part = to.createElement(output_default_part_str);
     2320    default_part.setAttribute(StaticStrings.NAME_ATTRIBUTE, part_str);
     2321    search.appendChild(default_part);
     2322
     2323    } // convertBaseDefaultSearchPartInternal
     2324   
     2325
     2326    ////////////////////////////////
     2327    // handling format statement code
     2328    ////////////////////////////////
     2329
     2330    static private Element doFormat(Document to, Element format, String name_str)
     2331    {
     2332    Element format_element = to.createElement(StaticStrings.FORMAT_STR);
     2333    if (name_str != null) {
     2334       
     2335        format_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     2336    }
     2337
     2338    // Don't write out an empty format statement of <format/> (i.e. format has no child nodes)
     2339    // as this will end up embedded in another format statement as <format><format/><format />
     2340    // This doubling up of format stmts will then prevent GLI from opening the collection again.
     2341    if (format != null && format.hasChildNodes()) {
     2342        // not an empty format statement
     2343        String gsf_text = XMLTools.xmlNodeToString(format);
     2344
     2345        //We don't want the <format> elements in the string
     2346        int startFormatIndex = gsf_text.indexOf(StaticStrings.FORMAT_START_TAG) + StaticStrings.FORMAT_START_TAG.length();
     2347        int endFormatIndex = gsf_text.lastIndexOf(StaticStrings.FORMAT_END_TAG);
     2348        gsf_text = gsf_text.substring(startFormatIndex, endFormatIndex);
     2349
     2350        XMLTools.setNodeText(format_element, gsf_text);
     2351    }
     2352    return format_element;
     2353    }
     2354
     2355    static private Element convertFormat(Document to, Element e)
     2356    {
     2357    String format_str = XMLTools.getNodeText(e);
     2358    Element format = to.createElement(StaticStrings.FORMAT_STR);
     2359    //XMLTools.copyAllChildren (format, e);
     2360    XMLTools.setNodeText(format, format_str);
     2361    return format;
     2362    }
     2363
     2364    ///////////////////////////////////////////////////////////////
     2365    // helper code for display items
     2366    ///////////////////////////////////////////////////////////////
     2367
     2368
     2369    static private void doSearchDisplayItems(Document to, Element from, String name, String type) {
     2370    Element toElement = to.getDocumentElement();
     2371    // Node displayItemListNode = XMLTools.getChildByTagNameIndexed(from, StaticStrings.DISPLAYITEMLIST_STR, 0);
     2372    // if (displayItemListNode == null) {
     2373    //     return;
     2374    // }
     2375    NodeList displayItems = from.getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
     2376    for (int i=0; i<displayItems.getLength(); i++) {
     2377        Element item = (Element) displayItems.item(i);
     2378        Element search_meta = processSingleDisplayItem(to, item, name, type);
     2379        if (search_meta == null) {
     2380        System.err.println("search meta is null "+name+", "+type);
     2381        }else {
     2382        toElement.appendChild(search_meta);
     2383        }
     2384    }
     2385    }
     2386
     2387    /** convert displayItem (item) into CollectionMeta (if type is null) or SearchMeta (if type is not null). Use new_name if not null. */
     2388    static private Element processSingleDisplayItem(Document to, Element item, String new_name, String type) {
     2389    // special case for collection description - is allowed html
     2390    boolean isCollDescr = new_name.equals(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
     2391
     2392    // Sadly, XMLTools.getNodeText(item) returns empty for any HTML in displayItem
     2393    // so we have to do it the hard way
     2394    // We can't take a shortcut like format statements, which also need to keep their
     2395    // tags intact in collConfig.xml, because we know in advance the format tag name
     2396    // Can't guess at what html tag names the user uses, and there may be several at
     2397    // the same level inside collDescription (e.g. multiple paragraphs)
     2398    String text = isCollDescr ? preserveHTMLInDescriptionDisplayItem(item)
     2399        : XMLTools.getNodeText(item); // else as before for all other displayItems
     2400   
     2401    //If there is nothing to display, don't bother creating the element
     2402    // Either lang or key should be set. If key set, no text node needed.
     2403    // if lang set, should have textnode. Check if it's meaningful
     2404    if (item.hasAttribute(StaticStrings.LANG_STR) && text.equals("")) {
     2405        return null;
     2406    }
     2407   
     2408    // get the value in 'lang=langcode' or 'key=keyname'
     2409    // We can have either a key attribute (with optional dictionary attribute, else dictionary is implicit)
     2410    // OR we can have a lang attr, with the nodetext containing the actual display string.
     2411    String lang = item.getAttribute(StaticStrings.LANG_STR);
     2412    String key = item.getAttribute(StaticStrings.KEY_ATTRIBUTE);
     2413    String name;
     2414    if (new_name != null) {
     2415        name = new_name;
     2416    } else {
     2417        name = item.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     2418    }
     2419
     2420
     2421    Element e;
     2422    if (type ==null) {
     2423        e = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT);
     2424    } else {
     2425        e = to.createElement(StaticStrings.SEARCHMETADATA_ELEMENT);
     2426    }
     2427    e.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
     2428    e.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
     2429   
     2430    if (type != null) {
     2431        e.setAttribute(StaticStrings.TYPE_ATTRIBUTE, type);
     2432    }
     2433    if(!lang.equals("")) {
     2434        e.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
     2435        text = text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
     2436        XMLTools.setNodeText(e, text);
     2437       
     2438    } else if(!key.equals("")) {
     2439        e.setAttribute(StaticStrings.KEY_ATTRIBUTE, key);
     2440        String dictionary = item.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
     2441        if(!dictionary.equals("")) {
     2442        e.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary);
     2443        }
     2444    }
     2445    return e;
     2446    }
     2447
     2448
     2449    /** Construct s <displayItem> element from e which is a CollectionMeta or a SearchMeta
     2450    i.e. internal DOM -> config file
     2451    */
     2452    static private Element constructDisplayItem(Element e, Document to, String name)
     2453    {
     2454    String lang_string = e.getAttribute(StaticStrings.LANGUAGE_ATTRIBUTE);
     2455    String key_string = e.getAttribute(StaticStrings.KEY_ATTRIBUTE);
     2456    String dictionary_string = e.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
     2457    String text = XMLTools.getNodeText(e);
     2458
     2459    Element displayItem = to.createElement(StaticStrings.DISPLAYITEM_STR);
     2460    displayItem.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
     2461
     2462    if(!lang_string.equals("")) {
     2463        displayItem.setAttribute(StaticStrings.LANG_STR, lang_string);
     2464        if (name.equals(StaticStrings.DESCRIPTION_STR)) {
     2465        // special case for collection description string, which is allowed html tags
     2466        text = Codec.transform(text, Codec.REINSTATE_HTML_TAGS);
     2467        }
     2468        XMLTools.setNodeText(displayItem, text);
     2469    }
     2470    if(!key_string.equals("")) {
     2471        displayItem.setAttribute(StaticStrings.KEY_ATTRIBUTE, key_string);
     2472        if(!dictionary_string.equals("")) {
     2473        displayItem.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary_string);
     2474        }
     2475    }
     2476    return displayItem;
     2477    }
     2478
     2479    static private Element constructDisplayItem(Element e, Document to)
     2480    {   
     2481    return constructDisplayItem(e, to, StaticStrings.NAME_ATTRIBUTE);
     2482    }
     2483
     2484
     2485
     2486    ////////////////////////////////////////////////////////////////////
     2487    // DOM tree manipulation
     2488    ///////////////////////////////////////////////////////////////////
     2489
     2490    // Append the element son to the element mother in the appropriate position.
     2491    static private void appendProperly(Element mother, Element son)
     2492    {
     2493    if (son == null)
     2494        return;
     2495
     2496    Node reference_node = findInsertionPoint(mother, son);
     2497    if (reference_node != null) {
     2498        mother.insertBefore(son, reference_node);
     2499    }
     2500    else {
     2501        mother.appendChild(son);
     2502    }
     2503    }
     2504
     2505    /**
     2506     * Find the best insertion position for the given DOM Element
     2507     * 'target_element' in the DOM Element 'document_element'. This should try
     2508     * to match command tag, and if found should then try to group by name or
     2509     * type (eg CollectionMeta), or append to end is no such grouping exists (eg
     2510     * Plugins). Failing a command match it will check against the command order
     2511     * for the best insertion location.
     2512     *
     2513     * @param target_element
     2514     *            the command Element to be inserted
     2515     * @return the Element which the given command should be inserted before, or
     2516     *         null to append to end of list
     2517     */
     2518    static private Node findInsertionPoint(Element document_element, Element target_element)
     2519    {
     2520    ///ystem.err.println("Find insertion point: " + target_element.getNodeName());
     2521    String target_element_name = target_element.getNodeName();
     2522
     2523    // Try to find commands with the same tag.
     2524    NodeList matching_elements = document_element.getElementsByTagName(target_element_name);
     2525    // If we found matching elements, then we have our most likely insertion location, so check within for groupings
     2526    if (matching_elements.getLength() != 0) {
     2527       
     2528        ///ystem.err.println("Found matching elements.");
     2529        // Only CollectionMeta are grouped.
     2530        if (target_element_name.equals(StaticStrings.COLLECTIONMETADATA_ELEMENT)) {
     2531        ///ystem.err.println("Dealing with collection metadata");
     2532        // 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.
     2533        // So if the command to be added is special add it immediately after any other special command
     2534        if (target_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) {
     2535                 
     2536            int index = 0;
     2537            Element matched_element = (Element) matching_elements.item(index);
     2538            Element sibling_element = (Element) matched_element.getNextSibling();
     2539            while (sibling_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) {
     2540                   
     2541            index++;
     2542            matched_element = (Element) matching_elements.item(index);
     2543            sibling_element = (Element) matched_element.getNextSibling();
     2544            }
     2545            if (sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) {
     2546                   
     2547            Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
     2548            document_element.insertBefore(newline_element, sibling_element);
     2549            }
     2550            return sibling_element;
     2551        }
     2552        // Otherwise try to find a matching 'name' and add after the last one in that group.
     2553        else {
     2554               
     2555            int index = 0;
     2556            target_element_name = target_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     2557            boolean found = false;
     2558            // Skip all of the special metadata
     2559            Element matched_element = (Element) matching_elements.item(index);
     2560            while (matched_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)) {
     2561                   
     2562            index++;
     2563            matched_element = (Element) matching_elements.item(index);
     2564            }
     2565            // Begin search
     2566            while (!found && matched_element != null) {
     2567                   
     2568            if (matched_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(target_element_name)) {
     2569                       
     2570                found = true;
    9772571            }
    978 
    979             // Handling 'displayItem' element of this 'classifier' element - for now, just copy in and out so they don't get deleted
    980             NodeList di_children = e.getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
    981            
    982             XMLTools.duplicateElementList(to, classify_element, di_children, true);
    983                        
    984             appendProperly(toElement, classify_element);
     2572            else {
     2573                   
     2574                index++;
     2575                matched_element = (Element) matching_elements.item(index);
     2576            }
     2577            }
     2578            // If we found a match, we need to continue checking until we find the last name match.
     2579            if (found) {
     2580                   
     2581            index++;
     2582            Element previous_sibling = matched_element;
     2583            Element sibling_element = (Element) matching_elements.item(index);
     2584            while (sibling_element != null && sibling_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(target_element_name)) {
     2585   
     2586                previous_sibling = sibling_element;
     2587                index++;
     2588                sibling_element = (Element) matching_elements.item(index);
     2589            }
     2590            // 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!
     2591            return previous_sibling.getNextSibling();
     2592            }
     2593            // If not found we just add after last metadata element
     2594            else {
     2595                   
     2596            Element last_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
     2597            return last_element.getNextSibling();
     2598            }
    9852599        }
    9862600
    987         // default format statement for all classifiers
    988         Element default_classifier_format = (Element) XMLTools.getChildByTagName(browseNode, StaticStrings.FORMAT_STR);
    989 
    990         to.getDocumentElement().appendChild(doFormat(to, default_classifier_format, StaticStrings.BROWSE_STR));
    991     }
    992 
    993     static private Element doFormat(Document to, Element format, String name_str)
    994     {
    995         Element format_element = to.createElement(StaticStrings.FORMAT_STR);
    996         if (name_str != null)
    997         {
    998             format_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
     2601        }
     2602        else {
     2603         
     2604        ///ystem.err.println("Not dealing with collection meta.");
     2605        Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
     2606        // 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)
     2607        Node sibling_element = matched_element.getNextSibling();
     2608        if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) {
     2609               
     2610            Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
     2611            document_element.insertBefore(newline_element, sibling_element);
    9992612        }
    1000 
    1001         // Don't write out an empty format statement of <format/> (i.e. format has no child nodes)
    1002         // as this will end up embedded in another format statement as <format><format/><format />
    1003         // This doubling up of format stmts will then prevent GLI from opening the collection again.
    1004         if (format != null && format.hasChildNodes())
    1005         { // not an empty format statement
    1006             String gsf_text = XMLTools.xmlNodeToString(format);
    1007 
    1008             //We don't want the <format> elements in the string
    1009             int startFormatIndex = gsf_text.indexOf(StaticStrings.FORMAT_START_TAG) + StaticStrings.FORMAT_START_TAG.length();
    1010             int endFormatIndex = gsf_text.lastIndexOf(StaticStrings.FORMAT_END_TAG);
    1011             gsf_text = gsf_text.substring(startFormatIndex, endFormatIndex);
    1012 
    1013             XMLTools.setNodeText(format_element, gsf_text);
     2613        return sibling_element; // Note that this may be null
     2614        }
     2615    }
     2616    ///ystem.err.println("No matching elements found.");
     2617    // Locate where this command is in the ordering
     2618    int command_index = -1;
     2619    for (int i = 0; command_index == -1 && i < CollectionConfiguration.COMMAND_ORDER.length; i++) {
     2620       
     2621        if (CollectionConfiguration.COMMAND_ORDER[i].equals(target_element_name)) {
     2622   
     2623        command_index = i;
     2624        }
     2625    }
     2626    ///ystem.err.println("Command index is: " + command_index);
     2627    // Now move forward, checking for existing elements in each of the preceeding command orders.
     2628    int preceeding_index = command_index - 1;
     2629    ///ystem.err.println("Searching before the target command.");
     2630    while (preceeding_index >= 0) {
     2631       
     2632        matching_elements = document_element.getElementsByTagName(CollectionConfiguration.COMMAND_ORDER[preceeding_index]);
     2633        // If we've found a match
     2634        if (matching_elements.getLength() > 0) {
     2635           
     2636        // We add after the last element
     2637        Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
     2638        // 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)
     2639        Node sibling_element = matched_element.getNextSibling();
     2640        if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) {
     2641               
     2642            Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
     2643            document_element.insertBefore(newline_element, sibling_element);
    10142644        }
    1015         return format_element;
    1016     }
    1017 
    1018     // Handling 'subcollection' elements in 'search' element of 'collectionConfig.xml'
    1019     static private void doSubcollection(Document to, Node searchNode)
    1020     {
    1021         Element toElement = to.getDocumentElement();
    1022         NodeList sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SUBCOLLECTION_STR);
    1023         int sub_nodes = sub_children.getLength();
    1024 
    1025         // There is no subcollection
    1026         if (sub_nodes < 1)
    1027         {
    1028             return;
     2645        return sibling_element; // Note that this may be null
     2646        }
     2647        preceeding_index--;
     2648    }
     2649    // If all that fails, we now move backwards through the commands
     2650    int susceeding_index = command_index + 1;
     2651    ///ystem.err.println("Searching after the target command.");
     2652    while (susceeding_index < CollectionConfiguration.COMMAND_ORDER.length) {
     2653
     2654        matching_elements = document_element.getElementsByTagName(CollectionConfiguration.COMMAND_ORDER[susceeding_index]);
     2655        // If we've found a match
     2656        if (matching_elements.getLength() > 0) {
     2657           
     2658        // We add before the first element
     2659        Element matched_element = (Element) matching_elements.item(0);
     2660        // 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)
     2661        Node sibling_element = matched_element.getPreviousSibling();
     2662        if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT)) {
     2663               
     2664            Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
     2665            document_element.insertBefore(newline_element, sibling_element);
    10292666        }
    1030 
    1031         for (int i = 0; i < sub_nodes; i++)
    1032         {
    1033             Element sub_child = (Element) sub_children.item(i);
    1034             String name_str = sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1035             String filter_str = sub_child.getAttribute(StaticStrings.FILTER_ATTRIBUTE);
    1036 
    1037             // filter_str is in the form '<! (if set)><metadata>/<metadata value>/<flag (if any)>'
    1038 
    1039             int pos = filter_str.indexOf(StaticStrings.SEPARATOR_CHARACTER);
    1040             String meta_str = "";
    1041             String meta_value_str = "";
    1042             String clude_str = "";
    1043             String flag_str = "";
    1044             if (pos == -1)
    1045             {
    1046 
    1047                 meta_str = meta_value_str = filter_str;
    1048                 clude_str = StaticStrings.INCLUDE_STR;
    1049             }
    1050             else
    1051             {
    1052                 clude_str = StaticStrings.INCLUDE_STR;
    1053                 if (filter_str.startsWith(StaticStrings.EXCLAMATION_CHARACTER))
    1054                 {
    1055                     clude_str = StaticStrings.EXCLUDE_STR;
    1056                     // Peel off "!"
    1057                     filter_str = filter_str.substring(StaticStrings.EXCLAMATION_CHARACTER.length());
    1058                 }
    1059 
    1060                 String[] strs = filter_str.split(StaticStrings.SEPARATOR_CHARACTER);
    1061                 if (strs[0] != null && strs[0] != "")
    1062                 {
    1063                     meta_str = strs[0];
    1064                 }
    1065                 if (!meta_str.equals(StaticStrings.FILENAME_STR) && meta_str.indexOf(StaticStrings.NS_SEP) == -1)
    1066                 {
    1067                     meta_str = StaticStrings.EXTRACTED_NAMESPACE + meta_str;
    1068                 }
    1069 
    1070                 if (strs[1] != null && strs[1] != "")
    1071                 {
    1072                     meta_value_str = strs[1];
    1073                 }
    1074                 if (strs.length > 2)
    1075                 {
    1076                     //This means there has been set a flag
    1077                     if (strs[2] != null && strs[2] != "")
    1078                     {
    1079                         flag_str = strs[2];
    1080                     }
    1081                 }
    1082             }
    1083             Element subcollection_element = to.createElement(StaticStrings.SUBCOLLECTION_ELEMENT);
    1084             subcollection_element.setAttribute(StaticStrings.NAME_STR, name_str);
    1085             subcollection_element.setAttribute(StaticStrings.CONTENT_ATTRIBUTE, meta_str);
    1086             subcollection_element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, clude_str);
    1087             if (flag_str != "")
    1088             {
    1089                 subcollection_element.setAttribute(StaticStrings.OPTIONS_ATTRIBUTE, flag_str);
    1090             }
    1091             XMLTools.setNodeText(subcollection_element, meta_value_str);
    1092 
    1093             toElement.appendChild(subcollection_element);
    1094         }
    1095     } // doSubCollection
    1096 
    1097     //Handle levels (document, section). In the internal structure, the element is called 'IndexOption'
    1098     static private void doLevel(Document to, Node searchNode)
    1099     {
    1100         Element toElement = to.getDocumentElement();
    1101         NodeList level_children = ((Element) searchNode).getElementsByTagName(StaticStrings.LEVEL_ATTRIBUTE);
    1102         int level_nodes = level_children.getLength();
    1103 
    1104         // it's mg, there's no level. So we construct a default 'indexOption' in the internal structure
    1105         if (level_nodes < 1)
    1106         {
    1107             Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
    1108             index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
    1109             index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVELS_STR);
    1110 
    1111             Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
    1112             option_element.setAttribute(StaticStrings.NAME_STR, StaticStrings.DOCUMENT_STR);
    1113             index_option.appendChild(option_element);
    1114 
    1115             appendProperly(toElement, index_option);
    1116 
    1117             return;
    1118         }
    1119 
    1120         Element index_options = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
    1121         index_options.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1122         index_options.setAttribute(StaticStrings.NAME_STR, StaticStrings.LEVELS_STR);
    1123 
    1124         for (int i = 0; i < level_nodes; i++)
    1125         {
    1126             Element level_element = (Element) level_children.item(i);
    1127             String level_str = level_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1128             Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
    1129             option_element.setAttribute(StaticStrings.NAME_STR, level_str);
    1130             index_options.appendChild(option_element);
    1131 
    1132             // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'level' element
    1133                         ArrayList collectionmetadata_list = doDisplayItemList(to, level_element, StaticStrings.NAME_STR, level_str, SearchMeta.TYPE_LEVEL);
    1134                         appendArrayList(toElement, collectionmetadata_list);
    1135                 }
    1136                 appendProperly(toElement, index_options);
    1137         } // doLevel
    1138 
    1139   // ArrayList displayItem_list = XMLTools.getNamedElementList(level_element, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR);
    1140             // if (displayItem_list == null)
    1141             // {
    1142             //  return;
    1143             // }
    1144             // for (int j = 0; j < displayItem_list.size(); j++)
    1145             // {
    1146             //  Element item = (Element) displayItem_list.get(j);
    1147             //  String text = XMLTools.getNodeText(item);
    1148 
    1149             //  //If there is nothing to display, don't bother creating the element
    1150             //  // Either lang or key should be set. If lang set, then should have textnode.
    1151             //  if (item.hasAttribute(StaticStrings.LANG_STR) && text.equals("")) {
    1152             //      continue;
    1153             //  }
    1154                
    1155             //  String lang = item.getAttribute(StaticStrings.LANG_ATTRIBUTE);
    1156             //  String key = item.getAttribute(StaticStrings.KEY_ATTRIBUTE);
    1157            
    1158             //  Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT);
    1159             //  collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1160             //  collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, level_str);
    1161                         //         collectionmetadata.setAttribute("type", "level");
    1162 
    1163             //  if(!lang.equals("")) {
    1164             //      collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
    1165             //      XMLTools.setNodeText(collectionmetadata, text);
    1166             //  }
    1167                
    1168             //  if(!key.equals("")) {
    1169             //      collectionmetadata.setAttribute(StaticStrings.KEY_ATTRIBUTE, key);
    1170             //      String dictionary = item.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
    1171             //      if(!dictionary.equals("")) {
    1172             //      collectionmetadata.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary);
    1173             //      }
    1174             //  }
    1175 
    1176             //  appendProperly(toElement, collectionmetadata);
    1177             // }
    1178         //}
    1179        
    1180                 //}
    1181 
    1182     //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.
    1183     static private void doIndexSubcollection(Document to, Node searchNode)
    1184     {
    1185         Element toElement = to.getDocumentElement();
    1186         NodeList index_sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SUBCOLLECTION_INDEX_ELEMENT);
    1187         int num_nodes = index_sub_children.getLength();
    1188 
    1189         // there is no subcollection index
    1190         if (num_nodes < 1)
    1191         {
    1192             return;
    1193         }
    1194 
    1195         Element subcollection_indexes = to.createElement(StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT);
    1196 
    1197         for (int i = 0; i < num_nodes; i++)
    1198         {
    1199             Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);
    1200             Element index_sub_child = (Element) index_sub_children.item(i);
    1201             String name_str = index_sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1202 
    1203             // name_str is in the form of comma separated strings, each of which is a subcollection filter name
    1204             String[] filters = name_str.split(StaticStrings.COMMA_CHARACTER);
    1205             for (int j = 0; j < filters.length; j++)
    1206             {
    1207 
    1208                 Element content_element = to.createElement(StaticStrings.CONTENT_ELEMENT);
    1209                 content_element.setAttribute(StaticStrings.NAME_STR, filters[j]);
    1210                 index_element.appendChild(content_element);
    1211             }
    1212             subcollection_indexes.appendChild(index_element);
    1213 
    1214             // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'indexSubcollection' element
    1215                         ArrayList collectionmetadata_list = doDisplayItemList(to, index_sub_child, StaticStrings.NAME_STR, name_str, SearchMeta.TYPE_PARTITION); // todo should be name_str???
    1216             appendArrayList(toElement, collectionmetadata_list);
    1217                 }
    1218                 appendProperly(toElement, subcollection_indexes);
    1219     } // doIndexSubCollection
    1220             // ArrayList displayItem_list = XMLTools.getNamedElementList(index_sub_child, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR);
    1221             // if (displayItem_list == null)
    1222             // {
    1223             //  // there is no display item for this element
    1224             //  continue;
    1225             // }
    1226             // for (int j = 0; j < displayItem_list.size(); j++)
    1227             // {
    1228             //  Element item = (Element) displayItem_list.get(j);
    1229             //  String text = XMLTools.getNodeText(item);
    1230                
    1231 
    1232             //  //If there is nothing to display, don't bother creating the element
    1233             //  // Either lang or key should be set. If key set, no textnode.
    1234             //  // if lang set, should have textnode. Check if it's meaningful
    1235             //  if (item.hasAttribute(StaticStrings.LANG_STR) && text.equals(""))
    1236             //  {
    1237             //      continue;
    1238             //  }
    1239 
    1240             //  String lang = item.getAttribute(StaticStrings.LANG_ATTRIBUTE);
    1241             //  String key = item.getAttribute(StaticStrings.KEY_ATTRIBUTE);
    1242 
    1243             //  Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT);
    1244             //  collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1245             //  collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    1246                         //         collectionmetadata.setAttribute("type", "subcollection");
    1247             //  if(!lang.equals("")) {
    1248             //      collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
    1249             //      XMLTools.setNodeText(collectionmetadata, text);
    1250             //  }
    1251             //  if(!key.equals("")) {
    1252             //      collectionmetadata.setAttribute(StaticStrings.KEY_ATTRIBUTE, key);
    1253             //      String dictionary = item.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
    1254             //      if(!dictionary.equals("")) {
    1255             //      collectionmetadata.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary);
    1256             //      }
    1257             //  }
    1258                
    1259             //  appendProperly(toElement, collectionmetadata);
    1260             // }
    1261                         //}
    1262 
    1263 
    1264     //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.
    1265     static private void doIndexLanguage(Document to, Node searchNode)
    1266     {
    1267         Element toElement = to.getDocumentElement();
    1268         NodeList index_sub_children = ((Element) searchNode).getElementsByTagName(StaticStrings.LANGUAGE_INDEX_ELEMENT);
    1269         int num_nodes = index_sub_children.getLength();
    1270 
    1271         // there is no subcollection index
    1272         if (num_nodes < 1)
    1273         {
    1274             return;
    1275         }
    1276 
    1277         Element language_indexes = to.createElement(StaticStrings.LANGUAGES_ELEMENT);
    1278 
    1279         for (int i = 0; i < num_nodes; i++)
    1280         {
    1281             Element language_element = to.createElement(StaticStrings.LANGUAGE_ELEMENT);
    1282             Element index_sub_child = (Element) index_sub_children.item(i);
    1283             String name_str = index_sub_child.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1284             language_element.setAttribute(StaticStrings.NAME_STR, name_str);
    1285             language_indexes.appendChild(language_element);
    1286 
    1287             // Contructing 'collectionmetadata' elements from the 'displayItem' of this 'indexLanguage' element
    1288                         ArrayList collectionmetadata_list = doDisplayItemList(to, index_sub_child, StaticStrings.NAME_STR, name_str, SearchMeta.TYPE_LANGUAGE); // todo should be name_str???
    1289             appendArrayList(toElement, collectionmetadata_list);
    1290 
    1291                 }
    1292         toElement.appendChild(language_indexes);
    1293     } //doIndexLanguage
    1294 
    1295             // ArrayList displayItem_list = XMLTools.getNamedElementList(index_sub_child, StaticStrings.DISPLAYITEM_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.NAME_STR);
    1296             // if (displayItem_list == null)
    1297             // {
    1298             //  // there is no display item for this element
    1299             //  continue;
    1300             // }
    1301             // for (int j = 0; j < displayItem_list.size(); j++)
    1302             // {
    1303             //  Element item = (Element) displayItem_list.get(j);
    1304             //  String text = XMLTools.getNodeText(item);
    1305             //  //If there is nothing to display, don't bother creating the element
    1306             //  // Either lang or key should be set. If key set, no textnode.
    1307             //  // if lang set, should have textnode. Check if it's meaningful
    1308             //  if (item.hasAttribute(StaticStrings.LANG_STR) && text.equals(""))
    1309             //  {
    1310             //      continue;
    1311             //  }
    1312 
    1313             //  // get the value in 'lang=langcode' or 'key=keyname'
    1314             //  // We can have either a key attribute (with optional dictionary attribute, else dictionary is implicit)
    1315             //  // OR we can have a lang attr, with the nodetext containing the actual display strin.g
    1316             //  String lang = item.getAttribute(StaticStrings.LANG_ATTRIBUTE);
    1317             //  String key = item.getAttribute(StaticStrings.KEY_ATTRIBUTE);
    1318 
    1319 
    1320             //  Element collectionmetadata = to.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT);
    1321             //  collectionmetadata.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1322             //  collectionmetadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    1323                         //         collectionmetadata.setAttribute("type", "lang");
    1324 
    1325             //  if(!lang.equals("")) {
    1326             //      collectionmetadata.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, lang);
    1327             //      XMLTools.setNodeText(collectionmetadata, text);
    1328             //  }
    1329             //  if(!key.equals("")) {
    1330             //      collectionmetadata.setAttribute(StaticStrings.KEY_ATTRIBUTE, key);
    1331             //      String dictionary = item.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
    1332             //      if(!dictionary.equals("")) {
    1333             //      collectionmetadata.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary);
    1334             //      }
    1335             //  }
    1336 
    1337             //  appendProperly(toElement, collectionmetadata);
    1338             // }
    1339 
    1340     // Handling search types
    1341     static private void doSearchType(Document to, Node searchNode)
    1342     {
    1343         NodeList type_children = ((Element) searchNode).getElementsByTagName(StaticStrings.SEARCHTYPE_ELEMENT);
    1344         int num_types = type_children.getLength();
    1345         String searchtype_str = "";
    1346         if (num_types < 1)
    1347         {
    1348             // not defined yet, add in default
    1349             searchtype_str = "plain,simpleform,advancedform";
    1350         }
    1351         else
    1352         {
    1353             for (int i = 0; i < num_types; i++)
    1354             {
    1355                 Node e = type_children.item(i);
    1356                 String t = ((Element) e).getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1357                 if (i > 0)
    1358                 {
    1359                     searchtype_str += ",";
    1360                 }
    1361                 searchtype_str += t;
    1362             }
    1363         }
    1364         searchtype_str = searchtype_str.trim();
    1365 
    1366         // pretend its a format statement
    1367         Element search_type_element = to.createElement(StaticStrings.FORMAT_STR);
    1368         search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT);
    1369         XMLTools.setNodeText(search_type_element, searchtype_str);
    1370         appendProperly(to.getDocumentElement(), search_type_element);
    1371 
    1372     }
    1373 
    1374     // Handling search format statement
    1375     static private void doSearchFormat(Document to, Node searchNode)
    1376     {
    1377         // THere is currently just one format element for search. HOwever, need to check for old config files which used to have <format name="searchTypes">
    1378         NodeList format_children = ((Element) searchNode).getElementsByTagName(StaticStrings.FORMAT_STR);
    1379         int format_nodes = format_children.getLength();
    1380         if (format_nodes < 1)
    1381         {
    1382             return;
    1383         }
    1384         Element format = null;
    1385         for (int i = 0; i < format_nodes; i++)
    1386         {
    1387             Node e = format_children.item(i);
    1388             if (e.hasAttributes() == false)
    1389             {
    1390                 //The format element for format statement has no attribute
    1391                 format = (Element) e;
    1392             }
    1393         }
    1394         //format statement for search
    1395         if (format != null)
    1396         {
    1397             (to.getDocumentElement()).appendChild(doFormat(to, format, StaticStrings.SEARCH_STR));
    1398         }
    1399     }
    1400 
    1401     // Handling defaultIndexLanguage and languageMetadata in collectionConfig.xml ('elementNameFrom'); in the internal structure, they are called 'DefaultLanguage' and 'LanguageMetadata' ('elementNameTo') respectively.
    1402     // Converting from collectionConfig.xml to the internal xml structure.
    1403     static private void doLanguageMetadata(Document to, Node searchNode)
    1404     {
    1405         Element toElement = to.getDocumentElement();
    1406         String elementNameFrom = StaticStrings.LANGUAGE_METADATA_ELEMENT_STR;
    1407         String elementNameTo = StaticStrings.LANGUAGE_METADATA_ELEMENT;
    1408         Node from_element = XMLTools.getChildByTagName(searchNode, elementNameFrom);
    1409         if (from_element == null)
    1410         {
    1411             return; // such an element not found
    1412         }
    1413 
    1414         Element to_element = to.createElement(elementNameTo);
    1415 
    1416         String name_str = ((Element) from_element).getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1417         if (name_str.indexOf(StaticStrings.NS_SEP) == -1)
    1418         {
    1419             name_str = StaticStrings.EXTRACTED_NAMESPACE + name_str;
    1420         }
    1421         to_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    1422         to_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1423 
    1424         toElement.appendChild(to_element);
    1425     }
    1426 
    1427     static private void doReplaceListRef(Document to, Element from)
    1428     {
    1429         Element toElement = to.getDocumentElement();
    1430 
    1431         NodeList replace_elements = from.getElementsByTagName(StaticStrings.REPLACELISTREF_STR);
    1432         XMLTools.duplicateElementList(to, toElement, replace_elements, true);
    1433     }
    1434 
    1435     //  int num_elems = replace_elements.getLength();
    1436     //  if (num_elems < 1)
    1437     //  {
    1438     //      return;
    1439     //  }
    1440     //  for (int i = 0; i < num_elems; i++)
    1441     //  {
    1442     //      Element to_element = XMLTools.duplicateElement(to, (Element) replace_elements.item(i), true);
    1443     //      toElement.appendChild(to_element);
    1444     //  }
    1445     // }
    1446 
    1447     static private void convertReplaceListRef(Document from, Document to)
    1448     {
    1449         Element toElement = to.getDocumentElement();
    1450 
    1451         NodeList replace_elements = from.getDocumentElement().getElementsByTagName(StaticStrings.REPLACELISTREF_STR);
    1452         XMLTools.duplicateElementList(to, toElement, replace_elements, true);
    1453     }
    1454 
    1455     // int num_elems = replace_elements.getLength();
    1456     // if (num_elems < 1)
    1457     // {
    1458     //  return;
    1459     // }
    1460     // for (int i = 0; i < num_elems; i++)
    1461     // {
    1462     //  Element to_element = XMLTools.duplicateElement(to, (Element) replace_elements.item(i), true);
    1463     //  toElement.appendChild(to_element);
    1464     // }
    1465     //  }
    1466 
    1467     /*
    1468      * replacelist currently not editable in GLI, just copy it in and back out
    1469      * again
    1470      */
    1471     static private void doReplaceList(Document to, Element from)
    1472     {
    1473         Element toElement = to.getDocumentElement();
    1474 
    1475         Node rl_element = XMLTools.getChildByTagName(from, StaticStrings.REPLACELIST_STR);
    1476         if (rl_element == null)
    1477         {
    1478             return; // such an element not found
    1479         }
    1480 
    1481         Element to_element = XMLTools.duplicateElement(to, (Element) rl_element, true);
    1482         toElement.appendChild(to_element);
    1483     }
    1484 
    1485     static private void convertReplaceList(Document from, Document to)
    1486     {
    1487         Element toElement = to.getDocumentElement();
    1488 
    1489         Node rl_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.REPLACELIST_STR);
    1490         if (rl_element == null)
    1491         {
    1492             return; // such an element not found
    1493         }
    1494 
    1495         Element to_element = XMLTools.duplicateElement(to, (Element) rl_element, true);
    1496         toElement.appendChild(to_element);
    1497     }
    1498 
    1499     /**
    1500      * serviceRackList is currently not editable in GLI - just copy it in from
    1501      * config file and write it out again.
    1502      */
    1503     static private void doServiceRackList(Document to, Element from)
    1504     {
    1505         Element toElement = to.getDocumentElement();
    1506 
    1507         Node srl_element = XMLTools.getChildByTagName(from, StaticStrings.SERVICE_RACK_LIST_ELEMENT);
    1508         if (srl_element == null)
    1509         {
    1510             return; // such an element not found
    1511         }
    1512 
    1513         Element to_element = XMLTools.duplicateElement(to, (Element) srl_element, true);
    1514         toElement.appendChild(to_element);
    1515     }
    1516 
    1517     static private void convertServiceRackList(Document from, Document to)
    1518     {
    1519         Element toElement = to.getDocumentElement();
    1520 
    1521         Node srl_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.SERVICE_RACK_LIST_ELEMENT);
    1522         if (srl_element == null)
    1523         {
    1524             return; // such an element not found
    1525         }
    1526 
    1527         Element to_element = XMLTools.duplicateElement(to, (Element) srl_element, true);
    1528         toElement.appendChild(to_element);
    1529     }
    1530 
    1531     static private void doDefaultIndexLanguage(Document to, Node searchNode)
    1532     {
    1533         Element toElement = to.getDocumentElement();
    1534         String elementNameFrom = StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT;
    1535         String elementNameTo = StaticStrings.LANGUAGE_DEFAULT_ELEMENT;
    1536         Node from_element = XMLTools.getChildByTagName(searchNode, elementNameFrom);
    1537         if (from_element == null)
    1538         {
    1539             return; // such an element not found
    1540         }
    1541 
    1542         Element to_element = to.createElement(elementNameTo);
    1543 
    1544         String name_str = ((Element) from_element).getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1545         to_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    1546         to_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1547 
    1548         toElement.appendChild(to_element);
    1549     }
    1550 
    1551     //Handle 'indexOption' (i.e. casefold, stem etc). In the internal structure, the element is called 'IndexOption'
    1552     static private void doIndexOption(Document to, Node searchNode)
    1553     {
    1554         Element toElement = to.getDocumentElement();
    1555         //Node index_option_node = XMLTools.getChildByTagName(searchNode, StaticStrings.INDEXOPTION_STR);
    1556         //if (index_option_node == null)
    1557         //{
    1558         //  return;
    1559         //}
    1560         //NodeList option_children = ((Element) index_option_node).getElementsByTagName(StaticStrings.OPTION_STR);
    1561         NodeList option_children = ((Element) searchNode).getElementsByTagName(StaticStrings.INDEXOPTION_STR);
    1562         int num_options = option_children.getLength();
    1563 
    1564         // for lucene, there is no 'indexOption'. We build a default 'indexOption' and 'assigned=false' in case the user switches to mg or mgpp
    1565         if (num_options < 1)
    1566         {
    1567             Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
    1568             index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
    1569             index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR);
    1570             String[] option_str = { StaticStrings.CASEFOLD_OPTION_STR, StaticStrings.STEM_OPTION_STR };
    1571             for (int i = 0; i < option_str.length; i++)
    1572             {
    1573                 Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
    1574                 option_element.setAttribute(StaticStrings.NAME_STR, option_str[i]);
    1575                 index_option.appendChild(option_element);
    1576             }
    1577             appendProperly(toElement, index_option);
    1578             return;
    1579         }
    1580 
    1581         Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
    1582         index_option.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1583         index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR);
    1584 
    1585         for (int i = 0; i < num_options; i++)
    1586         {
    1587             String option_str = ((Element) option_children.item(i)).getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1588             Element option_element = to.createElement(StaticStrings.OPTION_ELEMENT);
    1589             option_element.setAttribute(StaticStrings.NAME_STR, option_str);
    1590             index_option.appendChild(option_element);
    1591         }
    1592         appendProperly(toElement, index_option);
    1593     }
    1594 
    1595     static private Element doBuildType(Document to, String att_value)
    1596     {
    1597 
    1598         //construct 'BuildType' element
    1599         Element element = to.createElement(StaticStrings.BUILDTYPE_ELEMENT);
    1600         element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR);
    1601         element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR);
    1602         element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1603         element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
    1604 
    1605         XMLTools.setNodeText(element, att_value);
    1606 
    1607         return element;
    1608     }
    1609 
    1610     static private Element doDatabaseType(Document to, String att_value)
    1611     {
    1612 
    1613         //construct 'DatabaseType' element
    1614         Element element = to.createElement(StaticStrings.DATABASETYPE_ELEMENT);
    1615         element.setAttribute(StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR);
    1616         element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, StaticStrings.ENGLISH_LANGUAGE_STR);
    1617         element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1618         element.setAttribute(StaticStrings.SPECIAL_ATTRIBUTE, StaticStrings.TRUE_STR);
    1619 
    1620         XMLTools.setNodeText(element, att_value);
    1621 
    1622         return element;
    1623     }
    1624 
    1625     // Convert 'description', 'smallicon' etc.
    1626     static private void convertDisplayItemList(Document from, Document to)
    1627     {
    1628         Element displayItemList = to.createElement(StaticStrings.DISPLAYITEMLIST_STR);
    1629         Element destination = to.getDocumentElement();
    1630 
    1631         // certain special collectionmeta elements should have different names
    1632         // as displayItems in the collectionConfig.xml than they do in memory
    1633         Map attributeMap = new HashMap(4);
    1634         attributeMap.put(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR, StaticStrings.DESCRIPTION_STR);
    1635         attributeMap.put(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR, StaticStrings.NAME_STR);
    1636         attributeMap.put(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR, StaticStrings.SMALLICON_STR);
    1637         attributeMap.put(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR, StaticStrings.ICON_STR);
    1638 
    1639         NodeList e_list = from.getDocumentElement().getElementsByTagName(StaticStrings.COLLECTIONMETADATA_ELEMENT);
    1640         // if such elements don't exist, don't bother
    1641         if (e_list != null)
    1642         {
    1643 
    1644             for (int j = 0; j < e_list.getLength(); j++)
    1645             {
    1646                 Element e = (Element) e_list.item(j);
    1647                 if (e.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    1648                 {
    1649                     continue;
    1650                 }
    1651                                 // if we have a type, then we are index/sort/facet etc
    1652                                 if (!e.getAttribute(StaticStrings.TYPE_ATTRIBUTE).equals("")) {
    1653                                   continue;
    1654                                 }
    1655                
    1656                 String text = XMLTools.getNodeText(e);
    1657                 String lang = e.getAttribute(StaticStrings.LANGUAGE_ATTRIBUTE);
    1658                 String key = e.getAttribute(StaticStrings.KEY_ATTRIBUTE);
    1659                 String dictionary = e.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
    1660 
    1661                 String name_value = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1662                 String name_mapping = (String) attributeMap.get(name_value);
    1663                 if (name_mapping != null)
    1664                 {
    1665                     name_value = name_mapping;
    1666                 }
    1667 
    1668                 Element displayItem = constructElement(StaticStrings.DISPLAYITEM_STR, name_value, StaticStrings.LANG_STR, lang, text, StaticStrings.KEY_ATTRIBUTE, key, StaticStrings.DICTIONARY_ATTRIBUTE, dictionary, to);
    1669                 //Element displayItem = constructDisplayItem(e, to, name_value);
    1670                 displayItemList.appendChild(displayItem);
    1671             }
    1672 
    1673         }
    1674         destination.appendChild(displayItemList);
    1675     }
    1676 
    1677     // This method creates a DisplayItem element of the type of 'to' by using the ingredients from the element 'e'
    1678     static private Element constructDisplayItem(Element e, Document to, String name)
    1679     {
    1680         String lang_string = e.getAttribute(StaticStrings.LANGUAGE_ATTRIBUTE);
    1681         String key_string = e.getAttribute(StaticStrings.KEY_ATTRIBUTE);
    1682         String dictionary_string = e.getAttribute(StaticStrings.DICTIONARY_ATTRIBUTE);
    1683         String text = XMLTools.getNodeText(e);
    1684 
    1685         Element displayItem = to.createElement(StaticStrings.DISPLAYITEM_STR);
    1686         displayItem.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
    1687 
    1688         if(!lang_string.equals("")) {
    1689             displayItem.setAttribute(StaticStrings.LANG_STR, lang_string);
    1690             XMLTools.setNodeText(displayItem, text);
    1691         }
    1692         if(!key_string.equals("")) {
    1693             displayItem.setAttribute(StaticStrings.KEY_ATTRIBUTE, key_string);
    1694             if(!dictionary_string.equals("")) {
    1695             displayItem.setAttribute(StaticStrings.DICTIONARY_ATTRIBUTE, dictionary_string);
    1696             }
    1697         }
    1698         return displayItem;
    1699     }
    1700 
    1701     static private Element constructDisplayItem(Element e, Document to)
    1702     {   
    1703         return constructDisplayItem(e, to, StaticStrings.NAME_ATTRIBUTE);
    1704     }
    1705 
    1706   static private void convertSecurity(Document from, Document to)
    1707     {
    1708       Node security = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), StaticStrings.SECURITY_STR, 0);
    1709       if (security != null)
    1710         {
    1711           Element to_element = XMLTools.duplicateElement(to, (Element) security, true);
    1712           to.getDocumentElement().appendChild(to_element);
    1713        
    1714         }
    1715     }
    1716     static private void convertMetadataList(Document from, Document to)
    1717     {
    1718         Element metadataList = to.createElement(StaticStrings.METADATALIST_STR);
    1719         Element destination = to.getDocumentElement();
    1720 
    1721         String[] ele_names = { StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT };
    1722         String[] att_names = { StaticStrings.COLLECTIONMETADATA_CREATOR_STR, StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR, StaticStrings.COLLECTIONMETADATA_PUBLIC_STR };
    1723         for (int i = 0; i < ele_names.length; i++)
    1724         {
    1725             Element e = XMLTools.getNamedElement(from.getDocumentElement(), ele_names[i], StaticStrings.NAME_ATTRIBUTE, att_names[i]);
    1726             if (e == null)
    1727             {
    1728                 continue;
    1729             }
    1730             String text = XMLTools.getNodeText(e);
    1731             Element metadata = to.createElement(StaticStrings.METADATA_STR);
    1732             metadata.setAttribute(StaticStrings.NAME_ATTRIBUTE, att_names[i]);
    1733             metadata.setAttribute(StaticStrings.LANG_STR, StaticStrings.ENGLISH_LANGUAGE_STR);
    1734             XMLTools.setNodeText(metadata, text);
    1735             metadataList.appendChild(metadata);
    1736         }
    1737 
    1738         destination.appendChild(metadataList);
    1739     }
    1740 
    1741     // This method creates an element with the name 'element_name' of the type of 'to' by using the other three strings
    1742     static private Element constructElement(String element_name, String name_value, String lang_att, String lang_value, String text, String key_att, String key, String dict_att, String dictionary, Document to)
    1743     {
    1744         Element e = to.createElement(element_name);
    1745         e.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    1746         e.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_value);
    1747 
    1748         if(!lang_value.equals("")) {
    1749             e.setAttribute(lang_att, lang_value);
    1750 
    1751             // Handle collection description displayItems specially again: these are allowed to go
    1752             // into collConfig.xml file containing tag markers, to preserve any user-added html
    1753             // in a format easy to edit in collConfig (rather than filled with entities)
    1754             if(element_name.equals(StaticStrings.DISPLAYITEM_STR) && name_value.equals(StaticStrings.DESCRIPTION_STR)) {
    1755             //System.err.println("@@@ Before internal coll description converted to collConfig:\n" + text);
    1756             // special case again: the following is going to be undone shortly again,
    1757             // mirroring the inverse of going from collConfig.xml to internal collConfig format
    1758             // upon parse()
    1759             // but this is what works to preserve the ampersands for output to XML context
    1760             // past the next line
    1761             //text = text.replaceAll("&", "&amp;");
    1762             //text = Codec.transform(text, Codec.ESCAPEDHTML_TO_UNESCAPED);
    1763             text = Codec.transform(text, Codec.REINSTATE_HTML_TAGS);           
    1764             //System.err.println("@@@ After coll description converted to collConfig:\n" + text);
    1765             }
    1766             XMLTools.setNodeText(e, text);
    1767 
    1768         }       
    1769         if(!key.equals("")) {
    1770             e.setAttribute(key_att, key);
    1771             if(!dictionary.equals("")) {
    1772             e.setAttribute(dict_att, dictionary);
    1773             }
    1774         }
    1775 
    1776         return e;
    1777     }
    1778 
    1779     // Convert classify in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to)
    1780     static private void convertClassifier(Document from, Document to)
    1781     {
    1782         Element browse_element = to.createElement(StaticStrings.BROWSE_STR);
    1783         NodeList children = from.getDocumentElement().getElementsByTagName(StaticStrings.CLASSIFY_ELEMENT);
    1784 
    1785         int num_children = (children == null) ? 0 : children.getLength();
    1786 
    1787         if (num_children == 0)
    1788         {
    1789             return;
    1790         }
    1791 
    1792         for (int i = 0; i < num_children; i++)
    1793         {
    1794 
    1795             Element child = (Element) children.item(i);
    1796             if (child.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    1797             {
    1798                 continue;
    1799             }
    1800             String str = child.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
    1801             Element classifier_element = to.createElement(StaticStrings.CLASSIFIER_STR);
    1802             classifier_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, str);
    1803 
    1804             NodeList option_children = child.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
    1805             for (int j = 0; j < option_children.getLength(); j++)
    1806             {
    1807                 Element el = (Element) option_children.item(j);
    1808                 if (el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    1809                 {
    1810                     continue;
    1811                 }
    1812                 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1813                 String value_str = XMLTools.getNodeText(el);
    1814 
    1815                 if (name_str == null && value_str == null)
    1816                 {
    1817                     continue;
    1818                 }
    1819                 Element option_element = to.createElement(StaticStrings.OPTION_STR);
    1820                 if (name_str != null && name_str.equals(StaticStrings.METADATA_STR))
    1821                 {
    1822 
    1823                     // 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.
    1824                     String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
    1825                     value_str = "";
    1826                     for (int k = 0; k <= values.length - 1; k++)
    1827                     {
    1828                         if (values[k].startsWith(StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
    1829                         {
    1830                             values[k] = values[k].substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    1831                         }
    1832                         else
    1833                         {
    1834                             MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(values[k]);
    1835                             if (metadata_element != null)
    1836                             {
    1837                                 values[k] = metadata_element.getFullName();
    1838                             }
    1839                         }
    1840                         if (k < values.length - 1)
    1841                         {
    1842                             value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
    1843                         }
    1844                         else
    1845                         {
    1846                             value_str = value_str + values[k];
    1847                         }
    1848                     }
    1849                 }
    1850 
    1851                 if (!name_str.equals(""))
    1852                 {
    1853                     if (!name_str.startsWith(StaticStrings.MINUS_CHARACTER))
    1854                     {
    1855                         name_str = StaticStrings.MINUS_CHARACTER + name_str;
    1856                     }
    1857                     option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    1858                 }
    1859 
    1860                 if (!value_str.equals(""))
    1861                 {
    1862                     option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);
    1863                 }
    1864 
    1865                 classifier_element.appendChild(option_element);
    1866             }
    1867 
    1868             //format element for this classifier
    1869             Element e = (Element) XMLTools.getChildByTagName(child, StaticStrings.FORMAT_STR);
    1870 
    1871             if (e != null)
    1872             {
    1873                 classifier_element.appendChild(convertFormat(to, e));
    1874             }
    1875 
    1876             // Handling 'displayItem' element of this 'classifier' element - for now, just copy in and out so they don't get deleted
    1877             NodeList di_children = child.getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
    1878            
    1879             XMLTools.duplicateElementList(to, classifier_element, di_children, true);
    1880             browse_element.appendChild(classifier_element);
    1881         }
    1882 
    1883         //convert default classifier format
    1884         Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.BROWSE_STR);
    1885         browse_element.appendChild(convertFormat(to, e));
    1886 
    1887         to.getDocumentElement().appendChild(browse_element);
    1888     } // convertClassifier
    1889 
    1890     static private Element convertFormat(Document to, Element e)
    1891     {
    1892         String format_str = XMLTools.getNodeText(e);
    1893         Element format = to.createElement(StaticStrings.FORMAT_STR);
    1894         //XMLTools.copyAllChildren (format, e);
    1895         XMLTools.setNodeText(format, format_str);
    1896         return format;
    1897     }
    1898 
    1899     //convert format statement for search
    1900     static private void convertSearchFormat(Document from, Document to)
    1901     {
    1902         Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    1903         Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCH_STR);
    1904 
    1905         search.appendChild(convertFormat(to, e));
    1906 
    1907     }
    1908 
    1909     //convert format statement for display of the documents
    1910     static private void convertDisplayFormat(Document from, Document to)
    1911     {
    1912         Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.DISPLAY_STR);
    1913         if (e == null)
    1914         {
    1915             return;
    1916         }
    1917         Element display = to.createElement(StaticStrings.DISPLAY_STR);
    1918         display.appendChild(convertFormat(to, e));
    1919         to.getDocumentElement().appendChild(display);
    1920     }
    1921 
    1922     // convert global format statement
    1923     static private void convertGlobalFormat(Document from, Document to)
    1924     {
    1925         Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.GLOBAL_STR);
    1926 
    1927         to.getDocumentElement().appendChild(convertFormat(to, e));
    1928 
    1929     }
    1930 
    1931     // Convert plugins in the internal(i.e. Document from) to collectionconfig.xml (i.e. Document to)
    1932     static private void convertPlugins(Document from, Document to)
    1933     {
    1934         Element import_element = to.createElement(StaticStrings.IMPORT_STR);
    1935         Element plugin_list_element = to.createElement(StaticStrings.PLUGINLIST_STR);
    1936 
    1937         NodeList children = from.getDocumentElement().getElementsByTagName(StaticStrings.PLUGIN_ELEMENT);
    1938         int num_children = (children == null) ? 0 : children.getLength();
    1939         if (num_children == 0)
    1940         {
    1941             return;
    1942         }
    1943 
    1944         for (int i = 0; i < num_children; i++)
    1945         {
    1946 
    1947             Element child = (Element) children.item(i);
    1948             if (child.getAttribute(StaticStrings.SEPARATOR_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
    1949             {
    1950                 continue;
    1951             }
    1952             if (child.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    1953             {
    1954                 continue;
    1955             }
    1956 
    1957             String str = child.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
    1958             Element plugin_element = to.createElement(StaticStrings.PLUGIN_STR);
    1959             plugin_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, str);
    1960 
    1961             NodeList option_children = child.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
    1962             for (int j = 0; j < option_children.getLength(); j++)
    1963             {
    1964                 Element el = (Element) option_children.item(j);
    1965                 if (!el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
    1966                 {
    1967                     continue;
    1968                 }
    1969                 String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    1970                 String value_str = XMLTools.getNodeText(el);
    1971 
    1972                 if (name_str == null && value_str == null)
    1973                 {
    1974                     continue;
    1975                 }
    1976                 Element option_element = to.createElement(StaticStrings.OPTION_STR);
    1977                 if (name_str != null && name_str.equals(StaticStrings.METADATA_STR))
    1978                 {
    1979 
    1980                     // 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.*)
    1981                     String[] values = value_str.split(StaticStrings.COMMA_CHARACTER);
    1982                     value_str = "";
    1983                     for (int k = 0; k <= values.length - 1; k++)
    1984                     {
    1985                         if (values[k].startsWith(StaticStrings.EXTRACTED_NAMESPACE) && values[k].indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
    1986                         {
    1987                             values[k] = values[k].substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    1988                         }
    1989 
    1990                         if (k < values.length - 1)
    1991                         {
    1992                             value_str = value_str + values[k] + StaticStrings.COMMA_CHARACTER;
    1993                         }
    1994                         else
    1995                         {
    1996                             value_str = value_str + values[k];
    1997                         }
    1998                     }
    1999                 }
    2000 
    2001                 if (!name_str.equals(""))
    2002                 {
    2003                     if (!name_str.startsWith(StaticStrings.MINUS_CHARACTER))
    2004                     {
    2005                         name_str = StaticStrings.MINUS_CHARACTER + name_str;
    2006                     }
    2007                     option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    2008                 }
    2009 
    2010                 if (!value_str.equals(""))
    2011                 {
    2012                     option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);
    2013                 }
    2014 
    2015                 plugin_element.appendChild(option_element);
    2016             }//for loop ends
    2017 
    2018             plugin_list_element.appendChild(plugin_element);
    2019         }//for loop ends
    2020 
    2021         import_element.appendChild(plugin_list_element);
    2022 
    2023         //do the plugout element (used by building flax collections)
    2024         Node plugout = XMLTools.getChildByTagNameIndexed(from.getDocumentElement(), StaticStrings.PLUGOUT_ELEMENT, 0);
    2025         if (plugout != null)
    2026         {
    2027             Element to_element = XMLTools.duplicateElement(to, (Element) plugout, true);
    2028             import_element.appendChild(to_element);
    2029         }
    2030 
    2031         to.getDocumentElement().appendChild(import_element);
    2032     }
    2033 
    2034     //Handle 'searchType' of collectionConfig.xml. In the internal structure, its also called 'searchType', eg. plain, form
    2035     static private void convertSearchType(Document from, Document to)
    2036     {
    2037         Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.FORMAT_STR, StaticStrings.NAME_ATTRIBUTE, StaticStrings.SEARCHTYPE_ELEMENT);//searchType
    2038 
    2039         if (e == null)
    2040         {
    2041             return;
    2042         }
    2043         String searchtype_str = XMLTools.getNodeText(e).trim();
    2044         //Get the 'search' element from 'to'
    2045         Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    2046 
    2047         String[] types = searchtype_str.split(",");
    2048         for (int i = 0; i < types.length; i++)
    2049         {
    2050             Element search_type_element = to.createElement(StaticStrings.SEARCHTYPE_ELEMENT);
    2051             search_type_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, types[i]);
    2052             search.appendChild(search_type_element);
    2053         }
    2054     }
    2055 
    2056     static private void convertBuildType(Document from, Document to)
    2057     {
    2058         Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.BUILDTYPE_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.BUILDTYPE_STR);
    2059         if (e == null)
    2060         {
    2061             return;
    2062         }
    2063         String indexer = XMLTools.getNodeText(e);
    2064         Element search = to.createElement(StaticStrings.SEARCH_STR);
    2065         search.setAttribute(StaticStrings.TYPE_ATTRIBUTE, indexer);
    2066         to.getDocumentElement().appendChild(search);
    2067     }
    2068 
    2069     static private void convertDatabaseType(Document from, Document to)
    2070     {
    2071         Element e = XMLTools.getNamedElement(from.getDocumentElement(), StaticStrings.DATABASETYPE_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.DATABASETYPE_STR);
    2072         if (e == null)
    2073         {
    2074             return;
    2075         }
    2076         String db = XMLTools.getNodeText(e);
    2077         Element dbtype = to.createElement(StaticStrings.INFODB_STR);
    2078         dbtype.setAttribute(StaticStrings.TYPE_ATTRIBUTE, db);
    2079         to.getDocumentElement().appendChild(dbtype);
    2080     }
    2081 //
    2082   static private void convertBaseDefaultIndex(Document from, Document to, Element search, String internal_default_index_str, String output_default_index_str)
    2083     {
    2084         Element source = from.getDocumentElement();
    2085 
    2086         Element default_index_element = (Element) XMLTools.getChildByTagName(source, internal_default_index_str);
    2087         if (default_index_element == null)
    2088         {
    2089             return;
    2090         }
    2091 
    2092         String indexer = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
    2093         String level_str = default_index_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE);
    2094         // Debugging purposes
    2095         if (level_str.equals("") && indexer.equals(StaticStrings.MG_STR))
    2096         {
    2097             System.out.println("Bug: DefaultIndex should have its level attribute not empty.");
    2098         }
    2099 
    2100         NodeList content_elements = default_index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
    2101         int content_elements_length = content_elements.getLength();
    2102 
    2103         // Don't output anything if no indexes are set
    2104         if (content_elements_length == 0)
    2105         {
    2106             return;//
    2107         }
    2108 
    2109         String index_str = "";
    2110 
    2111         if (indexer.equals(StaticStrings.MG_STR))
    2112         {
    2113             //combine level with indexes
    2114             index_str = level_str + StaticStrings.COLON_CHARACTER;
    2115         }
    2116         else
    2117         { //for mgpp/lucene, just take index
    2118             //do nothing
    2119         }
    2120 
    2121         for (int k = 0; k < content_elements_length; k++)
    2122         {
    2123             Element content_element = (Element) content_elements.item(k);
    2124             if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2125             {
    2126                 continue;
    2127             }
    2128             String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2129 
    2130             if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
    2131             {
    2132                 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    2133             }
    2134 
    2135             index_str = index_str + name_str;
    2136 
    2137             // Make it comma separated string
    2138             if (k < content_elements_length - 1)
    2139             {
    2140                 index_str = index_str + StaticStrings.COMMA_CHARACTER;
    2141             }
    2142             content_element = null;
    2143         }//for loop ends
    2144 
    2145         Element default_index = to.createElement(output_default_index_str);
    2146         default_index.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_str);
    2147         search.appendChild(default_index);
    2148 
    2149     } // convertBaseDefaultIndex
    2150 
    2151     static private void convertDefaultIndexOld(Document from, Document to, Element search)
    2152     {
    2153         Element source = from.getDocumentElement();
    2154 
    2155         Element default_index_element = (Element) XMLTools.getChildByTagName(source, StaticStrings.INDEX_DEFAULT_ELEMENT);
    2156         if (default_index_element == null)
    2157         {
    2158             return;
    2159         }
    2160 
    2161         String indexer = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
    2162         String level_str = default_index_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE);
    2163         // Debugging purposes
    2164         if (level_str.equals("") && indexer.equals(StaticStrings.MG_STR))
    2165         {
    2166             System.out.println("Bug: DefaultIndex should have its level attribute not empty.");
    2167         }
    2168 
    2169         NodeList content_elements = default_index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
    2170         int content_elements_length = content_elements.getLength();
    2171 
    2172         // Don't output anything if no indexes are set
    2173         if (content_elements_length == 0)
    2174         {
    2175             return;//
    2176         }
    2177 
    2178         String index_str = "";
    2179 
    2180         if (indexer.equals(StaticStrings.MG_STR))
    2181         {
    2182             //combine level with indexes
    2183             index_str = level_str + StaticStrings.COLON_CHARACTER;
    2184         }
    2185         else
    2186         { //for mgpp/lucene, just take index
    2187             //do nothing
    2188         }
    2189 
    2190         for (int k = 0; k < content_elements_length; k++)
    2191         {
    2192             Element content_element = (Element) content_elements.item(k);
    2193             if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2194             {
    2195                 continue;
    2196             }
    2197             String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2198 
    2199             if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
    2200             {
    2201                 name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    2202             }
    2203 
    2204             index_str = index_str + name_str;
    2205 
    2206             // Make it comma separated string
    2207             if (k < content_elements_length - 1)
    2208             {
    2209                 index_str = index_str + StaticStrings.COMMA_CHARACTER;
    2210             }
    2211             content_element = null;
    2212         }//for loop ends
    2213 
    2214         Element default_index = to.createElement(StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE);
    2215         default_index.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_str);
    2216         search.appendChild(default_index);
    2217 
    2218     }
    2219 
    2220     static private void convertSubcollection(Document from, Document to)
    2221     {
    2222         Element source = from.getDocumentElement();
    2223         //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
    2224         Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    2225 
    2226         // Get the Subcollection element from the internal structure
    2227         NodeList subcollection_elements = source.getElementsByTagName(StaticStrings.SUBCOLLECTION_ELEMENT);
    2228         if (subcollection_elements == null)
    2229         {
    2230             return;
    2231         }
    2232         int subcollection_elements_length = subcollection_elements.getLength();
    2233 
    2234         if (subcollection_elements_length == 0)
    2235         { // no
    2236             return;
    2237         }
    2238 
    2239         for (int j = 0; j < subcollection_elements_length; j++)
    2240         {
    2241 
    2242             Element e = (Element) subcollection_elements.item(j);
    2243             if (e.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2244             {
    2245                 continue;
    2246             }
    2247             String content = e.getAttribute(StaticStrings.CONTENT_ATTRIBUTE);
    2248             String name = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2249             String options = e.getAttribute(StaticStrings.OPTIONS_ATTRIBUTE);
    2250             String type = e.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
    2251             String text = XMLTools.getNodeText(e);
    2252 
    2253             String filter = "";
    2254             if (type.equals(StaticStrings.EXCLUDE_STR))
    2255             {
    2256                 filter = StaticStrings.EXCLAMATION_CHARACTER;
    2257             }
    2258 
    2259             if (content.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && content.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
    2260             {
    2261                 content = content.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    2262             }
    2263             filter = filter + content + StaticStrings.SEPARATOR_CHARACTER + text;
    2264             if (options != null && options != "")
    2265             {
    2266                 filter = filter + StaticStrings.SEPARATOR_CHARACTER + options;
    2267             }
    2268             Element subcollection = to.createElement(StaticStrings.SUBCOLLECTION_STR);
    2269             subcollection.setAttribute(StaticStrings.FILTER_ATTRIBUTE, filter);
    2270             subcollection.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
    2271 
    2272             search.appendChild(subcollection);
    2273         }
    2274     }
    2275 
    2276     static private void convertSubcollectionIndexes(Document from, Document to)
    2277     {
    2278         Element source = from.getDocumentElement();
    2279         //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
    2280         Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    2281 
    2282         // Get the SubcollectionIndexes element from the internal structure
    2283         Element subcollection_indexes = (Element) XMLTools.getChildByTagName(source, StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT);
    2284         if (subcollection_indexes == null)
    2285         {
    2286             return;
    2287         }
    2288         NodeList index_elements = subcollection_indexes.getElementsByTagName(StaticStrings.INDEX_ELEMENT);
    2289         int index_elements_length = index_elements.getLength();
    2290 
    2291         if (index_elements_length == 0)
    2292         { // no indexes
    2293             return;
    2294         }
    2295 
    2296         for (int j = 0; j < index_elements_length; j++)
    2297         {
    2298             Element index_element = (Element) index_elements.item(j);
    2299             if (index_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2300             {
    2301                 continue;
    2302             }
    2303 
    2304             Element index = to.createElement(StaticStrings.SUBCOLLECTION_INDEX_ELEMENT);
    2305 
    2306             String index_value = "";
    2307 
    2308             NodeList content_elements = index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
    2309             int content_elements_length = content_elements.getLength();
    2310 
    2311             for (int k = 0; k < content_elements_length; k++)
    2312             {
    2313                 Element content_element = (Element) content_elements.item(k);
    2314                 if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2315                 {
    2316                     continue;
    2317                 }
    2318                 String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2319                 index_value += name_str;
    2320                 // Make it comma separated string
    2321                 if (k < content_elements_length - 1)
    2322                 {
    2323                     index_value += StaticStrings.COMMA_CHARACTER;
    2324                 }
    2325                 content_element = null;
    2326             }//for loop ends
    2327 
    2328             index.setAttribute(StaticStrings.NAME_ATTRIBUTE, index_value);
    2329 
    2330             // Now constructing 'displayItem' element for this 'indexSubcollection' element
    2331             // from the collectionmetadata element
    2332             // *** here
    2333             ArrayList collectionmetadata_list = getMatchingSearchMetaElements(source, index_value, SearchMeta.TYPE_PARTITION);
    2334             //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, index_value);
    2335 
    2336             if (collectionmetadata_list != null)
    2337             {
    2338 
    2339                 for (int k = 0; k < collectionmetadata_list.size(); k++)
    2340                 {
    2341                     Element collectionmetadata = (Element) collectionmetadata_list.get(k);
    2342                     if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2343                     {
    2344                         continue;
    2345                     }
    2346                     Element displayItem = constructDisplayItem(collectionmetadata, to);
    2347                     index.appendChild(displayItem);
    2348                 }
    2349             }
    2350 
    2351             search.appendChild(index);
    2352 
    2353         } //for loop ends
    2354     }
    2355 
    2356     static private void convertLanguages(Document from, Document to)
    2357     {
    2358         Element source = from.getDocumentElement();
    2359         //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
    2360         Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    2361 
    2362         // Get the Languages element from the internal structure
    2363         Element languages = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGES_ELEMENT);
    2364         if (languages == null)
    2365         {
    2366             return;
    2367         }
    2368         NodeList language_elements = languages.getElementsByTagName(StaticStrings.LANGUAGE_ELEMENT);
    2369         int language_elements_length = language_elements.getLength();
    2370 
    2371         if (language_elements_length == 0)
    2372         {
    2373             return;
    2374         }
    2375 
    2376         for (int j = 0; j < language_elements_length; j++)
    2377         {
    2378             Element element = (Element) language_elements.item(j);
    2379             if (element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2380             {
    2381                 continue;
    2382             }
    2383 
    2384             // Create indexLanguage element
    2385             Element index_language = to.createElement(StaticStrings.LANGUAGE_INDEX_ELEMENT);
    2386 
    2387             String name_str = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2388             index_language.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    2389 
    2390             // Now constructing 'displayItem' element for this 'indexLanguage' element
    2391             // from the collectionmetadata element
    2392             // *** here
    2393             ArrayList collectionmetadata_list = getMatchingSearchMetaElements(source, name_str, SearchMeta.TYPE_LANGUAGE);
    2394             //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, name_str);
    2395 
    2396             if (collectionmetadata_list != null)
    2397             {
    2398 
    2399                 for (int k = 0; k < collectionmetadata_list.size(); k++)
    2400                 {
    2401                     Element collectionmetadata = (Element) collectionmetadata_list.get(k);
    2402                     if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2403                     {
    2404                         continue;
    2405                     }
    2406                     Element displayItem = constructDisplayItem(collectionmetadata, to);
    2407                     index_language.appendChild(displayItem);
    2408                 }
    2409             }
    2410 
    2411             search.appendChild(index_language);
    2412 
    2413         } //for loop ends
    2414 
    2415         // Convert DefaultLanguage
    2416         // Get the DefaultLanguage element from the internal structure
    2417         Element default_language = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGE_DEFAULT_ELEMENT);
    2418         if (default_language != null)
    2419         {
    2420             String lang_name = default_language.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2421             Element default_index_language = to.createElement(StaticStrings.LANGUAGE_DEFAULT_INDEX_ELEMENT);
    2422             default_index_language.setAttribute(StaticStrings.NAME_ATTRIBUTE, lang_name);
    2423             search.appendChild(default_index_language);
    2424         }
    2425         // Convert LanguageMetadata
    2426         // Get the LanguageMetadata element from the internal structure
    2427         Element language_metadata = (Element) XMLTools.getChildByTagName(source, StaticStrings.LANGUAGE_METADATA_ELEMENT);
    2428         if (language_metadata != null)
    2429         {
    2430             String meta_name = language_metadata.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2431             Element language_meta = to.createElement(StaticStrings.LANGUAGE_METADATA_ELEMENT_STR);
    2432             if (meta_name.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && meta_name.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
    2433             {
    2434                 meta_name = meta_name.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    2435             }
    2436             language_meta.setAttribute(StaticStrings.NAME_ATTRIBUTE, meta_name);
    2437             search.appendChild(language_meta);
    2438         }
    2439     }
    2440 
    2441   //convert indexes and their displayItems, which go in 'search' element in collectionConfig.xml
    2442   //parameter 'to' is the document to be saved as collectionConfig.xml
    2443   //parameter 'from' is the internal xml structure
    2444   static private void convertIndex(Document from, Document to)
    2445   {
    2446     Element source = from.getDocumentElement();
    2447     //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
    2448     Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    2449     String buildtype = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
    2450     if (buildtype.equals(StaticStrings.MG_STR)){
    2451       convertMGIndex(from, to);
    2452       return;
    2453     }
    2454 
    2455    
    2456     //THere are two sets of indexes elements, find the one which is assigned 'true'
    2457     Element indexes = XMLTools.getNamedElement(source, StaticStrings.INDEXES_ELEMENT, StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    2458     if (indexes == null)
    2459     {
    2460       return;
    2461     }
    2462     NodeList index_elements = indexes.getElementsByTagName(StaticStrings.INDEX_ELEMENT);
    2463     int index_elements_length = index_elements.getLength();
    2464    
    2465     if (index_elements_length == 0)
    2466     { // no indexes
    2467       return;
    2468     }
    2469    
    2470     // do the levels
    2471     convertLevels(from, to, search);
    2472    
    2473     // indexes
    2474     convertBaseIndex(from, to, search, StaticStrings.INDEXES_ELEMENT, StaticStrings.INDEX_ELEMENT, StaticStrings.INDEX_LOW_STR);
    2475     //Convert default index
    2476     convertBaseDefaultIndex(from, to, search, StaticStrings.INDEX_DEFAULT_ELEMENT, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE);
    2477    
    2478     // sortfields
    2479     if (buildtype.equals(StaticStrings.LUCENE_STR) || buildtype.equals(StaticStrings.SOLR_STR)) {
    2480       convertBaseIndex(from, to, search, StaticStrings.SORTS_ELEMENT, StaticStrings.SORT_ELEMENT, StaticStrings.SORT_LOW_STR);
    2481       convertBaseDefaultIndex(from, to, search, StaticStrings.SORT_DEFAULT_ELEMENT, StaticStrings.SORT_DEFAULT_ELEMENT);
    2482     }
    2483     // facet fields
    2484     if (buildtype.equals(StaticStrings.SOLR_STR)) {
    2485       convertBaseIndex(from, to, search, StaticStrings.FACETS_ELEMENT, StaticStrings.FACET_ELEMENT, StaticStrings.FACET_LOW_STR);
    2486     }
    2487     convertIndexOptions(from, to, search);
    2488    
    2489   } // convertIndex
    2490 
    2491 
    2492   // this code is used for indexes, sortfields, facets
    2493   // internal_indexes_str = Indexes/Sorts/Facets - internal doc
    2494   // internal_index_str = Index/Sort/Facet - internal doc
    2495   // output_index_str = index/sortfield/facet - what goes in collectionConfig
    2496   private static void convertBaseIndex(Document from, Document to, Element search, String internal_indexes_str, String internal_index_str, String output_index_str)
    2497   {
    2498    
    2499     Element source = from.getDocumentElement();
    2500     Element indexes = XMLTools.getNamedElement(source, internal_indexes_str, StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    2501     if (indexes == null)
    2502     {
    2503       return;
    2504     }
    2505    
    2506 
    2507     NodeList index_elements = indexes.getElementsByTagName(internal_index_str);
    2508     int index_elements_length = index_elements.getLength();
    2509    
    2510     if (index_elements_length == 0)
    2511     { // no indexes
    2512       return;
    2513     }
    2514     for (int j = 0; j < index_elements_length; j++)
    2515     {
    2516       Element index_element = (Element) index_elements.item(j);
    2517       if (index_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2518       {
    2519         continue;
    2520       }
    2521      
    2522       Element index_ele = to.createElement(output_index_str);//index
    2523      
    2524       // Used for creating displayItem for this element 'index_ele' further below
    2525       // full_index_names contain 'ex.'
    2526       String full_index_name = "";
    2527       String level_str = "";
    2528      
    2529       StringBuffer index_value = new StringBuffer();
    2530      
    2531       NodeList content_elements = index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
    2532       int content_elements_length = content_elements.getLength();
    2533      
    2534       for (int k = 0; k < content_elements_length; k++)
    2535       {
    2536         Element content_element = (Element) content_elements.item(k);
    2537         if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2538         {
    2539           continue;
    2540         }
    2541         String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2542        
    2543         full_index_name = full_index_name + name_str;
    2544         if (k < content_elements_length - 1)
    2545         {
    2546           full_index_name = full_index_name + StaticStrings.COMMA_CHARACTER;
    2547         }
    2548        
    2549         if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
    2550         {
    2551           name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    2552         }
    2553        
    2554         index_value.append(name_str);
    2555         name_str = null;
    2556         // Make it comma separated string
    2557         if (k < content_elements_length - 1)
    2558         {
    2559           index_value.append(StaticStrings.COMMA_CHARACTER);
    2560         }
    2561         content_element = null;
    2562       } //k for loop ends
    2563 
    2564       // ok to here
    2565       String temp_str = index_value.toString();
    2566       index_ele.setAttribute(StaticStrings.NAME_ATTRIBUTE, temp_str);
    2567      
    2568       // Now constructing 'displayItem' element for this 'index_ele' element
    2569       // The index names in the collectionmetadata elements in the internal structure are not the names that
    2570       // are used in the content elements (i.e. ex.Source or dc.Subject and keywords), but the names that are
    2571       // in the configuration files (i.e. Source or dc.Subject)
    2572       // *** here
    2573       ArrayList collectionmetadata_list = getMatchingSearchMetaElements(source, temp_str, output_index_str); // TODO??? searchmeta type??
    2574       //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, new String[]{StaticStrings.NAME_ATTRIBUTE, StaticStrings.TYPE_ATTRIBUTE}, new String[]{ temp_str, output_index_str});
    2575 
    2576    
    2577       if (collectionmetadata_list == null)
    2578       {
    2579         //try the full name, i.e. with 'ex.'
    2580       collectionmetadata_list = getMatchingSearchMetaElements(source, full_index_name, output_index_str);
    2581         //collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, new String[]{StaticStrings.NAME_ATTRIBUTE, StaticStrings.TYPE_ATTRIBUTE}, new String[]{ full_index_name, output_index_str});
    2582       }
    2583      
    2584       if (collectionmetadata_list != null)
    2585       {
    2586        
    2587         for (int k = 0; k < collectionmetadata_list.size(); k++)
    2588         {
    2589           Element collectionmetadata = (Element) collectionmetadata_list.get(k);
    2590           if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2591           {
    2592             continue;
    2593           }
    2594           Element displayItem = constructDisplayItem(collectionmetadata, to);
    2595          
    2596           index_ele.appendChild(displayItem);
    2597         }
    2598       }
    2599       // goes wrong here
    2600    
    2601 
    2602  
    2603       // deal with any <option name='' value=''> children of this index
    2604       // e.g. <option name='solrfieldtype' value='text_es'>
    2605       NodeList option_children = index_element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
    2606       for (int k = 0; k < option_children.getLength(); k++)
    2607       {
    2608         Element el = (Element) option_children.item(k);
    2609         if (el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2610         {
    2611           continue;
    2612         }
    2613         String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2614         String value_str = XMLTools.getNodeText(el);
    2615        
    2616         if (name_str == null && value_str == null)
    2617         {
    2618           continue;
    2619         }
    2620         Element option_element = to.createElement(StaticStrings.OPTION_STR);
    2621         if (!name_str.equals("")) {
    2622           option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    2623         }
    2624         if (!value_str.equals("")) { // or no value attribute without name attribute?
    2625           option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);       
    2626         }
    2627         index_ele.appendChild(option_element);
    2628       }
    2629      
    2630       search.appendChild(index_ele);
    2631      
    2632     } //for loop ends
    2633    
    2634    
    2635    
    2636   } // convertBaseIndex
    2637 
    2638     static private void convertMGIndex(Document from, Document to)
    2639     {
    2640         Element source = from.getDocumentElement();
    2641         //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
    2642         Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    2643 
    2644         //THere are two sets of indexes elements, find the one which is assigned 'true'
    2645         Element indexes = XMLTools.getNamedElement(source, StaticStrings.INDEXES_ELEMENT, StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    2646         if (indexes == null)
    2647         {
    2648             return;
    2649         }
    2650         NodeList index_elements = indexes.getElementsByTagName(StaticStrings.INDEX_ELEMENT);
    2651         int index_elements_length = index_elements.getLength();
    2652 
    2653         if (index_elements_length == 0)
    2654         { // no indexes
    2655             return;
    2656         }
    2657 
    2658         // //find out it's mg or mgpp/lucene
    2659         // String mg = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
    2660         // boolean mg_indexer = false;
    2661         // if (mg.equals(StaticStrings.MG_STR))
    2662         // {
    2663         //  mg_indexer = true;//it's mg, then the level is set as attribute of
    2664         // }
    2665         // if (mg_indexer == false)
    2666         // {
    2667         //  // It's mgpp. Construct 'level' and 'defaultLevel' elements separately.
    2668         //  convertLevels(from, to, search);
    2669         // }
    2670 
    2671         for (int j = 0; j < index_elements_length; j++)
    2672         {
    2673             Element index_element = (Element) index_elements.item(j);
    2674             if (index_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2675             {
    2676                 continue;
    2677             }
    2678 
    2679             Element index_ele = to.createElement(StaticStrings.INDEX_LOW_STR);//index
    2680 
    2681             // Used for creating displayItem for this element 'index_ele' further below
    2682             // full_index_names contain 'ex.'
    2683             String full_index_name = "";
    2684             String level_str = "";
    2685 
    2686             StringBuffer index_value = new StringBuffer();
    2687             //  if (mg_indexer == true)
    2688             //{
    2689                 // For mg indexer, there is a 'level' attribute in the index element of the internal structure
    2690                 // But mgpp/lucene don't
    2691                 level_str = index_element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE);
    2692                 if (level_str.length() > 0)
    2693                 {
    2694                     index_value.append(level_str).append(StaticStrings.COLON_CHARACTER);
    2695                     //index_value = index_value.StaticStrings.COLON_CHARACTER;
    2696                 }
    2697                 //}
    2698 
    2699             NodeList content_elements = index_element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
    2700             int content_elements_length = content_elements.getLength();
    2701 
    2702             for (int k = 0; k < content_elements_length; k++)
    2703             {
    2704                 Element content_element = (Element) content_elements.item(k);
    2705                 if (content_element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2706                 {
    2707                     continue;
    2708                 }
    2709                 String name_str = content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2710 
    2711                 full_index_name = full_index_name + name_str;
    2712                 if (k < content_elements_length - 1)
    2713                 {
    2714                     full_index_name = full_index_name + StaticStrings.COMMA_CHARACTER;
    2715                 }
    2716 
    2717                 if (name_str.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && name_str.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1)
    2718                 {
    2719                     name_str = name_str.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    2720                 }
    2721 
    2722                 index_value.append(name_str);
    2723                 name_str = null;
    2724                 // Make it comma separated string
    2725                 if (k < content_elements_length - 1)
    2726                 {
    2727                     index_value.append(StaticStrings.COMMA_CHARACTER);
    2728                 }
    2729                 content_element = null;
    2730             }//for loop ends
    2731 
    2732             String temp_str = index_value.toString();
    2733             index_ele.setAttribute(StaticStrings.NAME_ATTRIBUTE, temp_str);
    2734 
    2735             // Now constructing 'displayItem' element for this 'index_ele' element
    2736             // The index names in the collectionmetadata elements in the internal structure are not the names that
    2737             // are used in the content elements (i.e. ex.Source or dc.Subject and keywords), but the names that are
    2738             // in the configuration files (i.e. Source or dc.Subject)// *** here
    2739             ArrayList collectionmetadata_list = getMatchingSearchMetaElements(source, temp_str, SearchMeta.TYPE_INDEX);
    2740             //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, temp_str);
    2741 
    2742             if (collectionmetadata_list == null)
    2743             {
    2744                 //try the full name, i.e. with 'ex.', first appending level info as we are mg
    2745                 full_index_name = level_str + StaticStrings.COLON_CHARACTER + full_index_name;
    2746                 // ** here
    2747                 collectionmetadata_list = getMatchingSearchMetaElements(source, full_index_name, SearchMeta.TYPE_INDEX);
    2748                 //collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, full_index_name);
    2749             }
    2750 
    2751             if (collectionmetadata_list != null)
    2752             {
    2753 
    2754                 for (int k = 0; k < collectionmetadata_list.size(); k++)
    2755                 {
    2756                     Element collectionmetadata = (Element) collectionmetadata_list.get(k);
    2757                     if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2758                     {
    2759                         continue;
    2760                     }
    2761                     Element displayItem = constructDisplayItem(collectionmetadata, to);
    2762 
    2763                     index_ele.appendChild(displayItem);
    2764                 }
    2765             }
    2766 
    2767             //mg has no options
    2768             // deal with any <option name='' value=''> children of this index
    2769             // e.g. <option name='solrfieldtype' value='text_es'>
    2770             // NodeList option_children = index_element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
    2771             // for (int k = 0; k < option_children.getLength(); k++)
    2772             // {
    2773             //  Element el = (Element) option_children.item(k);
    2774             //  if (el.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2775             //  {
    2776             //      continue;
    2777             //  }
    2778             //  String name_str = el.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2779             //  String value_str = XMLTools.getNodeText(el);
    2780 
    2781             //  if (name_str == null && value_str == null)
    2782             //  {
    2783             //      continue;
    2784             //  }
    2785             //  Element option_element = to.createElement(StaticStrings.OPTION_STR);
    2786             //  if (!name_str.equals("")) {
    2787             //      option_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    2788             //  }
    2789             //  if (!value_str.equals("")) { // or no value attribute without name attribute?
    2790             //      option_element.setAttribute(StaticStrings.VALUE_ATTRIBUTE, value_str);     
    2791             //  }
    2792             //  index_ele.appendChild(option_element);
    2793             // }
    2794 
    2795             search.appendChild(index_ele);
    2796 
    2797         } //for loop ends
    2798 
    2799         //Convert default index
    2800         convertBaseDefaultIndex(from, to, search, StaticStrings.INDEX_DEFAULT_ELEMENT, StaticStrings.INDEX_DEFAULT_ELEMENT_LOWERCASE);
    2801         convertIndexOptions(from, to, search);
    2802     } // convertMGIndex
    2803 
    2804 
    2805     static private void convertSort(Document from, Document to)
    2806     {
    2807         Element source = from.getDocumentElement();
    2808         //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
    2809         Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    2810 
    2811         // Get the Sorts element from the internal structure
    2812         Element sorts = (Element) XMLTools.getChildByTagName(source, StaticStrings.SORTS_ELEMENT);
    2813         if (sorts == null)
    2814         {
    2815             return;
    2816         }
    2817         NodeList sort_elements = sorts.getElementsByTagName(StaticStrings.SORT_ELEMENT);
    2818         int sort_elements_length = sort_elements.getLength();
    2819 
    2820         if (sort_elements_length == 0)
    2821         {
    2822             return;
    2823         }
    2824 
    2825         for (int j = 0; j < sort_elements_length; j++)
    2826         {
    2827             Element element = (Element) sort_elements.item(j);
    2828             if (element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2829             {
    2830                 continue;
    2831             }
    2832 
    2833             // Create sort element
    2834             Element new_sort = to.createElement(StaticStrings.SORT_LOW_STR);
    2835 
    2836             String name_str = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2837             new_sort.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    2838 
    2839             // Now constructing 'displayItem' element for this 'indexLanguage' element
    2840             // from the collectionmetadata element
    2841             // TODO this needs work to differentiate it from index
    2842             // *** here
    2843             ArrayList collectionmetadata_list = getMatchingSearchMetaElements(source, name_str, SearchMeta.TYPE_SORT);
    2844             //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, name_str);
    2845 
    2846             if (collectionmetadata_list != null)
    2847             {
    2848 
    2849                 for (int k = 0; k < collectionmetadata_list.size(); k++)
    2850                 {
    2851                     Element collectionmetadata = (Element) collectionmetadata_list.get(k);
    2852                     if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2853                     {
    2854                         continue;
    2855                     }
    2856                     Element displayItem = constructDisplayItem(collectionmetadata, to);
    2857                     new_sort.appendChild(displayItem);
    2858                 }
    2859             }
    2860 
    2861             search.appendChild(new_sort);
    2862 
    2863         } //for loop ends
    2864 
    2865         // Convert DefaultSort
    2866         // Get the DefaultSort element from the internal structure
    2867         Element default_sort = (Element) XMLTools.getChildByTagName(source, StaticStrings.SORT_DEFAULT_ELEMENT);
    2868         if (default_sort != null)
    2869         {
    2870             String sort_name = default_sort.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2871             Element new_default_sort = to.createElement(StaticStrings.SORT_DEFAULT_ELEMENT);
    2872             new_default_sort.setAttribute(StaticStrings.NAME_ATTRIBUTE, sort_name);
    2873             search.appendChild(new_default_sort);
    2874         }
    2875     } //convertSort
    2876 
    2877     static private void convertFacet(Document from, Document to)
    2878     {
    2879         Element source = from.getDocumentElement();
    2880         //Get the 'search' element from 'to' which has already been created in 'convertBuildType'
    2881         Element search = (Element) XMLTools.getChildByTagName(to.getDocumentElement(), StaticStrings.SEARCH_STR);
    2882 
    2883         // Get the Facets element from the internal structure
    2884         Element facets = (Element) XMLTools.getChildByTagName(source, StaticStrings.FACETS_ELEMENT);
    2885         if (facets == null)
    2886         {
    2887             return;
    2888         }
    2889         NodeList facet_elements = facets.getElementsByTagName(StaticStrings.FACET_ELEMENT);
    2890         int facet_elements_length = facet_elements.getLength();
    2891 
    2892         if (facet_elements_length == 0)
    2893         {
    2894             return;
    2895         }
    2896 
    2897         for (int j = 0; j < facet_elements_length; j++)
    2898         {
    2899             Element element = (Element) facet_elements.item(j);
    2900             if (element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2901             {
    2902                 continue;
    2903             }
    2904 
    2905             // Create facet element
    2906             Element new_facet = to.createElement(StaticStrings.FACET_LOW_STR);
    2907 
    2908             String name_str = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2909             new_facet.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    2910 
    2911             // Now constructing 'displayItem' element for this 'indexLanguage' element
    2912             // from the collectionmetadata element
    2913             // TODO this needs work to differentiate it from index
    2914             // ** here
    2915             ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.COLLECTIONMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, name_str);
    2916 
    2917             if (collectionmetadata_list != null)
    2918             {
    2919 
    2920                 for (int k = 0; k < collectionmetadata_list.size(); k++)
    2921                 {
    2922                     Element collectionmetadata = (Element) collectionmetadata_list.get(k);
    2923                     if (collectionmetadata.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2924                     {
    2925                         continue;
    2926                     }
    2927                     Element displayItem = constructDisplayItem(collectionmetadata, to);
    2928                     new_facet.appendChild(displayItem);
    2929                 }
    2930             }
    2931 
    2932             search.appendChild(new_facet);
    2933 
    2934         } //for loop ends
    2935    
    2936     } //convertFacet
    2937         //convert <facet> and <sort> and <defaultSort> elements
    2938         //which go in 'search' element in collectionConfig.xml
    2939     //parameter 'to' is the document to be saved as collectionConfig.xml
    2940     //parameter 'from' is the internal xml structure
    2941 
    2942 
    2943     // Convert levels for mgpp/lucene. This method is called by converIndex() when mgpp indexer is detected.
    2944     static private void convertLevels(Document from, Document to, Element search)
    2945     {
    2946         Element source = from.getDocumentElement();
    2947         Element index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTIONS_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVELS_STR);
    2948         if (index_option == null)
    2949         {
    2950             return;
    2951         }
    2952         //Debugging purposes
    2953         if (index_option.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    2954         {
    2955             DebugStream.println("For mgpp, there should be an IndexOption element for levels which is assigned 'true': possible bug.");
    2956         }
    2957 
    2958         NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
    2959         int num_elements = option_elements.getLength();
    2960 
    2961         // Don't output anything if no indexes are set
    2962         if (num_elements == 0)
    2963         {
    2964             return;//
    2965         }
    2966 
    2967         for (int k = 0; k < num_elements; k++)
    2968         {
    2969             Element e = (Element) option_elements.item(k);
    2970             String name_str = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    2971             Element level_element = to.createElement(StaticStrings.LEVEL_ELEMENT);
    2972             level_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_str);
    2973 
    2974             //Now construct displayItem for this level element from collectionmetadata
    2975             // ** here
    2976             ArrayList collectionmetadata_list = getMatchingSearchMetaElements(source, name_str, SearchMeta.TYPE_LEVEL);
    2977             //ArrayList collectionmetadata_list = XMLTools.getNamedElementList(source, StaticStrings.SEARCHMETADATA_ELEMENT, StaticStrings.NAME_ATTRIBUTE, name_str);
    2978 
    2979             if (collectionmetadata_list != null)
    2980             {
    2981 
    2982                 for (int j = 0; j < collectionmetadata_list.size(); j++)
    2983                 {
    2984                     Element collectionmetadata = (Element) collectionmetadata_list.get(j);
    2985 
    2986                     Element displayItem = constructDisplayItem(collectionmetadata, to);
    2987                     level_element.appendChild(displayItem);
    2988                 }
    2989             }
    2990             search.appendChild(level_element);
    2991         }
    2992 
    2993         //Convert default level
    2994         Element default_index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTION_DEFAULT_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.LEVEL_DEFAULT_STR);
    2995         if (default_index_option == null)
    2996         {
    2997             return;
    2998         }
    2999         Element default_level = to.createElement(StaticStrings.LEVEL_DEFAULT_ELEMENT);
    3000         String default_level_str = default_index_option.getAttribute(StaticStrings.VALUE_ATTRIBUTE);
    3001         default_level.setAttribute(StaticStrings.NAME_ATTRIBUTE, default_level_str);
    3002         search.appendChild(default_level);
    3003 
    3004     }
    3005 
    3006     // Convert indexoptions for mg/mgpp/lucene. This method is called by convertIndex().
    3007     static private void convertIndexOptions(Document from, Document to, Element search)
    3008     {
    3009         Element source = from.getDocumentElement();
    3010         Element index_option = XMLTools.getNamedElement(source, StaticStrings.INDEXOPTIONS_ELEMENT, StaticStrings.NAME_ATTRIBUTE, StaticStrings.INDEXOPTIONS_STR);
    3011         if (index_option == null)
    3012         {
    3013             return;
    3014         }
    3015         //Debugging purposes
    3016         if (index_option.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR))
    3017         {
    3018             DebugStream.println("There should be an IndexOption element which is assigned 'true': possible bug.");
    3019 
    3020             // for lucene and solr collections, don't write out stemming, casefolding and accentfolding indexOptions
    3021             // since they are not meant to be editable: stemming and casefolding are always on in lucene
    3022             String buildtype_value = search.getAttribute(StaticStrings.TYPE_ATTRIBUTE); //might be mg|mgpp|lucene|solr
    3023             if(buildtype_value.equalsIgnoreCase("solr") || buildtype_value.equalsIgnoreCase("lucene")) {
    3024                 return;
    3025             }
    3026         }
    3027         //Element indexOptionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
    3028         NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
    3029         int num_elements = option_elements.getLength();
    3030         // Don't output anything if no index
    3031         if (num_elements == 0)
    3032         {
    3033             return;//
    3034         }
    3035         //search.appendChild(indexOptionEl);
    3036 
    3037         for (int k = 0; k < num_elements; k++)
    3038         {
    3039             Element e = (Element) option_elements.item(k);
    3040             String name_att = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    3041             Element optionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
    3042             optionEl.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_att);
    3043             // default value?? on/off
    3044             //indexOptionEl.appendChild(optionEl);
    3045             search.appendChild(optionEl);
    3046         }
    3047 
    3048     }
    3049 
    3050     // handle top level elements which GLI knows nothing about
    3051     // we store them internally in a Unknown element for easy access when
    3052     // we write them out.
    3053     static private void doUnknownElements(Document to, Element from)
    3054     {
    3055         Element toElement = to.getDocumentElement();
    3056         Element unknownElement = to.createElement(StaticStrings.UNKNOWN_ELEMENT);
    3057         toElement.appendChild(unknownElement);
    3058 
    3059         Node child = from.getFirstChild();
    3060         while (child != null)
    3061         {
    3062             if (child.getNodeType() == Node.ELEMENT_NODE && !known_element_names.contains(child.getNodeName()))
    3063             {
    3064                 unknownElement.appendChild(XMLTools.duplicateElement(to, (Element) child, true));
    3065             }
    3066             child = child.getNextSibling();
    3067         }
    3068 
    3069     }
    3070 
    3071     // just copy all children of Unknown element into output doc.
    3072     static private void convertUnknownElements(Document from, Document to)
    3073     {
    3074 
    3075         Element toElement = to.getDocumentElement();
    3076         Node unknown_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.UNKNOWN_ELEMENT);
    3077 
    3078         Node child = unknown_element.getFirstChild();
    3079         while (child != null)
    3080         {
    3081             Element to_element = XMLTools.duplicateElement(to, (Element) child, true);
    3082             toElement.appendChild(to_element);
    3083 
    3084             child = child.getNextSibling();
    3085         }
    3086 
    3087     }
    3088 
    3089     // Append the element son to the element mother in the appropriate position.
    3090     static public void appendProperly(Element mother, Element son)
    3091     {
    3092         if (son == null)
    3093             return;
    3094 
    3095         Node reference_node = findInsertionPoint(mother, son);
    3096         if (reference_node != null)
    3097         {
    3098             mother.insertBefore(son, reference_node);
    3099         }
    3100         else
    3101         {
    3102             mother.appendChild(son);
    3103         }
    3104     }
    3105 
    3106     /**
    3107      * Find the best insertion position for the given DOM Element
    3108      * 'target_element' in the DOM Element 'document_element'. This should try
    3109      * to match command tag, and if found should then try to group by name or
    3110      * type (eg CollectionMeta), or append to end is no such grouping exists (eg
    3111      * Plugins). Failing a command match it will check against the command order
    3112      * for the best insertion location.
    3113      *
    3114      * @param target_element
    3115      *            the command Element to be inserted
    3116      * @return the Element which the given command should be inserted before, or
    3117      *         null to append to end of list
    3118      */
    3119     static public Node findInsertionPoint(Element document_element, Element target_element)
    3120     {
    3121         ///ystem.err.println("Find insertion point: " + target_element.getNodeName());
    3122         String target_element_name = target_element.getNodeName();
    3123 
    3124         // Try to find commands with the same tag.
    3125         NodeList matching_elements = document_element.getElementsByTagName(target_element_name);
    3126         // If we found matching elements, then we have our most likely insertion location, so check within for groupings
    3127         if (matching_elements.getLength() != 0)
    3128         {
    3129             ///ystem.err.println("Found matching elements.");
    3130             // Only CollectionMeta are grouped.
    3131             if (target_element_name.equals(StaticStrings.COLLECTIONMETADATA_ELEMENT))
    3132             {
    3133                 ///ystem.err.println("Dealing with collection metadata");
    3134                 // 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.
    3135                 // So if the command to be added is special add it immediately after any other special command
    3136                 if (target_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
    3137                 {
    3138                     int index = 0;
    3139                     Element matched_element = (Element) matching_elements.item(index);
    3140                     Element sibling_element = (Element) matched_element.getNextSibling();
    3141                     while (sibling_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
    3142                     {
    3143                         index++;
    3144                         matched_element = (Element) matching_elements.item(index);
    3145                         sibling_element = (Element) matched_element.getNextSibling();
    3146                     }
    3147                     if (sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT))
    3148                     {
    3149                         Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
    3150                         document_element.insertBefore(newline_element, sibling_element);
    3151                     }
    3152                     return sibling_element;
    3153                 }
    3154                 // Otherwise try to find a matching 'name' and add after the last one in that group.
    3155                 else
    3156                 {
    3157                     int index = 0;
    3158                     target_element_name = target_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    3159                     boolean found = false;
    3160                     // Skip all of the special metadata
    3161                     Element matched_element = (Element) matching_elements.item(index);
    3162                     while (matched_element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR))
    3163                     {
    3164                         index++;
    3165                         matched_element = (Element) matching_elements.item(index);
    3166                     }
    3167                     // Begin search
    3168                     while (!found && matched_element != null)
    3169                     {
    3170                         if (matched_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(target_element_name))
    3171                         {
    3172                             found = true;
    3173                         }
    3174                         else
    3175                         {
    3176                             index++;
    3177                             matched_element = (Element) matching_elements.item(index);
    3178                         }
    3179                     }
    3180                     // If we found a match, we need to continue checking until we find the last name match.
    3181                     if (found)
    3182                     {
    3183                         index++;
    3184                         Element previous_sibling = matched_element;
    3185                         Element sibling_element = (Element) matching_elements.item(index);
    3186                         while (sibling_element != null && sibling_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(target_element_name))
    3187                         {
    3188                             previous_sibling = sibling_element;
    3189                             index++;
    3190                             sibling_element = (Element) matching_elements.item(index);
    3191                         }
    3192                         // 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!
    3193                         return previous_sibling.getNextSibling();
    3194                     }
    3195                     // If not found we just add after last metadata element
    3196                     else
    3197                     {
    3198                         Element last_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
    3199                         return last_element.getNextSibling();
    3200                     }
    3201                 }
    3202 
    3203             }
    3204             else
    3205             {
    3206                 ///ystem.err.println("Not dealing with collection meta.");
    3207                 Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
    3208                 // 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)
    3209                 Node sibling_element = matched_element.getNextSibling();
    3210                 if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT))
    3211                 {
    3212                     Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
    3213                     document_element.insertBefore(newline_element, sibling_element);
    3214                 }
    3215                 return sibling_element; // Note that this may be null
    3216             }
    3217         }
    3218         ///ystem.err.println("No matching elements found.");
    3219         // Locate where this command is in the ordering
    3220         int command_index = -1;
    3221         for (int i = 0; command_index == -1 && i < CollectionConfiguration.COMMAND_ORDER.length; i++)
    3222         {
    3223             if (CollectionConfiguration.COMMAND_ORDER[i].equals(target_element_name))
    3224             {
    3225                 command_index = i;
    3226             }
    3227         }
    3228         ///ystem.err.println("Command index is: " + command_index);
    3229         // Now move forward, checking for existing elements in each of the preceeding command orders.
    3230         int preceeding_index = command_index - 1;
    3231         ///ystem.err.println("Searching before the target command.");
    3232         while (preceeding_index >= 0)
    3233         {
    3234             matching_elements = document_element.getElementsByTagName(CollectionConfiguration.COMMAND_ORDER[preceeding_index]);
    3235             // If we've found a match
    3236             if (matching_elements.getLength() > 0)
    3237             {
    3238                 // We add after the last element
    3239                 Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
    3240                 // 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)
    3241                 Node sibling_element = matched_element.getNextSibling();
    3242                 if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT))
    3243                 {
    3244                     Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
    3245                     document_element.insertBefore(newline_element, sibling_element);
    3246                 }
    3247                 return sibling_element; // Note that this may be null
    3248             }
    3249             preceeding_index--;
    3250         }
    3251         // If all that fails, we now move backwards through the commands
    3252         int susceeding_index = command_index + 1;
    3253         ///ystem.err.println("Searching after the target command.");
    3254         while (susceeding_index < CollectionConfiguration.COMMAND_ORDER.length)
    3255         {
    3256             matching_elements = document_element.getElementsByTagName(CollectionConfiguration.COMMAND_ORDER[susceeding_index]);
    3257             // If we've found a match
    3258             if (matching_elements.getLength() > 0)
    3259             {
    3260                 // We add before the first element
    3261                 Element matched_element = (Element) matching_elements.item(0);
    3262                 // 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)
    3263                 Node sibling_element = matched_element.getPreviousSibling();
    3264                 if (sibling_element != null && sibling_element.getNodeName().equals(CollectionConfiguration.NEWLINE_ELEMENT))
    3265                 {
    3266                     Element newline_element = document_element.getOwnerDocument().createElement(CollectionConfiguration.NEWLINE_ELEMENT);
    3267                     document_element.insertBefore(newline_element, sibling_element);
    3268                 }
    3269                 return sibling_element; // Note that this may be null
    3270             }
    3271             susceeding_index++;
    3272         }
    3273         // Well. Apparently there are no other commands in this collection configuration. So append away...
    3274         return null;
    3275     }
    3276 
    3277     // From collectionConfig.xml to internal structure:add 'ex.' namespace (if none).
    3278     // From internal structure to collectionConfig.xml:always peel off 'ex.' namespace (if any), except for format statement
    3279     //This method parses 'xml_file_doc' into 'dOc'
    3280     static public void parse(File xml_file, Document dOc)
    3281     {
    3282 
    3283         Document xml_file_doc = XMLTools.parseXMLFile(xml_file);
    3284         Element fromElement = xml_file_doc.getDocumentElement();
    3285         Element toElement = dOc.getDocumentElement();
    3286 
    3287         // security element. For now, we just save as is, as you can't edit this in GLI.
    3288         Node securityNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.SECURITY_STR,0);
    3289         // just save for now
    3290         if (securityNode != null) {
    3291           Element to_element = XMLTools.duplicateElement(dOc, (Element) securityNode, true);
    3292           toElement.appendChild(to_element);
    3293         }
    3294         // It's deliberately set that 'creator', 'maintainer', and 'public' are only in English (as they are just names).
    3295         // So the following ArrayList have only one element.
    3296         Node metadataListNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.METADATALIST_STR, 0);
    3297         if (metadataListNode != null)
    3298         {
    3299             ArrayList creator = doMetadataList(dOc, metadataListNode, StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_CREATOR_STR);
    3300             ArrayList maintainer = doMetadataList(dOc, metadataListNode, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_STR);
    3301             ArrayList is_public = doMetadataList(dOc, metadataListNode, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_STR);
    3302 
    3303             appendArrayList(toElement, creator);
    3304             appendArrayList(toElement, maintainer);
    3305             appendArrayList(toElement, is_public);
    3306         }
    3307 
    3308         Node databaseNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.INFODB_STR, 0);
    3309         String databasetype_value = "gdbm";
    3310         if (databaseNode != null)
    3311         {
    3312             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)
    3313         }
    3314 
    3315         Element databasetype = doDatabaseType(dOc, databasetype_value);
    3316         appendProperly(toElement, databasetype);
    3317 
    3318         Node searchNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.SEARCH_STR, 0);
    3319         String buildtype_value = ((Element) searchNode).getAttribute(StaticStrings.TYPE_ATTRIBUTE);//might be mg|mgpp|lucene|solr
    3320         Element buildtype = doBuildType(dOc, buildtype_value);
    3321         appendProperly(toElement, buildtype);
    3322 
    3323         Node importNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.IMPORT_STR, 0);
    3324         if (importNode == null)
    3325         {
    3326             System.out.println("There is no content in the 'import' block.");
    3327         }
    3328         if (importNode != null)
    3329         {
    3330             //do plugin list nodes
    3331             Node pluginListNode = XMLTools.getChildByTagNameIndexed((Element) importNode, StaticStrings.PLUGINLIST_STR, 0);
    3332             if (pluginListNode == null)
    3333             {
    3334                 System.out.println("There is no pluginlist set.");
    3335             }
    3336             if (pluginListNode != null)
    3337             {
    3338 
    3339                 doPlugins(dOc, pluginListNode);
    3340             }
    3341 
    3342             //do the plugout element (used by building flax collections)
    3343             Node plugout = XMLTools.getChildByTagNameIndexed((Element) importNode, StaticStrings.PLUGOUT_ELEMENT, 0);
    3344             if (plugout != null)
    3345             {
    3346                 Element to_element = XMLTools.duplicateElement(dOc, (Element) plugout, true);
    3347                 toElement.appendChild(to_element);
    3348             }
    3349         }
    3350 
    3351         Node browseNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.BROWSE_STR, 0);
    3352         if (browseNode != null)
    3353         {
    3354             if (browseNode == null)
    3355             {
    3356                 System.out.println("There is no classifier.");
    3357             }
    3358             doClassifiers(dOc, browseNode);
    3359         }
    3360 
    3361         Node displayItemListNode = XMLTools.getChildByTagNameIndexed(fromElement, StaticStrings.DISPLAYITEMLIST_STR, 0);
    3362         if (displayItemListNode != null)
    3363         {
    3364             ArrayList description = doDisplayItemList(dOc, displayItemListNode, StaticStrings.DESCRIPTION_STR, StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
    3365             ArrayList smallicon = doDisplayItemList(dOc, displayItemListNode, StaticStrings.SMALLICON_STR, StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR);
    3366             ArrayList icon = doDisplayItemList(dOc, displayItemListNode, StaticStrings.ICON_STR, StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR);
    3367             ArrayList name = doDisplayItemList(dOc, displayItemListNode, StaticStrings.NAME_STR, StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR);
    3368 
    3369             appendArrayList(toElement, description);
    3370             appendArrayList(toElement, smallicon);
    3371             appendArrayList(toElement, icon);
    3372             appendArrayList(toElement, name);
    3373 
    3374                         // add any other displayitems here??
    3375                         // why do we do these separately?
    3376         }
    3377 
    3378         if (buildtype_value.equalsIgnoreCase("mg"))
    3379         {
    3380             doMGIndexes(dOc, searchNode);
    3381         }
    3382         else
    3383         {
    3384             doMGPPIndexes(dOc, searchNode);
    3385         }
    3386 
    3387         if(buildtype_value.equalsIgnoreCase("solr") || buildtype_value.equalsIgnoreCase("lucene")) {
    3388             //doSolrFacetsAndSorts(dOc, searchNode); // <facet><displayItem /></facet> and <sort><displayItem /></sort>
    3389             doSorts(dOc, searchNode);
    3390             doDefaultSort(dOc, searchNode);
    3391             if (buildtype_value.equalsIgnoreCase("solr")) {
    3392             doFacets(dOc, searchNode);
    3393             }
    3394             // lucene will only have sort elements
    3395         }
    3396 
    3397         doDefaultIndex(dOc, searchNode);
    3398         doDefaultLevel(dOc, searchNode);
    3399         doLevel(dOc, searchNode);
    3400         doIndexOption(dOc, searchNode);
    3401         doSubcollection(dOc, searchNode);
    3402         doIndexSubcollection(dOc, searchNode);
    3403         doIndexLanguage(dOc, searchNode);
    3404         doDefaultIndexLanguage(dOc, searchNode);
    3405         doLanguageMetadata(dOc, searchNode);
    3406         doSearchType(dOc, searchNode);
    3407         doSearchFormat(dOc, searchNode);
    3408         doGlobalFormat(dOc, fromElement);
    3409         doDisplayFormat(dOc, fromElement);
    3410         doReplaceListRef(dOc, fromElement);
    3411         doReplaceList(dOc, fromElement);
    3412         doServiceRackList(dOc, fromElement);
    3413         doUnknownElements(dOc, fromElement);
    3414         // the official displayItems in the displayItemList element have already been handled above
    3415         // and created as collectionmetadata elements in the dOc object
    3416         // Now we add in all the *other* (remaining) displayItems as collectionmeta elements
    3417         NodeList collectionMetadataList = dOc.getDocumentElement().getElementsByTagName(StaticStrings.COLLECTIONMETADATA_ELEMENT);
    3418         Set setOfUniqueColMetaNames = new HashSet();
    3419         for (int i = 0; i < collectionMetadataList.getLength(); i++)
    3420         {
    3421             Element colMeta = (Element) collectionMetadataList.item(i);
    3422             String name = colMeta.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    3423             setOfUniqueColMetaNames.add(name);
    3424         }
    3425 
    3426         if (displayItemListNode != null)
    3427         { // this is to handle any extra elements from displayItemList (top level) of collectionConfig. but we filter out index etc ones.
    3428                   // However, I don't think we should have those there in the first place.
    3429             NodeList nl = ((Element) displayItemListNode).getElementsByTagName(StaticStrings.DISPLAYITEM_STR);
    3430 
    3431             // make a list of all unique attribute names that are specifically not
    3432             // description, smallicon, icon and name, since these are already processed above
    3433             Set setOfUniqueDisplayItemNames = new LinkedHashSet();
    3434             for (int i = 0; i < nl.getLength(); i++)
    3435             {
    3436                 Element displayItem = (Element) nl.item(i);
    3437                 String name = displayItem.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    3438 
    3439                 if (name.equals(""))
    3440                     continue; // no name attribute
    3441                 if (setOfUniqueColMetaNames.contains(name))
    3442                     continue;
    3443 
    3444                 if (name.equals(StaticStrings.DESCRIPTION_STR))
    3445                     continue;
    3446                 if (name.equals(StaticStrings.SMALLICON_STR))
    3447                     continue;
    3448                 if (name.equals(StaticStrings.ICON_STR))
    3449                     continue;
    3450                 if (name.equals(StaticStrings.NAME_STR))
    3451                     continue;
    3452                 // don't add displayItems that are handled by the indexers, etc. E.g. document:ex.Title
    3453                 if (name.indexOf(":") != -1)
    3454                     continue;
    3455 
    3456                 // otherwise
    3457                 setOfUniqueDisplayItemNames.add(name); // Set will ensure no duplicate names
    3458             }
    3459 
    3460             Iterator i = setOfUniqueDisplayItemNames.iterator();
    3461             while (i.hasNext())
    3462             {
    3463                 String displayItemName = (String) i.next();
    3464 
    3465                 ArrayList custom_displayItem = doDisplayItemList(dOc, displayItemListNode, displayItemName, displayItemName);
    3466                 appendArrayList(toElement, custom_displayItem);
    3467             }
    3468         }
    3469 
    3470     }
     2667        return sibling_element; // Note that this may be null
     2668        }
     2669        susceeding_index++;
     2670    }
     2671    // Well. Apparently there are no other commands in this collection configuration. So append away...
     2672    return null;
     2673    }
     2674
    34712675
    34722676    /**
     
    34932697        // especially after a self-closing tag
    34942698    }
    3495 
    3496     // If we have a positive number of lines remaining, it means it wasn't a self-closing
    3497     // tag. Need to remove the closing tag
     2699    if ( text.equals("")) {
     2700        //must have had self closing tag
     2701        return "";
     2702    }
     2703    lookFor = "</displayItem>";
     2704    int end = text.indexOf(lookFor);
     2705    if (end == -1) {
     2706        // there was no closing tag. something has gone wrong
     2707        return "";
     2708    }
     2709    text = text.substring(0,end);
     2710
     2711    // in case opening the file has indented the text, we strip off whitespace for each line
    34982712    String[] lines = text.split("\\r?\\n");
    34992713    text = "";             
    3500     if(lines.length > 1) {
    3501         for (int j = 0; j < lines.length-1; j++) { // skip last line: closing tag
     2714    if(lines.length > 0) {
     2715        for (int j = 0; j < lines.length; j++) {
    35022716        text += lines[j].trim() + "\n"; // Easiest solution:
    3503                                // trim white space of the one extra level of indentation
    3504                            // that became apparent when enclosing <dispItem> tags removed
    3505         }
    3506     }
    3507 
    3508     text = text.replaceAll("&amp;", "&");// feels stupid, when we're going to change it back again soon
    3509                // but it's the last bit needed to get GLI to preserve html coll descriptions
    3510                // while displaying the html as html (without char entities) in the config file editor
    3511    
    3512     return text; //already trimmed to remove all but final newline
    3513     }
    3514    
    3515     static public String generateStringVersion(Document doc)
    3516     {
    3517         return XMLTools.xmlNodeToString(doc);
    3518     }
    3519 
    3520     static public void save(File collect_config_xml_file, Document doc)
    3521     {
    3522         Document collection_config_xml_document = convertInternalToCollectionConfig(doc);
    3523         String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR, StaticStrings.DISPLAYITEM_STR };
    3524         XMLTools.writeXMLFile(collect_config_xml_file, collection_config_xml_document, nonEscapingTagNames);
    3525     }
    3526 
    3527     //Convert the internal XML DOM tree (dOc) into that of collectionConfig.xml (skeleton)
    3528     static private Document convertInternalToCollectionConfig(Document dOc)
    3529     {
    3530         //first parse an empty skeleton of xml config file
    3531         //The aim is to convert the internal structure into this skeleton
    3532         // This skeleton just has the CollectionConfig element and nothing else
    3533         Document skeleton = XMLTools.parseXMLFile("xml/CollectionConfig.xml", true);
    3534         convertSecurity(dOc, skeleton);
    3535         convertMetadataList(dOc, skeleton);
    3536         convertDisplayItemList(dOc, skeleton);
    3537         convertGlobalFormat(dOc, skeleton);
    3538         convertBuildType(dOc, skeleton);
    3539         convertDatabaseType(dOc, skeleton);
    3540         convertIndex(dOc, skeleton); // this will do index, defaultIndex, indexOptions, facets and sorting if needed
    3541         convertPlugins(dOc, skeleton);//also do the plugout element
    3542         convertClassifier(dOc, skeleton);
    3543         convertSubcollectionIndexes(dOc, skeleton);
    3544         convertLanguages(dOc, skeleton);
    3545         convertSubcollection(dOc, skeleton);
    3546         convertSearchType(dOc, skeleton);
    3547         convertSearchFormat(dOc, skeleton);
    3548         convertDisplayFormat(dOc, skeleton);
    3549         convertReplaceListRef(dOc, skeleton);
    3550         convertReplaceList(dOc, skeleton);
    3551         convertServiceRackList(dOc, skeleton);
    3552         convertUnknownElements(dOc, skeleton); // try to catch everything GLI doesn't know about
    3553 
    3554         return skeleton;
    3555     }
    3556 
    3557     // Append the elements, which are of Element type, in 'list' to Element 'to'
    3558     static private void appendArrayList(Element to, ArrayList list)
    3559     {
    3560         if (list == null)
    3561             return;
    3562 
    3563         for (int i = 0; i < list.size(); i++)
    3564         {
    3565             appendProperly(to, (Element) list.get(i));
    3566         }
    3567     }
     2717        // trim white space of the one extra level of indentation
     2718        // that became apparent when enclosing <dispItem> tags removed
     2719        }
     2720    }
     2721
     2722    text = text.replaceAll("&amp;", "&");
     2723    return text;
     2724
     2725    }
     2726
     2727    // Append the elements, which are of Element type, in 'list' to Element 'to'
     2728    static private void appendArrayList(Element to, ArrayList list)
     2729    {
     2730    if (list == null)
     2731        return;
     2732
     2733    for (int i = 0; i < list.size(); i++) {
     2734       
     2735        appendProperly(to, (Element) list.get(i));
     2736    }
     2737    }
     2738
    35682739
    35692740}
Note: See TracChangeset for help on using the changeset viewer.