Ignore:
Timestamp:
2003-11-30T21:43:23+13:00 (21 years ago)
Author:
jmt12
Message:

Here is the result of sixteen hours work over the weekend. I'm too tired to comment them all separately, but here are some of the highlights:
Rewrote how the 'base on collection' method actually retrieves and updates the collection configuration - ensuring the CDM.CollectionConfiguration class is used instead of the retarded Collection.CollectionConfiguration (which coincidently has had a name change to BasicCollectionConfiguration). Went through code search for places where the two versions had been confused. Rewrote large swathes of GDMDocument so as to differentiate between normal and extracted metadata - an attempt to prevent the snowballing extracted metadata problem. Fixed problem where GLI was correctly recieving the last few lines of an external process. The collection shortname is no longer visible, nor is the confusing double name for metadata elements. Also coloured folders in the trees are kaput. The users email is now saved as part of the GLI configuration and is used as appropriate to fill out collection fields. There are new options on the right click menus over trees to allow the expansion and collapsing of folders. 'Show Files' now shows all types (or at least 6 types) of image properly (arg, the plagues of copy and paste). 'Based On' collections are public, plugin list automatically moves to next entry if plugin removed (I guess we should do the same in every other screen?) and metadata arguments in plugins/classifiers are no longer editable. There are about a dozen other small things, but I can't remember them. Hope I remembered to set all of the files to UNIX line-endings.

Location:
trunk/gli/src/org/greenstone/gatherer/cdm
Files:
10 edited

Legend:

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

    r5936 r6051  
    400400        case Argument.METADATUM:
    401401        value = new JComboBox(Gatherer.c_man.getCollection().msm.getAssignedElements());
    402         ((JComboBox)value).setEditable(true);
     402        //((JComboBox)value).setEditable(true);
    403403        // Now ensure we have the existing value or default value selected if either exist.
    404404        if(existing_value != null) {
  • trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfiguration.java

    r5994 r6051  
    4646 */
    4747public class CollectionConfiguration
    48     extends StaticStrings {
    49 
    50     static public Document document;
    51 
    52     static public void main(String[] args) {
     48    extends StaticStrings {
     49
     50    static public Document document;
     51
     52    static public void main(String[] args) {
    5353    if(args.length >= 1) {
    54         File file = new File(args[0]);
    55         CollectionConfiguration collect_cfg = new CollectionConfiguration(file);
    56         collect_cfg.save(true);
    57         collect_cfg.save(false);
    58         collect_cfg = null;
     54        File file = new File(args[0]);
     55        CollectionConfiguration collect_cfg = new CollectionConfiguration(file);
     56        collect_cfg.save(true);
     57        collect_cfg.save(false);
     58        collect_cfg = null;
    5959    }
    6060    else {
    61         System.out.println("Usage: CollectionConfiguration <filename>");
    62     }
    63     }
    64 
    65     /** Find the best insertion position for the given DOM Element. This should try to match command tag, and if found should then try to group by name or type (eg CollectionMeta), or append to end is no such grouping exists (eg PlugIns). Failing a command match it will check against the command order for the best insertion location.
    66     * @param element the command Element to be inserted
    67     * @return the Element which the given command should be inserted before, or null to append to end of list
    68     */
    69     static public Node findInsertionPoint(Element target_element) {
     61        System.out.println("Usage: CollectionConfiguration <filename>");
     62    }
     63    }
     64
     65    /** Find the best insertion position for the given DOM Element. This should try to match command tag, and if found should then try to group by name or type (eg CollectionMeta), or append to end is no such grouping exists (eg PlugIns). Failing a command match it will check against the command order for the best insertion location.
     66    * @param element the command Element to be inserted
     67    * @return the Element which the given command should be inserted before, or null to append to end of list
     68    */
     69    static public Node findInsertionPoint(Element target_element) {
    7070    ///ystem.err.println("Find insertion point: " + target_element.getNodeName());
    7171    String target_element_name = target_element.getNodeName();
     
    7575    // If we found matching elements, then we have our most likely insertion location, so check within for groupings
    7676    if(matching_elements.getLength() != 0) {
    77         ///ystem.err.println("Found matching elements.");
    78         // Only CollectionMeta are grouped.
    79         if(target_element_name.equals(COLLECTIONMETADATA_ELEMENT)) {
     77        ///ystem.err.println("Found matching elements.");
     78        // Only CollectionMeta are grouped.
     79        if(target_element_name.equals(COLLECTIONMETADATA_ELEMENT)) {
    8080        ///ystem.err.println("Dealing with collection metadata");
    8181        // 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.
    8282        // So if the command to be added is special add it immediately after any other special command
    8383        if(target_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
    84             int index = 0;
    85             Element matched_element = (Element) matching_elements.item(index);
    86             Element sibling_element = (Element) matched_element.getNextSibling();
    87             while(sibling_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
     84            int index = 0;
     85            Element matched_element = (Element) matching_elements.item(index);
     86            Element sibling_element = (Element) matched_element.getNextSibling();
     87            while(sibling_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
    8888            index++;
    8989            matched_element = (Element) matching_elements.item(index);
    9090            sibling_element = (Element) matched_element.getNextSibling();
    91             }
    92             if(sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
     91            }
     92            if(sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
    9393            Element newline_element = document.createElement(NEWLINE_ELEMENT);
    9494            document_element.insertBefore(newline_element, sibling_element);
    95             }
    96             return sibling_element;
     95            }
     96            return sibling_element;
    9797        }
    9898        // Otherwise try to find a matching 'name' and add after the last one in that group.
    9999        else {
    100             int index = 0;
    101             target_element_name = target_element.getAttribute(NAME_ATTRIBUTE);
    102             boolean found = false;
    103             // Skip all of the special metadata
    104             Element matched_element = (Element) matching_elements.item(index);
    105             while(matched_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
     100            int index = 0;
     101            target_element_name = target_element.getAttribute(NAME_ATTRIBUTE);
     102            boolean found = false;
     103            // Skip all of the special metadata
     104            Element matched_element = (Element) matching_elements.item(index);
     105            while(matched_element.getAttribute(SPECIAL_ATTRIBUTE).equals(TRUE_STR)) {
    106106            index++;
    107107            matched_element = (Element) matching_elements.item(index);
    108             }
    109             // Begin search
    110             while(!found && matched_element != null) {
     108            }
     109            // Begin search
     110            while(!found && matched_element != null) {
    111111            if(matched_element.getAttribute(NAME_ATTRIBUTE).equals(target_element_name)) {
    112                 found = true;
     112                found = true;
    113113            }
    114114            else {
    115                 index++;
    116                 matched_element = (Element) matching_elements.item(index);
    117             }
    118             }
    119             // If we found a match, we need to continue checking until we find the last name match.
    120             if(found) {
     115                index++;
     116                matched_element = (Element) matching_elements.item(index);
     117            }
     118            }
     119            // If we found a match, we need to continue checking until we find the last name match.
     120            if(found) {
    121121            index++;
    122122            Element previous_sibling = matched_element;
    123123            Element sibling_element = (Element) matching_elements.item(index);
    124124            while(sibling_element != null && sibling_element.getAttribute(NAME_ATTRIBUTE).equals(target_element_name)) {
    125                 previous_sibling = sibling_element;
    126                 index++;
    127                 sibling_element = (Element) matching_elements.item(index);
     125                previous_sibling = sibling_element;
     126                index++;
     127                sibling_element = (Element) matching_elements.item(index);
    128128            }
    129129            // 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!
    130130            return previous_sibling.getNextSibling();
    131             }
    132             // If not found we just add after last metadata element
    133             else {
     131            }
     132            // If not found we just add after last metadata element
     133            else {
    134134            Element last_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
    135135            return last_element.getNextSibling();
    136             }
    137         }
    138 
    139         }
    140         else {
     136            }
     137        }
     138
     139        }
     140        else {
    141141        ///ystem.err.println("Not dealing with collection meta.");
    142142        Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
     
    144144        Node sibling_element = matched_element.getNextSibling();
    145145        if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
    146             Element newline_element = document.createElement(NEWLINE_ELEMENT);
    147             document_element.insertBefore(newline_element, sibling_element);
     146            Element newline_element = document.createElement(NEWLINE_ELEMENT);
     147            document_element.insertBefore(newline_element, sibling_element);
    148148        }
    149149        return sibling_element; // Note that this may be null
    150         }
     150        }
    151151    }
    152152    ///ystem.err.println("No matching elements found.");
     
    154154    int command_index = -1;
    155155    for(int i = 0; command_index == -1 && i < COMMAND_ORDER.length; i++) {
    156         if(COMMAND_ORDER[i].equals(target_element_name)) {
     156        if(COMMAND_ORDER[i].equals(target_element_name)) {
    157157        command_index = i;
    158         }
     158        }
    159159    }
    160160    ///ystem.err.println("Command index is: " + command_index);
     
    163163    ///ystem.err.println("Searching before the target command.");
    164164    while(preceeding_index >= 0) {
    165         matching_elements = document_element.getElementsByTagName(COMMAND_ORDER[preceeding_index]);
    166         // If we've found a match
    167         if(matching_elements.getLength() > 0) {
     165        matching_elements = document_element.getElementsByTagName(COMMAND_ORDER[preceeding_index]);
     166        // If we've found a match
     167        if(matching_elements.getLength() > 0) {
    168168        // We add after the last element
    169169        Element matched_element = (Element) matching_elements.item(matching_elements.getLength() - 1);
     
    171171        Node sibling_element = matched_element.getNextSibling();
    172172        if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
    173             Element newline_element = document.createElement(NEWLINE_ELEMENT);
    174             document_element.insertBefore(newline_element, sibling_element);
     173            Element newline_element = document.createElement(NEWLINE_ELEMENT);
     174            document_element.insertBefore(newline_element, sibling_element);
    175175        }
    176176        return sibling_element; // Note that this may be null
    177         }
    178         preceeding_index--;
     177        }
     178        preceeding_index--;
    179179    }
    180180    // If all that fails, we now move backwards through the commands
     
    182182    ///ystem.err.println("Searching after the target command.");
    183183    while(susceeding_index < COMMAND_ORDER.length) {
    184         matching_elements = document_element.getElementsByTagName(COMMAND_ORDER[susceeding_index]);
    185         // If we've found a match
    186         if(matching_elements.getLength() > 0) {
     184        matching_elements = document_element.getElementsByTagName(COMMAND_ORDER[susceeding_index]);
     185        // If we've found a match
     186        if(matching_elements.getLength() > 0) {
    187187        // We add before the first element
    188188        Element matched_element = (Element) matching_elements.item(0);
     
    190190        Node sibling_element = matched_element.getPreviousSibling();
    191191        if(sibling_element != null && sibling_element.getNodeName().equals(NEWLINE_ELEMENT)) {
    192             Element newline_element = document.createElement(NEWLINE_ELEMENT);
    193             document_element.insertBefore(newline_element, sibling_element);
     192            Element newline_element = document.createElement(NEWLINE_ELEMENT);
     193            document_element.insertBefore(newline_element, sibling_element);
    194194        }
    195195        return sibling_element; // Note that this may be null
    196         }
    197         susceeding_index++;
     196        }
     197        susceeding_index++;
    198198    }
    199199    // Well. Apparently there are no other commands in this collection configuration. So append away...
    200200    return null;
    201     }
    202 
    203     static public String toString(Element command_element, boolean show_extracted_namespace) {
     201    }
     202
     203    static public String toString(Element command_element, boolean show_extracted_namespace) {
    204204    String command_element_name = command_element.getNodeName();
    205205    if(command_element_name.equals(CLASSIFY_ELEMENT)) {
    206         return self.classifyToString(command_element, show_extracted_namespace);
     206        return self.classifyToString(command_element, show_extracted_namespace);
    207207    }
    208208    else if(command_element_name.equals(FORMAT_ELEMENT)) {
    209         return self.formatToString(command_element, show_extracted_namespace);
     209        return self.formatToString(command_element, show_extracted_namespace);
    210210    }
    211211    else if(command_element_name.equals(INDEXES_ELEMENT)) {
    212         return self.indexesToString(command_element, show_extracted_namespace);
     212        return self.indexesToString(command_element, show_extracted_namespace);
    213213    }
    214214    else if(command_element_name.equals(INDEX_DEFAULT_ELEMENT)) {
    215         return self.indexDefaultToString(command_element, show_extracted_namespace);
     215        return self.indexDefaultToString(command_element, show_extracted_namespace);
    216216    }
    217217    else if(command_element_name.equals(LANGUAGES_ELEMENT)) {
    218         return self.languagesToString(command_element);
     218        return self.languagesToString(command_element);
    219219    }
    220220    else if(command_element_name.equals(LANGUAGE_DEFAULT_ELEMENT)) {
    221         return self.languageDefaultToString(command_element);
     221        return self.languageDefaultToString(command_element);
    222222    }
    223223    else if(command_element_name.equals(LEVELS_ELEMENT)) {
    224         return self.levelsToString(command_element);
     224        return self.levelsToString(command_element);
    225225    }
    226226    else if(command_element_name.equals(COLLECTIONMETADATA_ELEMENT)) {
    227         return self.metadataToString(command_element, show_extracted_namespace);
     227        return self.metadataToString(command_element, show_extracted_namespace);
    228228    }
    229229    else if(command_element_name.equals(COLLECTIONMETADATA_CREATOR_ELEMENT)) {
    230         return self.metadataToString(command_element, show_extracted_namespace);
     230        return self.metadataToString(command_element, show_extracted_namespace);
    231231    }
    232232    else if(command_element_name.equals(COLLECTIONMETADATA_MAINTAINER_ELEMENT)) {
    233         return self.metadataToString(command_element, show_extracted_namespace);
     233        return self.metadataToString(command_element, show_extracted_namespace);
    234234    }
    235235    else if(command_element_name.equals(COLLECTIONMETADATA_PUBLIC_ELEMENT)) {
    236         return self.metadataToString(command_element, show_extracted_namespace);
     236        return self.metadataToString(command_element, show_extracted_namespace);
    237237    }
    238238    else if(command_element_name.equals(COLLECTIONMETADATA_BETA_ELEMENT)) {
    239         return self.metadataToString(command_element, show_extracted_namespace);
     239        return self.metadataToString(command_element, show_extracted_namespace);
    240240    }
    241241    else if(command_element_name.equals(PLUGIN_ELEMENT)) {
    242         return self.pluginToString(command_element, show_extracted_namespace);
     242        return self.pluginToString(command_element, show_extracted_namespace);
    243243    }
    244244    else if(command_element_name.equals(SEARCHTYPE_ELEMENT)) {
    245         return self.searchtypeToString(command_element);
     245        return self.searchtypeToString(command_element);
    246246    }
    247247    else if(command_element_name.equals(SUBCOLLECTION_ELEMENT)) {
    248         return self.subcollectionToString(command_element, show_extracted_namespace);
     248        return self.subcollectionToString(command_element, show_extracted_namespace);
    249249    }
    250250    else if(command_element_name.equals(SUBCOLLECTION_DEFAULT_INDEX_ELEMENT)) {
    251         return self.subcollectionDefaultIndexToString(command_element);
     251        return self.subcollectionDefaultIndexToString(command_element);
    252252    }
    253253    else if(command_element_name.equals(SUBCOLLECTION_INDEXES_ELEMENT)) {
    254         return self.subcollectionIndexesToString(command_element);
     254        return self.subcollectionIndexesToString(command_element);
    255255    }
    256256    else if(command_element_name.equals(SUPERCOLLECTION_ELEMENT)) {
    257         return self.supercollectionToString(command_element);
     257        return self.supercollectionToString(command_element);
    258258    }
    259259    else if(command_element_name.equals(UNKNOWN_ELEMENT)) {
    260         return self.unknownToString(command_element);
     260        return self.unknownToString(command_element);
    261261    }
    262262    return "";
    263     }
    264 
    265     /** Parses arguments from a tokenizer and returns a HashMap of mappings. The tricky bit here is that not all entries in the HashMap are name->value pairs, as some arguments are boolean and are turned on by their presence. Arguments are denoted by a '-' prefix.
    266     * @param tokenizer a CommandTokenizer based on the unconsumed portion of a command string
    267     * @return a HashMap containing the arguments parsed
    268     */
    269     static public HashMap parseArguments(CommandTokenizer tokenizer) {
     263    }
     264
     265    /** Parses arguments from a tokenizer and returns a HashMap of mappings. The tricky bit here is that not all entries in the HashMap are name->value pairs, as some arguments are boolean and are turned on by their presence. Arguments are denoted by a '-' prefix.
     266    * @param tokenizer a CommandTokenizer based on the unconsumed portion of a command string
     267    * @return a HashMap containing the arguments parsed
     268    */
     269    static public HashMap parseArguments(CommandTokenizer tokenizer) {
    270270    HashMap arguments = new HashMap();
    271271    String name = null;
    272272    String value = null;
    273273    while(tokenizer.hasMoreTokens() || name != null) {
    274         // First we retrieve a name if we need one.
    275         if(name == null) {
     274        // First we retrieve a name if we need one.
     275        if(name == null) {
    276276        name = tokenizer.nextToken();
    277         }
    278         // Now we attempt to retrieve a value
    279         if(tokenizer.hasMoreTokens()) {
     277        }
     278        // Now we attempt to retrieve a value
     279        if(tokenizer.hasMoreTokens()) {
    280280        value = tokenizer.nextToken();
    281281        // Test if the value is actually a name, and if so add the name by itself, then put value into name so that it is parsed correctly during the next loop.
    282282        if(value.startsWith(StaticStrings.MINUS_CHARACTER)) {
    283             arguments.put(name, null);
    284             name = value;
     283            arguments.put(name, null);
     284            name = value;
    285285        }
    286286        // Otherwise we have a typical name->value pair ready to go
    287287        else {
    288             arguments.put(name, value);
    289             name = null;
    290         }
    291         }
    292         // Otherwise its a binary flag
    293         else {
     288            arguments.put(name, value);
     289            name = null;
     290        }
     291        }
     292        // Otherwise its a binary flag
     293        else {
    294294        arguments.put(name, null);
    295295        name = null;
    296         }
     296        }
    297297    }
    298298    return arguments;
    299     }
    300 
    301     static private ArrayList known_metadata;
    302 
    303     static private CollectionConfiguration self;
    304 
    305     static final private String EXTRACTED_PREFIX = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP;
    306     /** Gives the preferred ordering of commands */
    307     static final private String[] COMMAND_ORDER = {StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT, StaticStrings.COLLECTIONMETADATA_BETA_ELEMENT, StaticStrings.SEARCHTYPE_ELEMENT, StaticStrings.PLUGIN_ELEMENT, StaticStrings.INDEXES_ELEMENT, StaticStrings.LEVELS_ELEMENT, StaticStrings.INDEX_DEFAULT_ELEMENT, StaticStrings.LANGUAGES_ELEMENT, StaticStrings.LANGUAGE_DEFAULT_ELEMENT, StaticStrings.SUBCOLLECTION_ELEMENT, StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT, StaticStrings.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT, StaticStrings.SUPERCOLLECTION_ELEMENT, StaticStrings.CLASSIFY_ELEMENT, StaticStrings.FORMAT_ELEMENT, StaticStrings.COLLECTIONMETADATA_ELEMENT};
    308 
    309     /** ************************** Public Data Members ***************************/
    310 
    311     /** ************************** Private Data Members ***************************/
    312 
    313     private File collect_config_file;
    314 
    315     /** ************************** Public Methods ***************************/
    316 
    317     public CollectionConfiguration(File collect_config_file) {
     299    }
     300
     301    static private ArrayList known_metadata;
     302
     303    static private CollectionConfiguration self;
     304
     305    static final private String EXTRACTED_PREFIX = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP;
     306    /** Gives the preferred ordering of commands */
     307    static final private String[] COMMAND_ORDER = {StaticStrings.COLLECTIONMETADATA_CREATOR_ELEMENT, StaticStrings.COLLECTIONMETADATA_MAINTAINER_ELEMENT, StaticStrings.COLLECTIONMETADATA_PUBLIC_ELEMENT, StaticStrings.COLLECTIONMETADATA_BETA_ELEMENT, StaticStrings.SEARCHTYPE_ELEMENT, StaticStrings.PLUGIN_ELEMENT, StaticStrings.INDEXES_ELEMENT, StaticStrings.LEVELS_ELEMENT, StaticStrings.INDEX_DEFAULT_ELEMENT, StaticStrings.LANGUAGES_ELEMENT, StaticStrings.LANGUAGE_DEFAULT_ELEMENT, StaticStrings.SUBCOLLECTION_ELEMENT, StaticStrings.SUBCOLLECTION_INDEXES_ELEMENT, StaticStrings.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT, StaticStrings.SUPERCOLLECTION_ELEMENT, StaticStrings.CLASSIFY_ELEMENT, StaticStrings.FORMAT_ELEMENT, StaticStrings.COLLECTIONMETADATA_ELEMENT};
     308
     309    /** ************************** Public Data Members ***************************/
     310
     311    /** ************************** Private Data Members ***************************/
     312
     313    private File collect_config_file;
     314
     315    /** ************************** Public Methods ***************************/
     316
     317    public CollectionConfiguration(File collect_config_file) {
    318318    this.self = this;
    319319    this.collect_config_file = collect_config_file;
     
    321321    String collect_config_name = collect_config_file.getName();
    322322    if(collect_config_name.equals(COLLECTCONFIGURATION_XML)) {
    323         // Parse with Utility but don't use class loader
    324         document = Utility.parse(collect_config_file, false);
     323        // Parse with Utility but don't use class loader
     324        document = Utility.parse(collect_config_file, false);
    325325    }
    326326    // Otherwise if this is a legacy collect.cfg file then read in the template and send to magic parser
    327327    else if(collect_config_name.equals(COLLECT_CFG)) {
    328         document = Utility.parse(PSEUDO_COLLECTCONFIGURATION_XML, true);
    329         parse(collect_config_file);
    330     }
    331     }
    332 
    333     /** This debug facility shows the currently loaded collect.cfg or CollectConfig.xml file as a DOM tree. */
    334     public void display() {
     328        document = Utility.parse(PSEUDO_COLLECTCONFIGURATION_XML, true);
     329        parse(collect_config_file);
     330    }
     331    }
     332
     333    /** This debug facility shows the currently loaded collect.cfg or CollectConfig.xml file as a DOM tree. */
     334    public void display() {
    335335    JDialog dialog = new JDialog(Gatherer.g_man, "Collection Configuration", false);
    336336    dialog.setSize(400,400);
     
    340340    refresh_button.addActionListener(new ActionListener() {
    341341        public void actionPerformed(ActionEvent event) {
    342             tree.setDocument(document);
    343         }
    344         });
     342            tree.setDocument(document);
     343        }
     344        });
    345345    content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    346346    content_pane.setLayout(new BorderLayout());
     
    348348    content_pane.add(refresh_button, BorderLayout.SOUTH);
    349349    dialog.show();
    350     }
    351 
    352     public Element getBeta() {
     350    }
     351
     352    public Element getBeta() {
    353353    Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_BETA_ELEMENT, null, null);
    354354    element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_BETA_STR);
    355355    element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
    356356    return element;
    357     }
    358 
    359     public Element getCreator() {
     357    }
     358
     359    public Element getCreator() {
    360360    Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_CREATOR_ELEMENT, null, null);
    361361    element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_CREATOR_STR);
    362362    element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
    363363    return element;
    364     }
    365 
    366     public Element getDocumentElement() {
     364    }
     365
     366    public Element getDocumentElement() {
    367367    return document.getDocumentElement();
    368     }
    369 
    370     public File getFile() {
     368    }
     369
     370    public File getFile() {
    371371    return collect_config_file;
    372     }
    373 
    374     /** Retrieve or create the languages Element. */
    375     public Element getLanguages() {
     372    }
     373
     374    /** Retrieve or create the languages Element. */
     375    public Element getLanguages() {
    376376    return getOrCreateElementByTagName(LANGUAGES_ELEMENT, null, null);
    377     }
    378 
    379     public Element getLevels() {
     377    }
     378
     379    public Element getLevels() {
    380380    return getOrCreateElementByTagName(LEVELS_ELEMENT, null, null);
    381     }
    382 
    383     public Element getMaintainer() {
     381    }
     382
     383    public Element getMaintainer() {
    384384    Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_MAINTAINER_ELEMENT, null, null);
    385385    element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_MAINTAINER_STR);
    386386    element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
    387387    return element;
    388     }
    389 
    390     /** Retrieve or create the indexes Element. Note that this method behaves differently from the other getBlah methods, in that it also has to keep in mind that indexes come in two flavours, MG and MGPP. */
    391     public Element getMGIndexes() {
     388    }
     389
     390    /** Retrieve or create the indexes Element. Note that this method behaves differently from the other getBlah methods, in that it also has to keep in mind that indexes come in two flavours, MG and MGPP. */
     391    public Element getMGIndexes() {
    392392    return getOrCreateElementByTagName(INDEXES_ELEMENT, MGPP_ATTRIBUTE, FALSE_STR);
    393     }
    394 
    395     public Element getMGPPIndexes() {
     393    }
     394
     395    public Element getMGPPIndexes() {
    396396    return getOrCreateElementByTagName(INDEXES_ELEMENT, MGPP_ATTRIBUTE, TRUE_STR);
    397     }
    398 
    399     public Element getPublic() {
     397    }
     398
     399    public Element getPublic() {
    400400    Element element = getOrCreateElementByTagName(COLLECTIONMETADATA_PUBLIC_ELEMENT, null, null);
    401401    element.setAttribute(NAME_ATTRIBUTE, COLLECTIONMETADATA_PUBLIC_STR);
    402402    element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
    403403    return element;
    404     }
    405 
    406     /** Retrieve or create the searchtype element. */
    407     public Element getSearchType() {
     404    }
     405
     406    /** Retrieve or create the searchtype element. */
     407    public Element getSearchType() {
    408408    ///ystem.err.println("Get or create element by tag name: " + name);
    409409    Element document_element = document.getDocumentElement();
     
    411411    int elements_length = elements.getLength();
    412412    if(elements_length > 0) {
    413         document_element = null;
    414         return (Element) elements.item(0);
     413        document_element = null;
     414        return (Element) elements.item(0);
    415415    }
    416416    // Create the element
     
    418418    Node target_node = findInsertionPoint(element);
    419419    if(target_node != null) {
    420         document_element.insertBefore(element, target_node);
     420        document_element.insertBefore(element, target_node);
    421421    }
    422422    else {
    423         document_element.appendChild(element);
     423        document_element.appendChild(element);
    424424    }
    425425    document_element = null;
     
    429429    element.appendChild(a_searchtype_element);
    430430    return element;
    431     }
    432 
    433     /** Retrieve or create the subindexes Element. */
    434     public Element getSubIndexes() {
     431    }
     432
     433    /** Retrieve or create the subindexes Element. */
     434    public Element getSubIndexes() {
    435435    return getOrCreateElementByTagName(SUBCOLLECTION_INDEXES_ELEMENT, null, null);
    436     }
    437 
    438     /** Retrieve or create the supercollections Element. */
    439     public Element getSuperCollection() {
     436    }
     437
     438    /** Retrieve or create the supercollections Element. */
     439    public Element getSuperCollection() {
    440440    return getOrCreateElementByTagName(SUPERCOLLECTION_ELEMENT, null, null);
    441     }
    442 
    443     public boolean ready() {
     441    }
     442
     443    public boolean ready() {
    444444    return document != null;
    445     }
    446 
    447     public void save() {
     445    }
     446
     447    public void save() {
    448448    save(false);
    449     }
    450 
    451     public void save(boolean force_xml) {
     449    }
     450
     451    public void save(boolean force_xml) {
    452452    if(collect_config_file.exists()) {
    453         File original_file = new File(collect_config_file.getParentFile(), COLLECT_CFG);
    454         File backup_file = new File(collect_config_file.getParentFile(), "collect.bak");
    455         if(backup_file.exists()) {
     453        File original_file = new File(collect_config_file.getParentFile(), COLLECT_CFG);
     454        File backup_file = new File(collect_config_file.getParentFile(), "collect.bak");
     455        if(backup_file.exists()) {
    456456        backup_file.delete();
    457         }
    458         if(!original_file.renameTo(backup_file)) {
     457        }
     458        if(!original_file.renameTo(backup_file)) {
    459459        Gatherer.println("Can't rename collect.cfg");
    460         }
     460        }
    461461    }
    462462    if(force_xml || collect_config_file.getName().equals(COLLECTCONFIGURATION_XML)) {
    463         ///ystem.err.println("Writing XML");
    464         Utility.export(document, new File(collect_config_file.getParentFile(), COLLECTCONFIGURATION_XML));
     463        ///ystem.err.println("Writing XML");
     464        Utility.export(document, new File(collect_config_file.getParentFile(), COLLECTCONFIGURATION_XML));
    465465    }
    466466    else {
    467         ///ystem.err.println("Writing text");
    468         try {
     467        ///ystem.err.println("Writing text");
     468        try {
    469469        FileWriter file_writer = new FileWriter(collect_config_file, false);
    470470        BufferedWriter buffered_writer = new BufferedWriter(file_writer);
     
    476476        boolean just_wrote_newline = false; // Prevent two or more newlines in a row
    477477        for(int i = 0; i < command_elements.getLength(); i++) {
    478             Node command_node = command_elements.item(i);
    479             if(command_node instanceof Element) {
     478            Node command_node = command_elements.item(i);
     479            if(command_node instanceof Element) {
    480480            Element command_element = (Element) command_node;
    481481            // The only thing left are NewLine elements
    482482            if(command_element.getNodeName().equals(NEWLINE_ELEMENT) && !just_wrote_newline) {
    483                 buffered_writer.newLine();
    484                 just_wrote_newline = true;
     483                buffered_writer.newLine();
     484                just_wrote_newline = true;
    485485            }
    486486            // Anything else we write to file, but only if it has been assigned, the exception being the Indexes element which just get commented if unassigned (a side effect of MG && MGPP compatibility)
    487487            else if(!command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR) || command_element.getNodeName().equals(INDEXES_ELEMENT) || command_element.getNodeName().equals(INDEX_DEFAULT_ELEMENT) || command_element.getNodeName().equals(LEVELS_ELEMENT)){
    488                 String command = toString(command_element, false);
    489                 if(command != null && command.length() > 0) {
     488                String command = toString(command_element, false);
     489                if(command != null && command.length() > 0) {
    490490                write(buffered_writer, command);
    491491                buffered_writer.newLine();
    492492                just_wrote_newline = false;
    493                 }
    494             }
    495             }
     493                }
     494            }
     495            }
    496496        }
    497497        buffered_writer.close();
    498498        known_metadata = null;
    499         }
    500         catch (Exception exception) {
     499        }
     500        catch (Exception exception) {
    501501        Gatherer.println("Error in CollectionConfiguration.save(boolean): " + exception);
    502502        Gatherer.printStackTrace(exception);
    503         }
    504     }
    505     }
    506 
    507     /** ************************** Private Methods ***************************/
    508 
    509     private String classifyToString(Element command_element, boolean show_extracted_namespace) {
     503        }
     504    }
     505    }
     506
     507    /** ************************** Private Methods ***************************/
     508
     509    private String classifyToString(Element command_element, boolean show_extracted_namespace) {
    510510    StringBuffer text = new StringBuffer(CLASSIFY_STR);
    511511    text.append(TAB_CHARACTER);
     
    515515    int option_elements_length = option_elements.getLength();
    516516    for(int j = 0; j < option_elements_length; j++) {
    517         Element option_element = (Element) option_elements.item(j);
    518         if(option_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
     517        Element option_element = (Element) option_elements.item(j);
     518        if(option_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
    519519        text.append(StaticStrings.MINUS_CHARACTER);
    520520        text.append(option_element.getAttribute(NAME_ATTRIBUTE));
    521521        String value_str = MSMUtils.getValue(option_element);
    522522        if(value_str.length() > 0) {
    523             // If the value happens to be the identifier of an extracted metadata element, then remove the namespace.
    524             if(!show_extracted_namespace && value_str.startsWith(EXTRACTED_PREFIX)) {
     523            // If the value happens to be the identifier of an extracted metadata element, then remove the namespace.
     524            if(!show_extracted_namespace && value_str.startsWith(EXTRACTED_PREFIX)) {
    525525            value_str = value_str.substring(EXTRACTED_PREFIX.length());
    526             }
    527             text.append(SPACE_CHARACTER);
    528             if(value_str.indexOf(SPACE_CHARACTER) == -1) {
     526            }
     527            text.append(SPACE_CHARACTER);
     528            if(value_str.indexOf(SPACE_CHARACTER) == -1) {
    529529            text.append(value_str);
    530             }
    531             else {
     530            }
     531            else {
    532532            text.append(SPEECH_CHARACTER);
    533533            text.append(value_str);
    534534            text.append(SPEECH_CHARACTER);
    535             }
     535            }
    536536        }
    537537        value_str = null;
    538538        if(j < option_elements_length - 1) {
    539             text.append(SPACE_CHARACTER);
    540         }
    541         }
    542         option_element = null;
     539            text.append(SPACE_CHARACTER);
     540        }
     541        }
     542        option_element = null;
    543543    }
    544544    option_elements = null;
    545545    return text.toString();
    546     }
    547 
    548     private String formatToString(Element command_element, boolean show_extracted_namespace) {
     546    }
     547
     548    private String formatToString(Element command_element, boolean show_extracted_namespace) {
    549549    StringBuffer text = new StringBuffer(FORMAT_STR);
    550550    text.append(SPACE_CHARACTER);
     
    553553    String value_str = command_element.getAttribute(VALUE_ATTRIBUTE);
    554554    if(value_str.length() != 0) {
    555         text.append(value_str);
     555        text.append(value_str);
    556556    }
    557557    else {
     
    560560       // Remove any references to a namespace for extracted metadata
    561561       if(!show_extracted_namespace) {
    562           value_str.replaceAll(EXTRACTED_PREFIX, "");
     562          value_str.replaceAll(EXTRACTED_PREFIX, "");
    563563       }
    564564       text.append(SPEECH_CHARACTER);
     
    568568    value_str = null;
    569569    return text.toString();
    570     }
    571 
    572     /** Retrieve or create the indexes Element. */
    573     private Element getOrCreateElementByTagName(String name, String conditional_attribute, String required_value) {
     570    }
     571
     572    /** Retrieve or create the indexes Element. */
     573    private Element getOrCreateElementByTagName(String name, String conditional_attribute, String required_value) {
    574574    Element document_element = document.getDocumentElement();
    575575    NodeList elements = document_element.getElementsByTagName(name);
    576576    int elements_length = elements.getLength();
    577577    if(elements_length > 0) {
    578         if(conditional_attribute == null) {
     578        if(conditional_attribute == null) {
    579579        document_element = null;
    580580        return (Element) elements.item(0);
    581         }
    582         else {
     581        }
     582        else {
    583583        for(int i = 0; i < elements_length; i++) {
    584             Element element = (Element) elements.item(i);
    585             if(element.getAttribute(conditional_attribute).equals(required_value)) {
     584            Element element = (Element) elements.item(i);
     585            if(element.getAttribute(conditional_attribute).equals(required_value)) {
    586586            document_element = null;
    587587            return element;
    588             }
    589             element = null;
    590         }
    591         }
     588            }
     589            element = null;
     590        }
     591        }
    592592    }
    593593    // Create the element
     
    595595    // If there was a property set it
    596596    if(conditional_attribute != null) {
    597         element.setAttribute(conditional_attribute, required_value);
     597        element.setAttribute(conditional_attribute, required_value);
    598598    }
    599599    Node target_node = findInsertionPoint(element);
    600600    if(target_node != null) {
    601         document_element.insertBefore(element, target_node);
     601        document_element.insertBefore(element, target_node);
    602602    }
    603603    else {
    604         document_element.appendChild(element);
     604        document_element.appendChild(element);
    605605    }
    606606    document_element = null;
    607607    return element;
    608     }
    609 
    610     private String indexesToString(Element command_element, boolean show_extracted_namespace) {
     608    }
     609
     610    private String indexesToString(Element command_element, boolean show_extracted_namespace) {
    611611    boolean comment_only = false;
    612612    StringBuffer text = new StringBuffer("");
    613613    if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
    614         text.append("#");
    615         comment_only = true;
     614        text.append("#");
     615        comment_only = true;
    616616    }
    617617    text.append(INDEX_STR);
    618618    text.append(TAB_CHARACTER);
    619619    if(!comment_only) {
    620         text.append(TAB_CHARACTER);
     620        text.append(TAB_CHARACTER);
    621621    }
    622622    NodeList index_elements = command_element.getElementsByTagName(INDEX_ELEMENT);
    623623    if (index_elements.getLength() == 0) { // no indexes
    624         return "";
     624        return "";
    625625    }
    626626    // For each index, write its level, a colon, then concatenate its child content elements into a single comma separated list
    627627    int index_elements_length = index_elements.getLength();
    628628    for(int j = 0; j < index_elements_length; j++) {
    629         Element index_element = (Element) index_elements.item(j);
    630         String level_str = index_element.getAttribute(LEVEL_ATTRIBUTE);
    631         if(level_str.length() > 0) {
     629        Element index_element = (Element) index_elements.item(j);
     630        String level_str = index_element.getAttribute(LEVEL_ATTRIBUTE);
     631        if(level_str.length() > 0) {
    632632        text.append(level_str);
    633633        text.append(StaticStrings.COLON_CHARACTER);
    634         }
    635         NodeList content_elements = index_element.getElementsByTagName(CONTENT_ELEMENT);
    636         int content_elements_length = content_elements.getLength();
    637         // Don't output anything if no indexes are set
    638         if(content_elements_length == 0) {
     634        }
     635        NodeList content_elements = index_element.getElementsByTagName(CONTENT_ELEMENT);
     636        int content_elements_length = content_elements.getLength();
     637        // Don't output anything if no indexes are set
     638        if(content_elements_length == 0) {
    639639        return null;
    640         }
    641         for(int k = 0; k < content_elements_length; k++) {
     640        }
     641        for(int k = 0; k < content_elements_length; k++) {
    642642        Element content_element = (Element) content_elements.item(k);
    643643        String name_str = content_element.getAttribute(NAME_ATTRIBUTE);
    644644        if(!show_extracted_namespace && name_str.startsWith(EXTRACTED_PREFIX)) {
    645             name_str = name_str.substring(EXTRACTED_PREFIX.length());
     645            name_str = name_str.substring(EXTRACTED_PREFIX.length());
    646646        }
    647647        text.append(name_str);
    648648        name_str = null;
    649649        if(k < content_elements_length - 1) {
    650             text.append(StaticStrings.COMMA_CHARACTER);
     650            text.append(StaticStrings.COMMA_CHARACTER);
    651651        }
    652652        content_element = null;
    653         }
    654         if(j < index_elements_length - 1) {
     653        }
     654        if(j < index_elements_length - 1) {
    655655        text.append(SPACE_CHARACTER);
    656         }
    657         content_elements = null;
    658         index_element = null;
     656        }
     657        content_elements = null;
     658        index_element = null;
    659659    }
    660660    index_elements = null;
    661661    return text.toString();
    662     }
    663 
    664     private String indexDefaultToString(Element command_element, boolean show_extracted_namespace) {
     662    }
     663
     664    private String indexDefaultToString(Element command_element, boolean show_extracted_namespace) {
    665665    StringBuffer text = new StringBuffer("");
    666666    if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(FALSE_STR)) {
    667         text.append("#");
     667        text.append("#");
    668668    }
    669669    text.append(INDEX_DEFAULT_STR);
     
    674674    int content_elements_length = content_elements.getLength();
    675675    for(int j = 0; j < content_elements_length; j++) {
    676         Element content_element = (Element) content_elements.item(j);
    677         String name_str = content_element.getAttribute(NAME_ATTRIBUTE);
    678         if(!show_extracted_namespace && name_str.startsWith(EXTRACTED_PREFIX)) {
     676        Element content_element = (Element) content_elements.item(j);
     677        String name_str = content_element.getAttribute(NAME_ATTRIBUTE);
     678        if(!show_extracted_namespace && name_str.startsWith(EXTRACTED_PREFIX)) {
    679679        name_str = name_str.substring(EXTRACTED_PREFIX.length());
    680         }
    681         text.append(name_str);
    682         name_str = null;
    683         if(j < content_elements_length - 1) {
     680        }
     681        text.append(name_str);
     682        name_str = null;
     683        if(j < content_elements_length - 1) {
    684684        text.append(StaticStrings.COMMA_CHARACTER);
    685         }
    686         content_element = null;
     685        }
     686        content_element = null;
    687687    }
    688688    content_elements = null;
    689689    return text.toString();
    690     }
    691 
    692     private String languagesToString(Element command_element) {
     690    }
     691
     692    private String languagesToString(Element command_element) {
    693693    StringBuffer text = new StringBuffer(LANGUAGES_STR);
    694694    text.append(TAB_CHARACTER);
     
    697697    int language_elements_length = language_elements.getLength();
    698698    if(language_elements_length == 0) {
    699         return null;
     699        return null;
    700700    }
    701701    for(int j = 0; j < language_elements_length; j++) {
    702         Element language_element = (Element) language_elements.item(j);
    703         text.append(language_element.getAttribute(NAME_ATTRIBUTE));
    704         if(j < language_elements_length - 1) {
     702        Element language_element = (Element) language_elements.item(j);
     703        text.append(language_element.getAttribute(NAME_ATTRIBUTE));
     704        if(j < language_elements_length - 1) {
    705705        text.append(SPACE_CHARACTER);
    706         }
     706        }
    707707    }
    708708    return text.toString();
    709     }
    710 
    711     private String languageDefaultToString(Element command_element) {
     709    }
     710
     711    private String languageDefaultToString(Element command_element) {
    712712    StringBuffer text = new StringBuffer(LANGUAGE_DEFAULT_STR);
    713713    text.append(TAB_CHARACTER);
    714714    text.append(command_element.getAttribute(NAME_ATTRIBUTE));
    715715    return text.toString();
    716     }
    717 
    718     private String levelsToString(Element command_element) {
     716    }
     717
     718    private String levelsToString(Element command_element) {
    719719    StringBuffer text = new StringBuffer("");
    720720    if(!command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
    721         text.append("#");
     721        text.append("#");
    722722    }
    723723    text.append(LEVELS_STR);
     
    728728    // Don't output anything if no levels are set.
    729729    if(content_elements_length == 0) {
    730         return null;
     730        return null;
    731731    }
    732732    for(int i = 0; i < content_elements_length; i++) {
    733         Element content_element = (Element) content_elements.item(i);
    734         text.append(content_element.getAttribute(NAME_ATTRIBUTE));
    735         text.append(SPACE_CHARACTER);
     733        Element content_element = (Element) content_elements.item(i);
     734        text.append(content_element.getAttribute(NAME_ATTRIBUTE));
     735        text.append(SPACE_CHARACTER);
    736736    }
    737737    return text.substring(0, text.length() - 1);
    738     }
    739 
    740     static public String metadataToString(Element command_element, boolean text_value) {
     738    }
     739
     740    static public String metadataToString(Element command_element, boolean text_value) {
    741741    boolean special = false;
    742742    // If there is no value attribute, then we don't write anything
     
    745745    // If the name is one of the special four, we don't write the collectionmeta first. Note the maintainer collectionmeta is singled out for 'prittying' reasons.
    746746    if(name_str.equals(COLLECTIONMETADATA_MAINTAINER_STR)) {
    747         text.append(name_str);
    748         text.append(TAB_CHARACTER);
    749         special = true;
     747        text.append(name_str);
     748        text.append(TAB_CHARACTER);
     749        special = true;
    750750    }
    751751    else if(name_str.equals(COLLECTIONMETADATA_BETA_STR) || name_str.equals(COLLECTIONMETADATA_CREATOR_STR) || name_str.equals(COLLECTIONMETADATA_PUBLIC_STR)) {
    752         text.append(name_str);
    753         text.append(TAB_CHARACTER);
    754         text.append(TAB_CHARACTER);
    755         special = true;
     752        text.append(name_str);
     753        text.append(TAB_CHARACTER);
     754        text.append(TAB_CHARACTER);
     755        special = true;
    756756    }
    757757    else {
    758         text.append(COLLECTIONMETADATA_STR);
    759         text.append(TAB_CHARACTER);
    760         text.append(name_str);
    761         text.append(SPACE_CHARACTER);
    762         String language_str = command_element.getAttribute(LANGUAGE_ATTRIBUTE);
    763         // If this is element is in english, and it is the first one found, we don't need to write the language argument.
    764         //if(!language_str.equals(ENGLISH_LANGUAGE_STR) || known_metadata == null || known_metadata.contains(name_str)) {
    765         // changed so that we always write the language string
    766         text.append(LBRACKET_CHARACTER);
    767         text.append(LANGUAGE_ARGUMENT);
    768         text.append(language_str);
    769         text.append(RBRACKET_CHARACTER);
    770         text.append(SPACE_CHARACTER);
    771         //}
    772         if(known_metadata != null) {
     758        text.append(COLLECTIONMETADATA_STR);
     759        text.append(TAB_CHARACTER);
     760        text.append(name_str);
     761        text.append(SPACE_CHARACTER);
     762        String language_str = command_element.getAttribute(LANGUAGE_ATTRIBUTE);
     763        // If this is element is in english, and it is the first one found, we don't need to write the language argument.
     764        //if(!language_str.equals(ENGLISH_LANGUAGE_STR) || known_metadata == null || known_metadata.contains(name_str)) {
     765        // changed so that we always write the language string
     766        text.append(LBRACKET_CHARACTER);
     767        text.append(LANGUAGE_ARGUMENT);
     768        text.append(language_str);
     769        text.append(RBRACKET_CHARACTER);
     770        text.append(SPACE_CHARACTER);
     771        //}
     772        if(known_metadata != null) {
    773773        known_metadata.add(name_str);
    774         }
    775         language_str = null;
     774        }
     775        language_str = null;
    776776    }
    777777    name_str = null;
    778    
     778
    779779    String value_str = MSMUtils.getValue(command_element);
    780780    // The value string we retrieved will be encoded for xml, so we now decode it - to text if text_value set. This parameter was originally show_extracted_namespace, but sincethis is only true for 'toString()' commands from within the CDM, its good enough to determine if this toString() will be used to display on screen, or write to collect.cfg
    781781    if(text_value == CollectionMeta.TEXT) {
    782         value_str = Codec.transform(value_str, Codec.DOM_TO_TEXT);
     782        value_str = Codec.transform(value_str, Codec.DOM_TO_TEXT);
    783783    }
    784784    else {
    785         value_str = Codec.transform(value_str, Codec.DOM_TO_GREENSTONE);
    786     }
    787    
     785        value_str = Codec.transform(value_str, Codec.DOM_TO_GREENSTONE);
     786    }
     787
    788788    // We don't wrap the email addresses in quotes, nor the other special metadata
    789789    if(special) {
    790         text.append(value_str);
     790        text.append(value_str);
    791791    }
    792792    else {
    793         text.append(SPEECH_CHARACTER);
    794         text.append(value_str);
    795         text.append(SPEECH_CHARACTER);
     793        text.append(SPEECH_CHARACTER);
     794        text.append(value_str);
     795        text.append(SPEECH_CHARACTER);
    796796    }
    797797    value_str = null;
    798798    return text.toString();
    799     }
    800 
    801     /** Parse a collect.cfg into a DOM model representation. */
    802     private void parse(File collect_config_file) {
    803     try {
    804         Element collect_cfg_element = document.getDocumentElement();
    805         // Read in the file one command at a time.
    806         FileReader in_reader = new FileReader(collect_config_file);
    807         BufferedReader in = new BufferedReader(in_reader);
    808         String command_str = null;
    809         while((command_str = in.readLine()) != null) {
    810         Element command_element = null;
    811         // A command may be broken over several lines.
    812         command_str = command_str.trim();
    813         boolean eof = false;
    814         while(!eof && command_str.endsWith(NEWLINE_CHARACTER)) {
    815             String next_line = in.readLine();
    816             if(next_line != null) {
    817             next_line = next_line.trim();
    818             if(next_line.length() > 0) {
    819                 // Remove the new line character
    820                 command_str = command_str.substring(0, command_str.lastIndexOf(NEWLINE_CHARACTER));
    821                 // And append the next line, which due to the test above must be non-zero length
    822                 command_str = command_str + next_line;
    823             }
    824             next_line = null;
    825             }
    826             // If we've reached the end of the file theres nothing more we can do
    827             else {
    828             eof = true;
    829             }
    830         }
    831         // If there is still a new line character, then we remove it and hope for the best
    832         if(command_str.endsWith(NEWLINE_CHARACTER)) {
    833             command_str = command_str.substring(0, command_str.lastIndexOf(NEWLINE_CHARACTER));
    834         }
    835         // Now we've either got a command to parse...
    836         if(command_str.length() != 0) {
    837             // Start trying to figure out what it is
    838             StringTokenizer tokenizer = new StringTokenizer(command_str);
    839             String command_type = tokenizer.nextToken().toLowerCase();
    840             tokenizer = null;
    841             // Why can't you switch on strings eh? We pass it to the various subparsers who each have a bash at parsing the command. If none can parse the command, an unknown element is created
    842             if(command_element == null && command_type.equals(CLASSIFY_STR)) {
    843             command_element = parseClassify(command_str);
    844             }
    845             if(command_element == null && command_type.equals(FORMAT_STR)) {
    846             command_element = parseFormat(command_str, in);
    847             }
    848             if(command_element == null && (command_type.equals(INDEX_STR)  || command_type.equals(COMMENTED_INDEXES_STR))) {
    849             command_element = parseIndex(command_str);
    850             }
    851             if(command_element == null && (command_type.equals(INDEX_DEFAULT_STR) || command_type.equals(COMMENTED_INDEX_DEFAULT_STR))) {
    852             command_element = parseIndexDefault(command_str);
    853             }
    854             if(command_element == null && command_type.equals(LANGUAGES_STR)) {
    855             command_element = parseLanguage(command_str);
    856             }
    857             if(command_element == null && command_type.equals(LANGUAGE_DEFAULT_STR)) {
    858             command_element = parseLanguageDefault(command_str);
    859             }
    860             if(command_element == null && (command_type.equals(LEVELS_STR) || command_type.equals(COMMENTED_LEVELS_STR))) {
    861             command_element = parseLevels(command_str);
    862             }
    863             if(command_element == null && command_type.equals(COLLECTIONMETADATA_STR)) {
    864             // collectionmeta may go over more than one line, so
    865             // pass in the reader
    866             command_element = parseMetadata(command_str, in);
    867             }
    868             if(command_element == null && (command_type.equals(COLLECTIONMETADATA_BETA_STR) || command_type.equals(COLLECTIONMETADATA_PUBLIC_STR) || command_type.equals(COLLECTIONMETADATA_CREATOR_STR) || command_type.equals(COLLECTIONMETADATA_MAINTAINER_STR))) {
    869             command_element = parseMetadataSpecial(command_str);
    870             }
    871             if(command_element == null && command_type.equals(PLUGIN_STR)) {
    872             command_element = parsePlugIn(command_str);
    873             }
    874             if(command_element == null && command_type.equals(SEARCHTYPE_STR)) {
    875             command_element = parseSearchType(command_str);
    876             }
    877             if(command_element == null && command_type.equals(SUBCOLLECTION_STR)) {
    878             command_element = parseSubCollection(command_str);
    879             }
    880             if(command_element == null && command_type.equals(SUBCOLLECTION_DEFAULT_INDEX_STR)) {
    881             command_element = parseSubCollectionDefaultIndex(command_str);
    882             }
    883             if(command_element == null && command_type.equals(SUBCOLLECTION_INDEX_STR)) {
    884             command_element = parseSubCollectionIndex(command_str);
    885             }
    886             if(command_element == null && (command_type.equals(SUPERCOLLECTION_STR) || command_type.equals(CCS_STR))) {
    887             command_element = parseSuperCollection(command_str);
    888             }
    889             // Doesn't match any known type
    890             command_type = null;
    891             if(command_element == null) {
     799    }
     800
     801    /** Parse a collect.cfg into a DOM model representation. */
     802    private void parse(File collect_config_file) {
     803        try {
     804            Element collect_cfg_element = document.getDocumentElement();
     805            // Read in the file one command at a time.
     806            FileReader in_reader = new FileReader(collect_config_file);
     807            BufferedReader in = new BufferedReader(in_reader);
     808            String command_str = null;
     809            while((command_str = in.readLine()) != null) {
     810                Element command_element = null;
     811                // A command may be broken over several lines.
     812                command_str = command_str.trim();
     813                boolean eof = false;
     814                while(!eof && command_str.endsWith(NEWLINE_CHARACTER)) {
     815                    String next_line = in.readLine();
     816                    if(next_line != null) {
     817                        next_line = next_line.trim();
     818                        if(next_line.length() > 0) {
     819                            // Remove the new line character
     820                            command_str = command_str.substring(0, command_str.lastIndexOf(NEWLINE_CHARACTER));
     821                            // And append the next line, which due to the test above must be non-zero length
     822                            command_str = command_str + next_line;
     823                        }
     824                        next_line = null;
     825                    }
     826                    // If we've reached the end of the file theres nothing more we can do
     827                    else {
     828                        eof = true;
     829                    }
     830                }
     831                // If there is still a new line character, then we remove it and hope for the best
     832                if(command_str.endsWith(NEWLINE_CHARACTER)) {
     833                    command_str = command_str.substring(0, command_str.lastIndexOf(NEWLINE_CHARACTER));
     834                }
     835                // Now we've either got a command to parse...
     836                if(command_str.length() != 0) {
     837                    // Start trying to figure out what it is
     838                    //StringTokenizer tokenizer = new StringTokenizer(command_str);
     839                    // Instead of a standard string tokenizer I'm going to use the new version of CommandTokenizer, which is not only smart enough to correctly notice speech marks and correctly parse them out, but now also takes the input stream so it can rebuild tokens that stretch over several lines.
     840                    CommandTokenizer tokenizer = new CommandTokenizer(command_str, in);
     841                    String command_type = tokenizer.nextToken().toLowerCase();
     842                    // Why can't you switch on strings eh? We pass it to the various subparsers who each have a bash at parsing the command. If none can parse the command, an unknown element is created
     843                    if(command_element == null && command_type.equals(CLASSIFY_STR)) {
     844                        command_element = parseClassify(command_str);
     845                    }
     846                    if(command_element == null && command_type.equals(FORMAT_STR)) {
     847                        command_element = parseFormat(tokenizer); // Revised to handle multiple lines
     848                    }
     849                    if(command_element == null && (command_type.equals(INDEX_STR)  || command_type.equals(COMMENTED_INDEXES_STR))) {
     850                        command_element = parseIndex(command_str);
     851                    }
     852                    if(command_element == null && (command_type.equals(INDEX_DEFAULT_STR) || command_type.equals(COMMENTED_INDEX_DEFAULT_STR))) {
     853                        command_element = parseIndexDefault(command_str);
     854                    }
     855                    if(command_element == null && command_type.equals(LANGUAGES_STR)) {
     856                        command_element = parseLanguage(command_str);
     857                    }
     858                    if(command_element == null && command_type.equals(LANGUAGE_DEFAULT_STR)) {
     859                        command_element = parseLanguageDefault(command_str);
     860                    }
     861                    if(command_element == null && (command_type.equals(LEVELS_STR) || command_type.equals(COMMENTED_LEVELS_STR))) {
     862                        command_element = parseLevels(command_str);
     863                    }
     864                    if(command_element == null && command_type.equals(COLLECTIONMETADATA_STR)) {
     865                        command_element = parseMetadata(tokenizer); // Revised to handle multiple lines
     866                    }
     867                    if(command_element == null && (command_type.equals(COLLECTIONMETADATA_BETA_STR) || command_type.equals(COLLECTIONMETADATA_PUBLIC_STR) || command_type.equals(COLLECTIONMETADATA_CREATOR_STR) || command_type.equals(COLLECTIONMETADATA_MAINTAINER_STR))) {
     868                        command_element = parseMetadataSpecial(command_str);
     869                    }
     870                    if(command_element == null && command_type.equals(PLUGIN_STR)) {
     871                        command_element = parsePlugIn(command_str);
     872                    }
     873                    if(command_element == null && command_type.equals(SEARCHTYPE_STR)) {
     874                        command_element = parseSearchType(command_str);
     875                    }
     876                    if(command_element == null && command_type.equals(SUBCOLLECTION_STR)) {
     877                        command_element = parseSubCollection(command_str);
     878                    }
     879                    if(command_element == null && command_type.equals(SUBCOLLECTION_DEFAULT_INDEX_STR)) {
     880                        command_element = parseSubCollectionDefaultIndex(command_str);
     881                    }
     882                    if(command_element == null && command_type.equals(SUBCOLLECTION_INDEX_STR)) {
     883                        command_element = parseSubCollectionIndex(command_str);
     884                    }
     885                    if(command_element == null && (command_type.equals(SUPERCOLLECTION_STR) || command_type.equals(CCS_STR))) {
     886                        command_element = parseSuperCollection(command_str);
     887                    }
     888            // Doesn't match any known type
     889            command_type = null;
     890            if(command_element == null) {
    892891            // No-one knows what to do with this command, so we create an Unknown command element
    893892            command_element = document.createElement(UNKNOWN_ELEMENT);
     
    897896        // Or an empty line to remember for later
    898897        else {
    899             command_element = document.createElement(NEWLINE_ELEMENT);
     898            command_element = document.createElement(NEWLINE_ELEMENT);
    900899        }
    901900        // Now command element shouldn't be null so we append it to the collection config DOM
    902901        collect_cfg_element.appendChild(command_element);
    903         }
     902        }
    904903    }
    905904    catch(Exception exception) {
    906         Gatherer.println("Error in CollectionConfiguration.parse(java.io.File): " + exception);
    907         Gatherer.printStackTrace(exception);
    908     }
    909     }
    910 
    911     private Element parseClassify(String command_str) {
     905        Gatherer.println("Error in CollectionConfiguration.parse(java.io.File): " + exception);
     906        Gatherer.printStackTrace(exception);
     907    }
     908    }
     909
     910    private Element parseClassify(String command_str) {
    912911    Element command_element = null;
    913912    try {
    914         CommandTokenizer tokenizer = new CommandTokenizer(command_str);
    915         // Check the token count. The token count from a command tokenizer isn't guarenteed to be correct, but it does give the maximum number of available tokens according to the underlying StringTokenizer (some of which may actually be append together by the CommandTokenizer as being a single argument).
    916         if(tokenizer.countTokens() >= 2) {  // Must support "classify Phind" (no args)
     913        CommandTokenizer tokenizer = new CommandTokenizer(command_str);
     914        // Check the token count. The token count from a command tokenizer isn't guarenteed to be correct, but it does give the maximum number of available tokens according to the underlying StringTokenizer (some of which may actually be append together by the CommandTokenizer as being a single argument).
     915        if(tokenizer.countTokens() >= 2) {  // Must support "classify Phind" (no args)
    917916        command_element = document.createElement(CLASSIFY_ELEMENT);
    918917        // First token is classify
     
    925924        Iterator names = arguments.keySet().iterator();
    926925        while(names.hasNext()) {
    927             String name = (String) names.next();
    928             String value = (String) arguments.get(name); // Can be null
    929             // The metadata argument gets added as the content attribute
    930             if(name.equals(METADATA_ARGUMENT) && value != null) {
     926            String name = (String) names.next();
     927            String value = (String) arguments.get(name); // Can be null
     928            // The metadata argument gets added as the content attribute
     929            if(name.equals(METADATA_ARGUMENT) && value != null) {
    931930            // 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.
    932931            if(value.indexOf(MSMUtils.NS_SEP) == -1) {
    933                 value = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + value;
     932                value = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + value;
    934933            }
    935934            //command_element.setAttribute(CONTENT_ATTRIBUTE, value);
    936             }
    937             // Everything else is an Option Element
    938             Element option_element = document.createElement(OPTION_ELEMENT);
    939             option_element.setAttribute(NAME_ATTRIBUTE, name.substring(1));
    940             if(value != null) {
     935            }
     936            // Everything else is an Option Element
     937            Element option_element = document.createElement(OPTION_ELEMENT);
     938            option_element.setAttribute(NAME_ATTRIBUTE, name.substring(1));
     939            if(value != null) {
    941940            // Remove any speech marks appended in strings containing whitespace
    942941            if(value.startsWith(SPEECH_CHARACTER) && value.endsWith(SPEECH_CHARACTER)) {
    943                 value = value.substring(1, value.length() - 1);
     942                value = value.substring(1, value.length() - 1);
    944943            }
    945944            MSMUtils.setValue(option_element, value);
    946             }
    947             option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
    948             option_element.setAttribute(CUSTOM_ATTRIBUTE, TRUE_STR);
    949             command_element.appendChild(option_element);
    950             option_element = null;
    951             name = null;
    952             value = null;
     945            }
     946            option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
     947            option_element.setAttribute(CUSTOM_ATTRIBUTE, TRUE_STR);
     948            command_element.appendChild(option_element);
     949            option_element = null;
     950            name = null;
     951            value = null;
    953952        }
    954953        names = null;
    955954        arguments = null;
    956         }
    957         tokenizer = null;
     955        }
     956        tokenizer = null;
    958957    }
    959958    catch(Exception error) {
    960959    }
    961960    return command_element;
    962     }
    963 
    964     private Element parseFormat(String command_str, BufferedReader in) {
     961    }
     962
     963    private Element parseFormat(CommandTokenizer tokenizer) {
     964        Element command_element = null;
     965        try {
     966            command_element = document.createElement(FORMAT_ELEMENT);
     967            String name_str = tokenizer.nextToken();
     968            String value_str = tokenizer.nextToken();
     969            if(name_str != null && value_str != null) {
     970                command_element.setAttribute(NAME_ATTRIBUTE, name_str);
     971                // If the value is true or false we add it as an attribute
     972                if(value_str.equalsIgnoreCase(TRUE_STR) || value_str.equalsIgnoreCase(FALSE_STR)) {
     973                    command_element.setAttribute(VALUE_ATTRIBUTE, value_str.toLowerCase());
     974                }
     975                // Otherwise it gets added as a text node
     976                else {
     977                    // Ready the value str (which can contain all sorts of funky characters) for writing as a DOM value
     978                    value_str = Codec.transform(value_str, Codec.GREENSTONE_TO_DOM);
     979                    MSMUtils.setValue(command_element, value_str);
     980                }
     981            }
     982            else {
     983                command_element = null;
     984            }
     985            name_str = null;
     986            value_str = null;
     987        }
     988        catch (Exception exception) {
     989            Gatherer.printStackTrace(exception);
     990            command_element = null;
     991        }
     992        return command_element;
     993    }
     994
     995    private Element parseIndex(String command_str) {
    965996    Element command_element = null;
    966997    try {
    967         CommandTokenizer tokenizer = new CommandTokenizer(command_str);
    968         if(tokenizer.countTokens() >= 3) {
    969         command_element = document.createElement(FORMAT_ELEMENT);
    970         // First token is format
    971         tokenizer.nextToken();
    972         command_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
    973         String value_str = tokenizer.nextToken();
    974         // If the value is true or false we add it as an attribute
    975         if(value_str.equalsIgnoreCase(TRUE_STR) || value_str.equalsIgnoreCase(FALSE_STR)) {
    976             command_element.setAttribute(VALUE_ATTRIBUTE, value_str.toLowerCase());
    977         }
    978         // Otherwise it gets added as a text node
    979         else {
    980 
    981             // now we need to handle the case where the value is enclosed in quotes (single or double) and may extend across multiple lines
    982             String start_string = value_str.substring(0,1);
    983             if (start_string.equals("\"") || start_string.equals("\'")) {
    984             if (value_str.endsWith(start_string) && value_str.length()!=1) {
    985                 // we remove the quotes from the ends
    986                 value_str = value_str.substring(1, value_str.length() - 1);
    987             } else {
    988                
    989                 // remove the first quote
    990                 StringBuffer value_raw = new StringBuffer(value_str.substring(1));
    991                 // add the new line back in
    992                 value_raw.append(StaticStrings.NEW_LINE_CHAR);
    993                 int pos = value_raw.indexOf(start_string);
    994                 int old_pos = 0;
    995                 while (pos != -1 && value_raw.charAt(pos-1)=='\\') {
    996                 old_pos = pos+1;
    997                 pos = value_raw.indexOf(start_string, old_pos);
    998                 }
    999                 while(pos == -1) {
    1000                 String next_line = in.readLine();
    1001                 if(next_line != null) {
    1002                     value_raw.append(next_line);
    1003                     value_raw.append(StaticStrings.NEW_LINE_CHAR);
    1004                 }
    1005                 next_line = null;
    1006                 pos = value_raw.indexOf(start_string, old_pos);
    1007                 while (pos != -1 && value_raw.charAt(pos-1)=='\\') {
    1008                     old_pos = pos+1;
    1009                     pos = value_raw.indexOf(start_string, old_pos);
    1010                 }
    1011                 }
    1012                
    1013                 value_str = value_raw.substring(0, value_raw.lastIndexOf(start_string));
    1014                 value_raw = null;
    1015                
    1016             } // else
    1017             } // if starts with a quote
    1018                    
    1019             if(value_str != null) {
    1020             // Ready the value str (which can contain all sorts of funky characters) for writing as a DOM value
    1021             value_str = Codec.transform(value_str, Codec.GREENSTONE_TO_DOM);
    1022             MSMUtils.setValue(command_element, value_str);
    1023             }
    1024             else {
    1025             command_element = null;
    1026             }
    1027             start_string = null;
    1028         }
    1029         value_str = null;
    1030        
    1031         }
    1032         tokenizer = null;
    1033     }
    1034     catch (Exception exception) {
    1035     }
    1036     return command_element;
    1037     }
    1038 
    1039     private Element parseIndex(String command_str) {
    1040     Element command_element = null;
    1041     try {
    1042         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1043         String command = tokenizer.nextToken();
    1044         command_element = document.createElement(INDEXES_ELEMENT);
    1045         command_element.setAttribute(ASSIGNED_ATTRIBUTE, (command.equals(INDEX_STR) ? TRUE_STR : FALSE_STR));
    1046         command = null;
    1047         if(!tokenizer.hasMoreTokens()) {
    1048        
     998        StringTokenizer tokenizer = new StringTokenizer(command_str);
     999        String command = tokenizer.nextToken();
     1000        command_element = document.createElement(INDEXES_ELEMENT);
     1001        command_element.setAttribute(ASSIGNED_ATTRIBUTE, (command.equals(INDEX_STR) ? TRUE_STR : FALSE_STR));
     1002        command = null;
     1003        if(!tokenizer.hasMoreTokens()) {
     1004
    10491005        // there are no indexes
    10501006        command_element.setAttribute(ASSIGNED_ATTRIBUTE, FALSE_STR);
     
    10521008        tokenizer = null;
    10531009        return command_element;
    1054         }
    1055        
    1056         while(tokenizer.hasMoreTokens()) {
     1010        }
     1011
     1012        while(tokenizer.hasMoreTokens()) {
    10571013        Element index_element = document.createElement(INDEX_ELEMENT);
    10581014        String index_str = tokenizer.nextToken();
     
    10601016        boolean old_index;
    10611017        if(index_str.indexOf(COLON_CHARACTER) != -1) {
    1062             old_index = true;
    1063             index_element.setAttribute(LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER)));
    1064             index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
    1065             command_element.setAttribute(MGPP_ATTRIBUTE, FALSE_STR);
     1018            old_index = true;
     1019            index_element.setAttribute(LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER)));
     1020            index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
     1021            command_element.setAttribute(MGPP_ATTRIBUTE, FALSE_STR);
    10661022        }
    10671023        else {
    1068             command_element.setAttribute(MGPP_ATTRIBUTE, TRUE_STR);
    1069             old_index = false;
     1024            command_element.setAttribute(MGPP_ATTRIBUTE, TRUE_STR);
     1025            old_index = false;
    10701026        }
    10711027        StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
    10721028        while(content_tokenizer.hasMoreTokens()) {
    1073             Element content_element = document.createElement(CONTENT_ELEMENT);
    1074             String content_str = content_tokenizer.nextToken();
    1075             // 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.
    1076             if(content_str.indexOf(MSMUtils.NS_SEP) == -1) {
     1029            Element content_element = document.createElement(CONTENT_ELEMENT);
     1030            String content_str = content_tokenizer.nextToken();
     1031            // 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.
     1032            if(content_str.indexOf(MSMUtils.NS_SEP) == -1) {
    10771033            if(content_str.equals(StaticStrings.TEXT_STR) || (!old_index && content_str.equals(StaticStrings.ALLFIELDS_STR))) {
    1078                 // Our special strings are OK.
     1034                // Our special strings are OK.
    10791035            }
    10801036            else {
    1081                 content_str = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + content_str;
    1082             }
    1083             }
    1084             content_element.setAttribute(NAME_ATTRIBUTE, content_str);
    1085             index_element.appendChild(content_element);
    1086             content_element = null;
     1037                content_str = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + content_str;
     1038            }
     1039            }
     1040            content_element.setAttribute(NAME_ATTRIBUTE, content_str);
     1041            index_element.appendChild(content_element);
     1042            content_element = null;
    10871043        }
    10881044        content_tokenizer = null;
     
    10901046        command_element.appendChild(index_element);
    10911047        index_element = null;
    1092         }
    1093         tokenizer = null;
     1048        }
     1049        tokenizer = null;
    10941050    }
    10951051    catch (Exception exception) {
    1096         exception.printStackTrace();
     1052        exception.printStackTrace();
    10971053    }
    10981054    return command_element;
    1099     }
    1100 
    1101     private Element parseIndexDefault(String command_str) {
     1055    }
     1056
     1057    private Element parseIndexDefault(String command_str) {
    11021058    Element command_element = null;
    11031059    try {
    1104         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1105         if(tokenizer.countTokens() >= 2) {
     1060        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1061        if(tokenizer.countTokens() >= 2) {
    11061062        command_element = document.createElement(INDEX_DEFAULT_ELEMENT);
    11071063        command_element.setAttribute(ASSIGNED_ATTRIBUTE, ((tokenizer.nextToken()).equals(INDEX_DEFAULT_STR) ? TRUE_STR : FALSE_STR));
     
    11111067        StringTokenizer content_tokenizer = new StringTokenizer(content_str, StaticStrings.COMMA_CHARACTER);
    11121068        while(content_tokenizer.hasMoreTokens()) {
    1113             Element content_element = document.createElement(CONTENT_ELEMENT);
    1114             content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
    1115             command_element.appendChild(content_element);
    1116             content_element = null;
     1069            Element content_element = document.createElement(CONTENT_ELEMENT);
     1070            content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
     1071            command_element.appendChild(content_element);
     1072            content_element = null;
    11171073        }
    11181074        content_tokenizer = null;
     
    11201076        content_str = null;
    11211077        index_str = null;
    1122         }
    1123         tokenizer = null;
     1078        }
     1079        tokenizer = null;
    11241080    }
    11251081    catch (Exception exception) {
    11261082    }
    11271083    return command_element;
    1128     }
    1129 
    1130     private Element parseLanguage(String command_str) {
     1084    }
     1085
     1086    private Element parseLanguage(String command_str) {
    11311087    Element command_element = null;
    11321088    try {
    1133         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1134         tokenizer.nextToken();
    1135         if(tokenizer.hasMoreTokens()) {
     1089        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1090        tokenizer.nextToken();
     1091        if(tokenizer.hasMoreTokens()) {
    11361092        command_element = document.createElement(LANGUAGES_ELEMENT);
    11371093        while(tokenizer.hasMoreTokens()) {
    1138             Element language_element = document.createElement(LANGUAGE_ELEMENT);
    1139             language_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
    1140             command_element.appendChild(language_element);
    1141             language_element = null;
    1142         }
    1143         }
    1144         tokenizer = null;
     1094            Element language_element = document.createElement(LANGUAGE_ELEMENT);
     1095            language_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
     1096            command_element.appendChild(language_element);
     1097            language_element = null;
     1098        }
     1099        }
     1100        tokenizer = null;
    11451101    }
    11461102    catch (Exception exception) {
    11471103    }
    11481104    return command_element;
    1149     }
    1150 
    1151     private Element parseLanguageDefault(String command_str) {
     1105    }
     1106
     1107    private Element parseLanguageDefault(String command_str) {
    11521108    Element command_element = null;
    11531109    try {
    1154         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1155         if(tokenizer.countTokens() >= 2) {
     1110        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1111        if(tokenizer.countTokens() >= 2) {
    11561112        command_element = document.createElement(LANGUAGE_DEFAULT_ELEMENT);
    11571113        tokenizer.nextToken();
     
    11601116        command_element.setAttribute(ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
    11611117        default_language_str = null;
    1162         }
    1163         tokenizer = null;
     1118        }
     1119        tokenizer = null;
    11641120    }
    11651121    catch (Exception exception) {
    11661122    }
    11671123    return command_element;
    1168     }
    1169 
    1170     private Element parseLevels(String command_str) {
     1124    }
     1125
     1126    private Element parseLevels(String command_str) {
    11711127    Element command_element = null;
    11721128    try {
    1173         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1174         // First token is command type (levels)
    1175         String command = tokenizer.nextToken();
    1176         if(tokenizer.hasMoreTokens()) {
     1129        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1130        // First token is command type (levels)
     1131        String command = tokenizer.nextToken();
     1132        if(tokenizer.hasMoreTokens()) {
    11771133        command_element = document.createElement(LEVELS_ELEMENT);
    11781134        command_element.setAttribute(ASSIGNED_ATTRIBUTE, (command.equals(LEVELS_STR) ? TRUE_STR : FALSE_STR));
    11791135        while(tokenizer.hasMoreTokens()) {
    1180             Element level_element = document.createElement(CONTENT_ELEMENT);
    1181             level_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
    1182             command_element.appendChild(level_element);
    1183             level_element = null;
    1184         }
    1185         }
    1186         command = null;
     1136            Element level_element = document.createElement(CONTENT_ELEMENT);
     1137            level_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
     1138            command_element.appendChild(level_element);
     1139            level_element = null;
     1140        }
     1141        }
     1142        command = null;
    11871143    }
    11881144    catch(Exception exception) {
    11891145    }
    11901146    return command_element;
    1191     }
    1192 
    1193     private Element parseMetadata(String command_str, BufferedReader in) {
     1147    }
     1148
     1149    private Element parseMetadata(CommandTokenizer tokenizer) {
     1150        Element command_element = null;
     1151        try {
     1152            command_element = document.createElement(COLLECTIONMETADATA_ELEMENT);
     1153            String name_str = tokenizer.nextToken();
     1154            String value_str = tokenizer.nextToken();
     1155            if(name_str != null && value_str != null) {
     1156                String language_str = "en"; // By default - why do we assume English???
     1157                // Check if the value string is actually a language string
     1158                if(value_str.startsWith(LBRACKET_CHARACTER) && value_str.endsWith(RBRACKET_CHARACTER)) {
     1159                    language_str = value_str.substring(value_str.indexOf(LANGUAGE_ARGUMENT) + 2, value_str.length() - 1);
     1160                    value_str = tokenizer.nextToken();
     1161                }
     1162                if(value_str != null) {
     1163                    // Ready the value str (which can contain all sorts of funky characters) for writing as a DOM value
     1164                    value_str = Codec.transform(value_str, Codec.GREENSTONE_TO_DOM);
     1165                    command_element.setAttribute(NAME_ATTRIBUTE, name_str);
     1166                    command_element.setAttribute(LANGUAGE_ATTRIBUTE, language_str);
     1167                    command_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
     1168                    MSMUtils.setValue(command_element, value_str);
     1169                }
     1170                else {
     1171                    command_element = null;
     1172                }
     1173                language_str = null;
     1174            }
     1175            else {
     1176                command_element = null;
     1177            }
     1178            name_str = null;
     1179            value_str = null;
     1180        }
     1181        catch (Exception exception) {
     1182            Gatherer.printStackTrace(exception);
     1183            command_element = null;
     1184        }
     1185        return command_element;
     1186    }
     1187
     1188    private Element parseMetadataSpecial(String command_str) {
    11941189    Element command_element = null;
    11951190    try {
    1196         CommandTokenizer tokenizer = new CommandTokenizer(command_str);
    1197         if(tokenizer.countTokens() >= 3) {
    1198         command_element = document.createElement(COLLECTIONMETADATA_ELEMENT);
    1199         // First token is command type
    1200         tokenizer.nextToken();
    1201         String name_str = tokenizer.nextToken();
    1202         String value_str = tokenizer.nextToken();
    1203         String language_str = "en"; // By default - why do we assume English???
    1204         // Check if the value string is actually a language string
    1205         if(value_str.startsWith(LBRACKET_CHARACTER) && value_str.endsWith(RBRACKET_CHARACTER)) {
    1206             language_str = value_str.substring(value_str.indexOf(LANGUAGE_ARGUMENT) + 2, value_str.length() - 1);
    1207             value_str = tokenizer.nextToken();
    1208         }
    1209 
    1210         // now we need to handle the case where the value is enclosed in quotes (single or double) and may extend across multiple lines
    1211         String start_string = value_str.substring(0,1);
    1212         if (start_string.equals("\"") || start_string.equals("\'")) {
    1213 
    1214             if (value_str.endsWith(start_string) && value_str.length()!=1) {
    1215             // we remove the quotes from the ends
    1216             value_str = value_str.substring(1, value_str.length() - 1);
    1217             } else {
    1218            
    1219             // remove the first quote
    1220             StringBuffer value_raw = new StringBuffer(value_str.substring(1));
    1221             // add the new line back in
    1222             value_raw.append(StaticStrings.NEW_LINE_CHAR);
    1223 
    1224             int pos = value_raw.indexOf(start_string);
    1225             int old_pos = 0;
    1226             while (pos != -1 && value_raw.charAt(pos-1)=='\\') {
    1227                 old_pos = pos+1;
    1228                 pos = value_raw.indexOf(start_string, old_pos);
    1229             }
    1230             while(pos == -1) {
    1231                 String next_line = in.readLine();
    1232                 if(next_line != null) {
    1233                 value_raw.append(next_line);
    1234                 value_raw.append(StaticStrings.NEW_LINE_CHAR);
    1235                 }
    1236                 next_line = null;
    1237                 pos = value_raw.indexOf(start_string, old_pos);
    1238                 while (pos != -1 && value_raw.charAt(pos-1)=='\\') {
    1239                 old_pos = pos+1;
    1240                 pos = value_raw.indexOf(start_string, old_pos);
    1241                 }
    1242             }
    1243            
    1244             value_str = value_raw.substring(0, value_raw.lastIndexOf(start_string));
    1245             value_raw = null;
    1246            
    1247             } // else
    1248         } // if starts with a quote
    1249                    
    1250         if(value_str != null) {
    1251             // Ready the value str (which can contain all sorts of funky characters) for writing as a DOM value
    1252             value_str = Codec.transform(value_str, Codec.GREENSTONE_TO_DOM);
    1253             command_element.setAttribute(NAME_ATTRIBUTE, name_str);
    1254             command_element.setAttribute(LANGUAGE_ATTRIBUTE, language_str);
    1255             command_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
    1256             MSMUtils.setValue(command_element, value_str);
    1257         }
    1258         else {
    1259             command_element = null;
    1260         }
    1261         language_str = null;
    1262         value_str = null;
    1263         name_str = null;
    1264         }
    1265         tokenizer = null;
    1266     }
    1267     catch (Exception exception) {
    1268     }
    1269     return command_element;
    1270     }
    1271 
    1272     private Element parseMetadataSpecial(String command_str) {
    1273     Element command_element = null;
    1274     try {
    1275         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1276         if(tokenizer.countTokens() >= 2) {
     1191        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1192        if(tokenizer.countTokens() >= 2) {
    12771193        String name_str = tokenizer.nextToken();
    12781194        String value_str = tokenizer.nextToken();
    12791195        if(name_str.equals(COLLECTIONMETADATA_BETA_STR)) {
    1280             command_element = document.createElement(COLLECTIONMETADATA_BETA_ELEMENT);
     1196            command_element = document.createElement(COLLECTIONMETADATA_BETA_ELEMENT);
    12811197        }
    12821198        else if(name_str.equals(COLLECTIONMETADATA_CREATOR_STR)) {
    1283             command_element = document.createElement(COLLECTIONMETADATA_CREATOR_ELEMENT);
     1199            command_element = document.createElement(COLLECTIONMETADATA_CREATOR_ELEMENT);
    12841200        }
    12851201        else if(name_str.equals(COLLECTIONMETADATA_MAINTAINER_STR)) {
    1286             command_element = document.createElement(COLLECTIONMETADATA_MAINTAINER_ELEMENT);
     1202            command_element = document.createElement(COLLECTIONMETADATA_MAINTAINER_ELEMENT);
    12871203        }
    12881204        else if(name_str.equals(COLLECTIONMETADATA_PUBLIC_STR)) {
    1289             command_element = document.createElement(COLLECTIONMETADATA_PUBLIC_ELEMENT);
     1205            command_element = document.createElement(COLLECTIONMETADATA_PUBLIC_ELEMENT);
    12901206        }
    12911207        if(command_element != null) {
    1292             command_element.setAttribute(NAME_ATTRIBUTE, name_str);
    1293             command_element.setAttribute(LANGUAGE_ATTRIBUTE, ENGLISH_LANGUAGE_STR);
    1294             command_element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
    1295             command_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
    1296             if(value_str.startsWith(SPEECH_CHARACTER) && value_str.endsWith(SPEECH_CHARACTER)) {
     1208            command_element.setAttribute(NAME_ATTRIBUTE, name_str);
     1209            command_element.setAttribute(LANGUAGE_ATTRIBUTE, ENGLISH_LANGUAGE_STR);
     1210            command_element.setAttribute(SPECIAL_ATTRIBUTE, TRUE_STR);
     1211            command_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
     1212            if(value_str.startsWith(SPEECH_CHARACTER) && value_str.endsWith(SPEECH_CHARACTER)) {
    12971213            value_str = value_str.substring(1, value_str.length() - 1);
    1298             }
    1299             MSMUtils.setValue(command_element, value_str);
     1214            }
     1215            MSMUtils.setValue(command_element, value_str);
    13001216        }
    13011217        value_str = null;
    13021218        name_str = null;
    1303         }
    1304         tokenizer = null;
     1219        }
     1220        tokenizer = null;
    13051221    }
    13061222    catch (Exception exception) {
    13071223    }
    13081224    return command_element;
    1309     }
    1310 
    1311     private Element parsePlugIn(String command_str) {
     1225    }
     1226
     1227    private Element parsePlugIn(String command_str) {
    13121228    Element command_element = null;
    13131229    boolean use_metadata_files = false;
    13141230    boolean show_progress = false;
    13151231    try {
    1316         CommandTokenizer tokenizer = new CommandTokenizer(command_str);
    1317         // Check the token count. The token count from a command tokenizer isn't guarenteed to be correct, but it does give the maximum number of available tokens according to the underlying StringTokenizer (some of which may actually be append together by the CommandTokenizer as being a single argument).
    1318         if(tokenizer.countTokens() >= 2) {
     1232        CommandTokenizer tokenizer = new CommandTokenizer(command_str);
     1233        // Check the token count. The token count from a command tokenizer isn't guarenteed to be correct, but it does give the maximum number of available tokens according to the underlying StringTokenizer (some of which may actually be append together by the CommandTokenizer as being a single argument).
     1234        if(tokenizer.countTokens() >= 2) {
    13191235        command_element = document.createElement(PLUGIN_ELEMENT);
    13201236        // First token is plugin
     
    13281244        Iterator names = arguments.keySet().iterator();
    13291245        while(names.hasNext()) {
    1330             String name = (String) names.next();
    1331             String value = (String) arguments.get(name); // Can be null
    1332             Element option_element = document.createElement(OPTION_ELEMENT);
    1333             if(name.substring(1).equals(USE_METADATA_FILES_ARGUMENT)) {
     1246            String name = (String) names.next();
     1247            String value = (String) arguments.get(name); // Can be null
     1248            Element option_element = document.createElement(OPTION_ELEMENT);
     1249            if(name.substring(1).equals(USE_METADATA_FILES_ARGUMENT)) {
    13341250            use_metadata_files = true;
    1335             }
    1336             else if(name.substring(1).equals(SHOW_PROGRESS_ARGUMENT)) {
    1337                show_progress = true;
    1338             }
    1339             option_element.setAttribute(NAME_ATTRIBUTE, name.substring(1));
    1340             option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
    1341             option_element.setAttribute(CUSTOM_ATTRIBUTE, TRUE_STR); // All arguments are considered to be custom until matched against base plugins arguments
    1342             if(value != null) {
     1251            }
     1252            else if(name.substring(1).equals(SHOW_PROGRESS_ARGUMENT)) {
     1253               show_progress = true;
     1254            }
     1255            option_element.setAttribute(NAME_ATTRIBUTE, name.substring(1));
     1256            option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
     1257            option_element.setAttribute(CUSTOM_ATTRIBUTE, TRUE_STR); // All arguments are considered to be custom until matched against base plugins arguments
     1258            if(value != null) {
    13431259            // Remove any speech marks appended in strings containing whitespace
    13441260            if(value.startsWith(SPEECH_CHARACTER) && value.endsWith(SPEECH_CHARACTER)) {
    1345                 value = value.substring(1, value.length() - 1);
     1261                value = value.substring(1, value.length() - 1);
    13461262            }
    13471263            if(name.equals(METADATA_ARGUMENT)) {
    1348                 // 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.
    1349                 if(value.indexOf(MSMUtils.NS_SEP) == -1) {
     1264                // 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.
     1265                if(value.indexOf(MSMUtils.NS_SEP) == -1) {
    13501266                value = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + value;
    1351                 }
     1267                }
    13521268            }
    13531269            MSMUtils.setValue(option_element, value);
    1354             }
    1355             command_element.appendChild(option_element);
    1356             option_element = null;
    1357             name = null;
    1358             value = null;
     1270            }
     1271            command_element.appendChild(option_element);
     1272            option_element = null;
     1273            name = null;
     1274            value = null;
    13591275        }
    13601276
    13611277        // We must have some RecPlug options: use_metadata_files, and show_progress
    13621278        if (type.equals(RECPLUG_STR)) {
    1363             if (!use_metadata_files) {
     1279            if (!use_metadata_files) {
    13641280            Element option_element = document.createElement(OPTION_ELEMENT);
    13651281            option_element.setAttribute(NAME_ATTRIBUTE, USE_METADATA_FILES_ARGUMENT);
     
    13681284            command_element.appendChild(option_element);
    13691285            option_element = null;
    1370             }
    1371             if(!show_progress) {
    1372                Element option_element = document.createElement(OPTION_ELEMENT);
    1373                option_element.setAttribute(NAME_ATTRIBUTE, SHOW_PROGRESS_ARGUMENT);
    1374                option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
    1375                option_element.setAttribute(CUSTOM_ATTRIBUTE, TRUE_STR);
    1376                command_element.appendChild(option_element);
    1377                option_element = null;
    1378             }
     1286            }
     1287            if(!show_progress) {
     1288               Element option_element = document.createElement(OPTION_ELEMENT);
     1289               option_element.setAttribute(NAME_ATTRIBUTE, SHOW_PROGRESS_ARGUMENT);
     1290               option_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
     1291               option_element.setAttribute(CUSTOM_ATTRIBUTE, TRUE_STR);
     1292               command_element.appendChild(option_element);
     1293               option_element = null;
     1294            }
    13791295        }
    13801296        type = null;
    13811297        names = null;
    13821298        arguments = null;
    1383         }
    1384         tokenizer = null;
     1299        }
     1300        tokenizer = null;
    13851301    }
    13861302    catch(Exception exception) {
    13871303    }
    13881304    return command_element;
    1389     }
    1390 
    1391     private Element parseSearchType(String command_str) {
     1305    }
     1306
     1307    private Element parseSearchType(String command_str) {
    13921308    Element command_element = null;
    13931309    try {
    1394         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1395         // First token is command type (levels)
    1396         tokenizer.nextToken();
    1397         if(tokenizer.hasMoreTokens()) {
     1310        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1311        // First token is command type (levels)
     1312        tokenizer.nextToken();
     1313        if(tokenizer.hasMoreTokens()) {
    13981314        command_element = document.createElement(SEARCHTYPE_ELEMENT);
    13991315        command_element.setAttribute(ASSIGNED_ATTRIBUTE, TRUE_STR);
    14001316        while(tokenizer.hasMoreTokens()) {
    1401             Element search_element = document.createElement(CONTENT_ELEMENT);
    1402             search_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
    1403             command_element.appendChild(search_element);
    1404             search_element = null;
    1405         }
    1406         }
     1317            Element search_element = document.createElement(CONTENT_ELEMENT);
     1318            search_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
     1319            command_element.appendChild(search_element);
     1320            search_element = null;
     1321        }
     1322        }
    14071323    }
    14081324    catch(Exception exception) {
    14091325    }
    14101326    return command_element;
    1411     }
    1412 
    1413     private Element parseSubCollection(String command_str) {
     1327    }
     1328
     1329    private Element parseSubCollection(String command_str) {
    14141330    Element command_element = null;
    14151331    try {
    1416         CommandTokenizer tokenizer = new CommandTokenizer(command_str);
    1417         if(tokenizer.countTokens() >= 3) {
     1332        CommandTokenizer tokenizer = new CommandTokenizer(command_str);
     1333        if(tokenizer.countTokens() >= 3) {
    14181334        command_element = document.createElement(SUBCOLLECTION_ELEMENT);
    14191335        // First token is command type
     
    14271343        // Set inclusion/exclusion flag, remove any exclaimation mark and the speech marks
    14281344        if(exclusion) {
    1429             full_pattern_str = full_pattern_str.substring(2, full_pattern_str.length() - 1);
    1430             command_element.setAttribute(TYPE_ATTRIBUTE, EXCLUDE_STR);
     1345            full_pattern_str = full_pattern_str.substring(2, full_pattern_str.length() - 1);
     1346            command_element.setAttribute(TYPE_ATTRIBUTE, EXCLUDE_STR);
    14311347        }
    14321348        else {
    1433             full_pattern_str = full_pattern_str.substring(1, full_pattern_str.length() - 1);
    1434             command_element.setAttribute(TYPE_ATTRIBUTE, INCLUDE_STR);
     1349            full_pattern_str = full_pattern_str.substring(1, full_pattern_str.length() - 1);
     1350            command_element.setAttribute(TYPE_ATTRIBUTE, INCLUDE_STR);
    14351351        }
    14361352        StringTokenizer pattern_tokenizer = new StringTokenizer(full_pattern_str, SEPARATOR_CHARACTER);
    14371353        if(pattern_tokenizer.countTokens() >= 2) {
    1438             String content_str = pattern_tokenizer.nextToken();
    1439             // 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.
    1440             if(!content_str.equals(StaticStrings.FILENAME_STR) && content_str.indexOf(MSMUtils.NS_SEP) == -1) {
     1354            String content_str = pattern_tokenizer.nextToken();
     1355            // 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.
     1356            if(!content_str.equals(StaticStrings.FILENAME_STR) && content_str.indexOf(MSMUtils.NS_SEP) == -1) {
    14411357            content_str = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + content_str;
    1442             }
    1443             command_element.setAttribute(CONTENT_ATTRIBUTE, content_str);
    1444             MSMUtils.setValue(command_element, pattern_tokenizer.nextToken());
    1445             if(pattern_tokenizer.hasMoreTokens()) {
     1358            }
     1359            command_element.setAttribute(CONTENT_ATTRIBUTE, content_str);
     1360            MSMUtils.setValue(command_element, pattern_tokenizer.nextToken());
     1361            if(pattern_tokenizer.hasMoreTokens()) {
    14461362            command_element.setAttribute(OPTIONS_ATTRIBUTE, pattern_tokenizer.nextToken());
    1447             }
     1363            }
    14481364        }
    14491365        pattern_tokenizer = null;
    1450         }
     1366        }
    14511367    }
    14521368    catch(Exception exception) {
    1453         exception.printStackTrace();
     1369        exception.printStackTrace();
    14541370    }
    14551371    return command_element;
    1456     }
    1457 
    1458     private Element parseSubCollectionDefaultIndex(String command_str) {
     1372    }
     1373
     1374    private Element parseSubCollectionDefaultIndex(String command_str) {
    14591375    Element command_element = null;
    14601376    try {
    1461         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1462         if(tokenizer.countTokens() == 2) {
     1377        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1378        if(tokenizer.countTokens() == 2) {
    14631379        command_element = document.createElement(SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
    14641380        tokenizer.nextToken();
     
    14671383        StringTokenizer content_tokenizer = new StringTokenizer(content_str, StaticStrings.COMMA_CHARACTER);
    14681384        while(content_tokenizer.hasMoreTokens()) {
    1469             Element content_element = document.createElement(CONTENT_ELEMENT);
    1470             content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
    1471             command_element.appendChild(content_element);
    1472             content_element = null;
     1385            Element content_element = document.createElement(CONTENT_ELEMENT);
     1386            content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
     1387            command_element.appendChild(content_element);
     1388            content_element = null;
    14731389        }
    14741390        content_tokenizer = null;
    14751391        content_str = null;
    1476         }
    1477         tokenizer = null;
     1392        }
     1393        tokenizer = null;
    14781394    }
    14791395    catch(Exception exception) {
    14801396    }
    14811397    return command_element;
    1482     }
    1483 
    1484     private Element parseSubCollectionIndex(String command_str) {
     1398    }
     1399
     1400    private Element parseSubCollectionIndex(String command_str) {
    14851401    Element command_element = null;
    14861402    try {
    1487         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1488         tokenizer.nextToken();
    1489         if(tokenizer.hasMoreTokens()) {
     1403        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1404        tokenizer.nextToken();
     1405        if(tokenizer.hasMoreTokens()) {
    14901406        command_element = document.createElement(SUBCOLLECTION_INDEXES_ELEMENT);
    1491         }
    1492         while(tokenizer.hasMoreTokens()) {
     1407        }
     1408        while(tokenizer.hasMoreTokens()) {
    14931409        Element subcollectionindex_element = document.createElement(INDEX_ELEMENT);
    14941410        //command_element.setAttribute(CONTENT_ATTRIBUTE, tokenizer.nextToken());
     
    14961412        StringTokenizer content_tokenizer = new StringTokenizer(content_str, StaticStrings.COMMA_CHARACTER);
    14971413        while(content_tokenizer.hasMoreTokens()) {
    1498             Element content_element = document.createElement(CONTENT_ELEMENT);
    1499             content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
    1500             subcollectionindex_element.appendChild(content_element);
    1501             content_element = null;
     1414            Element content_element = document.createElement(CONTENT_ELEMENT);
     1415            content_element.setAttribute(NAME_ATTRIBUTE, content_tokenizer.nextToken());
     1416            subcollectionindex_element.appendChild(content_element);
     1417            content_element = null;
    15021418        }
    15031419        content_tokenizer = null;
     
    15051421        command_element.appendChild(subcollectionindex_element);
    15061422        subcollectionindex_element = null;
    1507         }
    1508         tokenizer = null;
     1423        }
     1424        tokenizer = null;
    15091425    }
    15101426    catch (Exception exception) {
    15111427    }
    15121428    return command_element;
    1513     }
    1514 
    1515     private Element parseSuperCollection(String command_str) {
     1429    }
     1430
     1431    private Element parseSuperCollection(String command_str) {
    15161432    Element command_element = null;
    15171433    try {
    1518         StringTokenizer tokenizer = new StringTokenizer(command_str);
    1519         if(tokenizer.countTokens() >= 3) {
     1434        StringTokenizer tokenizer = new StringTokenizer(command_str);
     1435        if(tokenizer.countTokens() >= 3) {
    15201436        command_element = document.createElement(SUPERCOLLECTION_ELEMENT);
    15211437        tokenizer.nextToken();
    15221438        while(tokenizer.hasMoreTokens()) {
    1523             Element collection_element = document.createElement(COLLECTION_ELEMENT);
    1524             collection_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
    1525             command_element.appendChild(collection_element);
    1526             collection_element = null;
    1527         }
    1528         }
    1529         tokenizer = null;
     1439            Element collection_element = document.createElement(COLLECTION_ELEMENT);
     1440            collection_element.setAttribute(NAME_ATTRIBUTE, tokenizer.nextToken());
     1441            command_element.appendChild(collection_element);
     1442            collection_element = null;
     1443        }
     1444        }
     1445        tokenizer = null;
    15301446    }
    15311447    catch(Exception exception) {
    15321448    }
    15331449    return command_element;
    1534     }
    1535 
    1536     private String pluginToString(Element command_element, boolean show_extracted_namespace) {
     1450    }
     1451
     1452    private String pluginToString(Element command_element, boolean show_extracted_namespace) {
    15371453    StringBuffer text = new StringBuffer();
    15381454    if(!command_element.getAttribute(SEPARATOR_ATTRIBUTE).equals(TRUE_STR)) {
    1539         text.append(PLUGIN_STR);
    1540         text.append(TAB_CHARACTER);
    1541         text.append(TAB_CHARACTER);
    1542         text.append(command_element.getAttribute(TYPE_ATTRIBUTE));
    1543         // Retrieve, and output, the arguments
    1544         NodeList option_elements = command_element.getElementsByTagName(OPTION_ELEMENT);
    1545         int option_elements_length = option_elements.getLength();
    1546         if(option_elements_length > 0) {
     1455        text.append(PLUGIN_STR);
     1456        text.append(TAB_CHARACTER);
     1457        text.append(TAB_CHARACTER);
     1458        text.append(command_element.getAttribute(TYPE_ATTRIBUTE));
     1459        // Retrieve, and output, the arguments
     1460        NodeList option_elements = command_element.getElementsByTagName(OPTION_ELEMENT);
     1461        int option_elements_length = option_elements.getLength();
     1462        if(option_elements_length > 0) {
    15471463        text.append(SPACE_CHARACTER);
    15481464        for(int j = 0; j < option_elements_length; j++) {
    1549             Element option_element = (Element) option_elements.item(j);
    1550             if(option_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
     1465            Element option_element = (Element) option_elements.item(j);
     1466            if(option_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
    15511467            text.append(StaticStrings.MINUS_CHARACTER);
    15521468            text.append(option_element.getAttribute(NAME_ATTRIBUTE));
    15531469            String value_str = MSMUtils.getValue(option_element);
    15541470            if(!show_extracted_namespace && value_str.startsWith(EXTRACTED_PREFIX)) {
    1555                 value_str = value_str.substring(EXTRACTED_PREFIX.length());
     1471                value_str = value_str.substring(EXTRACTED_PREFIX.length());
    15561472            }
    15571473            if(value_str.length() > 0) {
    1558                 text.append(SPACE_CHARACTER);
    1559                 if(value_str.indexOf(SPACE_CHARACTER) == -1) {
     1474                text.append(SPACE_CHARACTER);
     1475                if(value_str.indexOf(SPACE_CHARACTER) == -1) {
    15601476                text.append(value_str);
    1561                 }
    1562                 else {
     1477                }
     1478                else {
    15631479                text.append(SPEECH_CHARACTER);
    15641480                text.append(value_str);
    15651481                text.append(SPEECH_CHARACTER);
    1566                 }
     1482                }
    15671483            }
    15681484            value_str = null;
    15691485            if(j < option_elements_length - 1) {
    1570                 text.append(SPACE_CHARACTER);
    1571             }
    1572             }
    1573             option_element = null;
    1574         }
    1575         }
    1576         option_elements = null;
     1486                text.append(SPACE_CHARACTER);
     1487            }
     1488            }
     1489            option_element = null;
     1490        }
     1491        }
     1492        option_elements = null;
    15771493    }
    15781494    return text.toString();
    1579     }
    1580 
    1581     private String searchtypeToString(Element command_element) {
     1495    }
     1496
     1497    private String searchtypeToString(Element command_element) {
    15821498    if(command_element.getAttribute(ASSIGNED_ATTRIBUTE).equals(TRUE_STR)) {
    1583         StringBuffer text = new StringBuffer(SEARCHTYPE_STR);
    1584         text.append(TAB_CHARACTER);
    1585         NodeList search_elements = command_element.getElementsByTagName(CONTENT_ELEMENT);
    1586         int search_elements_length = search_elements.getLength();
    1587         for(int i = 0; i < search_elements_length; i++) {
     1499        StringBuffer text = new StringBuffer(SEARCHTYPE_STR);
     1500        text.append(TAB_CHARACTER);
     1501        NodeList search_elements = command_element.getElementsByTagName(CONTENT_ELEMENT);
     1502        int search_elements_length = search_elements.getLength();
     1503        for(int i = 0; i < search_elements_length; i++) {
    15881504        Element search_element = (Element) search_elements.item(i);
    15891505        text.append(search_element.getAttribute(NAME_ATTRIBUTE));
    15901506        text.append(SPACE_CHARACTER);
    1591         }
    1592         return text.substring(0, text.length() - 1);
     1507        }
     1508        return text.substring(0, text.length() - 1);
    15931509    }
    15941510    else {
    1595         return null;
    1596     }
    1597     }
    1598 
    1599     private String subcollectionToString(Element command_element, boolean show_extracted_namespace) {
     1511        return null;
     1512    }
     1513    }
     1514
     1515    private String subcollectionToString(Element command_element, boolean show_extracted_namespace) {
    16001516    StringBuffer text = new StringBuffer(SUBCOLLECTION_STR);
    16011517    text.append(SPACE_CHARACTER);
     
    16051521    text.append(SPEECH_CHARACTER);
    16061522    if(command_element.getAttribute(TYPE_ATTRIBUTE).equals(EXCLUDE_STR)) {
    1607         text.append(EXCLAIMATION_CHARACTER);
     1523        text.append(EXCLAIMATION_CHARACTER);
    16081524    }
    16091525    String content_str = command_element.getAttribute(CONTENT_ATTRIBUTE);
    16101526    if(!show_extracted_namespace && content_str.startsWith(EXTRACTED_PREFIX)) {
    1611         content_str = content_str.substring(EXTRACTED_PREFIX.length());
     1527        content_str = content_str.substring(EXTRACTED_PREFIX.length());
    16121528    }
    16131529    text.append(content_str);
     
    16181534    String options_str = command_element.getAttribute(OPTIONS_ATTRIBUTE);
    16191535    if(options_str.length() > 0) {
    1620         text.append(options_str);
     1536        text.append(options_str);
    16211537    }
    16221538    options_str = null;
    16231539    text.append(SPEECH_CHARACTER);
    16241540    return text.toString();
    1625     }
    1626 
    1627     private String subcollectionDefaultIndexToString(Element command_element) {
     1541    }
     1542
     1543    private String subcollectionDefaultIndexToString(Element command_element) {
    16281544    StringBuffer text = new StringBuffer(SUBCOLLECTION_DEFAULT_INDEX_STR);
    16291545    text.append(TAB_CHARACTER);
     
    16311547    int content_elements_length = content_elements.getLength();
    16321548    for(int j = 0; j < content_elements_length; j++) {
    1633         Element content_element = (Element) content_elements.item(j);
    1634         text.append(content_element.getAttribute(NAME_ATTRIBUTE));
    1635         if(j < content_elements_length - 1) {
     1549        Element content_element = (Element) content_elements.item(j);
     1550        text.append(content_element.getAttribute(NAME_ATTRIBUTE));
     1551        if(j < content_elements_length - 1) {
    16361552        text.append(StaticStrings.COMMA_CHARACTER);
    1637         }
     1553        }
    16381554    }
    16391555    return text.toString();
    1640     }
    1641 
    1642     private String subcollectionIndexesToString(Element command_element) {
     1556    }
     1557
     1558    private String subcollectionIndexesToString(Element command_element) {
    16431559    StringBuffer text = new StringBuffer(SUBCOLLECTION_INDEX_STR);
    16441560    text.append(TAB_CHARACTER);
     
    16471563    int subcollectionindex_elements_length = subcollectionindex_elements.getLength();
    16481564    if(subcollectionindex_elements_length == 0) {
    1649         return null;
     1565        return null;
    16501566    }
    16511567    for(int j = 0; j < subcollectionindex_elements_length; j++) {
    1652         Element subcollectionindex_element = (Element) subcollectionindex_elements.item(j);
    1653         NodeList content_elements = subcollectionindex_element.getElementsByTagName(CONTENT_ELEMENT);
    1654         int content_elements_length = content_elements.getLength();
    1655         for(int k = 0; k < content_elements_length; k++) {
     1568        Element subcollectionindex_element = (Element) subcollectionindex_elements.item(j);
     1569        NodeList content_elements = subcollectionindex_element.getElementsByTagName(CONTENT_ELEMENT);
     1570        int content_elements_length = content_elements.getLength();
     1571        for(int k = 0; k < content_elements_length; k++) {
    16561572        Element content_element = (Element) content_elements.item(k);
    16571573        text.append(content_element.getAttribute(NAME_ATTRIBUTE));
    16581574        if(k < content_elements_length - 1) {
    1659             text.append(StaticStrings.COMMA_CHARACTER);
    1660         }
    1661         }
    1662         if(j < subcollectionindex_elements_length - 1) {
     1575            text.append(StaticStrings.COMMA_CHARACTER);
     1576        }
     1577        }
     1578        if(j < subcollectionindex_elements_length - 1) {
    16631579        text.append(SPACE_CHARACTER);
    1664         }
     1580        }
    16651581    }
    16661582    return text.toString();
    1667     }
    1668 
    1669     private String supercollectionToString(Element command_element) {
     1583    }
     1584
     1585    private String supercollectionToString(Element command_element) {
    16701586    NodeList content_elements = command_element.getElementsByTagName(COLLECTION_ELEMENT);
    16711587    int content_elements_length = content_elements.getLength();
    16721588    if(content_elements_length > 1) {
    1673         StringBuffer text = new StringBuffer(SUPERCOLLECTION_STR);
    1674         text.append(TAB_CHARACTER);
    1675         for(int j = 0; j < content_elements_length; j++) {
     1589        StringBuffer text = new StringBuffer(SUPERCOLLECTION_STR);
     1590        text.append(TAB_CHARACTER);
     1591        for(int j = 0; j < content_elements_length; j++) {
    16761592        Element content_element = (Element) content_elements.item(j);
    16771593        text.append(content_element.getAttribute(NAME_ATTRIBUTE));
    16781594        if(j < content_elements_length - 1) {
    1679             text.append(SPACE_CHARACTER);
    1680         }
    1681         }
    1682         return text.toString();
     1595            text.append(SPACE_CHARACTER);
     1596        }
     1597        }
     1598        return text.toString();
    16831599    }
    16841600    return null;
    1685     }
    1686 
    1687     private String unknownToString(Element command_element) {
     1601    }
     1602
     1603    private String unknownToString(Element command_element) {
    16881604    return MSMUtils.getValue(command_element);
    1689     }
    1690 
    1691     /** Write the text to the buffer. This is used so we don't have to worry about storing intermediate String values just so we can calaulate length and offset.
    1692     * @param writer the BufferedWriter to which the str will be written
    1693     * @param str the String to be written
    1694     */
    1695     private void write(BufferedWriter writer, String str)
     1605    }
     1606
     1607    /** Write the text to the buffer. This is used so we don't have to worry about storing intermediate String values just so we can calaulate length and offset.
     1608    * @param writer the BufferedWriter to which the str will be written
     1609    * @param str the String to be written
     1610    */
     1611    private void write(BufferedWriter writer, String str)
    16961612    throws IOException {
    16971613    writer.write(str, 0, str.length());
    1698     }
     1614    }
    16991615}
  • trunk/gli/src/org/greenstone/gatherer/cdm/CollectionDesignManager.java

    r5995 r6051  
    9696    classifier_manager = new ClassifierManager();
    9797    general_manager = new GeneralManager();
    98    
     98
    9999    searchtype_manager = new SearchTypeManager(collect_config.getSearchType());
    100100    if(searchtype_manager.isMGPPEnabled()) {
     
    104104        index_manager = new IndexManager(collect_config.getMGIndexes());
    105105    }
    106    
     106
    107107    metadataset_view = new MetadataSetView();
    108108    plugin_manager = new PlugInManager();
     
    156156    general_manager.gainFocus();
    157157    }
    158    
     158
    159159    /** Retrieve the name of the collection configuration file which is being used as the source of the information in this object.
    160160     * @return The files absolute path as a <strong>String</strong>.
     
    192192     collection_released = true;
    193193      }
    194      
     194
    195195      general_manager.loseFocus();
    196196      collect_config.save();
    197      
     197
    198198      // Readd collection
    199199      ///ystem.err.println("Would have added collection if it had been released.");
     
    206206      }
    207207    }
    208    
     208
     209   /** Ensures that the collection is now public. Useful for collections that are based on another, or that are about to be exported */
     210   public void setCollectionAsPublic() {
     211       CollectionMeta public_collectionmeta = new CollectionMeta(CollectionDesignManager.collect_config.getPublic());
     212       if(public_collectionmeta != null) {
     213            public_collectionmeta.setValue(CollectionConfiguration.TRUE_STR);
     214            public_collectionmeta = null;
     215       }
     216   }
     217
    209218    /** Method used during a global search and replace to highlight the appropriate record within the Collection Design Managers version of the Metadata Set Manager (view only).
    210219     * @param element The name of the desired element as a <strong>String</strong>.
     
    221230    private class CDMChangeListener
    222231    implements ActionListener, DocumentListener {
    223    
     232
    224233    public void actionPerformed(ActionEvent event) {
    225234        Gatherer.c_man.getCollection().setSaved(false);
     
    230239        Gatherer.c_man.getCollection().setSaved(false);
    231240    }
    232          
     241
    233242    /** Gives notification that there was an insert into the document. */
    234243    public void insertUpdate(DocumentEvent e) {
    235244        Gatherer.c_man.getCollection().setSaved(false);
    236245    }
    237          
     246
    238247    /** Gives notification that a portion of the document has been removed. */
    239248    public void removeUpdate(DocumentEvent e) {
  • trunk/gli/src/org/greenstone/gatherer/cdm/CommandTokenizer.java

    r6033 r6051  
    3838
    3939/**************************************************************************************
    40  * Title:        Gatherer
     40 * Title:       Gatherer
    4141 * Description:  The Gatherer: a tool for gathering and enriching a digital collection.
    42  * Company:      The University of Waikato
    43  * Written:      07/05/02
    44  * Revised:      03/10/02 - Commented
     42 * Company:   The University of Waikato
     43 * Written:   07/05/02
     44 * Revised:   03/10/02 - Commented
    4545 **************************************************************************************/
     46import java.io.BufferedReader;
    4647import java.util.StringTokenizer;
     48import org.greenstone.gatherer.Gatherer;
     49import org.greenstone.gatherer.util.StaticStrings;
    4750
    4851/** This class provides an extension to the standard StringTokenizer in that it recognizes quotes (or some form of bracketting) enclose a single token so in something like: <br>format Search '&lt;table&gt;&lt;img src=... &lt;/table&gt;'<br> the formatting string is parsed as a single token. Unfortunately this makes countTokens() unreliable for exact measurement of tokens remaining, and only useful for determining if there are tokens left to be processed (includes any that have already been read into command buffer).
     
    5053 * @version 2.3
    5154 */
    52 public class CommandTokenizer
    53     extends StringTokenizer {
    54 
    55     private int last_type = -1;
    56 
    57     static final public int BRACKET_ENCLOSED      = 0;
    58     static final public int DOUBLE_QUOTE_ENCLOSED = 1;
    59     static final public int NORMAL                = 2;
    60     static final public int QUOTE_ENCLOSED        = 3;
    61 
    62     /** Constructor.
    63      * @param command The command <strong>String</strong> you wish to tokenize.
    64      */
    65     public CommandTokenizer(String command) {
    66     super(command);
    67     }
    68 
    69     /* private int getLastType() {
    70     return last_type;
    71     } */
    72 
    73     /* private boolean isComment() {
    74     return (last_type == DOUBLE_QUOTE_ENCLOSED || last_type == QUOTE_ENCLOSED);
    75     } */
    76 
    77     /** Method to retrieve the next token from the command, taking care to group tokens enclosed in speech marks.
    78      * @return A <strong>String</strong> containing the next token from the command.
    79      */
    80     public String nextToken() {
    81     String result = null;
    82     if(hasMoreTokens()) {
    83         StringBuffer buffer = new StringBuffer(super.nextToken());
    84         switch(buffer.charAt(0)) {
    85         case '\"':
    86         while((buffer.length() == 1 || buffer.charAt(buffer.length() - 1) != '\"') && hasMoreTokens()) {
    87             buffer.append(" ");
    88             buffer.append(super.nextToken());
    89             ///ystem.err.println("Current Buffer = '" + buffer.toString() + "'");
    90         }
    91         ///ystem.err.println("Final Buffer = '" + buffer.toString() + "'");
    92         last_type = DOUBLE_QUOTE_ENCLOSED;
    93         break;
    94         case '\'':
    95         while((buffer.length() == 1 || buffer.charAt(buffer.length() - 1) != '\'') && hasMoreTokens()) {
    96             buffer.append(" ");
    97             buffer.append(super.nextToken());
    98         }
    99         last_type = QUOTE_ENCLOSED;
    100         break;
    101         case '[':
    102         while((buffer.length() == 1 || buffer.charAt(buffer.length() - 1) != ']') && hasMoreTokens()) {
    103             buffer.append(" ");
    104             buffer.append(super.nextToken());
    105         }
    106         last_type = BRACKET_ENCLOSED;
    107         break;
    108         default:
    109         last_type = NORMAL;
    110         }
    111         result = buffer.toString();
    112     }
    113     return result;
    114     }
    115 
    116     /** Unfortunately the StringBuffer doesn't have a built in endsWith method, so I'll just have to implement my own.
    117      * @param str The <strong>StringBuffer</strong> we are checking the end of.
    118      * @param target The <strong>String</strong> fragment we are searching for.
    119      * @return <i>true</i> if str ends with target, <i>false</i> otherwise.
    120      */
    121     private boolean endsWith(StringBuffer str, String target) {
    122     String temp = str.toString();
    123     if(temp.endsWith(target) != (str.lastIndexOf(target) == str.length() - target.length())) {
    124         ///ystem.err.println("Holy error that'll crash the HFile creator if it happens twice, Batman!");
    125         ///ystem.err.println("String = '" + temp + "'");
    126         ///ystem.err.println("Target = '" + target + "'");
    127     }
    128     return str.lastIndexOf(target) == str.length() - target.length();
    129     }
     55public class CommandTokenizer {
     56
     57    static final public int BRACKET_ENCLOSED            = 0;
     58    static final public int DOUBLE_QUOTE_ENCLOSED   = 1;
     59    static final public int NORMAL                      = 2;
     60    static final public int QUOTE_ENCLOSED              = 3;
     61
     62    private BufferedReader in_stream;
     63    private int count = -1;
     64    private StringTokenizer internal_tokenizer;
     65
     66    /** Basic Constructor. Used to parse tokens from a string keeping tokens surrounded by speechmarks or square brackets intact. Thus something like:<br>
     67     * collectionmeta collectionextra [l = en] "Hello World"<br>
     68     * is tokenized thus<br>
     69     * {'collectionmeta', 'collectionextra', 'l = en', 'Hello World'}
     70     * @param command the command String you wish to tokenize
     71     */
     72    public CommandTokenizer(String command) {
     73        this.internal_tokenizer = new StringTokenizer(command);
     74        this.in_stream = null;
     75    }
     76
     77    /** Advanced Constructor. As above but with one major difference. Since it is provided an input stream (presumably where the command string originated from), it is able to parse a quote enclosed command token that stretches over several lines. Each newline is preserved in the resulting token. There is an extra bitchslap here as comething like a collection extra might have html code in them that contain escaped speechmarks, so extra care must be taken not to break at them. Thus something like:<br>
     78     * collectionmeta collectionextra [l = en] "<br>
     79     *     an example of the crazy as description we sometimes get which includes of all things something like <a href=\"this.html\"<br>
     80     *     >this</a> which you could easily see might be a problem if I parse this niavely."<br>
     81     * is tokenized thus<br>
     82     * {'collectionmeta', 'collectionextra', 'l = en', '\nan example of the crazy as description we sometimes get which includes of all things something like <a href=\"this.html\"\n>this</a> which you could easily see might be a problem if I parse this niavely.'}
     83     * @param command the command String you wish to tokenize
     84     * @param in_stream a BufferedReader from which the tokenizer can draw further lines as necessary
     85     */
     86    public CommandTokenizer(String command, BufferedReader in_stream) {
     87        ///atherer.println("***** CommandTokenizer *****\nparse:\t" + command + "\n****************************");
     88        this.internal_tokenizer = new StringTokenizer(command);
     89        this.in_stream = in_stream;
     90    }
     91
     92    /** Returns the minumum number of remaining tokens before the tokenizer runs out of string. There may be more tokens than this count, but never less. The discrepancy is due to internal functionality and the fact we can't read ahead in the string or associated stream without risking the need for unpredictable push-back
     93     * @return the minumum number of tokens available as an int
     94     */
     95    public int countTokens() {
     96        if(count == 0 && internal_tokenizer.countTokens() > 1) {
     97             return 1;
     98        }
     99        if(count == -1) {
     100             count = internal_tokenizer.countTokens();
     101        }
     102        return count;
     103    }
     104
     105    /** Determine if there are still tokens available.
     106     * @return true if there are more tokens, false otherwise
     107     */
     108    public boolean hasMoreTokens() {
     109         return internal_tokenizer.hasMoreTokens();
     110    }
     111
     112    /** Method to retrieve the next token from the command, taking care to group tokens enclosed in speech marks.
     113     * @return a String containing the next token from the command
     114     */
     115    public String nextToken() {
     116        String result = null;
     117        if(internal_tokenizer.hasMoreTokens()) {
     118            StringBuffer buffer = new StringBuffer(internal_tokenizer.nextToken());
     119            switch(buffer.charAt(0)) {
     120                case StaticStrings.DOUBLEQUOTE_CHAR:
     121                    result = buildToken(buffer, StaticStrings.DOUBLEQUOTE_CHAR, true);
     122                    break;
     123                case StaticStrings.SINGLEQUOTE_CHAR:
     124                    result = buildToken(buffer, StaticStrings.SINGLEQUOTE_CHAR, true);
     125                    break;
     126                case StaticStrings.OPENBRACKET_CHAR:
     127                    result = buildToken(buffer, StaticStrings.CLOSEBRACKET_CHAR, false);
     128                    break;
     129                default:
     130                    result = buffer.toString();
     131            }
     132            buffer = null;
     133        }
     134        // Because of our tricky counting system we never want to have negative tokens remaining. In fact, unless the internal string buffer is empty, we will return a count of 1 anyway
     135        if(count > 0) {
     136            count = count - 1;
     137        }
     138        ///atherer.println("----- CommandTokenizer -----\ntoken:\t" + result + "\n----------------------------");
     139        return result;
     140    }
     141
     142    /** Parse in the next token. paying heed to enclosing characters demands, escaped characters, newlines and empty buffers and consequential unexpected end of tokens
     143     * @param buffer the StringBuffer in which the partial token is stored (at the first bit that caused this method to be called)
     144     * @param end_char the sentinel char we are watching for as it encloses a token
     145     * @param strip_characters a boolean denoting whether the enclosing characters should be stripped off
     146     * @return the token, either in its entirity less the enclosing characters if required or, if an unexpected end occured, whatever we parsed without its starting enclosing character, again only if required. In fact if we weren't asked to strip characters then we add the enclosing character back in
     147     */
     148    private String buildToken(StringBuffer buffer, char end_char, boolean strip_characters) {
     149        while(buffer.charAt(buffer.length() - 1) != end_char || (buffer.length() > 3 && buffer.charAt(buffer.length() - 2) == StaticStrings.BACKSLASH_CHAR)) {
     150            try {
     151                // The first version is for the basic tokenizer which has no idea of an input stream, so runs out tokens at the same time as the internal tokenizer does
     152                if(internal_tokenizer.hasMoreTokens()) {
     153                    buffer.append(StaticStrings.SPACE_CHAR);
     154                    buffer.append(internal_tokenizer.nextToken());
     155                }
     156                // While the second version can draw more lines from the stream until eof occurs
     157                else if(in_stream != null) {
     158                    String line_str = null;
     159                    while(!internal_tokenizer.hasMoreTokens() && (line_str = in_stream.readLine()) != null) {
     160                        ///atherer.println("+++++ CommandTokenizer +++++\nappend:\t" + line_str + "\n+++++++++++++++++++++++++++++");
     161                        // Its at this stage the our token count becomes completely patu
     162                        internal_tokenizer = new StringTokenizer(line_str);
     163                        buffer.append(StaticStrings.NEW_LINE_CHAR); // A new line in the final token
     164                    }
     165                    line_str = null;
     166                    if(internal_tokenizer.hasMoreTokens()) {
     167                        // Don't add a space if we just added a newline
     168                        if(buffer.charAt(buffer.length() - 1) != StaticStrings.NEW_LINE_CHAR) {
     169                            buffer.append(StaticStrings.SPACE_CHAR);
     170                        }
     171                        buffer.append(internal_tokenizer.nextToken());
     172                    }
     173                    // We've prematurely run out of content, so throw the dummy, or at least return whatever we managed to parse sans its opening character
     174                    else {
     175                        if(strip_characters) {
     176                            return buffer.substring(1);
     177                        }
     178                        else {
     179                            buffer.append(end_char);
     180                            return buffer.toString();
     181                        }
     182                    }
     183                }
     184                // We've prematurely run out of content, so throw the dummy, or at least return whatever we managed to parse sans its opening character
     185                else {
     186                    if(strip_characters) {
     187                        return buffer.substring(1);
     188                    }
     189                    else {
     190                        buffer.append(end_char);
     191                        return buffer.toString();
     192                    }
     193                }
     194            }
     195            // Exception throw when we attempted reading from the input stream, so throw the dummy, or at least return whatever we managed to parse sans its opening character
     196            catch(Exception exception) {
     197                Gatherer.printStackTrace(exception);
     198                if(strip_characters) {
     199                    return buffer.substring(1);
     200                }
     201                else {
     202                    buffer.append(end_char);
     203                    return buffer.toString();
     204                }
     205            }
     206        }
     207        // Return the string sans enclosing characters
     208        if(buffer.length() > 0 && strip_characters) {
     209            return buffer.substring(1, buffer.length() - 1);
     210        }
     211        else {
     212            return buffer.toString();
     213        }
     214    }
    130215}
  • trunk/gli/src/org/greenstone/gatherer/cdm/GeneralManager.java

    r6003 r6051  
    133133    /** This class represents the visual component of the general options stored in the CollectionDesignManager. */
    134134    private class GeneralControl
    135     extends JPanel 
     135    extends JPanel
    136136    implements Control {
    137137    private boolean ready = false;
     
    262262        instruction_panel.add(title_label, BorderLayout.NORTH);
    263263        instruction_panel.add(new JScrollPane(instructions_textarea), BorderLayout.CENTER);
    264        
     264
    265265        creator_panel.setLayout(new BorderLayout());
    266266        creator_panel.add(creator_label, BorderLayout.WEST);
     
    334334        small_icon_textfield.setText(icon_collection_small_collectionmeta.getValue(CollectionMeta.TEXT));
    335335        small_icon_textfield.setCaretPosition(0);
     336        // I forgot to keep the checkboxes up to date. Why hasn't this caused problems before today?
     337        public_checkbox.setSelected(public_collectionmeta.getValue(CollectionMeta.TEXT).equals(CollectionConfiguration.TRUE_STR));
     338        beta_checkbox.setSelected(beta_collectionmeta.getValue(CollectionMeta.TEXT).equals(CollectionConfiguration.TRUE_STR));
    336339        ready = true;
    337340    }
     
    343346        beta_collectionmeta.setValue((beta_checkbox.isSelected() ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
    344347        public_collectionmeta.setValue((public_checkbox.isSelected() ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
    345         creator_collectionmeta.setValue(creator_emailfield.getText());
     348        String creator_email_str = creator_emailfield.getText();
     349        creator_collectionmeta.setValue(creator_email_str);
     350        Gatherer.config.setEmail(creator_email_str); // Store the email address in the configuration
    346351        collection_extra_collectionmeta.setValue(description_textarea.getText());
    347352        icon_collection_collectionmeta.setValue(icon_textfield.getText());
     
    356361    private class BrowseListener
    357362        implements ActionListener {
    358        
     363
    359364        public void actionPerformed(ActionEvent event) {
    360365        // Open an almost standard file browser to the images folder of the current collection
     
    405410        }
    406411        }
    407        
     412
    408413        /** ImageFilter.java is a 1.4 example used by FileChooserDemo2.java. */
    409         private class ImageFilter 
     414        private class ImageFilter
    410415        extends javax.swing.filechooser.FileFilter {
    411        
     416
    412417        private Pattern pattern = null;
    413        
     418
    414419        public ImageFilter() {
    415420            pattern = Pattern.compile(".*\\.(gif|png|jpe?g)");
    416421        }
    417        
     422
    418423        // Accept all directories and all .col files
    419424        public boolean accept(File f) {
     
    422427            return f.isDirectory() || matcher.matches();
    423428        }
    424        
     429
    425430        // The description of this filter
    426431        public String getDescription() {
  • trunk/gli/src/org/greenstone/gatherer/cdm/IndexManager.java

    r5931 r6051  
    331331    Gatherer.c_man.configurationChanged();
    332332    }
    333    
     333
    334334    /** This method is reponsible for changing the underlying Index commands from MG to MGPP and back again. This turns out to be easyish for MG->MGPP and very hard for the reverse. For the former we remove the level fragment and make sure the same levels are set, then we produce a list of the sources involved, breaking down comma seperated lists and making sure each item it unique. Changing back the other way turns out to be impossible, so we don't (beyond generating document:text, section:text and paragraph:text if text is an index and the respective levels are present). In either case we start by creating a comment containing the old index information.
    335335     * @param  state true to enable MGPP indexes, false to use standard MG style ones
     
    378378            index = null;
    379379            }
    380             // Replace mg element with mgpp element 
     380            // Replace mg element with mgpp element
    381381            setRoot(mgpp_element);
    382382
     
    426426        }
    427427        else {
    428             // Replace mg element with mgpp element 
     428            // Replace mg element with mgpp element
    429429            setRoot(mgpp_element);
    430430        }
     
    444444            default_index.setAssigned(true);
    445445        }
    446         // If mg element has no indexes, and the current mgpp index include a text one, then generate text indexes for each of the registered levels. 
     446        // If mg element has no indexes, and the current mgpp index include a text one, then generate text indexes for each of the registered levels.
    447447        NodeList indexes = mgpp_element.getElementsByTagName(CollectionConfiguration.INDEX_ELEMENT);
    448448        if(indexes.getLength() == 0) {
     
    489489    /** This class creates a set of controls for editing the indexes. */
    490490    private class IndexControl
    491     extends JPanel 
     491    extends JPanel
    492492    implements Control {
    493493
     
    728728        else if(source_list.isSelectionEmpty()) {
    729729        add_enabled = false;
    730         } 
     730        }
    731731        // If we get this far, create a dummy index and see if its already assigned in the collection
    732732        else {
     
    806806        return component;
    807807        }
    808          
     808
    809809    }
    810810
    811811    private class MoveListener
    812812        implements ActionListener {
    813        
     813
    814814        private boolean move_up;
    815815
     
    849849    private class SetDefaultListener
    850850        implements ActionListener {
    851        
     851
    852852        public void actionPerformed(ActionEvent event) {
    853853        Index index = (Index) index_list.getSelectedValue();
     
    879879        validateAddButton();
    880880        }
    881        
     881
    882882        /** Gives notification that there was an insert into the document. */
    883883        public void insertUpdate(DocumentEvent e) {
    884884        validateAddButton();
    885885        }
    886        
     886
    887887        /** Gives notification that a portion of the document has been removed. */
    888888        public void removeUpdate(DocumentEvent e) {
     
    928928        // Create Indexes
    929929        JPanel indexes_panel = new JPanel();
    930        
     930
    931931        JPanel current_indexes_panel = new JPanel();
    932932
     
    10531053        index_spacer_panel.add(index_body_panel, BorderLayout.NORTH);
    10541054        index_spacer_panel.add(index_empty_panel, BorderLayout.CENTER);
    1055        
     1055
    10561056        indexes_panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    10571057        indexes_panel.setLayout(new BorderLayout());
     
    10611061        // Create Levels
    10621062        JPanel levels_panel = new JPanel();
    1063        
     1063
    10641064        JPanel current_levels_panel = new JPanel();
    10651065
     
    11191119        add_level_button.setMnemonic(KeyEvent.VK_A);
    11201120        Dictionary.registerBoth(add_level_button, "CDM.IndexManager.MGPP.Add_Level", "CDM.IndexManager.MGPP.Add_Level_Tooltip");
    1121        
     1121
    11221122        remove_level_button = new JButton("CDM.IndexManager.MGPP.Remove_Level");
    11231123        remove_level_button.setEnabled(false);
     
    11731173        level_spacer_panel.add(level_body_panel, BorderLayout.NORTH);
    11741174        level_spacer_panel.add(level_empty_panel, BorderLayout.CENTER);
    1175        
     1175
    11761176        levels_panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    11771177        levels_panel.setLayout(new BorderLayout());
     
    11811181        // Create General
    11821182        JPanel header_panel = new JPanel();
    1183        
     1183
    11841184        title_label = new JLabel();
    11851185        title_label.setHorizontalAlignment(JLabel.CENTER);
     
    13761376        validateAddButton();
    13771377        }
    1378          
     1378
    13791379        /** Gives notification that a portion of the document has been removed.
    13801380         * @param  event a DocumentEvent containing information about the text removed
     
    13831383        validateAddButton();
    13841384        }
    1385        
     1385
    13861386        /** Change the enable state of the add button depending on the current value in the search type combobox. */
    13871387        public void validateAddButton() {
     
    14381438        validateAddButton();
    14391439        }
    1440          
     1440
    14411441        /** Gives notification that a portion of the document has been removed.
    14421442         * @param  event a DocumentEvent containing information about the text removed
     
    14451445        validateAddButton();
    14461446        }
    1447        
     1447
    14481448        /** Change the enable state of the add button depending on the current value in the search type combobox. */
    14491449        public void validateAddButton() {
     
    15001500
    15011501    /** Replace really only replaces the string. */
    1502     private class ReplaceIndexActionListener 
     1502    private class ReplaceIndexActionListener
    15031503        implements ActionListener {
    15041504
     
    15261526        }
    15271527    }
    1528    
     1528
    15291529    private class RemoveIndexActionListener
    15301530        implements ActionListener {
  • trunk/gli/src/org/greenstone/gatherer/cdm/MetadataSetView.java

    r5593 r6051  
    158158    /** This class creates and lays-out the various controls for reviewing the metadata sets, and their commands as they would appear in the collection configuration file. */
    159159    private class MetadataSetControl
    160     extends JPanel 
     160    extends JPanel
    161161    implements Control {
    162162    /** The label denoting the element list. */
     
    324324        String namespace = set.getNamespace();
    325325        // Watch out for the greenstone set, with its namespace of ""
    326         if(namespace == null || namespace.length() == 0) {
    327         namespace = "greenstone";
    328         }
    329         return "metadataset " + namespace + " \"" + set.getFile().getName() + "\"";
     326        return "metadataset " + namespace + " \"" + set.getName() + "\"";
    330327    }
    331328    }
  • trunk/gli/src/org/greenstone/gatherer/cdm/PlugInManager.java

    r5926 r6051  
    967967     */
    968968    private class RemoveListener
    969         implements ActionListener {
    970         /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls.
    971          * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
    972          */
    973         public void actionPerformed(ActionEvent event) {
    974         if(!plugin_list.isSelectionEmpty()) {
    975             Object [] objects = plugin_list.getSelectedValues();
    976             for(int i = 0; i < objects.length; i++) {
    977             if(objects[i] instanceof PlugIn) {
    978                 removePlugIn((PlugIn)objects[i]);
     969        implements ActionListener {
     970        /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls.
     971         * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
     972         */
     973        public void actionPerformed(ActionEvent event) {
     974            int selected_index = plugin_list.getSelectedIndex();
     975            if(selected_index != -1) {
     976                PlugIn selected_plugin = (PlugIn) plugin_list.getSelectedValue();
     977                removePlugIn(selected_plugin);
     978                selected_plugin = null;
     979                // Select the next plugin if available
     980                if(selected_index < plugin_list.getModel().getSize()) {
     981                    // If the new selection is above the separator we can remove it
     982                    if(selected_index < findSeparatorIndex()) {
     983                        plugin_list.setSelectedIndex(selected_index);
     984                        remove.setEnabled(true);
     985                    }
     986                    // Otherwise select the first non-removable plugin
     987                    else {
     988                        plugin_list.setSelectedIndex(selected_index + 1);
     989                        remove.setEnabled(false);
     990                    }
     991                }
     992                else {
     993                    remove.setEnabled(false);
     994                }
     995                // Refresh the available plugins
     996                plugin.setModel(new DefaultComboBoxModel(getAvailable()));
    979997            }
    980             }
    981             // Refresh the available plugins
    982             plugin.setModel(new DefaultComboBoxModel(getAvailable()));
    983         }
    984         remove.setEnabled(false);
    985         }
     998            else {
     999                remove.setEnabled(false);
     1000            }
     1001            /*
     1002            if(!plugin_list.isSelectionEmpty()) {
     1003                Object [] objects = plugin_list.getSelectedValues();
     1004                for(int i = 0; i < objects.length; i++) {
     1005                    if(objects[i] instanceof PlugIn) {
     1006                        removePlugIn((PlugIn)objects[i]);
     1007                    }
     1008                }
     1009                // Refresh the available plugins
     1010                plugin.setModel(new DefaultComboBoxModel(getAvailable()));
     1011            }
     1012            */
     1013        }
    9861014    }
    9871015    }
  • trunk/gli/src/org/greenstone/gatherer/cdm/SearchTypeManager.java

    r5928 r6051  
    2929/**************************************************************************************
    3030 * Written:      16/07/03
    31  * Revised:     
     31 * Revised:
    3232 **************************************************************************************/
    3333import java.awt.*;
     
    8282    return controls;
    8383    }
    84    
    85     public String getSearchTypes() {
    86     StringBuffer search_types = new StringBuffer();
    87     ArrayList types = children();
    88     for (int i=0; i<types.size(); i++) {
    89         if (i>0) {
    90         search_types.append(",");
    91         }
    92         search_types.append(((SearchType)types.get(i)).getName());
    93     }
    94     return search_types.toString();
    95     }
    96     /** Be examining the SearchType 'root' we were created with, determine if mgpp is enabled.
    97      * @return true if MGPP is enabled, false otherwise
    98      */
    99     public boolean isMGPPEnabled() {
    100     return root.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR);
    101     }
     84
     85    /** Return a list of the currently assigned search types as a comma separated string.
     86     * @return a String
     87     */
     88    public String getSearchTypes() {
     89        StringBuffer search_types = new StringBuffer();
     90        ArrayList types = children();
     91        for (int i = 0; i < types.size(); i++) {
     92            if (i>0) {
     93                search_types.append(",");
     94            }
     95            search_types.append(((SearchType)types.get(i)).getName());
     96        }
     97        return search_types.toString();
     98    }
     99
     100    /** Be examining the SearchType 'root' we were created with, determine if mgpp is enabled.
     101     * @return true if MGPP is enabled, false otherwise
     102     */
     103    public boolean isMGPPEnabled() {
     104        return root.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR);
     105    }
    102106
    103107    public void moveSearchType(SearchType search_type, boolean direction) {
     
    127131    remove(search_type);
    128132    add(index, search_type);
    129     Gatherer.c_man.configurationChanged(); 
     133    Gatherer.c_man.configurationChanged();
    130134    }
    131135
     
    147151    private JButton move_up_button;
    148152    private JButton remove_button;
    149    
     153
    150154    private JCheckBox enable_advanced_searches_checkbox;
    151155
     
    267271        inner_panel.add(current_search_types_panel, BorderLayout.CENTER);
    268272        inner_panel.add(search_type_panel, BorderLayout.SOUTH);
    269        
     273
    270274        spacer_panel.setLayout(new BorderLayout());
    271275        spacer_panel.add(inner_panel, BorderLayout.NORTH);
     
    280284    public void destroy() {
    281285    }
    282    
     286
    283287    public void gainFocus() {
    284288        instructions_textarea.setCaretPosition(0);
     
    413417
    414418    /** Listens for changes in the search types combobox, and enabled add button appropriately. */
    415     private class SearchTypesActionDocumentListener 
     419    private class SearchTypesActionDocumentListener
    416420        implements ActionListener, DocumentListener {
    417421        /** Called whenever a selection action occurs on the combobox.
     
    434438        validateAddButton();
    435439        }
    436          
     440
    437441        /** Gives notification that a portion of the document has been removed.
    438442         * @param  event a DocumentEvent containing information about the text removed
     
    441445        validateAddButton();
    442446        }
    443        
     447
    444448        /** Change the enable state of the add button depending on the current value in the search type combobox. */
    445449        private void validateAddButton() {
  • trunk/gli/src/org/greenstone/gatherer/cdm/SuperCollectionManager.java

    r5590 r6051  
    3737import org.greenstone.gatherer.checklist.CheckList;
    3838import org.greenstone.gatherer.checklist.Entry;
    39 import org.greenstone.gatherer.collection.CollectionConfiguration;
     39import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
    4040import org.greenstone.gatherer.util.StaticStrings;
    4141import org.greenstone.gatherer.util.Utility;
     
    4343
    4444/** This class contains the information about what supercollection has been specified (if any) and methods for changing this information. Note that there is a major difference between this manager and the others in that its DOM model is never used directly in any list component. It is only used to decide whether a certain entry in the actual checklist is checked. */
    45 public class SuperCollectionManager 
     45public class SuperCollectionManager
    4646    extends DOMProxyListModel {
    4747
     
    107107    /** Provides controls for altering the SuperCollection settings. */
    108108    private class SuperCollectionControl
    109     extends JPanel 
     109    extends JPanel
    110110    implements Control {
    111111
     
    119119        // Creation
    120120        JPanel header_panel = new JPanel();
    121        
     121
    122122        JLabel title_label = new JLabel();
    123123        title_label.setHorizontalAlignment(JLabel.CENTER);
     
    141141        header_panel.add(title_label, BorderLayout.NORTH);
    142142        header_panel.add(new JScrollPane(instructions), BorderLayout.CENTER);
    143        
     143
    144144        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    145145        setLayout(new BorderLayout());
     
    198198        File collect_cfg_file = new File(possible_collections[i], Utility.CONFIG_DIR);
    199199        if(collect_cfg_file.exists()) {
    200             CollectionConfiguration collect_cfg = new CollectionConfiguration(collect_cfg_file);
     200            BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(collect_cfg_file);
    201201            String collection_title = collect_cfg.getName();
    202202            String collection_name = possible_collections[i].getName();
     
    210210            collection_checklist_model.add(entry);
    211211            entry = null;
    212            
     212
    213213            }
    214214            collection_name = null;
Note: See TracChangeset for help on using the changeset viewer.