Changeset 6051


Ignore:
Timestamp:
2003-11-30T21:43:23+13:00 (20 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
Files:
1 added
32 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/buglist/status.txt

    r6038 r6051  
    29293.2
    3030Fixed (16-10-03)
    31 Metadata importing should have happened automatically. To investigate further. Tracked down an error in ElementWrapper that was causing a NPE when attempting to import metadata with files - but only if you hadn't based your collection on a previous one. Its possible that is what was causing the problem/confusion here
     31Metadata importing should have happened automatically. To investigate further.<br>Tracked down an error in ElementWrapper that was causing a NPE when attempting to import metadata with files - but only if you hadn't based your collection on a previous one. Its possible that is what was causing the problem/confusion here
    3232
    3333203B005
     
    140140Unknown
    1411416
    142 Fixed 22-10-2003
    143 Default strings for all features to be added by way of a combobox containing currently/commonly used format strings. Turns out that one multipurpose default format string can be used. Added 'Use Default Format' button to format manager which becomes active when a part is selected that has a default format string available
     142Fixed - 22-10-03
     143Default strings for all features to be added by way of a combobox containing currently/commonly used format strings<br>Turns out that one multipurpose default format string can be used. Added 'Use Default Format' button to format manager which becomes active when a part is selected that has a default format string available
    144144
    145145203F019
     
    2052055
    206206Fixed
    207 Adding suggested information to help. Tooltips also being added. Tooltips complete. Section on basic functionality removed from help documents due to translation constraints
     207Adding suggested information to help. Tooltips also being added<br>Tooltips complete. Section on basic functionality removed from help documents due to translation constraints
    208208
    209209203F027
     
    324324Linux, Win98, WinXP
    325325NA
    326 Fixed 22-10-2003
    327 Include 'expand text' button for extracted metadata. Investigate other methods for displaying HTML based information. Expand text button in place
     326Fixed 22-10-03
     327Include 'expand text' button for extracted metadata. Investigate other methods for displaying HTML based information<br>Expand text button in place
    328328
    329329203B042
     
    396396Win98, Win2000
    3973976
    398 Fixed 22-10-2003
    399 Ensure GLI correctly detects when it needs to produce hfiles. Elements in metadata sets can now be told if they are to generate hfiles as necessary, however of the three mentioned above only AZList was a bug. Organization has a flat structure so doesn't really need a Hierarchy classifier (a AZCompactList would do)
     398Fixed - 22-10-03
     399Ensure GLI correctly detects when it needs to produce hfiles<br>Elements in metadata sets can now be told if they are to generate hfiles as necessary, however of the three mentioned above only AZList was a bug. Organization has a flat structure so doesn't really need a Hierarchy classifier (a AZCompactList would do)
    400400
    401401203F051
     
    428428Win98, Win2000
    4294296
    430 Fixed 16-10-2003
    431 Ensure that selecting a fixed feature clears component selection and adjusts output state appropriately. It was, the problem lay in trying to change the gui from within the EventThread again - SwingUtilities to the rescue.
     430Fixed (16-10-03)
     431Ensure that selecting a fixed feature clears component selection and adjusts output state appropriately<br>It was, the problem lay in trying to change the gui from within the EventThread again - SwingUtilities to the rescue.
    432432
    433433203B055
     
    436436Win98, Win2000
    4374376
    438 Fixed 16-10-2003
    439 First index should be the default if none other is selected. Fixed as part of the redesign of the indexes page
     438Fixed (16-10-03)
     439First index should be the default if none other is selected.<br>Fixed as part of the redesign of the indexes page
    440440
    441441203B056
     
    14281428All
    14291429NA
    1430 Fixed 11-11-2003
    1431 Something to do with Codec transform not being applied at the right place<br>Actually the whole idea of using double escapes is flawed as this just causing further problems during building. Instead replace escape with some 'safe' character (What about newline?). Of course, this would be transparent to the user as they have been explicitly told in several help documents to use escape.<br>Why CVS didn't update when I changed the status of this bug before I don't know - but it is now officially, completely and finally fixed.
     1430Fixed 05-11-03
     1431Something to do with Codec transform not being applied at the right place<br>Actually the whole idea of using double escapes is flawed as this just causing further problems during building. Instead replace escape with some 'safe' character (What about newline?). Of course, this would be transparent to the user as they have been explicitly told in several help documents to use escape.<br>Have now used the '|' character behind the scenes as it doesn't seem to cause problems in GLI and Greenstone. Of course the user still sees and uses '\' to denote hierarchical paths.
    14321432
    14331433203B180
     
    14441444All
    14451445NA
    1446 Fixed 27-11-2003
    1447 OK<br>Gone. The 'alias' was the unique identifier of a particular row in the hfile - perhaps key would have been a more descriptive name - anyhow I now just use the full-path of the metadata value which is gareunteed to be unique (whereas allowing people to enter their own 'alias' would have required GLI to test this).
     1446Fixed - 05-11-03
     1447The value alias is meant to be a unique identifier for a certain hierarchy path - this isn't made clear in the documents, and is far less of an issue for computer generate documents as it would've been for hand written ones
    14481448
    14491449203B182
     
    19961996All
    19971997NA
    1998 Pending
     1998Fixed 13-11-03
    19991999Ensure description metadata extracted from plugins/classifiers and utilized by the comboboxes
    20002000
     
    20122012All
    20132013NA
    2014 Fixed
     2014Fixed 13-11-03
    20152015Increase empty string checking
    20162016
     
    21242124All
    21252125NA
    2126 Pending Again
    2127 Make memory use reasonable<br>Reinstated the idea of caching metadata.xml files rather than trying to load them all
     2126Fixed - 06-11-03
     2127Make memory use reasonable<br>I've made memory savings in two ways (hopefully). First I've re-activated the idea of only caching a certain number of MDSDocuments in memory (its currently arbitarily set at twenty five), as one of the causes of this problem was hundreds of small MDSDocuments being loaded. The second problem is that the threaded task that loaded all of the documents initially never released the tree nodes after creating them - thus if your collection contains hundreds of folder nodes, each with a small mds, you'd blow your memory allowance. Since caching has been re-enabled I've simply disabled the loader thread (which used to be necessary for hierarchies when I had to depend on the stupid numbering scheme - this however has hopefully been addressed with the hvalue attribute in MDS documents).
    21282128
    21292129203B320
  • trunk/gli/classes/dictionary.properties

    r6050 r6051  
    348348#
    349349#***** Collection *****
    350 Collection.Collection:{32}Collection: {0}{34}
     350Collection.Collection:{32}Collection:{34}
    351351Collection.Delete_Tooltip:Delete selected files and folders
    352352Collection.Filter_Tooltip:Restrict the files shown in the file tree
     
    555555General.Apply:Apply
    556556General.Apply_Tooltip:Apply the current settings but do not exit the dialog
    557 General.Browse:Browse
     557General.Browse:Browse...
    558558General.Browse_Tooltip:Choose a filepath on your computer
    559559General.Cancel:Cancel
     
    698698#
    699699#***** Menu Options *****
     700Menu.Collapse:Close Folder
    700701Menu.Edit:Edit
    701702Menu.Edit_Copy:Copy (ctrl-c)
     
    706707Menu.Edit_Search:Search
    707708Menu.Edit_Undo:Undo
     709Menu.Expand:Open Folder
    708710Menu.File:File
    709711Menu.File_Associations:File Associations...
     
    899901NewCollectionPrompt.Collection_Description:Description of content:
    900902#NewCollectionPrompt.Collection_Email:Author's Email:
    901 #NewCollectionPrompt.Collection_Name:Short Name:
     903NewCollectionPrompt.Collection_Name:Short Name:
    902904#NewCollectionPrompt.Collection_Name_Tooltip:Short collection name, used internally (must be 8 characters or less)
    903905NewCollectionPrompt.Description_Error:The description field must be filled out. Please correct.
     
    909911NewCollectionPrompt.Metadata_Instructions2:(Note: You can add new ones later).
    910912NewCollectionPrompt.Metadata_Title_Existing:Select metadata sets.
    911 NewCollectionPrompt.Name_Error:You have either failed to enter a name for the collection, or the name you have choosen is already in use. Please correct.
     913#NewCollectionPrompt.Name_Error:You have either failed to enter a name for the collection, or the name you have choosen is already in use. Please correct.
    912914NewCollectionPrompt.NewCollection:-- New Collection --
    913915NewCollectionPrompt.Select_MDS:Available metadata sets:
    914916NewCollectionPrompt.Set_Contains:This metadata set contains the elements
    915917NewCollectionPrompt.Title:Create a new Collection.
     918NewCollectionPrompt.Title_Clash:The title you have choosen for your collection is already in use. Please correct.
    916919NewCollectionPrompt.Title_Error:The title field must be filled out. Please correct.
    917920#***** New Folder Prompt *****
     
    962965Preferences.General:General
    963966Preferences.General_Tooltip:Set some general preferences
     967Preferences.General.Email:Users Email:
     968Preferences.General.Email_Tooltip:The email address automatically used for any collection created with the GLI
    964969Preferences.General.Interface_Language:Interface Language:
    965970Preferences.General.Interface_Language_Tooltip:Select the language you wish the interface and its controls to be displayed in.
  • trunk/gli/src/org/greenstone/gatherer/Configuration.java

    r6025 r6051  
    453453    public void set(String property, boolean general, boolean value) {
    454454    if(property.startsWith("workflow")) {
    455         System.err.println("Set property: " + property + ", general=" + general + ", value=" + value);
     455        Gatherer.println("Set property: " + property + ", general=" + general + ", value=" + value);
    456456    }
    457457    setString(property, general, (value ? "true" : "false"));
  • 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;
  • trunk/gli/src/org/greenstone/gatherer/collection/Collection.java

    r5815 r6051  
    4343import org.greenstone.gatherer.Gatherer;
    4444import org.greenstone.gatherer.cdm.CollectionDesignManager;
     45import org.greenstone.gatherer.cdm.CollectionMeta;
     46import org.greenstone.gatherer.cdm.CollectionMetaManager;
    4547import org.greenstone.gatherer.collection.BuildOptions;
     48import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
    4649import org.greenstone.gatherer.collection.CollectionManager;
    4750import org.greenstone.gatherer.file.FileNode;
     
    5962 */
    6063public class Collection {
    61     /** A reference to the BuildOptions. */
    62     public BuildOptions build_options;
    63     /** A reference to the Collection Design Manager. */
    64     public CollectionDesignManager cdm;
    65     /** A reference to the Greenstone Directory Metadata Manager. */
    66     public GDMManager gdm;
    67     /** A reference to the Metadata Set Manager. */
    68     public MetadataSetManager msm;
    69     /** <i>true</i> if the currently loaded collection has been saved since the last significant change, <i>false</i> otherwise. */
    70     private boolean saved = false;
    71     /** The collectio configuration file for this collection. */
    72     private CollectionConfiguration collect_cfg;
    73     /** The document around which this collection class is based. */
    74     private Document document;
    75     /** The file the collection is in (the file may not actually exist, such in the case of a legacy collection)! */
    76     private File file;
     64    /** A reference to the BuildOptions. */
     65    public BuildOptions build_options;
     66    /** A reference to the Collection Design Manager. */
     67    public CollectionDesignManager cdm;
     68    /** A reference to the Greenstone Directory Metadata Manager. */
     69    public GDMManager gdm;
     70    /** A reference to the Metadata Set Manager. */
     71    public MetadataSetManager msm;
     72    /** <i>true</i> if the currently loaded collection has been saved since the last significant change, <i>false</i> otherwise. */
     73    private boolean saved = false;
     74    /** The document around which this collection class is based. */
     75    private Document document;
     76    /** The file the collection is in (the file may not actually exist, such in the case of a legacy collection)! */
     77    private File file;
    7778   /** The name of the argument element. */
    7879   static final private String ARGUMENT = "Argument";
    7980   static final private String BASE_COLLECTION = "base_collection";
    80     /** The name of the build element. */
    81     static final private String BUILD = "Build";
    82     /** The name of the build config element. */
    83     static final private String BUILD_CONFIG = "BuildConfig";
    84     /** The name of the collection xml template. */
    85     static final private String COLLECTION_XML_TEMPLATE = "xml/template.col";
    86     /** The name of the directory mappings element. */
    87     static final private String DIRECTORY_MAPPINGS = "DirectoryMappings";
    88     /** The name of the file attribute. */
    89     static final private String FILE = "file";
    90     /** The name of the import element. */
    91     static final private String IMPORT = "Import";
    92     /** The name of the imported attribute. */
    93     static final private String IMPORTED = "imported";
    94     /** The name of the mapping element. */
    95     static final private String MAPPING = "Mapping";
    96     /** The name of the name attribute. */
    97     static final private String NAME = "name";
    98     /** The name of the true value. */
    99     static final private String TRUE = "true";
    100     /** Constructor. */
    101     public Collection(File collection_xml) {
    102     this.file = collection_xml;
    103     // Try to load this collections details.
    104     document = Utility.parse(collection_xml, false);
    105     // If that fails load the default settings for a collection.
    106     if(document == null) {
    107         document = Utility.parse(COLLECTION_XML_TEMPLATE, true);
    108     }
    109     // Point the Configuration class at our gatherer config arguments.
    110     Gatherer.config.setCollectionConfiguration(document);
    111     // We also attempt to parse the collection configuration file.
    112     collect_cfg = new CollectionConfiguration(new File(collection_xml.getParentFile(), Utility.CONFIG_DIR));
    113     // Finally create all of the child managers that are directly dependant on a collection
    114     build_options = new BuildOptions(getBuildValues(), getImportValues());       
    115     }
    116     /** Add a special directory mapping. */
    117     public boolean addDirectoryMapping(String name, File file) {
     81    /** The name of the build element. */
     82    static final private String BUILD = "Build";
     83    /** The name of the build config element. */
     84    static final private String BUILD_CONFIG = "BuildConfig";
     85    /** The name of the collection xml template. */
     86    static final private String COLLECTION_XML_TEMPLATE = "xml/template.col";
     87    /** The name of the directory mappings element. */
     88    static final private String DIRECTORY_MAPPINGS = "DirectoryMappings";
     89    /** The name of the file attribute. */
     90    static final private String FILE = "file";
     91    /** The name of the import element. */
     92    static final private String IMPORT = "Import";
     93    /** The name of the imported attribute. */
     94    static final private String IMPORTED = "imported";
     95    /** The name of the mapping element. */
     96    static final private String MAPPING = "Mapping";
     97    /** The name of the name attribute. */
     98    static final private String NAME = "name";
     99    /** The name of the true value. */
     100    static final private String TRUE = "true";
     101    /** Constructor. */
     102    public Collection(File collection_xml) {
     103        this.file = collection_xml;
     104        // Try to load this collections details.
     105        document = Utility.parse(collection_xml, false);
     106        // If that fails load the default settings for a collection.
     107        if(document == null) {
     108            document = Utility.parse(COLLECTION_XML_TEMPLATE, true);
     109        }
     110        // Point the Configuration class at our gatherer config arguments.
     111        Gatherer.config.setCollectionConfiguration(document);
     112        // Finally create all of the child managers that are directly dependant on a collection
     113        build_options = new BuildOptions(getBuildValues(), getImportValues());
     114    }
     115
     116    /** Add a special directory mapping. */
     117    public boolean addDirectoryMapping(String name, File file) {
    118118    boolean result = false;
    119119    try {
    120         Element document_element = document.getDocumentElement();
    121         Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS);
     120        Element document_element = document.getDocumentElement();
     121        Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS);
    122122                // Ensure the name isn't already in use.
    123         boolean found = false;
    124         NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING);
    125         for(int i = 0; !found && i < mappings.getLength(); i++) {
     123        boolean found = false;
     124        NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING);
     125        for(int i = 0; !found && i < mappings.getLength(); i++) {
    126126        Element mapping_element = (Element) mappings.item(i);
    127127        if(mapping_element.getAttribute(NAME).equalsIgnoreCase(name)) {
    128             found = true;
     128            found = true;
    129129        }
    130130        mapping_element = null;
    131         }
    132         // Otherwise add the mapping.
    133         if(!found) {
     131        }
     132        // Otherwise add the mapping.
     133        if(!found) {
    134134        Element mapping_element = document.createElement(MAPPING);
    135135        mapping_element.setAttribute(NAME, name);
     
    138138        result = true;
    139139        mapping_element = null;
    140         }
    141         mappings = null;
    142         directory_mappings_element = null;
    143         document_element = null;
    144         saved = false;
     140        }
     141        mappings = null;
     142        directory_mappings_element = null;
     143        document_element = null;
     144        saved = false;
    145145    }
    146146    catch (Exception error) {
    147         Gatherer.printStackTrace(error);
     147        Gatherer.printStackTrace(error);
    148148    }
    149149    return result;
    150     }
    151 
    152     /** Destructor.
    153     * @see org.greenstone.gatherer.collection.CollectionModel */
    154     public void destroy() {
     150    }
     151
     152    /** Destructor.
     153    * @see org.greenstone.gatherer.collection.CollectionModel */
     154    public void destroy() {
    155155    cdm.destroy();
    156156    gdm.destroy();
     
    161161    gdm = null;
    162162    msm = null;
    163     }
     163    }
    164164
    165165   /** Determine the path to the base collection.
    166     * @return the path as a String
    167     */
     166    * @return the path as a String
     167    */
    168168   public String getBaseCollection() {
    169       return getString(BASE_COLLECTION);
     169      return getString(BASE_COLLECTION);
    170170   }
    171    
    172     /** Determine the number of documents and folders in this collection. */
    173     public int getCount() {
     171
     172    /** Determine the number of documents and folders in this collection. */
     173    public int getCount() {
    174174    return getCount((TreeNode)Gatherer.c_man.getRecordSet().getRoot(), true, true);
    175     }
    176 
    177     /** Calculates the number of documents in this collection. */
    178     public int getDocumentCount() {
     175    }
     176
     177    /** Calculates the number of documents in this collection. */
     178    public int getDocumentCount() {
    179179    return getCount((TreeNode)Gatherer.c_man.getRecordSet().getRoot(), false, true);
    180     }
    181     /** Retrieve the description of this collection.
    182      * @return The description as a <strong>String</strong>.
    183      */
    184     public String getDescription() {
    185     return collect_cfg.getDescription();
    186     }
    187 
    188     public String getCollectionType() {
    189     return collect_cfg.getBuildType();
    190     }
    191 
    192     public String getSearchTypes() {
    193     return collect_cfg.getSearchTypes();
    194     }
    195     /** Retrieve a specific directory mapping associated with this collection.
    196      * @param name The name of the mapping to retrieve as a <strong>String</strong>.
    197      * @return The <strong>File</strong> this name maps to, or <i>null</i> if no such mapping.
    198      */
    199     /* private File getDirectoryMapping(String name) {
    200     File result = null;
    201     try {
    202         Element document_element = document.getDocumentElement();
    203         Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS);
    204                 // Ensure the name isn't already in use.
    205         boolean found = false;
    206         NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING);
    207         for(int i = 0; !found && i < mappings.getLength(); i++) {
    208         Element mapping_element = (Element) mappings.item(i);
    209         if(mapping_element.getAttribute(NAME).equalsIgnoreCase(name)) {
    210             result = new File(MSMUtils.getValue(mapping_element));
    211             found = true;
    212         }
    213         mapping_element = null;
    214         }
    215         mappings = null;
    216         directory_mappings_element = null;
    217         document_element = null;
    218     }
    219     catch(Exception error) {
    220         Gatherer.printStackTrace(error);
    221     }
    222     return result;
    223     } */
    224     /** Retrieve the special directory mappings associated with this collection.
    225      * @return A <strong>HashMap</strong> containing mappings from names to directories.
    226      */
    227     public HashMap getDirectoryMappings() {
    228     HashMap special_directories = new HashMap();
    229     try {
    230         Element document_element = document.getDocumentElement();
    231         Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS);
    232                 // Ensure the name isn't already in use.
    233         boolean found = false;
    234         NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING);
    235         for(int i = 0; !found && i < mappings.getLength(); i++) {
    236         Element mapping_element = (Element) mappings.item(i);
    237         String name = mapping_element.getAttribute(NAME);
    238         File file = new File(mapping_element.getAttribute(FILE));
    239         special_directories.put(name, file);
    240         file = null;
    241         name = null;
    242         mapping_element = null;
    243         }
    244         mappings = null;
    245         directory_mappings_element = null;
    246         document_element = null;
    247     }
    248     catch(Exception error) {
    249         Gatherer.printStackTrace(error);
    250     }         
    251     return special_directories;
    252     }
    253     /** Retrieve the authors email for this collection.
    254      * @return The email as a <strong>String</strong>.
    255      */
    256     public String getEmail() {
    257     return collect_cfg.getCreator();
    258     }
    259     /** Counts the number of folders used in the current record set. */
    260     /* private int getFolderCount() {
    261     return getCount((TreeNode)Gatherer.c_man.getRecordSet().getRoot(), true, false);
    262     } */
    263     /** Determine if this collection has had an import action run upon it since the last major change.
    264      * @return <i>true</i> if an import has occured, <i>false</i> otherwise.
    265      */
    266     /* private boolean getImported() {
    267     return get(IMPORTED);
    268     } */
    269     /** Retrieve the short name for this collection.
    270      * @return The name as a <strong>String</strong>.
    271      */
    272     public String getName() {
    273     return file.getParentFile().getName();
    274     }
    275     /** Determine if this collection has been saved since the last major change.
    276      * @return <i>true</i> if it has been saved recently, <i>false</i> otherwise.
    277      */
    278     public boolean getSaved() {
    279     return saved;
    280     }
    281     /** Retrieve the title of this collection.
    282      * @return The title as a <strong>String</strong>.
    283      */
    284     public String getTitle() {
    285     return collect_cfg.getName();
    286     }
    287     /** Remove a previously defined special directory mapping.
    288      * @param name The name of the mapping to remove as a <strong>String</strong>.
    289      * @return The <strong>File</strong> of the mapping removed.
    290      */
    291     public File removeDirectoryMapping(String name) {
    292     File file = null;
    293     try {
    294         Element document_element = document.getDocumentElement();
    295         Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS);
    296                 // Ensure the name isn't already in use.
    297         boolean found = false;
    298         NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING);
    299         for(int i = 0; !found && i < mappings.getLength(); i++) {
    300         Element mapping_element = (Element) mappings.item(i);
    301         if(mapping_element.getAttribute(NAME).equalsIgnoreCase(name)) {
    302             file = new File(MSMUtils.getValue(mapping_element));
    303             directory_mappings_element.removeChild(mapping_element);
    304             found = true;
    305         }
    306         mapping_element = null;
    307         }
    308         mappings = null;
    309         directory_mappings_element = null;
    310         document_element = null;
    311         saved = false;
    312     }
    313     catch(Exception error) {
    314         Gatherer.printStackTrace(error);
    315     }   
    316     return file;
    317     }
    318     /** Save this xml document to the given file. */
    319     public void save() {
     180    }
     181
     182    /** Retrieve the description of this collection.
     183     * @return a String
     184     */
     185    public String getDescription() {
     186        if(cdm == null) {
     187            return StaticStrings.EMPTY_STR;
     188        }
     189        CollectionMeta collection_extra_collectionmeta = cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
     190        return collection_extra_collectionmeta.getValue(CollectionMeta.TEXT);
     191    }
     192
     193    /** Retrieve the special directory mappings associated with this collection.
     194     * @return A <strong>HashMap</strong> containing mappings from names to directories.
     195     */
     196    public HashMap getDirectoryMappings() {
     197        HashMap special_directories = new HashMap();
     198        try {
     199            Element document_element = document.getDocumentElement();
     200            Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS);
     201            // Ensure the name isn't already in use.
     202            boolean found = false;
     203            NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING);
     204            for(int i = 0; !found && i < mappings.getLength(); i++) {
     205                Element mapping_element = (Element) mappings.item(i);
     206                String name = mapping_element.getAttribute(NAME);
     207                File file = new File(mapping_element.getAttribute(FILE));
     208                special_directories.put(name, file);
     209                file = null;
     210                name = null;
     211                mapping_element = null;
     212            }
     213            mappings = null;
     214            directory_mappings_element = null;
     215            document_element = null;
     216        }
     217        catch(Exception error) {
     218            Gatherer.printStackTrace(error);
     219        }
     220        return special_directories;
     221    }
     222    /** Retrieve the authors email for this collection.
     223     * @return The email as a <strong>String</strong>.
     224     */
     225    public String getEmail() {
     226        if(cdm == null) {
     227            return StaticStrings.EMPTY_STR;
     228        }
     229        CollectionMeta creator_collectionmeta = new CollectionMeta(CollectionDesignManager.collect_config.getCreator());
     230        return creator_collectionmeta.getValue(CollectionMeta.TEXT);
     231    }
     232
     233    /** Retrieve the short name for this collection.
     234     * @return The name as a <strong>String</strong>.
     235     */
     236    public String getName() {
     237        return file.getParentFile().getName();
     238    }
     239
     240    /** Determine if this collection has been saved since the last major change.
     241     * @return <i>true</i> if it has been saved recently, <i>false</i> otherwise.
     242     */
     243    public boolean getSaved() {
     244        return saved;
     245    }
     246
     247    /** Retrieve the title of this collection.
     248     * @return The title as a <strong>String</strong>.
     249     */
     250    public String getTitle() {
     251        if(cdm == null) {
     252            return StaticStrings.EMPTY_STR;
     253        }
     254        CollectionMeta collection_name_collectionmeta = cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR);
     255        return collection_name_collectionmeta.getValue(CollectionMeta.TEXT);
     256    }
     257    /** Remove a previously defined special directory mapping.
     258     * @param name The name of the mapping to remove as a <strong>String</strong>.
     259     * @return The <strong>File</strong> of the mapping removed.
     260     */
     261    public File removeDirectoryMapping(String name) {
     262        File file = null;
     263        try {
     264            Element document_element = document.getDocumentElement();
     265            Element directory_mappings_element = (Element) MSMUtils.getNodeFromNamed(document_element, DIRECTORY_MAPPINGS);
     266            // Ensure the name isn't already in use.
     267            boolean found = false;
     268            NodeList mappings = directory_mappings_element.getElementsByTagName(MAPPING);
     269            for(int i = 0; !found && i < mappings.getLength(); i++) {
     270                Element mapping_element = (Element) mappings.item(i);
     271                if(mapping_element.getAttribute(NAME).equalsIgnoreCase(name)) {
     272                    file = new File(MSMUtils.getValue(mapping_element));
     273                    directory_mappings_element.removeChild(mapping_element);
     274                    found = true;
     275                }
     276                mapping_element = null;
     277            }
     278            mappings = null;
     279            directory_mappings_element = null;
     280            document_element = null;
     281            saved = false;
     282        }
     283        catch(Exception error) {
     284            Gatherer.printStackTrace(error);
     285        }
     286        return file;
     287    }
     288    /** Save this xml document to the given file. */
     289    public void save() {
    320290    Utility.export(document, file);
    321     }
     291    }
    322292
    323293   public void setBaseCollection(String base_collection) {
    324       set(BASE_COLLECTION, base_collection);
     294      set(BASE_COLLECTION, base_collection);
    325295   }
    326    
    327     /** Set the value of imported to the given value.
    328     * @param value The new value for imported, <i>true</i> if the collection has been imported successfully, <i>false</i> otherwise.
    329     */
    330     public void setImported(boolean value) {
     296
     297    /** Set the value of imported to the given value.
     298    * @param value The new value for imported, <i>true</i> if the collection has been imported successfully, <i>false</i> otherwise.
     299    */
     300    public void setImported(boolean value) {
    331301    set(IMPORTED, value);
    332302    saved = false;
    333     }
    334     /** Set the value of saved to the given value.
    335     * @param value The new value for saved, <i>true</i> if the collection has been saved recently, <i>false</i> otherwise.
    336     */
    337     public void setSaved(boolean value) {
     303    }
     304    /** Set the value of saved to the given value.
     305    * @param value The new value for saved, <i>true</i> if the collection has been saved recently, <i>false</i> otherwise.
     306    */
     307    public void setSaved(boolean value) {
    338308    saved = value;
    339     }
    340     /** Set the value of title to the given value.
    341      * @param title The new <strong>String</strong> title.
    342      */
    343     public void setTitle(String title) {
    344     collect_cfg.setName(title);
    345     }
    346     /** Method called to return a textual representation of a class, which in this case is the collections title.
    347      * @return A <strong>String</strong> containing the collections title.
    348      */
    349     public String toString() {
    350     return collect_cfg.getName();
    351     }
    352     /** Get the value of a collection argument. */
    353     private boolean get(String name) {
     309    }
     310    /** Set the value of title to the given value.
     311     * @param title The new <strong>String</strong> title.
     312     */
     313    public void setTitle(String title) {
     314        if(cdm != null) {
     315            CollectionMeta collection_name_collectionmeta = cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR);
     316            collection_name_collectionmeta.setValue(title);
     317        }
     318    }
     319    /** Method called to return a textual representation of a class, which in this case is the collections title.
     320     * @return A <strong>String</strong> containing the collections title.
     321     */
     322    public String toString() {
     323        return getTitle();
     324    }
     325    /** Get the value of a collection argument. */
     326    private boolean get(String name) {
    354327    boolean result = false;
    355328    try {
    356         Element document_element = document.getDocumentElement();
    357         NodeList arguments = document_element.getElementsByTagName(ARGUMENT);
    358         boolean found = false;
    359         for(int i = 0; !found && i < arguments.getLength(); i++) {
     329        Element document_element = document.getDocumentElement();
     330        NodeList arguments = document_element.getElementsByTagName(ARGUMENT);
     331        boolean found = false;
     332        for(int i = 0; !found && i < arguments.getLength(); i++) {
    360333        Element argument_element = (Element) arguments.item(i);
    361334        if(argument_element.getParentNode() == document_element) {
    362             if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
     335            if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
    363336            String value = MSMUtils.getValue(argument_element);
    364337            if(value.equalsIgnoreCase(TRUE)) {
    365                 result = true;
     338                result = true;
    366339            }
    367340            found = true;
    368341            value = null;
    369             }
     342            }
    370343        }
    371344        argument_element = null;
    372         }
    373         arguments = null;
    374         document_element = null;
     345        }
     346        arguments = null;
     347        document_element = null;
    375348    }
    376349    catch (Exception error) {
    377         Gatherer.printStackTrace(error);
     350        Gatherer.printStackTrace(error);
    378351    }
    379352    return result;
    380     }
    381 
    382     /** Get the value of a collection argument. */
    383     private String getString(String name) {
     353    }
     354
     355    /** Get the value of a collection argument. */
     356    private String getString(String name) {
    384357    String result = "";
    385358    try {
    386         Element document_element = document.getDocumentElement();
    387         NodeList arguments = document_element.getElementsByTagName(ARGUMENT);
    388         boolean found = false;
    389         for(int i = 0; !found && i < arguments.getLength(); i++) {
     359        Element document_element = document.getDocumentElement();
     360        NodeList arguments = document_element.getElementsByTagName(ARGUMENT);
     361        boolean found = false;
     362        for(int i = 0; !found && i < arguments.getLength(); i++) {
    390363        Element argument_element = (Element) arguments.item(i);
    391364        if(argument_element.getParentNode() == document_element) {
    392             if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
     365            if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
    393366            result = MSMUtils.getValue(argument_element);
    394367            found = true;
    395             }
     368            }
    396369        }
    397370        argument_element = null;
    398         }
    399         arguments = null;
    400         document_element = null;
     371        }
     372        arguments = null;
     373        document_element = null;
    401374    }
    402375    catch (Exception error) {
    403         Gatherer.printStackTrace(error);
     376        Gatherer.printStackTrace(error);
    404377    }
    405378    return result;
    406     }   
    407 
    408     /** Method to retrieve the current build options associated with this Collection. */
    409     private Element getBuildValues() {
     379    }
     380
     381    /** Method to retrieve the current build options associated with this Collection. */
     382    private Element getBuildValues() {
    410383    Element build_values_element = null;
    411384    try {
    412         Element document_element = document.getDocumentElement();
    413         Element build_config_element = (Element) MSMUtils.getNodeFromNamed(document_element, BUILD_CONFIG);
    414         build_values_element = (Element) MSMUtils.getNodeFromNamed(build_config_element, BUILD);
    415         build_config_element = null;
    416         document_element = null;
     385        Element document_element = document.getDocumentElement();
     386        Element build_config_element = (Element) MSMUtils.getNodeFromNamed(document_element, BUILD_CONFIG);
     387        build_values_element = (Element) MSMUtils.getNodeFromNamed(build_config_element, BUILD);
     388        build_config_element = null;
     389        document_element = null;
    417390    }
    418391    catch (Exception error) {
    419         Gatherer.printStackTrace(error);
     392        Gatherer.printStackTrace(error);
    420393    }
    421394    return build_values_element;
    422     }
    423 
    424     /** Count either documents or folders, depending on the state of the given boolean. */
    425     private int getCount(TreeNode node, boolean count_folders, boolean count_files) {
     395    }
     396
     397    /** Count either documents or folders, depending on the state of the given boolean. */
     398    private int getCount(TreeNode node, boolean count_folders, boolean count_files) {
    426399    int count = 0;
    427400    File file = ((FileNode)node).getFile();
    428401    if(file.isFile() && count_files) {
    429         count++;
     402        count++;
    430403    }
    431404    else if(file.isDirectory() && count_folders) {
    432         count++;
     405        count++;
    433406    }
    434407    for(int i = 0; i < node.getChildCount(); i++) {
    435         count = count + getCount(node.getChildAt(i), count_folders, count_files);
     408        count = count + getCount(node.getChildAt(i), count_folders, count_files);
    436409    }
    437410    return count;
    438     }
    439 
    440     /** Method to retrieve the current import options associated with this Collection. */
    441     public Element getImportValues() {
     411    }
     412
     413    /** Method to retrieve the current import options associated with this Collection. */
     414    public Element getImportValues() {
    442415    Element import_values_element = null;
    443416    try {
    444         Element document_element = document.getDocumentElement();
    445         Element build_config_element = (Element) MSMUtils.getNodeFromNamed(document_element, BUILD_CONFIG);
    446         import_values_element = (Element) MSMUtils.getNodeFromNamed(build_config_element, IMPORT);
    447         build_config_element = null;
    448         document_element = null;
     417        Element document_element = document.getDocumentElement();
     418        Element build_config_element = (Element) MSMUtils.getNodeFromNamed(document_element, BUILD_CONFIG);
     419        import_values_element = (Element) MSMUtils.getNodeFromNamed(build_config_element, IMPORT);
     420        build_config_element = null;
     421        document_element = null;
    449422    }
    450423    catch (Exception error) {
    451         Gatherer.printStackTrace(error);
     424        Gatherer.printStackTrace(error);
    452425    }
    453426    return import_values_element;
    454     }
     427    }
    455428
    456429   /** Set the value of a collection argument. */
    457430   private void set(String name, boolean value) {
    458       set(name, (value ? StaticStrings.TRUE_STR : StaticStrings.FALSE_STR));
     431      set(name, (value ? StaticStrings.TRUE_STR : StaticStrings.FALSE_STR));
    459432   }
    460    
     433
    461434   private void set(String name, String value) {
    462       try {
     435      try {
    463436     Element document_element = document.getDocumentElement();
    464437     NodeList arguments = document_element.getElementsByTagName(ARGUMENT);
    465438     boolean found = false;
    466439     for(int i = 0; !found && i < arguments.getLength(); i++) {
    467         Element argument_element = (Element) arguments.item(i);
    468         if(argument_element.getParentNode() == document_element) {
    469            if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
     440        Element argument_element = (Element) arguments.item(i);
     441        if(argument_element.getParentNode() == document_element) {
     442           if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
    470443          // Strip any current value nodes.
    471444          while(argument_element.hasChildNodes()) {
    472             argument_element.removeChild(argument_element.getFirstChild());
     445            argument_element.removeChild(argument_element.getFirstChild());
    473446          }
    474447          // Append new value
    475448          argument_element.appendChild(document.createTextNode(value));
    476449          found = true;
    477            }
    478         }
    479         argument_element = null;
     450           }
     451        }
     452        argument_element = null;
    480453     }
    481454     // Append it
    482455     if(!found) {
    483         Element argument_element = document.createElement(ARGUMENT);
    484         argument_element.setAttribute(NAME, name);
    485         argument_element.appendChild(document.createTextNode(value));
    486         document_element.appendChild(argument_element);
    487         argument_element = null;
     456        Element argument_element = document.createElement(ARGUMENT);
     457        argument_element.setAttribute(NAME, name);
     458        argument_element.appendChild(document.createTextNode(value));
     459        document_element.appendChild(argument_element);
     460        argument_element = null;
    488461     }
    489462     arguments = null;
    490463     document_element = null;
    491       }
    492       catch (Exception error) {
     464      }
     465      catch (Exception error) {
    493466     Gatherer.printStackTrace(error);
    494       }
     467      }
    495468   }
    496469}
  • trunk/gli/src/org/greenstone/gatherer/collection/CollectionManager.java

    r6026 r6051  
    4747import org.greenstone.gatherer.Gatherer;
    4848import org.greenstone.gatherer.cdm.CollectionDesignManager;
     49import org.greenstone.gatherer.cdm.CollectionMeta;
     50import org.greenstone.gatherer.cdm.CollectionMetaManager;
    4951import org.greenstone.gatherer.collection.Collection;
    5052import org.greenstone.gatherer.collection.SaveCollectionTask;
     
    380382        updateCollectionCFG(new File(base_collection_directory, Utility.CONFIG_DIR), new File(a_dir, Utility.CONFIG_DIR), description, email, title);
    381383        }
    382        
     384
    383385        // Always import the extracted metadata set if we didn't already
    384386        if(collection.msm.getSet(Utility.EXTRACTED_METADATA_NAMESPACE) == null) {
    385387           collection.msm.importMDS(new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION), false);
    386388        }
    387            
     389
    388390        collection.cdm = new CollectionDesignManager(new File(getCollectionConfig()));
     391
     392        // Now that we have a CDM, update several settings, such as if we created this collection by basing it on another, set it as public automatically
     393        if(base_collection_directory != null) {
     394            // Update the creator and maintainer
     395            CollectionMeta creator_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getCreator());
     396            creator_collectionmeta.setValue(email);
     397            creator_collectionmeta = null;
     398            CollectionMeta maintainer_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getMaintainer());
     399            maintainer_collectionmeta.setValue(email);
     400            maintainer_collectionmeta = null;
     401            // Update the collection title
     402            CollectionMeta collection_name_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR);
     403            collection_name_collectionmeta.setValue(title);
     404            collection_name_collectionmeta = null;
     405            // And now the description
     406            CollectionMeta collection_extra_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
     407            collection_extra_collectionmeta.setValue(description);
     408            collection_extra_collectionmeta = null;
     409            // All collections based on others are automatically public
     410            CollectionMeta public_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getPublic());
     411            public_collectionmeta.setValue(StaticStrings.TRUE_STR);
     412            public_collectionmeta = null;
     413            // Finally reset the icons
     414            CollectionMeta icon_collection_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR);
     415            icon_collection_collectionmeta.setValue(StaticStrings.EMPTY_STR);
     416            icon_collection_collectionmeta = null;
     417            CollectionMeta icon_collection_small_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR);
     418            icon_collection_small_collectionmeta.setValue(StaticStrings.EMPTY_STR);
     419            icon_collection_small_collectionmeta = null;
     420        }
     421
    389422        collection.gdm = new GDMManager();
    390423
     
    740773    }
    741774
    742     // Special case of a user trying to open an old greenstone collection. 
     775    // Special case of a user trying to open an old greenstone collection.
    743776    File metadata_directory = new File(collection_directory, Utility.META_DIR);
    744777    if(!metadata_directory.exists()) {
    745            
     778
    746779        Gatherer.println("CollectionManager.loadCollection: trying to load up a non-gatherer collection");
    747780        non_gatherer_collection = true;
     
    758791        dialog = null;
    759792    }
    760    
     793
    761794    if(choice != LockFileDialog.YES_OPTION) {
    762795        // user has cancelled
     
    766799    }
    767800
    768    
     801
    769802    try {
    770803        if(lock_file.exists()) {
     
    787820        msm = collection.msm; // Legacy
    788821        collection.msm.load();
    789        
     822
    790823        // if non-gatherer collection, need to add some metadata sets
    791824        if (non_gatherer_collection) {
     
    798831        }
    799832        }
    800            
     833
    801834        collection.cdm = new CollectionDesignManager(new File(collection_file.getParent(), Utility.CONFIG_DIR));
    802835        if (non_gatherer_collection) {
     
    806839        lci = null;
    807840        }
    808        
     841
    809842        // Whether the collection is legacy or not, we should now be able to prepared the GDMManager
    810843        collection.gdm = new GDMManager();
    811        
     844
    812845        // Tell everyone that it worked.
    813846        String[] args = new String[1];
     
    836869        }
    837870    }
    838    
     871
    839872    lock_file = null;
    840873    collection_directory = null;
    841    
     874
    842875    args2 = null;
    843876    return result;
    844877    }
    845    
     878
    846879    /** I started giving the user the choice of using an existing meta set or creating a new one. The second option being so that they didn't have to add/merge/ignore each element, they could all be added automatically. However, I am not sure where the merge prompt gets called from, and it is not essential, so I am leaving it for now - it shoudl be added back in and finished. [kjdon] */
    847880    private boolean addSomeMetadataSets(File collection_dir) {
    848    
    849    
     881
     882
    850883    ExternalCollectionPrompt external_prompt = new ExternalCollectionPrompt();
    851884    int meta_choice = external_prompt.getMetadataChoice();
     
    853886    if (cancelled) {
    854887        return false;
    855     } 
    856    
     888    }
     889
    857890    /*if (meta_choice == ExternalCollectionPrompt.NEW_META_SET) {
    858         NewMetaSetPrompt nmsp = new NewMetaSetPrompt();     
     891        NewMetaSetPrompt nmsp = new NewMetaSetPrompt();
    859892        if (nmsp.isCancelled()) {
    860893        return false;
     
    883916
    884917    return true;
    885     }   
     918    }
    886919
    887920    private boolean searchForMetadata(TreeModel collection_tree, FileNode current_node) {
     
    10421075    else if(event.getStatus() == GShell.ERROR) {
    10431076        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Preview_Ready_Failed"), Dictionary.get("CollectionManager.Preview_Ready_Title"), JOptionPane.ERROR_MESSAGE);
    1044         Gatherer.g_man.collectionChanged(ready()); 
     1077        Gatherer.g_man.collectionChanged(ready());
    10451078    }
    10461079    }
     
    10841117    public void registerBuildMonitor(GShellProgressMonitor monitor) {
    10851118    build_monitor = monitor;
    1086     } 
     1119    }
    10871120    /** This method associates the collection copy monitor with the copy monitor created in CreatePane.
    10881121     * @param monitor A <strong>GShellProgressMonitor</strong> which we will use as the copy monitor.
     
    12071240           Gatherer.println("Index = " + index_dir.getAbsolutePath());
    12081241        }
    1209            
     1242
    12101243        File build_dir = new File(getCollectionBuild(), "temp.txt");
    12111244        build_dir = build_dir.getParentFile();
     
    12871320     }
    12881321
    1289     private void updateCollectionCFG(File base_cfg, File new_cfg, String description, String email, String title) {
    1290     boolean first_name = true;
    1291     boolean first_extra = true;
    1292     String collection_path = (base_cfg.getParentFile().getParentFile()).getAbsolutePath();
    1293 
    1294     HashMap mappings = collection.msm.profiler.getActions(collection_path);
    1295     if(mappings == null) {
    1296         Gatherer.println("Mappings is null, which is odd. Leaving all configuration commands which use metadata as they are.");
    1297     }
    1298 
    1299     // Now read in base_cfg line by line, parsing important onces and/or replacing them with information pertinent to our collection. Each line is then written back out to the new collect.cfg file.
    1300     try {
    1301         BufferedReader in = new BufferedReader(new FileReader(base_cfg));
    1302         BufferedWriter out = new BufferedWriter(new FileWriter(new_cfg, false)); // Overwrite whats there.
    1303         String command = null;
    1304         while((command = in.readLine()) != null) {
    1305         // We have to test the end of command for the special character '\'. If found, remove it and append the next line, then repeat.
    1306         while(command.trim().endsWith("\\")) {
    1307             command = command.substring(0, command.lastIndexOf("\\"));
    1308             String next_line = in.readLine();
    1309             if(next_line != null) {
    1310             command = command + next_line;
    1311             }
     1322    private void updateCollectionCFG(File base_cfg, File new_cfg, String description, String email, String title) {
     1323        boolean first_name = true;
     1324        boolean first_extra = true;
     1325        String collection_path = (base_cfg.getParentFile().getParentFile()).getAbsolutePath();
     1326
     1327        HashMap mappings = collection.msm.profiler.getActions(collection_path);
     1328        if(mappings == null) {
     1329            Gatherer.println("Mappings is null, which is odd. Leaving all configuration commands which use metadata as they are.");
    13121330        }
    1313         ///ystem.err.println("Read: " + command);
    1314         // Now we've finished parsing a line, determine what to do with it.
    1315         String command_lc = command.toLowerCase();
    1316         // We replace the creator string with our own.
    1317         if(command_lc.startsWith(Utility.CFG_CREATOR)) {
    1318            ///ystem.err.println("Found creator - replace with current");
    1319            write(out, Utility.CFG_CREATOR + " " + email);
    1320         }
    1321         else if(command_lc.startsWith(Utility.CFG_MAINTAINER)) {
    1322            ///ystem.err.println("Found maintainer - replace with current");
    1323            write(out, Utility.CFG_MAINTAINER + " " + email);
    1324         }
    1325         else if(command_lc.startsWith(Utility.CFG_COLLECTIONMETA_COLLECTIONNAME)) {
    1326             if(first_name) {
    1327             write(out, Utility.CFG_COLLECTIONMETA_COLLECTIONNAME + " \"" + title + "\"");
    1328             first_name = false;
    1329             }
    1330         }
    1331         else if(command_lc.startsWith(Utility.CFG_COLLECTIONMETA_COLLECTIONEXTRA)) {
    1332             if(first_extra) {
    1333             write(out, Utility.CFG_COLLECTIONMETA_COLLECTIONEXTRA + " \"" + description + "\"");
    1334             first_extra = false;
    1335             }
    1336         }
    1337         else if(command_lc.startsWith(Utility.CFG_COLLECTIONMETA_ICONCOLLECTION)) {
    1338             write(out, Utility.CFG_COLLECTIONMETA_ICONCOLLECTION + " \"\"");
    1339         }
    1340 
     1331
     1332        // Now read in base_cfg line by line, parsing important onces and/or replacing them with information pertinent to our collection. Each line is then written back out to the new collect.cfg file.
     1333        try {
     1334            BufferedReader in = new BufferedReader(new FileReader(base_cfg));
     1335            BufferedWriter out = new BufferedWriter(new FileWriter(new_cfg, false)); // Overwrite whats there.
     1336            String command = null;
     1337            while((command = in.readLine()) != null) {
     1338            // We have to test the end of command for the special character '\'. If found, remove it and append the next line, then repeat.
     1339            while(command.trim().endsWith("\\")) {
     1340                command = command.substring(0, command.lastIndexOf("\\"));
     1341                String next_line = in.readLine();
     1342                if(next_line != null) {
     1343                    command = command + next_line;
     1344                }
     1345            }
     1346            ///ystem.err.println("Read: " + command);
     1347            // Now we've finished parsing a line, determine what to do with it.
     1348            String command_lc = command.toLowerCase();
     1349            // We replace the creator string with our own.
     1350            /*
     1351            if(command_lc.startsWith(Utility.CFG_CREATOR)) {
     1352                ///ystem.err.println("Found creator - replace with current");
     1353                write(out, Utility.CFG_CREATOR + " " + email);
     1354            }
     1355            else if(command_lc.startsWith(Utility.CFG_MAINTAINER)) {
     1356                ///ystem.err.println("Found maintainer - replace with current");
     1357                write(out, Utility.CFG_MAINTAINER + " " + email);
     1358            }
     1359            else if(command_lc.startsWith(Utility.CFG_COLLECTIONMETA_COLLECTIONNAME)) {
     1360                if(first_name) {
     1361                    write(out, Utility.CFG_COLLECTIONMETA_COLLECTIONNAME + " \"" + title + "\"");
     1362                    first_name = false;
     1363                }
     1364            }
     1365            else if(command_lc.startsWith(Utility.CFG_COLLECTIONMETA_COLLECTIONEXTRA)) {
     1366                if(first_extra) {
     1367                    write(out, Utility.CFG_COLLECTIONMETA_COLLECTIONEXTRA + " \"" + description + "\"");
     1368                    first_extra = false;
     1369                }
     1370            }
     1371            else if(command_lc.startsWith(Utility.CFG_COLLECTIONMETA_ICONCOLLECTION)) {
     1372                write(out, Utility.CFG_COLLECTIONMETA_ICONCOLLECTION + " \"\"");
     1373            }
     1374            */
    13411375        // Just before we try more general parsing there are the special cases to check. These are explicit changes required by some collections to produce sensible results.
    1342         else if(special_case == SPECIAL_DLS && command_lc.equals("classify      hierarchy -hfile azlist.txt -metadata azlist -sort title -buttonname title -hlist_at_top")) {
    1343             write(out, "classify AZList -metadata dls.Title -buttonname Title");
    1344         }
    1345         else if(command_lc.startsWith(Utility.CFG_CLASSIFY)) {
     1376            if(special_case == SPECIAL_DLS && command_lc.equals("classify      hierarchy -hfile azlist.txt -metadata azlist -sort title -buttonname title -hlist_at_top")) {
     1377                write(out, "classify AZList -metadata dls.Title -buttonname Title");
     1378            }
     1379            else if(command_lc.startsWith(Utility.CFG_CLASSIFY)) {
    13461380            StringTokenizer tokenizer = new StringTokenizer(command);
    13471381            StringBuffer text = new StringBuffer(tokenizer.nextToken());
  • trunk/gli/src/org/greenstone/gatherer/gui/CollectionPane.java

    r5854 r6051  
    6565 */
    6666public class CollectionPane
    67     extends JPanel
    68     implements ActionListener, FocusListener {
    69     /** The group encompassing all of the components available as drop targets for drag and drop actions. Required so that only one component renders the ghost and higlights itself as a target, which the other members are restored to their original, pristine, condition. */
    70     private DragGroup group                  =  null;
    71     /** The tree showing the files within the collection. */
    72     private DragTree collection_tree        =  null;
    73     /** The tree showing the available source workspace. */
    74     private WorkspaceTree workspace_tree    =  null;
    75     /** The threaded queue that handles the actually movement of files, so that the gui remains responsive. */
    76     private FileQueue file_queue          =  null;
    77     /** The filter currently applied to the collection tree. */
    78     private Filter collection_filter = null;
    79     /** The filter currently applied to the workspace tree. */
    80     private Filter workspace_filter = null;
    81     /** The collection model which is used to build, and hold the data of, the collection tree. */
    82     private TreeModel collection    = null;
    83     /** The GTree model used as the data source for the workspace tree. */
    84     private TreeModel workspace          =  null;
    85     /** The button used to cancel all pending file queue jobs. */
    86     private JButton stop_action           =  null;
    87     /** The button used to create a new folder in the collection tree. */
    88     private JButton new_folder            =  null;
    89     /** The label shown at the top of the collection tree. */
    90     private JLabel collection_label       =  null;
    91     /** The label shown in the status area explaining the file apon which action is taking place. */
    92     private JLabel filename_label        =  null;
    93     /** The label shown explaining the current state of the file queue thread. */
    94     private JLabel status_label           =  null;
    95     /** The label at the top of the workspace tree. */
    96     private JLabel workspace_label        =  null;
    97     /** The panel that contains the collection tree. */
    98     private JPanel collection_pane        =  null;
    99     /** The panel that contains the various controls including the status area. */
    100     private JPanel control_pane           =  null;
    101     /** The panel that contains the workspace tree. */
    102     private JPanel workspace_pane        =  null;
    103     /** The scrollable area into which the collection tree is placed. */
    104     private JScrollPane collection_scroll =  null;
    105     /** The scrollable area into which the workspace tree is placed. */
    106     private JScrollPane workspace_scroll  =  null;
    107     /** A split pane seperating the two trees, allowing for the screen real-estate for each to be changed. */
    108     private JSplitPane tree_pane          =  null;
    109     /** Text fragment arguments used to fill in phrases returned from the dictionary. */
    110     private String args[]                =  null;
    111     /** Ensures that expansion and selection events between collection trees based on the same model are synchronized. */
    112     private TreeSynchronizer collection_tree_sync = null;
    113     /** Ensures that expansion and selection events between workspace trees based on the same model are synchronized. */
    114     private TreeSynchronizer workspace_tree_sync = null;
    115     /** The button used to delete files, which also doubles as a drop target for files from the Trees. */
    116     private UndoManager bin_button            =  null;
    117     /** The default size of a label in the interface. */
    118     static final private Dimension LABEL_SIZE = new Dimension(100,30);
    119     /** The default size of a special mapping dialog. */
    120     static final Dimension DIALOG_SIZE = new Dimension(400, 120);
    121     /** The minimum size a gui component can become. */
    122     static private Dimension MIN_SIZE    = new Dimension( 90,  90);
    123     /** The default size of the status area. */
    124     static private Dimension STATUS_SIZE = new Dimension(450, 120);
    125     /** The initial size of the trees. */
    126     static private Dimension TREE_SIZE   = new Dimension(400, 430);
    127 
    128     /* Constructor.
    129     * @param tree_sync Ensures that expansion events between like trees are synchronized.
    130     * @see org.greenstone.gatherer.file.FileManager
    131     * @see org.greenstone.gatherer.file.FileQueue
    132     */
    133     public CollectionPane(TreeSynchronizer workspace_tree_sync, TreeSynchronizer collection_tree_sync) {
     67    extends JPanel
     68    implements ActionListener, FocusListener {
     69    /** The group encompassing all of the components available as drop targets for drag and drop actions. Required so that only one component renders the ghost and higlights itself as a target, which the other members are restored to their original, pristine, condition. */
     70    private DragGroup group               =  null;
     71    /** The tree showing the files within the collection. */
     72    private DragTree collection_tree        =  null;
     73    /** The tree showing the available source workspace. */
     74    private WorkspaceTree workspace_tree    =  null;
     75    /** The threaded queue that handles the actually movement of files, so that the gui remains responsive. */
     76    private FileQueue file_queue          =  null;
     77    /** The filter currently applied to the collection tree. */
     78    private Filter collection_filter = null;
     79    /** The filter currently applied to the workspace tree. */
     80    private Filter workspace_filter = null;
     81    /** The collection model which is used to build, and hold the data of, the collection tree. */
     82    private TreeModel collection    = null;
     83    /** The GTree model used as the data source for the workspace tree. */
     84    private TreeModel workspace       =  null;
     85    /** The button used to cancel all pending file queue jobs. */
     86    private JButton stop_action        =  null;
     87    /** The button used to create a new folder in the collection tree. */
     88    private JButton new_folder          =  null;
     89    /** The label shown at the top of the collection tree. */
     90    private JLabel collection_label    =  null;
     91    /** The label shown in the status area explaining the file apon which action is taking place. */
     92    private JLabel filename_label        =  null;
     93    /** The label shown explaining the current state of the file queue thread. */
     94    private JLabel status_label        =  null;
     95    /** The label at the top of the workspace tree. */
     96    private JLabel workspace_label      =  null;
     97    /** The panel that contains the collection tree. */
     98    private JPanel collection_pane      =  null;
     99    /** The panel that contains the various controls including the status area. */
     100    private JPanel control_pane        =  null;
     101    /** The panel that contains the workspace tree. */
     102    private JPanel workspace_pane        =  null;
     103    /** The scrollable area into which the collection tree is placed. */
     104    private JScrollPane collection_scroll =  null;
     105    /** The scrollable area into which the workspace tree is placed. */
     106    private JScrollPane workspace_scroll  =  null;
     107    /** A split pane seperating the two trees, allowing for the screen real-estate for each to be changed. */
     108    private JSplitPane tree_pane          =  null;
     109    /** Text fragment arguments used to fill in phrases returned from the dictionary. */
     110    private String args[]                =  null;
     111    /** Ensures that expansion and selection events between collection trees based on the same model are synchronized. */
     112    private TreeSynchronizer collection_tree_sync = null;
     113    /** Ensures that expansion and selection events between workspace trees based on the same model are synchronized. */
     114    private TreeSynchronizer workspace_tree_sync = null;
     115    /** The button used to delete files, which also doubles as a drop target for files from the Trees. */
     116    private UndoManager bin_button          =  null;
     117    /** The default size of a label in the interface. */
     118    static final private Dimension LABEL_SIZE = new Dimension(100,30);
     119    /** The default size of a special mapping dialog. */
     120    static final Dimension DIALOG_SIZE = new Dimension(400, 120);
     121    /** The minimum size a gui component can become. */
     122    static private Dimension MIN_SIZE   = new Dimension( 90,  90);
     123    /** The default size of the status area. */
     124    static private Dimension STATUS_SIZE = new Dimension(450, 120);
     125    /** The initial size of the trees. */
     126    static private Dimension TREE_SIZE   = new Dimension(400, 430);
     127
     128    /* Constructor.
     129    * @param tree_sync Ensures that expansion events between like trees are synchronized.
     130    * @see org.greenstone.gatherer.file.FileManager
     131    * @see org.greenstone.gatherer.file.FileQueue
     132    */
     133    public CollectionPane(TreeSynchronizer workspace_tree_sync, TreeSynchronizer collection_tree_sync) {
    134134    this.group = new DragGroup();
    135135    this.file_queue = Gatherer.f_man.getQueue();
     
    149149    new_folder.setPreferredSize(MIN_SIZE);
    150150    Dictionary.registerTooltip(new_folder, "Collection.New_Folder_Tooltip");
    151     }
    152 
    153     /** Any implementation of ActionListener requires this method so that when an action is performed the appropriate effect can occur. In this case there are three valid possibilities. If the action occured on the recycle bin, then delete the current selection from the collection tree. If the action instead occured on the new folder button, then create a new folder under the current (single) selection in the collection tree. And finally if the cancel button was pressed, cancel the current, and remaining, jobs on the file queue. */
    154     public void actionPerformed(ActionEvent event) {
     151    }
     152
     153    /** Any implementation of ActionListener requires this method so that when an action is performed the appropriate effect can occur. In this case there are three valid possibilities. If the action occured on the recycle bin, then delete the current selection from the collection tree. If the action instead occured on the new folder button, then create a new folder under the current (single) selection in the collection tree. And finally if the cancel button was pressed, cancel the current, and remaining, jobs on the file queue. */
     154    public void actionPerformed(ActionEvent event) {
    155155    // If a user has clicked on the bin button directly remove whatever
    156156    // files are selected in the active tree.
    157157    if(event.getSource() == bin_button) {
    158         if(!bin_button.ignore()) {
     158        if(!bin_button.ignore()) {
    159159        // Find the active tree (you've made selections in).
    160160        DragTree tree = (DragTree) group.getActive();
     
    164164        TreePath paths[] = tree.getSelectionPaths();
    165165        if(paths != null) {
    166             FileNode[] source_nodes = new FileNode[paths.length];
    167             for(int i = 0; i < paths.length; i++) {
     166            FileNode[] source_nodes = new FileNode[paths.length];
     167            for(int i = 0; i < paths.length; i++) {
    168168            source_nodes[i] = (FileNode)(paths[i].getLastPathComponent());
    169             }
    170             Gatherer.f_man.action(tree, source_nodes, bin_button, null);
    171         }
    172         }
     169            }
     170            Gatherer.f_man.action(tree, source_nodes, bin_button, null);
     171        }
     172        }
    173173    }
    174174    // If a user has clicked on new_folder create a new folder under
    175175    // whatever node is selected.
    176176    else if(event.getSource() == new_folder && collection_tree != null) {
    177         int count = collection_tree.getSelectionCount();
    178         boolean error = false;
    179         if(count == 1) {
     177        int count = collection_tree.getSelectionCount();
     178        boolean error = false;
     179        if(count == 1) {
    180180        TreePath path = collection_tree.getSelectionPath();
    181181        FileNode node = (FileNode) path.getLastPathComponent();
    182182        if(node.getAllowsChildren()) {
    183             Gatherer.f_man.newFolder(collection_tree, node);
     183            Gatherer.f_man.newFolder(collection_tree, node);
    184184        }
    185185        else {
    186             // try the parent
    187             FileNode parent = (FileNode)node.getParent();
    188             if (parent!=null && parent.getAllowsChildren()) {
     186            // try the parent
     187            FileNode parent = (FileNode)node.getParent();
     188            if (parent!=null && parent.getAllowsChildren()) {
    189189            Gatherer.f_man.newFolder(collection_tree, parent);
    190             } else {
     190            } else {
    191191            error = true;
    192             }
    193         }
    194         }
    195         else {
     192            }
     193        }
     194        }
     195        else {
    196196        error = true;
    197         }
    198         if(error) {
     197        }
     198        if(error) {
    199199        // instead of an error, we now create a new folder at the root
    200200        FileNode node = (FileNode) collection_tree.getModel().getRoot();
    201201        Gatherer.f_man.newFolder(collection_tree, node);
    202202        //JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.No_Parent_For_New_Folder"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    203         }
     203        }
    204204    }
    205205    else if(event.getSource() == stop_action) {
    206         file_queue.cancelAction();
    207     }
    208     }
    209     /** Called whenever a significant change occurs in the current collections state, such as a new collection being loaded or the current one being closed. Several actions must occur in the GUI to indicate this change to the user, such as en/disabling the collection tree.
    210     * @param ready <i>true</i> if a collection is loaded and ready to be modified, <i>false</i> otherwise.
    211     * @see org.greenstone.gatherer.Configuration
    212     * @see org.greenstone.gatherer.Gatherer
    213     * @see org.greenstone.gatherer.collection.CollectionManager
    214     * @see org.greenstone.gatherer.gui.Coloring
    215     * @see org.greenstone.gatherer.gui.Filter
    216     * @see org.greenstone.gatherer.util.TreeSynchronizer
    217     */
    218     public void collectionChanged(boolean ready) {
     206        file_queue.cancelAction();
     207    }
     208    }
     209    /** Called whenever a significant change occurs in the current collections state, such as a new collection being loaded or the current one being closed. Several actions must occur in the GUI to indicate this change to the user, such as en/disabling the collection tree.
     210    * @param ready <i>true</i> if a collection is loaded and ready to be modified, <i>false</i> otherwise.
     211    * @see org.greenstone.gatherer.Configuration
     212    * @see org.greenstone.gatherer.Gatherer
     213    * @see org.greenstone.gatherer.collection.CollectionManager
     214    * @see org.greenstone.gatherer.gui.Coloring
     215    * @see org.greenstone.gatherer.gui.Filter
     216    * @see org.greenstone.gatherer.util.TreeSynchronizer
     217    */
     218    public void collectionChanged(boolean ready) {
    219219    // Try to retrieve the collections record set.
    220220    collection = Gatherer.c_man.getRecordSet();
    221221    if(collection != null) {
    222         args = new String[1];
    223         args[0] = Gatherer.c_man.getCollection().getName();
    224         Dictionary.registerText(collection_label, "Collection.Collection", args);
    225         collection_tree.setModel(collection);
    226         collection_tree.repaint();
    227         collection_filter.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     222        //args = new String[1];
     223        //args[0] = Gatherer.c_man.getCollection().getName();
     224        Dictionary.registerText(collection_label, "Collection.Collection");
     225        collection_tree.setModel(collection);
     226        collection_tree.repaint();
     227        collection_filter.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    228228    }
    229229    else {
    230         String args[] = new String[1];
    231         args[0] = Dictionary.get("Collection.No_Collection");
    232         Dictionary.registerText(collection_label, "Collection.Collection", args);
    233         args = null;
    234         collection_tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Error")));
    235         collection_filter.setBackground(Color.lightGray);
     230        String args[] = new String[1];
     231        args[0] = Dictionary.get("Collection.No_Collection");
     232        Dictionary.registerText(collection_label, "Collection.Collection", args);
     233        args = null;
     234        collection_tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Error")));
     235        collection_filter.setBackground(Color.lightGray);
    236236    }
    237237    collection_tree.setEnabled(ready);
     
    251251    stop_action.setEnabled(ready);
    252252    new_folder.setEnabled(ready);
    253     }
    254 
    255     /** Generates the pane on controls used to 'collect' files into the collection. Resposible for creating, connecting and laying out these controls. */
    256     public void display() {
     253    }
     254
     255    /** Generates the pane on controls used to 'collect' files into the collection. Resposible for creating, connecting and laying out these controls. */
     256    public void display() {
    257257    // Create Components.
    258258    KeyListenerImpl key_listener = new KeyListenerImpl();
     
    306306    collection_pane.setSize(TREE_SIZE);
    307307
    308     args = new String[1];
    309     args[0] = Dictionary.get("Collection.No_Collection");
     308    //args = new String[1];
     309    //args[0] = Dictionary.get("Collection.No_Collection");
    310310    collection_label = new JLabel();
    311311    collection_label.setOpaque(true);
    312     Dictionary.registerText(collection_label, "Collection.Collection", args);
     312    Dictionary.registerText(collection_label, "Collection.No_Collection");
    313313
    314314    collection = Gatherer.c_man.getRecordSet();
    315315    if(collection != null) {
    316         collection_tree = new DragTree(Utility.COLLECTION_TREE, collection, null, true);
    317         collection_tree.setEnabled(true);
     316        collection_tree = new DragTree(Utility.COLLECTION_TREE, collection, null, true);
     317        collection_tree.setEnabled(true);
    318318    }
    319319    else {
    320         collection_tree = new DragTree(Utility.COLLECTION_TREE, null, true);
    321         collection_tree.setEnabled(false);
     320        collection_tree = new DragTree(Utility.COLLECTION_TREE, null, true);
     321        collection_tree.setEnabled(false);
    322322    }
    323323    group.add(collection_tree);
     
    340340    collection_filter = Gatherer.g_man.getFilter(collection_tree);
    341341    if(collection != null) {
    342         collection_filter.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     342        collection_filter.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    343343    }
    344344    else {
    345         collection_filter.setBackground(Color.lightGray);
     345        collection_filter.setBackground(Color.lightGray);
    346346    }
    347347    // Change the default colours of this filters combobox.
     
    427427    this.add(tree_pane, BorderLayout.CENTER);
    428428    this.add(control_pane, BorderLayout.SOUTH);
    429     }
    430     /** This method ensures that a certain tree path is visible and selected within the collection tree, expanding nodes if necessary. If the method is successful the bounds of the new selection are returned. */
    431     public Rectangle expandPath(TreePath path) {
     429    }
     430    /** This method ensures that a certain tree path is visible and selected within the collection tree, expanding nodes if necessary. If the method is successful the bounds of the new selection are returned. */
     431    public Rectangle expandPath(TreePath path) {
    432432    collection_tree.setImmediate(true);
    433433    collection_tree.scrollPathToVisible(path);
     
    435435    collection_tree.setImmediate(false);
    436436    return collection_tree.getRowBounds(collection_tree.getRowForPath(path));
    437     }
    438     /** Called whenever this pane gains focus, this method ensures that the various tree renderers are correctly colouring the tree (as these settings sometimes get lost).
    439     * @param event A <strong>FocusEvent</strong> containing details about the focus action performed.
    440     */
    441     public void focusGained(FocusEvent event) {
     437    }
     438    /** Called whenever this pane gains focus, this method ensures that the various tree renderers are correctly colouring the tree (as these settings sometimes get lost).
     439    * @param event A <strong>FocusEvent</strong> containing details about the focus action performed.
     440    */
     441    public void focusGained(FocusEvent event) {
    442442    DefaultTreeCellRenderer def = new DefaultTreeCellRenderer();
    443443    DefaultTreeCellRenderer w = (DefaultTreeCellRenderer)workspace_tree.getCellRenderer();
    444444    DefaultTreeCellRenderer c = (DefaultTreeCellRenderer)collection_tree.getCellRenderer();
    445445    if(event.getSource() == workspace_tree) {
    446         w.setBackgroundSelectionColor(def.getBackgroundSelectionColor());
    447         c.setBackgroundSelectionColor(Color.lightGray);
     446        w.setBackgroundSelectionColor(def.getBackgroundSelectionColor());
     447        c.setBackgroundSelectionColor(Color.lightGray);
    448448    }
    449449    else if(event.getSource() == collection_tree) {
    450         c.setBackgroundSelectionColor(def.getBackgroundSelectionColor());
    451         w.setBackgroundSelectionColor(Color.lightGray);
     450        c.setBackgroundSelectionColor(def.getBackgroundSelectionColor());
     451        w.setBackgroundSelectionColor(Color.lightGray);
    452452    }
    453453    repaint();
    454     }
    455     /** Implementation side-effect, not used in any way.
    456     * @param event A <strong>FocusEvent</strong> containing details about the focus action performed.
    457     */
    458     public void focusLost(FocusEvent event) {
    459     }
    460 
    461     /** Called to inform this control panel that it has just gained focus as an effect of the user clicking on its tab.
    462     * @see org.greenstone.gatherer.tree.GTree
    463     */
    464     public void gainFocus() {
     454    }
     455    /** Implementation side-effect, not used in any way.
     456    * @param event A <strong>FocusEvent</strong> containing details about the focus action performed.
     457    */
     458    public void focusLost(FocusEvent event) {
     459    }
     460
     461    /** Called to inform this control panel that it has just gained focus as an effect of the user clicking on its tab.
     462    * @see org.greenstone.gatherer.tree.GTree
     463    */
     464    public void gainFocus() {
    465465    // Update the menubar's idea of whats been selected
    466466    if (collection_tree != null) {
    467         if (collection_tree.isSelectionEmpty()) {
     467        if (collection_tree.isSelectionEmpty()) {
    468468        Gatherer.g_man.menu_bar.setMetaAuditSuffix(null);
    469         }
    470         else {
     469        }
     470        else {
    471471        Gatherer.g_man.menu_bar.setMetaAuditSuffix(collection_tree.getSelectionDetails());
    472         }
     472        }
    473473    }
    474474    // Update the meta-audit view to show the current selection, if any.
    475475    Gatherer.g_man.meta_audit.setRecords(getSelected());
    476     }
    477 
    478     /** Retrieve a list of the currently selected file records in the active tree. */
    479     public FileNode[] getSelected() {
     476    }
     477
     478    /** Retrieve a list of the currently selected file records in the active tree. */
     479    public FileNode[] getSelected() {
    480480    TreePath paths[] = collection_tree.getSelectionPaths();
    481481    FileNode records[] = null;
    482482    if(paths != null) {
    483         records = new FileNode[paths.length];
    484         for(int i = 0; i < records.length; i++) {
     483        records = new FileNode[paths.length];
     484        for(int i = 0; i < records.length; i++) {
    485485        records[i] = (FileNode) paths[i].getLastPathComponent();
    486         }
     486        }
    487487    }
    488488    return records;
    489     }
    490 
    491     public String getSelectionDetails() {
     489    }
     490
     491    public String getSelectionDetails() {
    492492    return collection_tree.getSelectionDetails();
    493     }
    494 
    495 
    496     public void refreshCollectionTree(int refresh_reason)
    497     {
     493    }
     494
     495
     496    public void refreshCollectionTree(int refresh_reason)
     497    {
    498498    collection_tree.refresh(null);
    499     }
    500 
    501 
    502     public void refreshWorkspaceTree(int refresh_reason)
    503     {
     499    }
     500
     501
     502    public void refreshWorkspaceTree(int refresh_reason)
     503    {
    504504    workspace_tree.refresh(refresh_reason);
    505     }
    506 
    507 
    508     /** Used to set the enabled state, and hence the colouring, of the two tree labels.
    509     * @param label The <strong>JLabel</strong> to be affected.
    510     * @param state <i>true</i> for enabled, i.e. when a collection is ready, <i>false</i> otherwise.
    511     * @param foreground The <strong>Color</strong> to make the foreground text of the label when enabled.
    512     * @param background The <strong>Color</strong> to make the background of the label when enabled.
    513     */
    514     private void setEnabled(JLabel label, boolean state, Color foreground, Color background) {
     505    }
     506
     507
     508    /** Used to set the enabled state, and hence the colouring, of the two tree labels.
     509    * @param label The <strong>JLabel</strong> to be affected.
     510    * @param state <i>true</i> for enabled, i.e. when a collection is ready, <i>false</i> otherwise.
     511    * @param foreground The <strong>Color</strong> to make the foreground text of the label when enabled.
     512    * @param background The <strong>Color</strong> to make the background of the label when enabled.
     513    */
     514    private void setEnabled(JLabel label, boolean state, Color foreground, Color background) {
    515515    ///ystem.err.println("Setting the label color to state " + state);
    516516    if(state) {
    517         label.setBackground(background);
    518         label.setForeground(foreground);
     517        label.setBackground(background);
     518        label.setForeground(foreground);
    519519    }
    520520    else {
    521         label.setBackground(Color.lightGray);
    522         label.setForeground(Color.black);
     521        label.setBackground(Color.lightGray);
     522        label.setForeground(Color.black);
    523523    }
    524524    label.repaint();
    525525    ///ystem.err.println("Color is now " + label.getBackground());
    526     }
    527 
    528     /** When a user right-clicks within the trees on the collection pane view they are presented with a small popup menu of context based options. This class provides such functionality.
    529      */
    530     private class GPopupMenu
    531     extends JPopupMenu
    532     implements ActionListener {
    533     /** The tree over which the right click action occured. */
    534     private DragTree tree = null;
    535     /** The file record over which the right click action occured, if any. */
    536     private FileNode node = null;
    537     /** A menu item enabled if a delete action is appropriate in the menus current context. */
    538     private JMenuItem delete = null;
    539     /** A menu item enabled if a special directory mapping is appropriate in the menus current context. */
    540     private JMenuItem map = null;
    541     /** A menu item enabled if a new folder action is appropriate in the menus current context. */
    542     private JMenuItem new_folder = null;
    543     /** A menu item enabled if a show meta-audit dialog action is appropriate in the menus current context. */
    544     private JMenuItem show_metaaudit = null;
    545     /** A menu item allowing a user to unmap a special directory, if and only if a special directory is selected. */
    546     private JMenuItem unmap = null;
    547     /** Constructor. */
    548     public GPopupMenu(DragTree tree, MouseEvent event) {
    549         super();
    550         this.tree = tree;
    551         TreePath path = tree.getClosestPathForLocation(event.getX(), event.getY());
    552         if(path != null) {
    553         node = (FileNode)path.getLastPathComponent();
    554         // Set Options based on selection and tree
    555         if(tree.getSelectionCount() != 0 && tree == collection_tree) {
    556             String[] args = new String[1];
    557             args[0] = collection_tree.getSelectionDetails();
    558             show_metaaudit = new JMenuItem(Dictionary.get("Menu.Metadata_View", args), KeyEvent.VK_V);
    559             show_metaaudit.addActionListener(this);
    560             add(show_metaaudit);
    561         }
    562         if(tree == collection_tree && node != null && node.getFile() != null && node.getFile().isDirectory() && !node.isReadOnly()) {
    563             new_folder = new JMenuItem(Dictionary.get("CollectionPopupMenu.New_Folder"), KeyEvent.VK_N);
    564             new_folder.addActionListener(this);
    565             add(new_folder);
    566             add(new JSeparator());
    567         }
    568         if(tree == collection_tree && tree.getSelectionCount() != 0 && node != null && !node.isReadOnly()) {
    569             delete = new JMenuItem(Dictionary.get("CollectionPopupMenu.Delete"), KeyEvent.VK_D);
    570             delete.addActionListener(this);
    571             add(delete);
    572         }
    573         if(tree == workspace_tree && node != null && !node.isLeaf()) {
    574             String node_name = node.toString();
    575             FileNode root = (FileNode) tree.getModel().getRoot();
    576             if(!node_name.equals(Dictionary.get("Tree.World")) && !node_name.equals(Dictionary.get("Tree.Root")) && !node_name.equals(Dictionary.get("Tree.Public")) && !node_name.equals(Dictionary.get("Tree.Private"))) {
    577             // You can unmap 1st level nodes.
    578             if(root.getIndex(node) != -1) {
    579                 unmap = new JMenuItem(Dictionary.get("MappingPrompt.Unmap"), KeyEvent.VK_U);
    580                 unmap.addActionListener(this);
    581                 add(unmap);
     526    }
     527
     528        /** When a user right-clicks within the trees on the collection pane view they are presented with a small popup menu of context based options. This class provides such functionality.
     529         */
     530        private class GPopupMenu
     531            extends JPopupMenu
     532            implements ActionListener {
     533
     534            /** The tree over which the right click action occured. */
     535            private DragTree tree = null;
     536            /** The file record over which the right click action occured, if any. */
     537            private FileNode node = null;
     538            private JMenuItem collapse_expand_folder_menuitem;
     539            /** A menu item enabled if a delete action is appropriate in the menus current context. */
     540            private JMenuItem delete = null;
     541            /** A menu item enabled if a special directory mapping is appropriate in the menus current context. */
     542            private JMenuItem map = null;
     543            /** A menu item enabled if a new folder action is appropriate in the menus current context. */
     544            private JMenuItem new_folder = null;
     545            /** A menu item enabled if a show meta-audit dialog action is appropriate in the menus current context. */
     546            private JMenuItem show_metaaudit = null;
     547            /** A menu item allowing a user to unmap a special directory, if and only if a special directory is selected. */
     548            private JMenuItem unmap = null;
     549            private TreePath path = null;
     550            /** Constructor. */
     551            public GPopupMenu(DragTree tree, MouseEvent event) {
     552                super();
     553                this.tree = tree;
     554                this.path = tree.getClosestPathForLocation(event.getX(), event.getY());
     555                if(path != null) {
     556                node = (FileNode)path.getLastPathComponent();
     557                    // Any folder node gets a menu item allowing you to collapse or expand it depending on its current status
     558                    if(!node.isLeaf()) {
     559                        // Collapse
     560                        if(tree.isExpanded(path)) {
     561                            collapse_expand_folder_menuitem = new JMenuItem(Dictionary.get("Menu.Collapse"), KeyEvent.VK_C);
     562                        }
     563                        // Expand
     564                        else {
     565                            collapse_expand_folder_menuitem = new JMenuItem(Dictionary.get("Menu.Expand"), KeyEvent.VK_O);
     566                        }
     567                        collapse_expand_folder_menuitem.addActionListener(this);
     568                        add(collapse_expand_folder_menuitem);
     569                    }
     570                    // Set Options based on selection and tree
     571                    if(tree.getSelectionCount() != 0 && tree == collection_tree) {
     572                        String[] args = new String[1];
     573                        args[0] = collection_tree.getSelectionDetails();
     574                        show_metaaudit = new JMenuItem(Dictionary.get("Menu.Metadata_View", args), KeyEvent.VK_V);
     575                        show_metaaudit.addActionListener(this);
     576                        add(show_metaaudit);
     577                    }
     578                    if(tree == collection_tree && node != null && node.getFile() != null && node.getFile().isDirectory() && !node.isReadOnly()) {
     579                        new_folder = new JMenuItem(Dictionary.get("CollectionPopupMenu.New_Folder"), KeyEvent.VK_N);
     580                        new_folder.addActionListener(this);
     581                        add(new_folder);
     582                        add(new JSeparator());
     583                    }
     584                    if(tree == collection_tree && tree.getSelectionCount() != 0 && node != null && !node.isReadOnly()) {
     585                        delete = new JMenuItem(Dictionary.get("CollectionPopupMenu.Delete"), KeyEvent.VK_D);
     586                        delete.addActionListener(this);
     587                        add(delete);
     588                    }
     589                    if(tree == workspace_tree && node != null && !node.isLeaf()) {
     590                        String node_name = node.toString();
     591                        FileNode root = (FileNode) tree.getModel().getRoot();
     592                        if(!node_name.equals(Dictionary.get("Tree.World")) && !node_name.equals(Dictionary.get("Tree.Root")) && !node_name.equals(Dictionary.get("Tree.Public")) && !node_name.equals(Dictionary.get("Tree.Private"))) {
     593                            // You can unmap 1st level nodes.
     594                            if(root.getIndex(node) != -1) {
     595                                unmap = new JMenuItem(Dictionary.get("MappingPrompt.Unmap"), KeyEvent.VK_U);
     596                                unmap.addActionListener(this);
     597                                add(unmap);
     598                            }
     599                            // Or map any other level directories.
     600                            else {
     601                                map = new JMenuItem(Dictionary.get("MappingPrompt.Map"), KeyEvent.VK_M);
     602                                map.addActionListener(this);
     603                                add(map);
     604                            }
     605                        }
     606                    }
     607                    show(tree, event.getX(), event.getY());
     608                }
    582609            }
    583             // Or map any other level directories.
    584             else {
    585                 map = new JMenuItem(Dictionary.get("MappingPrompt.Map"), KeyEvent.VK_M);
    586                 map.addActionListener(this);
    587                 add(map);
     610
     611            /** Called whenever one of the menu items is actioned apon, this method then causes the appropriate effect. */
     612            public void actionPerformed(ActionEvent event) {
     613                Object source = event.getSource();
     614                if(source == delete) {
     615                    // Retrieve the selection. Of course this gets a bit tricky as the user may have right clicked over a node not in the current selection, in which case we remove only that node.
     616                    TreePath[] selection_paths = tree.getSelectionPaths();
     617                    if(selection_paths != null) {
     618                        FileNode[] source_nodes = new FileNode[selection_paths.length];
     619                        boolean found = false;
     620                        for(int i = 0; i < selection_paths.length; i++) {
     621                            source_nodes[i] = (FileNode) selection_paths[i].getLastPathComponent();
     622                            if(node != null) {
     623                                found = found || source_nodes[i].equals(node);
     624                            }
     625                        }
     626                        if(node != null && !found) {
     627                            source_nodes = null;
     628                            source_nodes = new FileNode[1];
     629                            source_nodes[0] = node;
     630                        }
     631                        // Fire a delete action
     632                        Gatherer.f_man.action(tree, source_nodes, bin_button, null);
     633                        source_nodes = null;
     634                    }
     635                    selection_paths = null;
     636                }
     637                else if(source == map && node != null) {
     638                    MappingPrompt mp = new MappingPrompt(node.getFile());
     639                    mp.destroy();
     640                    mp = null;
     641                }
     642                else if(source == new_folder && node != null) {
     643                    Gatherer.f_man.newFolder(tree, node);
     644                }
     645                else if(source == show_metaaudit) {
     646                    Gatherer.g_man.showMetaAuditBox();
     647                }
     648                else if(source == unmap && node != null) {
     649                    Gatherer.c_man.removeDirectoryMapping(node);
     650                }
     651                else if(source == collapse_expand_folder_menuitem && path != null && node != null && !node.isLeaf()) {
     652                    // Collapse
     653                    if(tree.isExpanded(path)) {
     654                        tree.collapsePath(path);
     655                    }
     656                    // Expand
     657                    else {
     658                        tree.expandPath(path);
     659                    }
     660                }
    588661            }
    589             }
    590         }
    591         show(tree, event.getX(), event.getY());
    592         }
    593     }
    594     /** Called whenever one of the menu items is actioned apon, this method then causes the appropriate effect. */
    595     public void actionPerformed(ActionEvent event) {
    596         if(event.getSource() == delete) {
    597         // Retrieve the selection. Of course this gets a bit tricky as the user may have right clicked over a node not in the current selection, in which case we remove only that node.
    598         TreePath[] selection_paths = tree.getSelectionPaths();
    599         if(selection_paths != null) {
    600             FileNode[] source_nodes = new FileNode[selection_paths.length];
    601             boolean found = false;
    602             for(int i = 0; i < selection_paths.length; i++) {
    603             source_nodes[i] = (FileNode) selection_paths[i].getLastPathComponent();
    604             if(node != null) {
    605                 found = found || source_nodes[i].equals(node);
    606             }
    607             }
    608             if(node != null && !found) {
    609             source_nodes = null;
    610             source_nodes = new FileNode[1];
    611             source_nodes[0] = node;
    612             }
    613             // Fire a delete action
    614             Gatherer.f_man.action(tree, source_nodes, bin_button, null);
    615             source_nodes = null;
    616         }
    617         selection_paths = null;
    618         }
    619         else if(event.getSource() == map && node != null) {
    620         MappingPrompt mp = new MappingPrompt(node.getFile());
    621         mp.destroy();
    622         mp = null;
    623         }
    624         else if(event.getSource() == new_folder && node != null) {
    625         Gatherer.f_man.newFolder(tree, node);
    626         }
    627         else if(event.getSource() == show_metaaudit) {
    628         Gatherer.g_man.showMetaAuditBox();
    629         }
    630         else if(event.getSource() == unmap && node != null) {
    631         Gatherer.c_man.removeDirectoryMapping(node);
    632         }
    633     }
    634     }
    635 
    636     /** This class listens for certain key presses, such as [Enter] or [Delete], and responds appropriately. */
    637     private class KeyListenerImpl
     662        }
     663
     664    /** This class listens for certain key presses, such as [Enter] or [Delete], and responds appropriately. */
     665    private class KeyListenerImpl
    638666    extends KeyAdapter {
    639667    /** Called whenever a key that was pressed is released, it is this action that will cause the desired effects (this allows for the key event itself to be processed prior to this listener dealing with it). */
    640668    public void keyReleased(KeyEvent event) {
    641669                ///ystem.err.println("Key Release detected. " + event.getKeyCode());
    642         if(event.getKeyCode() == KeyEvent.VK_DELETE) {
     670        if(event.getKeyCode() == KeyEvent.VK_DELETE) {
    643671        // Get the selected files from the tree and removal them using the default dnd removal method.
    644672        // Find the active tree (you've made selections in).
     
    649677        TreePath paths[] = tree.getSelectionPaths();
    650678        if(paths != null) {
    651             FileNode[] source_nodes = new FileNode[paths.length];
    652             for(int i = 0; i < source_nodes.length; i++) {
     679            FileNode[] source_nodes = new FileNode[paths.length];
     680            for(int i = 0; i < source_nodes.length; i++) {
    653681            source_nodes[i] = (FileNode) paths[i].getLastPathComponent();
    654             }
    655             Gatherer.f_man.action(tree, source_nodes, bin_button, null);
    656             source_nodes = null;
    657         }
    658         }
    659         else if(event.getKeyCode() == KeyEvent.VK_ENTER) {
     682            }
     683            Gatherer.f_man.action(tree, source_nodes, bin_button, null);
     684            source_nodes = null;
     685        }
     686        }
     687        else if(event.getKeyCode() == KeyEvent.VK_ENTER) {
    660688        // Get the first selected file.
    661689        DragTree tree = (DragTree)event.getSource();
    662690        TreePath path = tree.getSelectionPath();
    663691        if(path != null) {
    664             File file = ((FileNode)path.getLastPathComponent()).getFile();
    665             if(file != null && file.isFile()) {
     692            File file = ((FileNode)path.getLastPathComponent()).getFile();
     693            if(file != null && file.isFile()) {
    666694            Gatherer.self.spawnApplication(file);
    667             }
    668             else {
    669             if(!tree.isExpanded(path)) {
    670                 tree.expandPath(path);
    671695            }
    672696            else {
    673                 tree.collapsePath(path);
     697            if(!tree.isExpanded(path)) {
     698                tree.expandPath(path);
    674699            }
    675             }
    676         }
    677         }
    678     }
    679     }
    680 
    681     /** This provides a small prompt for gathering addition details about a special directory mapping such as its symbolic name. */
    682     private class MappingPrompt
     700            else {
     701                tree.collapsePath(path);
     702            }
     703            }
     704        }
     705        }
     706    }
     707    }
     708
     709    /** This provides a small prompt for gathering addition details about a special directory mapping such as its symbolic name. */
     710    private class MappingPrompt
    683711    extends JDialog
    684712    implements ActionListener, KeyListener {
     
    688716    private JTextField name_field = null;
    689717    public MappingPrompt(File file) {
    690         super(Gatherer.g_man);
    691         setModal(true);
    692         setSize(DIALOG_SIZE);
    693         Dictionary.setText(this, "MappingPrompt.Title");
    694 
    695         // Creation
    696         JPanel content_pane = (JPanel) getContentPane();
    697         JPanel center_pane = new JPanel();
    698         JPanel file_pane = new JPanel();
    699         JLabel file_label = new JLabel();
    700         file_label.setPreferredSize(LABEL_SIZE);
    701         Dictionary.setText(file_label, "MappingPrompt.File");
    702         JLabel file_field = new JLabel(file.getAbsolutePath());
    703         JPanel name_pane = new JPanel();
    704         JLabel name_label = new JLabel();
    705         name_label.setPreferredSize(LABEL_SIZE);
    706         Dictionary.setText(name_label, "MappingPrompt.Name");
    707         name_field = new JTextField(file.getName());
    708         JPanel button_pane = new JPanel();
    709         ok_button = new JButton();
    710         ok_button.setEnabled(name_field.getText().length() > 0);
    711         Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
    712         cancel_button = new JButton();
    713         Dictionary.setBoth(cancel_button, "General.Cancel", "General.Cancel_Tooltip");
    714 
    715         // Connection
    716         cancel_button.addActionListener(this);
    717         ok_button.addActionListener(this);
    718         name_field.addKeyListener(this);
    719         // Layout
    720         file_pane.setLayout(new BorderLayout());
    721         file_pane.add(file_label, BorderLayout.WEST);
    722         file_pane.add(file_field, BorderLayout.CENTER);
    723 
    724         name_pane.setLayout(new BorderLayout());
    725         name_pane.add(name_label, BorderLayout.WEST);
    726         name_pane.add(name_field, BorderLayout.CENTER);
    727 
    728         center_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    729         center_pane.setLayout(new GridLayout(2,1,5,5));
    730         center_pane.add(file_pane);
    731         center_pane.add(name_pane);
    732 
    733         button_pane.setLayout(new GridLayout(1,2,5,5));
    734         button_pane.add(ok_button);
    735         button_pane.add(cancel_button);
    736 
    737         content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    738         content_pane.setLayout(new BorderLayout());
    739         content_pane.add(center_pane, BorderLayout.CENTER);
    740         content_pane.add(button_pane, BorderLayout.SOUTH);
    741         // Display
    742         Dimension screen_size = Gatherer.config.screen_size;
    743         setLocation((screen_size.width - DIALOG_SIZE.width) / 2, (screen_size.height - DIALOG_SIZE.height) / 2);
    744         show();
    745         // If not cancelled create mapping.
    746         if(!cancelled) {
     718        super(Gatherer.g_man);
     719        setModal(true);
     720        setSize(DIALOG_SIZE);
     721        Dictionary.setText(this, "MappingPrompt.Title");
     722
     723        // Creation
     724        JPanel content_pane = (JPanel) getContentPane();
     725        JPanel center_pane = new JPanel();
     726        JPanel file_pane = new JPanel();
     727        JLabel file_label = new JLabel();
     728        file_label.setPreferredSize(LABEL_SIZE);
     729        Dictionary.setText(file_label, "MappingPrompt.File");
     730        JLabel file_field = new JLabel(file.getAbsolutePath());
     731        JPanel name_pane = new JPanel();
     732        JLabel name_label = new JLabel();
     733        name_label.setPreferredSize(LABEL_SIZE);
     734        Dictionary.setText(name_label, "MappingPrompt.Name");
     735        name_field = new JTextField(file.getName());
     736        JPanel button_pane = new JPanel();
     737        ok_button = new JButton();
     738        ok_button.setEnabled(name_field.getText().length() > 0);
     739        Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
     740        cancel_button = new JButton();
     741        Dictionary.setBoth(cancel_button, "General.Cancel", "General.Cancel_Tooltip");
     742
     743        // Connection
     744        cancel_button.addActionListener(this);
     745        ok_button.addActionListener(this);
     746        name_field.addKeyListener(this);
     747        // Layout
     748        file_pane.setLayout(new BorderLayout());
     749        file_pane.add(file_label, BorderLayout.WEST);
     750        file_pane.add(file_field, BorderLayout.CENTER);
     751
     752        name_pane.setLayout(new BorderLayout());
     753        name_pane.add(name_label, BorderLayout.WEST);
     754        name_pane.add(name_field, BorderLayout.CENTER);
     755
     756        center_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     757        center_pane.setLayout(new GridLayout(2,1,5,5));
     758        center_pane.add(file_pane);
     759        center_pane.add(name_pane);
     760
     761        button_pane.setLayout(new GridLayout(1,2,5,5));
     762        button_pane.add(ok_button);
     763        button_pane.add(cancel_button);
     764
     765        content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     766        content_pane.setLayout(new BorderLayout());
     767        content_pane.add(center_pane, BorderLayout.CENTER);
     768        content_pane.add(button_pane, BorderLayout.SOUTH);
     769        // Display
     770        Dimension screen_size = Gatherer.config.screen_size;
     771        setLocation((screen_size.width - DIALOG_SIZE.width) / 2, (screen_size.height - DIALOG_SIZE.height) / 2);
     772        show();
     773        // If not cancelled create mapping.
     774        if(!cancelled) {
    747775        Gatherer.c_man.addDirectoryMapping(name_field.getText(), file);
    748         }
     776        }
    749777    }
    750778    public void actionPerformed(ActionEvent event) {
    751         if(event.getSource() == cancel_button) {
     779        if(event.getSource() == cancel_button) {
    752780        cancelled = true;
    753         }
    754         dispose();
     781        }
     782        dispose();
    755783    }
    756784    public void destroy() {
    757         cancel_button = null;
    758         ok_button = null;
    759         name_field = null;
     785        cancel_button = null;
     786        ok_button = null;
     787        name_field = null;
    760788    }
    761789    public void keyPressed(KeyEvent event) {
    762790    }
    763791    public void keyReleased(KeyEvent event) {
    764         ok_button.setEnabled(name_field.getText().length() > 0);
     792        ok_button.setEnabled(name_field.getText().length() > 0);
    765793
    766794    }
    767795    public void keyTyped(KeyEvent event) {
    768796    }
    769     }
    770     /** This class listens for mouse clicks and responds right mouse button clicks (popup menu). */
    771     private class MouseListenerImpl
     797    }
     798    /** This class listens for mouse clicks and responds right mouse button clicks (popup menu). */
     799    private class MouseListenerImpl
    772800    extends MouseAdapter {
    773801    /** Any subclass of MouseAdapter can override this method to respond to mouse click events. In this case we want to open a pop-up menu if we detect a right mouse click over one of our registered components, and start an external application if someone double clicks on a certain file record. */
    774802    public void mouseClicked(MouseEvent event) {
    775         if(SwingUtilities.isRightMouseButton(event)) {
     803        if(SwingUtilities.isRightMouseButton(event)) {
    776804        new GPopupMenu((DragTree)event.getSource(), event);
    777         }
    778     }
    779     }
     805        }
     806    }
     807    }
    780808}
  • trunk/gli/src/org/greenstone/gatherer/gui/Filter.java

    r5772 r6051  
    7474    static final private Dimension SIZE = new Dimension(100,25);
    7575    /** Preprogrammed default filters. */
    76     static final private String DEFAULTS[] = {"^.*\\.html?$", "^.*\\.xml$", "^.*\\.txt$", "(^.*\\.jpe?g$)|(^.*\\.png$)|(^.\\.gif$)|(^.\\.bmp$)|(^.\\.tif$)"};
     76    static final private String DEFAULTS[] = {"^.*\\.html?$", "^.*\\.xml$", "^.*\\.txt$", "(^.*\\.jpe?g$)|(^.*\\.png$)|(^.*\\.gif$)|(^.*\\.bmp$)|(^.*\\.tif$)"};
    7777
    7878    /** Constructor.
     
    129129    }
    130130
    131     /** Used to restore the filter state to enabled, the normal state during collection editing. 
     131    /** Used to restore the filter state to enabled, the normal state during collection editing.
    132132     * @param state The new state for the filter. <i>true</i> for enabled, <i>false</i> otherwise.
    133133     */
     
    282282    }
    283283    /** An object that holds a filter entry. This is string used for the filter pattern and, if not custom built, its name. */
    284     private class Entry 
     284    private class Entry
    285285    implements Comparable {
    286286    /** The compiled pattern created from a regular expression. */
  • trunk/gli/src/org/greenstone/gatherer/gui/GUIManager.java

    r6040 r6051  
    202202    }
    203203    else if(esrc == menu_bar.file_options) {
     204         // Just incase the user has edited the GeneralSettings of a collection without losing focus afterwards. Well I'm forever losing foc... ooh shiney.
     205         config_pane.loseFocus();
     206         // And spawn a new preferences.
    204207        new Preferences();
    205208    }
     
    459462
    460463        preview_pane = new PreviewPane();
    461         preview_pane.display(); 
    462         if(Gatherer.config.get("workflow.preview", true)) {         
     464        preview_pane.display();
     465        if(Gatherer.config.get("workflow.preview", true)) {
    463466        tab_pane.addTab("GUI.Preview", Utility.getImage("final.gif"), preview_pane);
    464467        tab_pane.setEnabledAt(tab_pane.indexOfComponent(preview_pane), false);
  • trunk/gli/src/org/greenstone/gatherer/gui/MetaEditPane.java

    r6027 r6051  
    234234      this.element = element;
    235235      // Transform the raw text to be GREENSTONE and DOM compatible - as that will be its next destination immediately after being added to the value model
    236       this.value = Codec.transform(value, Codec.ENCODE_PATH); 
     236      this.value = Codec.transform(value, Codec.ENCODE_PATH);
    237237      this.value = Codec.transform(this.value, Codec.REMOVE_SQUARE_BRACKET);
    238238      this.value = Codec.transform(this.value, Codec.TEXT_TO_DOM);
     
    335335    if(ready) {
    336336        TreeModel collection_model = Gatherer.c_man.getRecordSet();
    337         String[] args = new String[1];
    338         args[0] = Gatherer.c_man.getCollection().getName();
    339         Dictionary.registerText(collection_label, "Collection.Collection", args);
     337        //String[] args = new String[1];
     338        //args[0] = Gatherer.c_man.getCollection().getName();
     339        Dictionary.registerText(collection_label, "Collection.Collection");
    340340        // Update label coloring.
    341341        collection_label.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
     
    389389    ///atherer.println("\tCreating collection_label");
    390390    collection_label = new JLabel();
    391     Dictionary.registerText(collection_label, "Collection.Collection");
     391    Dictionary.registerText(collection_label, "Collection.No_Collection");
    392392    collection_label.setOpaque(true);
    393393
     
    972972
    973973
    974     /** Provides a popup menu to display when a right mouse button click is detected over the collection tree. */
    975     private class RightButtonMenu
    976     extends JPopupMenu
    977     implements ActionListener {
    978     /** Constructor.
    979      * @param event The <strong>MouseEvent</strong> that triggered the creation of this menu. Used to determine where the menu will be located.
    980      */
    981     private RightButtonMenu(MouseEvent event) {
    982         super();
    983         // Creation
    984         String[] args = new String[1];
    985         args[0] = collection_tree.getSelectionDetails();
    986         JMenuItem show_metaaudit = new JMenuItem(Dictionary.get("Menu.Metadata_View", args), KeyEvent.VK_V);
    987         show_metaaudit.addActionListener(this);
    988         add(show_metaaudit);
    989         // Display
    990         show(collection_tree, event.getX(), event.getY());
    991         show_metaaudit = null;
    992     }
    993 
    994     /** Called whenever a user clicks on the single menu item, view all assigned metadata.
    995      * @param event An <strong>ActionEvent</strong> containing further information about the action.
    996      * @see org.greenstone.gatherer.Gatherer
    997      * @see org.greenstone.gatherer.gui.GUIManager
    998      */
    999     public void actionPerformed(ActionEvent event) {
    1000         Gatherer.g_man.showMetaAuditBox();
    1001     }
    1002     }
     974    /** Provides a popup menu to display when a right mouse button click is detected over the collection tree. */
     975    private class RightButtonMenu
     976        extends JPopupMenu
     977        implements ActionListener {
     978
     979        private FileNode node;
     980        private JMenuItem collapse_expand_folder_menuitem;
     981        private JMenuItem show_metaaudit;
     982        private TreePath path;
     983
     984        /** Constructor.
     985         * @param event The <strong>MouseEvent</strong> that triggered the creation of this menu. Used to determine where the menu will be located.
     986         */
     987        private RightButtonMenu(MouseEvent event) {
     988            super();
     989            this.path = collection_tree.getClosestPathForLocation(event.getX(), event.getY());
     990            this.node = (FileNode)path.getLastPathComponent();
     991           // Creation
     992            // Any folder node gets a menu item allowing you to collapse or expand it depending on its current status
     993            if(!node.isLeaf()) {
     994                // Collapse
     995                if(collection_tree.isExpanded(path)) {
     996                    collapse_expand_folder_menuitem = new JMenuItem(Dictionary.get("Menu.Collapse"), KeyEvent.VK_C);
     997                }
     998                // Expand
     999                else {
     1000                    collapse_expand_folder_menuitem = new JMenuItem(Dictionary.get("Menu.Expand"), KeyEvent.VK_O);
     1001                }
     1002                collapse_expand_folder_menuitem.addActionListener(this);
     1003                add(collapse_expand_folder_menuitem);
     1004            }
     1005            String[] args = new String[1];
     1006            args[0] = collection_tree.getSelectionDetails();
     1007            show_metaaudit = new JMenuItem(Dictionary.get("Menu.Metadata_View", args), KeyEvent.VK_V);
     1008            show_metaaudit.addActionListener(this);
     1009            add(show_metaaudit);
     1010            // Display
     1011            show(collection_tree, event.getX(), event.getY());
     1012            show_metaaudit = null;
     1013        }
     1014
     1015        /** Called whenever a user clicks on the single menu item, view all assigned metadata.
     1016         * @param event An <strong>ActionEvent</strong> containing further information about the action.
     1017         * @see org.greenstone.gatherer.Gatherer
     1018         * @see org.greenstone.gatherer.gui.GUIManager
     1019         */
     1020        public void actionPerformed(ActionEvent event) {
     1021            Object source = event.getSource();
     1022            if(source == show_metaaudit) {
     1023                Gatherer.g_man.showMetaAuditBox();
     1024            }
     1025            else if(source == collapse_expand_folder_menuitem && path != null && node != null && !node.isLeaf()) {
     1026                // Collapse
     1027                if(collection_tree.isExpanded(path)) {
     1028                    collection_tree.collapsePath(path);
     1029                }
     1030                // Expand
     1031                else {
     1032                    collection_tree.expandPath(path);
     1033                }
     1034            }
     1035        }
     1036    }
    10031037
    10041038
  • trunk/gli/src/org/greenstone/gatherer/gui/NewCollectionDetailsPrompt.java

    r6041 r6051  
     1/**
     2 *#########################################################################
     3 *
     4 * A component of the Gatherer application, part of the Greenstone digital
     5 * library suite from the New Zealand Digital Library Project at the
     6 * University of Waikato, New Zealand.
     7 *
     8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
     9 *
     10 * Copyright (C) 1999 New Zealand Digital Library Project
     11 *
     12 * This program is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU General Public License as published by
     14 * the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * This program is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU General Public License
     23 * along with this program; if not, write to the Free Software
     24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     25 *########################################################################
     26 */
    127package org.greenstone.gatherer.gui;
    228
     
    1036import org.greenstone.gatherer.Dictionary;
    1137import org.greenstone.gatherer.Gatherer;
    12 import org.greenstone.gatherer.collection.CollectionConfiguration;
     38import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
    1339import org.greenstone.gatherer.util.Utility;
    1440import org.greenstone.gatherer.gui.SimpleMenuBar;
     
    6086        File metadata_directory = new File(possible_collections[i], Utility.META_DIR);
    6187        if(collect_cfg_file.exists()) {
    62         CollectionConfiguration collect_cfg = new CollectionConfiguration(collect_cfg_file);
     88        BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(collect_cfg_file);
    6389        String collection_name = collect_cfg.getName();
    6490        // Even if there is no metadata directory we add it if its one of the 'big five + 1' that we know how to handle.
     
    74100        // Else not a collection at all. Someones pulling a fast one.
    75101    }
    76    
     102
    77103    // Sort the result.
    78104    Collections.sort(base_collection_model);
     
    135161    cancel_button.setMnemonic(KeyEvent.VK_C);
    136162    Dictionary.setBoth(cancel_button, "General.Cancel", "General.Cancel_Tooltip");
    137    
     163
    138164    //ColorListener email_color_listener = new ColorListener(address, host); No more email
    139165
     
    203229    center_pane.setLayout(new BorderLayout());
    204230    center_pane.add(description_pane, BorderLayout.CENTER);
    205          
     231
    206232    bottom_pane.setLayout(new BorderLayout());
    207233    bottom_pane.add(base_collection_pane, BorderLayout.CENTER);
     
    245271     * @return the filename as a String
    246272     */
    247     public String getName() {
    248     // Retrieve the first 8 non-whitespace characters of title_final.
    249     StringBuffer name_buffer = new StringBuffer("");
    250     int i = 0;
    251     while(i < title_final.length() && name_buffer.length() < 8) {
    252         char c = title_final.charAt(i);
    253         if(!Character.isWhitespace(c)) {
    254         name_buffer.append(Character.toLowerCase(c));
    255         }
    256         i++;
    257     }
    258     // We need to ensure the filename is unique
    259     int counter = 0;
    260     while(filenameClashes(name_buffer.toString())) {
    261         counter++;
    262         String suffix = String.valueOf(counter);
    263         name_buffer.replace(name_buffer.length() - suffix.length(), name_buffer.length(), suffix);
    264     }
    265     // All done
    266     return name_buffer.toString();
    267     }
     273    public String getName() {
     274        // Retrieve the first 8 non-whitespace characters of title_final.
     275        StringBuffer name_buffer = new StringBuffer("");
     276        int i = 0;
     277        while(i < title_final.length() && name_buffer.length() < 8) {
     278            char c = title_final.charAt(i);
     279            if(!Character.isWhitespace(c)) {
     280                name_buffer.append(Character.toLowerCase(c));
     281            }
     282            i++;
     283        }
     284        // We need to ensure the filename is unique
     285        int counter = 0;
     286        StringBuffer new_name_buffer = new StringBuffer(name_buffer.toString());
     287        while(filenameClashes(new_name_buffer.toString())) {
     288            new_name_buffer = new StringBuffer(name_buffer.toString());
     289            counter++;
     290            String suffix = String.valueOf(counter);
     291            // If we have to truncate the namestring so as to fit the suffix
     292            if(suffix.length() + new_name_buffer.length() > 8) {
     293                new_name_buffer.replace(new_name_buffer.length() - suffix.length(), new_name_buffer.length(), suffix);
     294            }
     295            // Or just append it if that isn't necessary
     296            else {
     297                new_name_buffer.append(suffix);
     298            }
     299
     300        }
     301        // All done
     302        return new_name_buffer.toString();
     303    }
    268304
    269305    private boolean filenameClashes(String filename) {
     
    283319
    284320
    285     private class BrowseListener 
     321    private class BrowseListener
    286322    implements ActionListener {
    287323    public void actionPerformed(ActionEvent event) {
     
    298334        if(file != null) {
    299335        file = file.getParentFile();
    300         CollectionConfiguration collect_cfg = new CollectionConfiguration(new File(file, Utility.META_DIR));
     336        BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(new File(file, Utility.META_DIR));
    301337        Item item = new Item(file, collect_cfg.getName());
    302338        base_collection.addItem(item);
    303339        base_collection.setSelectedItem(item);
    304         }           
     340        }
    305341    }
    306342    }
     
    336372    }
    337373
    338     private class CreateListener
    339     implements ActionListener {
     374    private class CreateListener
     375        implements ActionListener {
     376
    340377    public void actionPerformed(ActionEvent event) {
    341         // Validate.
    342         title_final = title.getText();
    343         if(title_final.length() == 0) {
    344         JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
    345         title.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
    346         title.setBackground(Gatherer.config.getColor("coloring.error_background", false));
    347         return;
    348         }
    349         // We must ensure that the collection title is unique. This is a pain in the nether regions as we are forced to load the collect.cfg of each other collection in turn looking for a conflicting title
    350         else {
    351 
    352 
    353         }
     378        // Validate.
     379        title_final = title.getText();
     380        if(title_final.length() == 0) {
     381            JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
     382            title.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
     383            title.setBackground(Gatherer.config.getColor("coloring.error_background", false));
     384            return;
     385        }
     386        // We must ensure that the collection title is unique. This is a pain in the nether regions as we are forced to load the collect.cfg of each other collection in turn looking for a conflicting title
     387        else {
     388            File collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path));
     389            File children[] = collection_directory.listFiles();
     390            for(int i = 0; children != null && i < children.length; i++) {
     391                if(children[i].isDirectory()) {
     392                    BasicCollectionConfiguration other_collection = new BasicCollectionConfiguration(new File(children[i], Utility.CONFIG_DIR));
     393                    if(other_collection.getName().equalsIgnoreCase(title_final)) {
     394                        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Clash"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
     395                        title.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
     396                        title.setBackground(Gatherer.config.getColor("coloring.error_background", false));
     397                        return;
     398                    }
     399                    other_collection = null;
     400                }
     401            }
     402        }
     403
    354404        /* Suppress filename
    355405        name_final = file.getText();
     
    382432        host.setForeground(Gatherer.config.getColor("coloring.error_foreground", false));
    383433        host.setBackground(Gatherer.config.getColor("coloring.error_background", false));
    384         return; 
     434        return;
    385435        }
    386436        */
     
    412462    }
    413463
    414     private class Item 
     464    private class Item
    415465    implements Comparable {
    416466    private File file;
     
    435485
    436486    /*
    437     private class RestrictedTextField 
     487    private class RestrictedTextField
    438488    extends JTextField {
    439489    public RestrictedTextField(RestrictedTextDocument document, String value, int cols) {
     
    445495    }
    446496
    447     private class RestrictedTextDocument 
     497    private class RestrictedTextDocument
    448498    extends PlainDocument {
    449499    private char block[];
     
    468518        }
    469519    }
    470     public void insertString(int offs, String str, AttributeSet a) 
     520    public void insertString(int offs, String str, AttributeSet a)
    471521        throws BadLocationException {
    472522        // Remove any blocked characters.
     
    505555        updateFilename();
    506556    }
    507          
     557
    508558    ** Gives notification that a portion of the document has been removed. *
    509559    public void removeUpdate(DocumentEvent e) {
  • trunk/gli/src/org/greenstone/gatherer/gui/OpenCollectionDialog.java

    r5593 r6051  
    4848import org.greenstone.gatherer.Dictionary;
    4949import org.greenstone.gatherer.Gatherer;
    50 import org.greenstone.gatherer.collection.CollectionConfiguration;
     50import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
    5151import org.greenstone.gatherer.collection.CollectionManager;
     52import org.greenstone.gatherer.util.StaticStrings;
    5253import org.greenstone.gatherer.util.Utility;
    5354
    54 public class OpenCollectionDialog 
     55public class OpenCollectionDialog
    5556    extends JFileChooser {
    5657    static final private ImageIcon LOCKED_COLLECTION_ICON = Utility.getImage("lcolicn.gif");
    5758    static final private ImageIcon NORMAL_COLLECTION_ICON = Utility.getImage("ncolicn.gif");
    58     /** The name of the mouse listener that initiates editing on a double click. */ 
     59    /** The name of the mouse listener that initiates editing on a double click. */
    5960    static final private String SINGLE_CLICK_LISTENER = "SingleClickListener";
    6061
     
    8182    }
    8283
    83     public void destroy() { 
     84    public void destroy() {
    8485    }
    8586
     
    104105     */
    105106    static public void disableRename(Component c) {
    106     if (c instanceof JList){             
     107    if (c instanceof JList){
    107108        EventListener[] listeners=c.getListeners(MouseListener.class);
    108109        for(int i=0; listeners != null && i < listeners.length; i++) {
     
    122123        }
    123124    }
    124     } 
     125    }
    125126
    126127
    127128    /* The DescriptionPreview accessory is adapted from the ImagePreview.java (an example used by FileChooserDemo2.java). */
    128     private class DescriptionPreview 
     129    private class DescriptionPreview
    129130    extends JPanel
    130131    implements PropertyChangeListener {
     
    153154        if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {
    154155        file = null;
    155         update = true;           
     156        update = true;
    156157        }
    157158        // If a file became selected, find out which one.
     
    170171            File config_file = new File(file.getParentFile(), Utility.CONFIG_DIR);
    171172            if(config_file.exists()) {
    172             CollectionConfiguration collect_cfg = new CollectionConfiguration(config_file);
     173            BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(config_file);
     174            text.setText(StaticStrings.SPEECH_CHARACTER + collect_cfg.getName() + StaticStrings.SPEECH_CHARACTER + StaticStrings.NEW_LINE_CHAR);
    173175            text.setText(collect_cfg.getDescription());
    174176            text.setCaretPosition(0);
     
    180182
    181183    /** ImageFilter.java is a 1.4 example used by FileChooserDemo2.java. */
    182     private class GathererFilter 
     184    private class GathererFilter
    183185    extends FileFilter {
    184186
     
    196198    private class GathererFileSystemView
    197199    extends FileSystemView {
    198          
     200
    199201    private FileSystemView default_system_view = FileSystemView.getFileSystemView();
    200    
     202
    201203    /** Creates a new folder with a default folder name. */
    202     public File createNewFolder(File containingDir) 
     204    public File createNewFolder(File containingDir)
    203205        throws IOException {
    204206        return default_system_view.createNewFolder(containingDir);
    205     }         
     207    }
    206208
    207209    /** Gets the list of shown (i.e. */
  • trunk/gli/src/org/greenstone/gatherer/gui/Preferences.java

    r5847 r6051  
    1313import org.greenstone.gatherer.checklist.CheckList;
    1414import org.greenstone.gatherer.checklist.Entry;
     15import org.greenstone.gatherer.gui.EmailField;
    1516import org.greenstone.gatherer.gui.ModalDialog;
    1617import org.greenstone.gatherer.gui.SimpleMenuBar;
     
    2425
    2526    private CheckList warning_preferences_check_list;
     27    private EmailField email_field;
    2628    private JButton apply_button;
    2729    private JButton cancel_button;
     
    3941    private JCheckBox workflow_preview;
    4042    private JComboBox language_combobox;
     43    private JLabel email_label;
    4144    private JLabel language_label;
    4245    private JLabel library_path_label;
     
    5154    private Preferences self;
    5255
    53     static final Dimension LABEL_SIZE = new Dimension(150, 25);
     56    static final Dimension LABEL_SIZE = new Dimension(175, 25);
    5457    static final Dimension ROW_SIZE = new Dimension(640, 25);
    5558    static final Dimension SIZE = new Dimension(640, 345);
     
    136139    proxy_host_label = new JLabel();
    137140    proxy_host_label.setPreferredSize(LABEL_SIZE);
    138     Dictionary.registerText(proxy_host_label, "Preferences.Connection.Proxy_Host"); 
     141    Dictionary.registerText(proxy_host_label, "Preferences.Connection.Proxy_Host");
    139142    proxy_host_field = new JTextField(Gatherer.config.getString("general.proxy_host", true));
    140143    proxy_host_field.setEnabled(currently_enabled);
     
    227230    classes_folder = null;
    228231
     232    // Users email
     233    JPanel email_pane = new JPanel();
     234    email_label = new JLabel();
     235    email_label.setPreferredSize(LABEL_SIZE);
     236    Dictionary.registerText(email_label, "Preferences.General.Email");
     237    email_field = new EmailField(Gatherer.config.getColor("coloring.error_background", false));
     238    email_field.setText(Gatherer.config.getEmail());
     239    Dictionary.registerTooltip(email_field, "Preferences.General.Email_Tooltip");
     240
    229241    // Extracted metadata
    230242    view_extracted_metadata_checkbox = new JCheckBox();
     
    255267
    256268    // Layout
     269    email_pane.setLayout(new BorderLayout());
     270    email_pane.add(email_label, BorderLayout.WEST);
     271    email_pane.add(email_field, BorderLayout.CENTER);
     272
    257273    language_pane.setLayout(new BorderLayout());
    258274    language_pane.add(language_label, BorderLayout.WEST);
     
    261277    general_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    262278    general_pane.setLayout(new GridLayout(5,1,0,5));
     279    general_pane.add(email_pane);
     280    general_pane.add(language_pane);
    263281    general_pane.add(view_extracted_metadata_checkbox);
    264282    general_pane.add(show_file_size_checkbox);
    265     general_pane.add(language_pane);
    266283
    267284    return general_pane;
     
    399416
    400417    public void dispose() {
    401     // Dispose
    402     super.dispose();
     418        // Where's my code for unregistering all of the components?!?
     419
     420        // Dispose
     421        super.dispose();
    403422    }
    404423
     
    428447
    429448        // General preferences
     449        Gatherer.config.setEmail(email_field.getText());
     450
    430451        Gatherer.config.set("general.show_file_size", Configuration.COLLECTION_SPECIFIC, show_file_size_checkbox.isSelected());
    431452        Gatherer.g_man.refreshTrees(DragTree.TREE_DISPLAY_CHANGED);
     
    472493    }
    473494
    474     private class DictionaryEntry 
     495    private class DictionaryEntry
    475496    implements Comparable {
    476497    private Locale locale;
     
    526547        workflow_design.setSelected(element.getEnabled("design"));
    527548        workflow_export.setSelected(element.getEnabled("export"));
    528         workflow_preview.setSelected(element.getEnabled("preview"));           
     549        workflow_preview.setSelected(element.getEnabled("preview"));
    529550        }
    530551    }
     
    570591    public String toString() {
    571592        if(text == null) {
    572         text = element.getFirstChild().getNodeValue(); 
     593        text = element.getFirstChild().getNodeValue();
    573594        }
    574595        return text;
  • trunk/gli/src/org/greenstone/gatherer/gui/PreviewPane.java

    r5815 r6051  
    4949
    5050public class PreviewPane
    51     extends JPanel {
    52 
    53     private CalHTMLPane view   = null;
    54     private int back_count    = 0;
    55     private int forward_count  = 0;
    56     private JButton back       = null;
    57     private JButton forward    = null;
    58     private JButton home       = null;
    59     private JButton reload = null;
    60     private JLabel status      = null;
    61     private Observer observer = null;
    62     private URL homepage = null;
    63 
    64     static final public String BLANK_PAGE = "<html><head><title>No Page</title></head><body></body></html>";
    65 
    66     public PreviewPane() {
     51    extends JPanel {
     52
     53    private CalHTMLPane view   = null;
     54    private int back_count  = 0;
     55    private int forward_count  = 0;
     56    private JButton back       = null;
     57    private JButton forward = null;
     58    private JButton home       = null;
     59    private JButton reload = null;
     60    private JLabel status     = null;
     61    private Observer observer = null;
     62    private URL homepage = null;
     63
     64    static final public String BLANK_PAGE = "<html><head><title>No Page</title></head><body></body></html>";
     65
     66    public PreviewPane() {
    6767    super();
    6868
     
    9595
    9696    status = new JLabel();
    97     Dictionary.registerText(status, "Browser.Ready"); 
    98     }
    99 
    100     public void collectionChanged(boolean ready) {
     97    Dictionary.registerText(status, "Browser.Ready");
     98    }
     99
     100    public void collectionChanged(boolean ready) {
    101101    // If we were showing a page, but that page is no longer available, then return to a blank page
    102102    if(!ready && homepage != null) {
    103         homepage = null;
    104         view.showHTMLDocument(BLANK_PAGE);
     103        homepage = null;
     104        view.showHTMLDocument(BLANK_PAGE);
    105105    }
    106106    if (ready && Gatherer.config.exec_address != null) {
    107         // reload the home page for the current collection
    108         try {
     107        // reload the home page for the current collection
     108        try {
    109109        // Now load the collection
    110         Collection this_coll = Gatherer.c_man.getCollection();
     110        Collection this_collection = Gatherer.c_man.getCollection();
     111        String search_types = this_collection.cdm.searchtype_manager.getSearchTypes();
    111112        String extra_args = "";
    112         String build_type = this_coll.getCollectionType();
    113         if (build_type.equals("mgpp")) {
    114             // we need some more args on the url
    115             String search_types = this_coll.getSearchTypes();
    116             if (search_types.equals("")) {
    117             extra_args = "&ct=1&qt=0&qto=3";
    118             } else if (search_types.equals("plain")) {
    119             extra_args = "&ct=1&qt=0&qto=1";
    120             } else if (search_types.equals("form")) {
    121             extra_args = "&ct=1&qt=1&qto=2";
    122             } else if (search_types.equals("plain,form")) {
    123             extra_args = "&ct=1&qt=0&qto=3";
    124             } else if (search_types.equals("form,plain")) {
    125             extra_args = "&ct=1&qt=1&qto=3";
    126             }
    127         }
    128        
    129         homepage = new URL(Gatherer.config.exec_address.toString() + "?a=p&p=about&c=" + this_coll.getName()+extra_args);
     113        if (search_types.length() > 0) {
     114            // we need some more args on the url
     115            if (search_types.equals("")) {
     116                extra_args = "&ct=1&qt=0&qto=3";
     117            } else if (search_types.equals("plain")) {
     118                extra_args = "&ct=1&qt=0&qto=1";
     119            } else if (search_types.equals("form")) {
     120                extra_args = "&ct=1&qt=1&qto=2";
     121            } else if (search_types.equals("plain,form")) {
     122                extra_args = "&ct=1&qt=0&qto=3";
     123            } else if (search_types.equals("form,plain")) {
     124                extra_args = "&ct=1&qt=1&qto=3";
     125            }
     126        }
     127
     128        homepage = new URL(Gatherer.config.exec_address.toString() + "?a=p&p=about&c=" + this_collection.getName() + extra_args);
    130129        String[] args = new String[1];
    131130        args[0] = homepage.toString();
    132131        Dictionary.registerText(status, "Browser.Loading", args);
    133132        view.showHTMLDocument(homepage, null, true);
    134         }
    135         catch (MalformedURLException exception) {
     133        }
     134        catch (MalformedURLException exception) {
    136135        Gatherer.printStackTrace(exception);
    137         }
    138     }
    139     }
    140 
    141     public void display() {
     136        }
     137    }
     138    }
     139
     140    public void display() {
    142141    JPanel control_pane = new JPanel();
    143142    control_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     
    157156    add(a_panel, BorderLayout.CENTER);
    158157    add(status, BorderLayout.SOUTH);
    159     }
    160 
    161     /** This method is called when the user selects the 'Preview' tab from the views bar. Can be used to display a particular page or perform some other relevant tests (ensure internet connection to specified server maybe?)
    162     */
    163     public void gainFocus() {
     158    }
     159
     160    /** This method is called when the user selects the 'Preview' tab from the views bar. Can be used to display a particular page or perform some other relevant tests (ensure internet connection to specified server maybe?)
     161    */
     162    public void gainFocus() {
    164163    if(Gatherer.c_man.ready() && Gatherer.c_man.built()) {
    165         if(homepage == null && Gatherer.config.exec_address != null) {
     164        if(homepage == null && Gatherer.config.exec_address != null) {
    166165        try {
    167             // Now load the collection
    168             homepage = new URL(Gatherer.config.exec_address.toString() + "?a=p&p=about&c=" + Gatherer.c_man.getCollection().getName());
    169             String[] args = new String[1];
    170             args[0] = homepage.toString();
    171             Dictionary.registerText(status, "Browser.Loading", args);
    172             view.showHTMLDocument(homepage);
     166            // Now load the collection
     167            homepage = new URL(Gatherer.config.exec_address.toString() + "?a=p&p=about&c=" + Gatherer.c_man.getCollection().getName());
     168            String[] args = new String[1];
     169            args[0] = homepage.toString();
     170            Dictionary.registerText(status, "Browser.Loading", args);
     171            view.showHTMLDocument(homepage);
    173172        }
    174173        catch (MalformedURLException exception) {
    175             Gatherer.printStackTrace(exception);
    176         }
    177         }
     174            Gatherer.printStackTrace(exception);
     175        }
     176        }
    178177    }
    179178    validate();
    180     }
    181 
    182     public void configServer(String command) {
     179    }
     180
     181    public void configServer(String command) {
    183182    try {
    184         String url = Gatherer.config.exec_address.toString() + command;
    185         ///ystem.err.println("Action: " + url);
    186         view.setLoadSynchronously(true);
    187         view.showHTMLDocument(new URL(url));
    188         view.setLoadSynchronously(false);
    189         ///ystem.err.println("Complete.");
    190         url = null;
     183        String url = Gatherer.config.exec_address.toString() + command;
     184        ///ystem.err.println("Action: " + url);
     185        view.setLoadSynchronously(true);
     186        view.showHTMLDocument(new URL(url));
     187        view.setLoadSynchronously(false);
     188        ///ystem.err.println("Complete.");
     189        url = null;
    191190    }
    192191    catch(Exception error) {
    193         ///ystem.err.println("Bad URL.");
    194     }
    195     }
    196 
    197     public void validate() {
     192        ///ystem.err.println("Bad URL.");
     193    }
     194    }
     195
     196    public void validate() {
    198197    back.setEnabled(back_count > 0);
    199198    home.setEnabled(homepage != null);
    200199    forward.setEnabled(forward_count > 0);
    201200    reload.setEnabled(homepage != null);
    202     }
    203 
    204     private class BackListener
     201    }
     202
     203    private class BackListener
    205204    implements ActionListener {
    206205    public void actionPerformed(ActionEvent event) {
    207         view.goBack();
    208         back_count--;
    209         forward_count++;
    210         validate();
    211     }
    212     }
    213 
    214     private class ForwardListener
     206        view.goBack();
     207        back_count--;
     208        forward_count++;
     209        validate();
     210    }
     211    }
     212
     213    private class ForwardListener
    215214    implements ActionListener {
    216215    public void actionPerformed(ActionEvent event) {
    217         view.goForward();
    218         back_count++;
    219         forward_count--;
    220         validate();
    221     }
    222     }
    223 
    224     private class HomeListener
     216        view.goForward();
     217        back_count++;
     218        forward_count--;
     219        validate();
     220    }
     221    }
     222
     223    private class HomeListener
    225224    implements ActionListener {
    226225    public void actionPerformed(ActionEvent event) {
    227         view.showHTMLDocument(homepage);
    228         back_count++;
    229         forward_count = 0;
    230         validate();
    231     }
    232     }
    233 
    234     private class ReloadListener
     226        view.showHTMLDocument(homepage);
     227        back_count++;
     228        forward_count = 0;
     229        validate();
     230    }
     231    }
     232
     233    private class ReloadListener
    235234    implements ActionListener {
    236235    public void actionPerformed(ActionEvent event) {
    237         view.reloadDocument();
    238     }
    239     }
    240 
    241     private class Observer
     236        view.reloadDocument();
     237    }
     238    }
     239
     240    private class Observer
    242241    extends DefaultCalHTMLObserver {
    243242    public int state = CalCons.DOC_LOADED;
    244243    public void linkActivatedUpdate(CalHTMLPane pane, URL url, String target_frame, String j_name) {
    245         back_count++;
    246         forward_count = 0;
    247         validate();
     244        back_count++;
     245        forward_count = 0;
     246        validate();
    248247    }
    249248
    250249    public void linkFocusUpdate(CalHTMLPane pane, URL url) {
    251         String[] args = new String[1];
    252         args[0] = url.toString();
    253         Dictionary.registerText(status, "Browser.Follow", args);
     250        String[] args = new String[1];
     251        args[0] = url.toString();
     252        Dictionary.registerText(status, "Browser.Follow", args);
    254253    }
    255254
    256255    public void statusUpdate(CalHTMLPane pane, int state, URL url, int value, String message) {
    257         this.state = state;
    258         String[] args = new String[1];
    259         args[0] = url.toString();
    260 
    261         switch(state) {
     256        this.state = state;
     257        String[] args = new String[1];
     258        args[0] = url.toString();
     259
     260        switch(state) {
    262261        // The Pane is attempting to connect to the given URL to receive data.
    263         case CalCons.PRE_CONNECT:
     262        case CalCons.PRE_CONNECT:
    264263        ///ystem.err.println("Preconnect: " + state + " - " + message);
    265264        break;
    266265        // The Pane was unable to connect to the given URL or was unable to parse the content. Most likely this will be due to an incorrectly specified URL. The message argument may contain further details of the reason for failure.
    267         case CalCons.PARSE_FAILED:
     266        case CalCons.PARSE_FAILED:
    268267        ///ystem.err.println("Parse Failed: " + state + " - " + message);
    269268        Dictionary.registerText(status, "Browser.CannotConnect", args);
    270269        break;
    271270        // The Pane has established a connection to the given URL and is receiving any content.
    272         case CalCons.CONNECTED:
     271        case CalCons.CONNECTED:
    273272        ///ystem.err.println("Connected: " + state + " - " + message);
    274273        Dictionary.registerText(status, "Browser.Loading", args);
    275274        break;
    276275        // The size of the content at the given URL is known and is contained in the value argument.
    277         case CalCons.DOC_LENGTH:
     276        case CalCons.DOC_LENGTH:
    278277        ///ystem.err.println("Doc Length: " + state + " - " + message);
    279278        break;
    280279        // The title of the document for the given URL is known and is contained in the message argument. Only the title of a document in the Pane's top level frame will be sent to this method. If the document has no name, the message will be null, unless the document is a Frameset document in which case the message "Frameset" will be sent.
    281         case CalCons.TITLE:
     280        case CalCons.TITLE:
    282281        ///ystem.err.println("Title: " + state + " - " + message);
    283282        break;
    284283        // An exception has been thrown during parsing of the data from the URL. This will most likely be an IOException such as a server time-out.
    285         case CalCons.PARSE_FAILED_POST_CONNECT:
     284        case CalCons.PARSE_FAILED_POST_CONNECT:
    286285        ///ystem.err.println("Parse Failed Post Connect: " + state + " - " + message);
    287286        Dictionary.registerText(status, "Browser.TimedOut", args);
    288287        break;
    289288        // The document has been parsed but formatting cannot be completed because the document contains images of unspecified size. The parsing thread is waiting for image updates to give it the information it needs to format and display the document.
    290         case CalCons.WAITING_FOR_IMAGES:
     289        case CalCons.WAITING_FOR_IMAGES:
    291290        ///ystem.err.println("Waiting For Images: " + state + " - " + message + " - " + url.toString());
    292291        break;
    293292        // All text and image data has been received, parsed and the document structure determined.
    294         case CalCons.DOC_LOADED:
     293        case CalCons.DOC_LOADED:
    295294        ///ystem.err.println("Doc Loaded: " + state + " - " + message);
    296295        Dictionary.registerText(status, "Browser.Ready");
    297296        break;
    298         }
    299     }
    300     }
     297        }
     298    }
     299    }
    301300}
  • trunk/gli/src/org/greenstone/gatherer/gui/SimpleOpenCollectionDialog.java

    r5939 r6051  
    3535import org.greenstone.gatherer.Dictionary;
    3636import org.greenstone.gatherer.Gatherer;
    37 import org.greenstone.gatherer.collection.CollectionConfiguration;
     37import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
    3838import org.greenstone.gatherer.gui.ModalDialog;
    3939import org.greenstone.gatherer.util.StaticStrings;
     
    7171
    7272    JPanel center_pane = new JPanel();
    73    
     73
    7474    JPanel collection_list_pane = new JPanel();
    7575    JLabel collection_list_label = new JLabel();
     
    155155    private class AdvancedListener
    156156    implements ActionListener {
    157    
     157
    158158    public void actionPerformed(ActionEvent event) {
    159159        result = BROWSE_OPTION;
     
    164164    private class CancelListener
    165165    implements ActionListener {
    166    
     166
    167167    public void actionPerformed(ActionEvent event) {
    168168        result = CANCEL_OPTION;
    169169        SimpleOpenCollectionDialog.this.dispose();
    170170    }
    171     }   
     171    }
    172172
    173173    private class CollectionListSelectionListener
     
    192192        }
    193193        else {
    194         CollectionConfiguration collection_configuration = (CollectionConfiguration) collection_list.getSelectedValue();
     194        BasicCollectionConfiguration collection_configuration = (BasicCollectionConfiguration) collection_list.getSelectedValue();
    195195        description_textarea.setText(collection_configuration.getDescription());
    196196        description_textarea.setCaretPosition(0);
     
    214214        String collection_foldername = collection_folder.getName();
    215215        if(!collection_folder.isFile() && !collection_foldername.equals(StaticStrings.MODEL_COLLECTION_NAME)) {
    216            CollectionConfiguration collection_configuration = new CollectionConfiguration(new File(collection_folder, Utility.CONFIG_DIR));
     216           BasicCollectionConfiguration collection_configuration = new BasicCollectionConfiguration(new File(collection_folder, Utility.CONFIG_DIR));
    217217           if(!collection_configuration.getName().equals(StaticStrings.ERROR_STR)) {
    218218              data.add(collection_configuration);
     
    247247    private class OpenListener
    248248    implements ActionListener {
    249    
     249
    250250    public void actionPerformed(ActionEvent event) {
    251251        result = OK_OPTION;
    252         CollectionConfiguration collection_configuration = (CollectionConfiguration) collection_list.getSelectedValue();
     252        BasicCollectionConfiguration collection_configuration = (BasicCollectionConfiguration) collection_list.getSelectedValue();
    253253        File collect_cfg_file = collection_configuration.getFile();
    254254        File etc_folder = collect_cfg_file.getParentFile();
     
    261261        SimpleOpenCollectionDialog.this.dispose();
    262262    }
    263     } 
     263    }
    264264}
  • trunk/gli/src/org/greenstone/gatherer/gui/table/GTableModel.java

    r6028 r6051  
    5050 * @version 2.3b
    5151 */
    52 public class GTableModel 
    53     extends AbstractTableModel 
     52public class GTableModel
     53    extends AbstractTableModel
    5454    implements MSMListener {
    5555
     
    7070    // Register this model with the msm manager.
    7171    if (Gatherer.c_man.ready()) {
    72         Gatherer.c_man.getCollection().msm.addMSMListener(this); 
     72        Gatherer.c_man.getCollection().msm.addMSMListener(this);
    7373    }
    7474    }
     
    200200        // Ensure the position is within the current metadata
    201201        if (i >= current_metadata.size()) {
    202         i = current_metadata.size() - 1;
     202            i = current_metadata.size() - 1;
    203203        }
    204204
    205205        // Select the same row as before, except if it would select a different element
    206206        ElementWrapper element = metadatum.getElement();
     207        if(i < 0) {
     208              Gatherer.println("Could not find suitable row to select!");
     209              return;
     210         }
    207211        Metadata newly_selected_metadatum = (Metadata) current_metadata.get(i);
    208212        if (!newly_selected_metadatum.getElement().equals(element)) {
    209         // Try one row previous
    210         i--;
    211         newly_selected_metadatum = (Metadata) current_metadata.get(i);
    212         if (!newly_selected_metadatum.getElement().equals(element)) {
    213             Gatherer.println("Could not find suitable row to select!");
    214             return;
    215         }
     213            // Try one row previous
     214            i--;
     215            if(i < 0) {
     216                  Gatherer.println("Could not find suitable row to select!");
     217                  return;
     218             }
     219
     220            newly_selected_metadatum = (Metadata) current_metadata.get(i);
     221            if (!newly_selected_metadatum.getElement().equals(element)) {
     222                Gatherer.println("Could not find suitable row to select!");
     223                return;
     224            }
    216225        }
    217226
     
    298307    /** Determine if the given metadata is common to all selected file nodes given the context of the current view. */
    299308   public boolean isCommon(Metadata entry) {
    300       return (entry.getCount() == file_nodes.length);
     309      return (entry.getCount() >= file_nodes.length);
    301310   }
    302    
     311
    303312    /** Determine if the given metadata is common to all selected file nodes given the context of the current view. */
    304313    public boolean isCommon(int row) {
     
    352361                showInheritedMetadataWarning();
    353362                }
    354                
     363
    355364                // If the piece of metadata is in the list, increment its count
    356365                int index = current_metadata.indexOf(metadatum);
     
    364373                index = add(current_metadata, metadatum);
    365374                fireTableRowsInserted(index, index);
    366                
     375
    367376                // Remember we have seen this element
    368377                if (known_elements.contains(element) == false) {
  • trunk/gli/src/org/greenstone/gatherer/gui/tree/DragTreeCellRenderer.java

    r5915 r6051  
    4646import org.greenstone.gatherer.util.Utility;
    4747
    48 public class DragTreeCellRenderer 
     48public class DragTreeCellRenderer
    4949    extends DefaultTreeCellRenderer {
    50      
     50
    5151    private boolean in_focus = false;
    5252    private Color selection_background;
    5353    private Color selection_foreground;
    54      
    55     static final private ImageIcon GREY_FOLDER = Utility.getImage("greyfolder.gif", true);
    56     static final private ImageIcon GREEN_FILE = Utility.getImage("greenfile.gif", true);
    57     static final private ImageIcon GREEN_FOLDER = Utility.getImage("greenfolder.gif", true);
     54
     55    //static final private ImageIcon GREY_FOLDER = Utility.getImage("greyfolder.gif", true);
     56    //static final private ImageIcon GREEN_FILE = Utility.getImage("greenfile.gif", true);
     57    //static final private ImageIcon GREEN_FOLDER = Utility.getImage("greenfolder.gif", true);
    5858
    5959    public DragTreeCellRenderer() {
     
    7474    if(value instanceof FileNode) {
    7575        FileNode node = (FileNode) value;
    76        
     76
    7777        String new_value = null;
    7878        if(Gatherer.config.get("general.show_file_size", Configuration.COLLECTION_SPECIFIC) && node.getFile() != null && !node.getAllowsChildren()) {
     
    8585        tree_cell = (JLabel) super.getTreeCellRendererComponent(tree, new_value, sel, expanded, leaf, row, hasFocus);
    8686
     87        /*
    8788        if(node.getFile() == null || node.isFileSystemRoot()) {
    88         ((JLabel)tree_cell).setIcon(GREY_FOLDER);
     89            ((JLabel)tree_cell).setIcon(GREY_FOLDER);
    8990        }
    9091        else if(node.isInCurrentCollection()) {
    91         if(!node.getFile().isFile()) {
     92            if(!node.getFile().isFile()) {
    9293            ((JLabel)tree_cell).setIcon(GREEN_FOLDER);
    93         }
    94         else {
     94            }
     95            else {
    9596            ((JLabel)tree_cell).setIcon(GREEN_FILE);
    96         }
     97            }
    9798        }
     99        */
    98100    }
    99101    else {
     
    102104    return tree_cell;
    103105    }
    104          
     106
    105107    public void loseFocus() {
    106108    setBackgroundSelectionColor(Color.lightGray);
  • trunk/gli/src/org/greenstone/gatherer/msm/ElementWrapper.java

    r6043 r6051  
    5050import org.w3c.dom.*;
    5151
    52 /** This class provides a convience wrapper around a DOM model Element to allow Components such as the MetadataTable to display this information properly. 
     52/** This class provides a convience wrapper around a DOM model Element to allow Components such as the MetadataTable to display this information properly.
    5353 * @author John Thompson
    5454 * @version 2.3
    5555 */
    56 public class ElementWrapper 
     56public class ElementWrapper
    5757    implements Comparable {
    5858    /** The DOM element this wrapper is wrapped around. */
     
    6262    /** Constructor for elements with no namespace necessary.
    6363     * @param element The DOM <strong>Element</strong> this is to be based on.
    64      */ 
     64     */
    6565    public ElementWrapper(Element element) {
    6666    this.element = element;
     
    6969        this.namespace = parent.getAttribute("namespace");
    7070    }
    71    
     71
    7272    }
    7373
     
    9494    return toString().compareTo(object.toString());
    9595    }
    96     /** Decrement the number of occurances of this metadata element. 
     96    /** Decrement the number of occurances of this metadata element.
    9797     * @see org.greenstone.gatherer.msm.MSMUtils
    9898     */
     
    179179    }
    180180
    181     /** Increment the number of occurances of this metadata element. 
     181    /** Increment the number of occurances of this metadata element.
    182182     * @see org.greenstone.gatherer.msm.MSMUtils
    183183     */
     
    185185    MSMUtils.setOccurance(element, 1);
    186186    }
    187    
     187
    188188    public boolean isHierarchy() {
    189189    return element.getAttribute(StaticStrings.HIERARCHY_ATTRIBUTE).equalsIgnoreCase(StaticStrings.TRUE_STR);
     
    227227
    228228    // Return just the element name, unless the element identifier differs
    229     if (element_name_no_namespace.equals(element_identifier)) {
     229    //if (element_name_no_namespace.equals(element_identifier)) {
    230230        return element_name;
    231     }
    232     else {
    233         return element_name + " (" + element_identifier + ")";
    234     }
     231    //}
     232    //else {
     233    //    return element_name + " (" + element_identifier + ")";
     234    //}
    235235    }
    236236}
  • trunk/gli/src/org/greenstone/gatherer/msm/GDMDocument.java

    r6029 r6051  
    4545 */
    4646public class GDMDocument {
    47     /** Record if the document this object is based on is up to date. */
    48     private boolean up_to_date = true;
    49     /** The document this class sources its data from. */
    50     private Document base_document;
    51     static final private String ACCUMULATE = "accumulate";
    52     /** The pattern to match when searching for directory level assignments. */
    53     static final private String DIRECTORY_FILENAME = ".*";
    54     static final private String DESCRIPTION_ELEMENT = "Description";
    55     static final private String FILENAME_ELEMENT = "FileName";
    56     static final private String FILESET_ELEMENT = "FileSet";
    57     static final private String HVALUE_ATTRIBUTE = "hvalue";
    58     static final private String MODE_ATTRIBUTE = "mode";
    59     static final private String OVERWRITE = "overwrite";
    60 
    61     /** Constructor which creates a brand new metadata.xml document. */
    62     public GDMDocument() {
     47    /** Record if the document this object is based on is up to date. */
     48    private boolean up_to_date = true;
     49    /** The document this class sources its data from. */
     50    private Document base_document;
     51    static final private String ACCUMULATE = "accumulate";
     52    /** The pattern to match when searching for directory level assignments. */
     53    static final private String DIRECTORY_FILENAME = ".*";
     54    static final private String DESCRIPTION_ELEMENT = "Description";
     55    static final private String FILENAME_ELEMENT = "FileName";
     56    static final private String FILESET_ELEMENT = "FileSet";
     57    static final private String HVALUE_ATTRIBUTE = "hvalue";
     58    static final private String MODE_ATTRIBUTE = "mode";
     59    static final private String OVERWRITE = "overwrite";
     60    static final private String[] ALL_METADATA_TYPES = {StaticStrings.METADATA_ELEMENT, StaticStrings.EXTRACTED_METADATA_ELEMENT};
     61
     62    /** Constructor which creates a brand new metadata.xml document. */
     63    public GDMDocument() {
    6364    // Create new document. We do this by loading a copy of the template. */
    6465    this.base_document = Utility.parse(Utility.GREENSTONEDIRECTORYMETADATA_TEMPLATE, true);
    65     }
    66 
    67     /** Constructor which parses an existing metadata.xml document. */
    68     public GDMDocument(File file) {
     66    }
     67
     68    /** Constructor which parses an existing metadata.xml document. */
     69    public GDMDocument(File file) {
    6970    try {
    70         this.base_document = Utility.parse(file.getAbsolutePath(), false);
     71        this.base_document = Utility.parse(file.getAbsolutePath(), false);
    7172    }
    7273    catch (Exception error) {
    73         // Poorly formed, or completely invalid metadata.xml file!
    74     }
    75     }
    76 
    77     /** Constructor which wraps around an existing metadata.xml document. */
    78     public GDMDocument(Document base_document) {
     74        // Poorly formed, or completely invalid metadata.xml file!
     75    }
     76    }
     77
     78    /** Constructor which wraps around an existing metadata.xml document. */
     79    public GDMDocument(Document base_document) {
    7980    this.base_document = base_document;
    80     }
    81 
    82     /** Add this metadata to the named file. There is one tricky thing to consider. Whenever a metadata entry is added it is taken to be accumulating except if it is the first added, in which case it overwrites! Actually this gets worse, as we could have been told to append this metadata to a document which already inherits metadata. Thus we need a new argument to determine whether this add was triggered by an append or a replace. */
    83     public void addMetadata(String filename, Metadata metadata, boolean force_accumulate) {
     81    }
     82
     83    /** Add this metadata to the named file. There is one tricky thing to consider. Whenever a metadata entry is added it is taken to be accumulating except if it is the first added, in which case it overwrites! Actually this gets worse, as we could have been told to append this metadata to a document which already inherits metadata. Thus we need a new argument to determine whether this add was triggered by an append or a replace. */
     84    public void addMetadata(String filename, Metadata metadata, boolean force_accumulate) {
    8485    Gatherer.println("Add '" + metadata + "' to " + (filename != null ? filename : "directory."));
    8586    try {
    86         // Retrieve the document element.
    87         Element directorymetadata_element = base_document.getDocumentElement();
    88         // Iterate through the filesets looking for one that matches the given filename.
    89         Element fileset_element = null;
    90         boolean found = false;
    91         NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
    92         for(int i = 0; !found && i < fileset_elements.getLength(); i++) {
     87        // Retrieve the document element.
     88        Element directorymetadata_element = base_document.getDocumentElement();
     89        // Iterate through the filesets looking for one that matches the given filename.
     90        Element fileset_element = null;
     91        boolean found = false;
     92        NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
     93        for(int i = 0; !found && i < fileset_elements.getLength(); i++) {
    9394        fileset_element = (Element) fileset_elements.item(i);
    9495        NodeList filename_elements = fileset_element.getElementsByTagName(FILENAME_ELEMENT);
    9596        for(int j = 0; !found && j < filename_elements.getLength(); j++) {
    96             Element filename_element = (Element) filename_elements.item(j);
    97             String filename_pattern = MSMUtils.getValue(filename_element);
    98             // Have we found a match. If so break out of for loop.
    99             if(filename != null && filename.matches(filename_pattern) && !filename_pattern.equals(DIRECTORY_FILENAME)) {
     97            Element filename_element = (Element) filename_elements.item(j);
     98            String filename_pattern = MSMUtils.getValue(filename_element);
     99            // Have we found a match. If so break out of for loop.
     100            if(filename != null && filename.matches(filename_pattern) && !filename_pattern.equals(DIRECTORY_FILENAME)) {
    100101            ///ystem.err.println("Adding to existing file fileset!");
    101102            found = true;
    102             }
    103             else if(filename == null && filename_pattern.equals(DIRECTORY_FILENAME)) {
     103            }
     104            else if(filename == null && filename_pattern.equals(DIRECTORY_FILENAME)) {
    104105            ///ystem.err.println("Adding to existing folder fileset!");
    105106            ///ystem.err.println("filename_pattern = '" + filename_pattern + "'");
    106107            found = true;
    107             }
    108             // No match. On to the next one.
    109             else {
     108            }
     109            // No match. On to the next one.
     110            else {
    110111            fileset_element = null;
    111             }
    112             filename_pattern = null;
    113             filename_element = null;
    114         }
    115         }
    116         fileset_elements = null;
    117         // If we still haven't found an existing fileset, then its time to create one.
    118         if(fileset_element == null) {
     112            }
     113            filename_pattern = null;
     114            filename_element = null;
     115        }
     116        }
     117        fileset_elements = null;
     118        // If we still haven't found an existing fileset, then its time to create one.
     119        if(fileset_element == null) {
    119120        ///ystem.err.println("Creating a new fileset.");
    120121        fileset_element = base_document.createElement(FILESET_ELEMENT);
     
    126127        // If the filename is null then we add a directory metadata set as directorymetadata_element's first child
    127128        if(filename == null) {
    128             filename_text = base_document.createTextNode(DIRECTORY_FILENAME);
    129             if(directorymetadata_element.hasChildNodes()) {
     129            filename_text = base_document.createTextNode(DIRECTORY_FILENAME);
     130            if(directorymetadata_element.hasChildNodes()) {
    130131            directorymetadata_element.insertBefore(fileset_element, directorymetadata_element.getFirstChild());
    131             }
    132             else {
     132            }
     133            else {
    133134            directorymetadata_element.appendChild(fileset_element);
    134             }
     135            }
    135136        }
    136137        // Otherwise we just append the new fileset to directorymetadata_element's children.
    137138        else {
    138             filename_text = base_document.createTextNode(filename);
    139             directorymetadata_element.appendChild(fileset_element);
     139            filename_text = base_document.createTextNode(filename);
     140            directorymetadata_element.appendChild(fileset_element);
    140141        }
    141142        filename_element.appendChild(filename_text);
     
    143144        description_element = null;
    144145        filename_element = null;
    145         }
    146         // Now, finally, we can add the metadata.
    147         Element metadata_element = base_document.createElement(StaticStrings.METADATA_ELEMENT);
    148         String name = metadata.getElement().getName();
    149         if(name.startsWith(Utility.EXTRACTED_METADATA_NAMESPACE)) {
    150         name = name.substring(Utility.EXTRACTED_METADATA_NAMESPACE.length() + 1);
    151         }
    152         metadata_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
    153 
    154         // To determine if this metadata entry should overwrite or accumulate we check if there are other entries with the same element in this fileset.
    155         boolean will_accumulate = false;
    156         NodeList sibling_description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
    157         for(int k = 0; !will_accumulate && k < sibling_description_elements.getLength(); k++) {
     146        }
     147        // Now, finally, we can add the metadata.
     148        Element metadata_element = null;
     149        String name = metadata.getElement().getName();
     150        // If this is extracted metadata, we use a special element name that won't be recognized by greenstone
     151        if(name.startsWith(Utility.EXTRACTED_METADATA_NAMESPACE)) {
     152              metadata_element = base_document.createElement(ALL_METADATA_TYPES[1]);
     153              name = name.substring(Utility.EXTRACTED_METADATA_NAMESPACE.length() + 1);
     154         }
     155         else {
     156              metadata_element = base_document.createElement(ALL_METADATA_TYPES[0]);
     157         }
     158        metadata_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
     159
     160        // To determine if this metadata entry should overwrite or accumulate we check if there are other entries with the same element in this fileset.
     161        boolean will_accumulate = false;
     162        NodeList sibling_description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
     163        for(int k = 0; !will_accumulate && k < sibling_description_elements.getLength(); k++) {
    158164        Element sibling_description_element = (Element) sibling_description_elements.item(k);
    159         NodeList sibling_metadata_elements = sibling_description_element.getElementsByTagName(StaticStrings.METADATA_ELEMENT);
    160         for(int l = 0; !will_accumulate && l < sibling_metadata_elements.getLength(); l++) {
    161             Element sibling_metadata_element = (Element) sibling_metadata_elements.item(l);
    162             // It appears that its possible that we can be asked to add the same metadata twice (especially after a copy action is cancelled then repeated). So we check if we have been asked to add exactly the same value twice.
    163             if(sibling_metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE))) {
    164                 // Check the values and return if they are the same.
    165                if(metadata.getAbsoluteValue().equals(MSMUtils.getValue(sibling_metadata_element))) {
    166               return;
    167                }
    168                will_accumulate = true;
    169             }
    170             sibling_metadata_element = null;
    171         }
    172         sibling_metadata_elements = null;
     165        // We have to do this for each type of metadata
     166        for(int z = 0; z < ALL_METADATA_TYPES.length; z++) {
     167            NodeList sibling_metadata_elements = sibling_description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
     168            for(int l = 0; !will_accumulate && l < sibling_metadata_elements.getLength(); l++) {
     169                Element sibling_metadata_element = (Element) sibling_metadata_elements.item(l);
     170                // It appears that its possible that we can be asked to add the same metadata twice (especially after a copy action is cancelled then repeated). So we check if we have been asked to add exactly the same value twice.
     171                if(sibling_metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE))) {
     172                    // Check the values and return if they are the same.
     173                   if(metadata.getAbsoluteValue().equals(MSMUtils.getValue(sibling_metadata_element))) {
     174                      return;
     175                   }
     176                   will_accumulate = true;
     177                }
     178                sibling_metadata_element = null;
     179            }
     180            sibling_metadata_elements = null;
     181        }
    173182        sibling_description_element = null;
    174         }
    175         sibling_description_elements = null;
    176         if(will_accumulate || force_accumulate) { //mode.equals(ACCUMULATE)) {
     183        }
     184        sibling_description_elements = null;
     185        if(will_accumulate || force_accumulate) { //mode.equals(ACCUMULATE)) {
    177186        metadata_element.setAttribute(MODE_ATTRIBUTE, ACCUMULATE);
    178         }
     187        }
    179188        // As we can't possibly store all the metadata in memory, nor can we ensure that the indexes written to file remain the same until the new time we look at this file, and to avoid having to open a rewrite every collection document whenever any value tree changes, I'm writing the value out as a full path string
    180189        GValueModel model = Gatherer.c_man.getCollection().msm.getValueTree(metadata.getElement());
     
    186195            node_value = metadata.getAbsoluteValue();
    187196        }
    188         ///ystem.err.println("Creating node in GDMDocument: '" + node_value + "'");
    189         metadata_element.appendChild(base_document.createTextNode(node_value));
    190         // Retrieve the first description element for this fileset (there should only be one, but I'll play it safe).
    191         NodeList description_elements = fileset_element.getElementsByTagName("Description");
    192         Element description_element = (Element) description_elements.item(0);
    193         description_element.appendChild(metadata_element);
    194         description_element = null;
    195         metadata_element = null;
     197        ///ystem.err.println("Creating node in GDMDocument: '" + node_value + "'");
     198        metadata_element.appendChild(base_document.createTextNode(node_value));
     199        // Retrieve the first description element for this fileset (there should only be one, but I'll play it safe).
     200        NodeList description_elements = fileset_element.getElementsByTagName("Description");
     201        Element description_element = (Element) description_elements.item(0);
     202        description_element.appendChild(metadata_element);
     203        description_element = null;
     204        metadata_element = null;
    196205                //mode = null;
    197         fileset_element = null;
    198         directorymetadata_element = null;
    199         up_to_date = false;
     206        fileset_element = null;
     207        directorymetadata_element = null;
     208        up_to_date = false;
    200209    }
    201210    catch (Exception error) {
    202         Gatherer.printStackTrace(error);
    203     }
    204     }
    205 
    206     public int countMetadata() {
     211        Gatherer.printStackTrace(error);
     212    }
     213    }
     214
     215    public int countMetadata() {
    207216    int count = 0;
    208217    try {
    209         // Retrieve the document element.
    210         Element directorymetadata_element = base_document.getDocumentElement();
    211         // Iterate through the filesets, checking the FileName child element against    the target file's name using regular expression matching.
    212         NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
    213         for(int i = 0; i < fileset_elements.getLength(); i++) {
     218        // Retrieve the document element.
     219        Element directorymetadata_element = base_document.getDocumentElement();
     220        // Iterate through the filesets, checking the FileName child element against    the target file's name using regular expression matching.
     221        NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
     222        for(int i = 0; i < fileset_elements.getLength(); i++) {
    214223        Element fileset_element = (Element) fileset_elements.item(i);
    215224        NodeList description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
    216225        for(int k = 0; k < description_elements.getLength(); k++) {
    217             Element description_element = (Element) description_elements.item(k);
    218             NodeList metadata_elements = description_element.getElementsByTagName(StaticStrings.METADATA_ELEMENT);
    219             count = count + metadata_elements.getLength();
    220             metadata_elements = null;
    221             description_element = null;
     226            Element description_element = (Element) description_elements.item(k);
     227            // We have to do this for each type of metadata
     228            for(int z = 0; z < ALL_METADATA_TYPES.length; z++) {
     229                NodeList metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
     230                count = count + metadata_elements.getLength();
     231                metadata_elements = null;
     232            }
     233            description_element = null;
    222234        }
    223235        description_elements = null;
    224236        fileset_element = null;
    225         }
    226         fileset_elements = null;
    227         directorymetadata_element = null;
     237        }
     238        fileset_elements = null;
     239        directorymetadata_element = null;
    228240    }
    229241    catch (Exception error) {
    230         Gatherer.printStackTrace(error);
     242        Gatherer.printStackTrace(error);
    231243    }
    232244    return count;
    233     }
    234 
    235     /** Retrieve the document this class is wrapping. */
    236     public Document getDocument() {
     245    }
     246
     247    /** Retrieve the document this class is wrapping. */
     248    public Document getDocument() {
    237249    return base_document;
    238     }
    239     /** Get all of the metadata, including directory level, associated with this file. */
    240     public ArrayList getMetadata(String filename, boolean remove, ArrayList metadatum_so_far, File file, boolean append_folder_level) {
     250    }
     251    /** Get all of the metadata, including directory level, associated with this file. */
     252    public ArrayList getMetadata(String filename, boolean remove, ArrayList metadatum_so_far, File file, boolean append_folder_level) {
    241253    return getMetadata(filename, remove, metadatum_so_far, file, append_folder_level, false);
    242     }
    243     /** Retrieve the metadata associated with the given filename. Keep track of what metadata should be overwritten and what should be accumulated. Also make note of the source file, and remove the metadata if required. Finally if purge is set retrieve every piece of metadata in this file. */
    244     public ArrayList getMetadata(String filename, boolean remove, ArrayList metadatum_so_far, File file, boolean append_folder_level, boolean purge) {
     254    }
     255    /** Retrieve the metadata associated with the given filename. Keep track of what metadata should be overwritten and what should be accumulated. Also make note of the source file, and remove the metadata if required. Finally if purge is set retrieve every piece of metadata in this file. */
     256    public ArrayList getMetadata(String filename, boolean remove, ArrayList metadatum_so_far, File file, boolean append_folder_level, boolean purge) {
    245257    Gatherer.println("Get metadata for " + filename);
    246258    ArrayList metadatum = null;
    247259    if(metadatum_so_far == null) {
    248         metadatum = new ArrayList();
     260        metadatum = new ArrayList();
    249261    }
    250262    else {
    251         metadatum = metadatum_so_far;
     263        metadatum = metadatum_so_far;
    252264    }
    253265    try {
    254         // Retrieve the document element.
    255         Element directorymetadata_element = base_document.getDocumentElement();
    256         // Iterate through the filesets, checking the FileName child element against    the target file's name using regular expression matching.
    257         NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
    258         for(int i = 0; i < fileset_elements.getLength(); i++) {
     266        // Retrieve the document element.
     267        Element directorymetadata_element = base_document.getDocumentElement();
     268        // Iterate through the filesets, checking the FileName child element against    the target file's name using regular expression matching.
     269        NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
     270        for(int i = 0; i < fileset_elements.getLength(); i++) {
    259271        Element fileset_element = (Element) fileset_elements.item(i);
    260272        NodeList filename_elements = fileset_element.getElementsByTagName(FILENAME_ELEMENT);
    261273        for(int j = 0; j < filename_elements.getLength(); j++) {
    262             Element filename_element = (Element) filename_elements.item(j);
    263             String filename_text = MSMUtils.getValue(filename_element);
    264             if((filename != null && (filename.matches(filename_text) || (append_folder_level && filename.indexOf(File.separator) != -1 && filename_text.equals(filename.substring(0, filename.indexOf(File.separator)))))) || ((filename == null || append_folder_level) && filename_text.equals(DIRECTORY_FILENAME)) || purge) {
     274            Element filename_element = (Element) filename_elements.item(j);
     275            String filename_text = MSMUtils.getValue(filename_element);
     276            if((filename != null && (filename.matches(filename_text) || (append_folder_level && filename.indexOf(File.separator) != -1 && filename_text.equals(filename.substring(0, filename.indexOf(File.separator)))))) || ((filename == null || append_folder_level) && filename_text.equals(DIRECTORY_FILENAME)) || purge) {
    265277            // If they match add all of the metadata found in the Description child element, remembering to abide by desired mode (accumulate vs. overwrite).
     278            // Normal metadata
    266279            NodeList description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
    267280            for(int k = 0; k < description_elements.getLength(); k++) {
    268                 Element description_element = (Element) description_elements.item(k);
    269                 NodeList metadata_elements = description_element.getElementsByTagName(StaticStrings.METADATA_ELEMENT);
    270                 for(int l = 0; l < metadata_elements.getLength(); l++) {
    271                 Element metadata_element = (Element) metadata_elements.item(l);
    272                 String raw_element = metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    273                 //String language = metadata_element.getAttribute("language");
    274                 String mode = metadata_element.getAttribute(MODE_ATTRIBUTE);
    275                 String raw_value = MSMUtils.getValue(metadata_element);
    276                 // Raw value is in GREENSTONE form, convert to DOM
    277                 raw_value = Codec.transform(raw_value, Codec.GREENSTONE_TO_DOM);
    278                 // ***** LEGACY SUPPORT *****
    279                 // If this raw_value contains a '\' character, but no '\\', '[' or ']' characters, then replace the '\' with a '\\'
    280                 if(raw_value.indexOf(StaticStrings.ESCAPE_STR) != -1) {
    281                     Gatherer.println("Detected Legacy Path: " + raw_value);
    282                     raw_value = raw_value.replaceAll(StaticStrings.ESCAPE_PATTERN, StaticStrings.PIPE_STR);
    283                     Gatherer.println("Updated Path To: " + raw_value);
    284                     MSMUtils.setValue(metadata_element, raw_value);
     281                Element description_element = (Element) description_elements.item(k);
     282                // We have to do this for each type of metadata
     283                for(int z = 0; z < ALL_METADATA_TYPES.length; z++) {
     284                    NodeList metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
     285                    for(int l = 0; l < metadata_elements.getLength(); l++) {
     286                         Element metadata_element = (Element) metadata_elements.item(l);
     287                         String raw_element = metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     288                         //String language = metadata_element.getAttribute("language");
     289                         String mode = metadata_element.getAttribute(MODE_ATTRIBUTE);
     290                         String raw_value = MSMUtils.getValue(metadata_element);
     291                         // Raw value is in GREENSTONE form, convert to DOM
     292                         raw_value = Codec.transform(raw_value, Codec.GREENSTONE_TO_DOM);
     293                         // ***** LEGACY SUPPORT *****
     294                         // If this raw_value contains a '\' character, but no '\\', '[' or ']' characters, then replace the '\' with a '\\'
     295                         if(raw_value.indexOf(StaticStrings.ESCAPE_STR) != -1) {
     296                             Gatherer.println("Detected Legacy Path: " + raw_value);
     297                             raw_value = raw_value.replaceAll(StaticStrings.ESCAPE_PATTERN, StaticStrings.PIPE_STR);
     298                             Gatherer.println("Updated Path To: " + raw_value);
     299                             MSMUtils.setValue(metadata_element, raw_value);
     300                         }
     301                         // **************************
     302                         // Using the element string and value, retrieve a matching Metadata object from the cache
     303                         Metadata metadata = null;
     304                         // If this element has hierarchy values then we must ensure the raw value is a full path, not an index.
     305                         // Try to retrieve an already comstructed piece of metadata from file - but not if we are purging, as this will stuff up anything that is still using that metadata - such as the GTable
     306                         if(GDMManager.metadata_cache.contains(raw_element, raw_value) && !purge) {
     307                             ///ystem.err.println("HIT! Retrieve metadata from cache: " + raw_element + " -> " + raw_value + "\n");
     308                             metadata = (Metadata) GDMManager.metadata_cache.get(raw_element, raw_value);
     309                         }
     310                         else {
     311                             ElementWrapper element = Gatherer.c_man.getCollection().msm.getElement(raw_element);
     312                             if (element != null) {
     313                                 GValueNode value = Metadata.getDefaultValueNode(element, raw_value);
     314                                 ///ystem.err.println("Miss. Create new metadata: " + raw_element + " -> " + raw_value + "\n");
     315                                 metadata = new Metadata(element, value);
     316                                 if(!purge) {
     317                                     GDMManager.metadata_cache.put(raw_element, raw_value, metadata);
     318                                 }
     319                                 ///ystem.err.println("Added metadata to cache: " + raw_element + " -> " + raw_value + "\n");
     320                                 value = null;
     321                                 element = null;
     322                             }
     323                         }
     324                         // check whether the metadata is null
     325                         if (metadata != null) {
     326                             // We determine whether this metadata is file or folder level
     327                             if(filename != null) {
     328                                 ///ystem.err.println("Filename   = " + filename);
     329                                 ///ystem.err.println("filename_text = " + filename_text);
     330                                 // If can only be file level if there is no folder path details in filename and if the filename matched the filename text node (it may have matched .* instead)!
     331                                 if(filename.indexOf(File.separator) == -1 && filename.equals(filename_text)) {
     332                                     metadata.setFileLevel(true);
     333                                     ///ystem.err.println("File level!!!");
     334                                 }
     335                                 else {
     336                                     metadata.setFileLevel(false);
     337                                     ///ystem.err.println("Inherited!!!");
     338                                 }
     339                             }
     340                             else {
     341                                 ///ystem.err.println("Filename is null therefore this is file level metadata.");
     342                                 metadata.setFileLevel(true);
     343                             }
     344                             metadata.setFile(file);
     345                             // If mode is overwrite, then remove any previous values for this metadata element.
     346                             if(mode.equals("accumulate")) {
     347                                 metadata.setAccumulate(true);
     348                             }
     349                             else {
     350                                 metadata.setAccumulate(false);
     351                                 ///ystem.err.println("Metadata overwrites: " + metadata);
     352                                 for(int m = metadatum.size() - 1; m >= 0; m--) {
     353                                     Metadata old_metadata = (Metadata) metadatum.get(m);
     354                                     if(old_metadata.getElement().equals(metadata.getElement())) {
     355                                         metadatum.remove(m);
     356                                         ///ystem.err.println("Removing overridden metadata: " + old_metadata);
     357                                     }
     358                                     old_metadata = null;
     359                                 }
     360                             }
     361                             mode = null;
     362                             // Add the completed metadata and clean up
     363                             ///ystem.err.println("Adding metadata: " + metadata);
     364                             metadatum.add(metadata);
     365                             // Having found our metadata check if the value from the xml matches the one from the gvaluenode. If not update it. This happens whenever hierarchy information is involved (indexes rapidly become obsolete).
     366                             // If remove was set, remove it. We can only remove pure file level metadata, or folder level iff we were asked for folder level.
     367                             if(remove && ((filename != null && filename.matches(filename_text) && !filename_text.equals(DIRECTORY_FILENAME)) || (filename == null && filename_text.equals(DIRECTORY_FILENAME)))) {
     368                                 ///ystem.err.println("Removing " + metadata + " from " + file);
     369                                 description_element.removeChild(metadata_element);
     370                                 // Remove the description element if empty.
     371                                 if(!description_element.hasChildNodes()) {
     372                                     fileset_element.removeChild(description_element);
     373                                 }
     374                             }
     375                             else {
     376                                 //String current_value = metadata.getAbsoluteValue();
     377                                 String current_value = Codec.transform(metadata.getValueNode().getFullPath(false), Codec.TEXT_TO_DOM);
     378                                 ///ystem.err.println("Checking the current hfile: " + current_value);
     379                                 ///ystem.err.println("Against whats in the hfile: " + current_value);
     380                                 if(!raw_value.equals(current_value)) {
     381                                     // Remove old text
     382                                     while(metadata_element.hasChildNodes()) {
     383                                         metadata_element.removeChild(metadata_element.getFirstChild());
     384                                     }
     385                                     // Add new.
     386                                     metadata_element.appendChild(base_document.createTextNode(current_value));
     387                                 }
     388                             }
     389                         }
     390                         metadata = null;
     391                         raw_value = null;
     392                         raw_element = null;
     393                         metadata_element = null;
     394                     }
     395                     metadata_elements = null;
    285396                }
    286                 // **************************
    287                 // Using the element string and value, retrieve a matching Metadata object from the cache
    288                 Metadata metadata = null;
    289                 // If this element has hierarchy values then we must ensure the raw value is a full path, not an index.
    290                 // Try to retrieve an already comstructed piece of metadata from file - but not if we are purging, as this will stuff up anything that is still using that metadata - such as the GTable
    291                 if(GDMManager.metadata_cache.contains(raw_element, raw_value) && !purge) {
    292                     ///ystem.err.println("HIT! Retrieve metadata from cache: " + raw_element + " -> " + raw_value + "\n");
    293                     metadata = (Metadata) GDMManager.metadata_cache.get(raw_element, raw_value);
    294                 }
    295                 else {
    296                     ElementWrapper element = Gatherer.c_man.getCollection().msm.getElement(raw_element);
    297                     if (element != null) {
    298 
    299                     GValueNode value = Metadata.getDefaultValueNode(element, raw_value);
    300                     ///ystem.err.println("Miss. Create new metadata: " + raw_element + " -> " + raw_value + "\n");
    301                     metadata = new Metadata(element, value);
    302                     if(!purge) {
    303                         GDMManager.metadata_cache.put(raw_element, raw_value, metadata);
    304                     }
    305                     ///ystem.err.println("Added metadata to cache: " + raw_element + " -> " + raw_value + "\n");
    306                     value = null;
    307                     element = null;
    308                     }
    309                 }
    310                 // check whether the metadata is null
    311                 if (metadata != null) {
    312                 // We determine whether this metadata is file or folder level
    313                     if(filename != null) {
    314                     ///ystem.err.println("Filename      = " + filename);
    315                     ///ystem.err.println("filename_text = " + filename_text);
    316                     // If can only be file level if there is no folder path details in filename and if the filename matched the filename text node (it may have matched .* instead)!
    317                     if(filename.indexOf(File.separator) == -1 && filename.equals(filename_text)) {
    318                         metadata.setFileLevel(true);
    319                         ///ystem.err.println("File level!!!");
    320                     }
    321                     else {
    322                         metadata.setFileLevel(false);
    323                         ///ystem.err.println("Inherited!!!");
    324                     }
    325                     }
    326                     else {
    327                     ///ystem.err.println("Filename is null therefore this is file level metadata.");
    328                     metadata.setFileLevel(true);
    329                     }
    330                     metadata.setFile(file);
    331 
    332                 // If mode is overwrite, then remove any previous values for this metadata element.
    333                     if(mode.equals("accumulate")) {
    334                     metadata.setAccumulate(true);
    335                     }
    336                     else {
    337                     metadata.setAccumulate(false);
    338                     ///ystem.err.println("Metadata overwrites: " + metadata);
    339                     for(int m = metadatum.size() - 1; m >= 0; m--) {
    340                         Metadata old_metadata = (Metadata) metadatum.get(m);
    341                     if(old_metadata.getElement().equals(metadata.getElement())) {
    342                         metadatum.remove(m);
    343                         ///ystem.err.println("Removing overridden metadata: " + old_metadata);
    344                     }
    345                     old_metadata = null;
    346                     }
    347                     }
    348                     mode = null;
    349 
    350                 // Add the completed metadata and clean up
    351                 ///ystem.err.println("Adding metadata: " + metadata);
    352                     metadatum.add(metadata);
    353 
    354                 // Having found our metadata check if the value from the xml matches the one from the gvaluenode. If not update it. This happens whenever hierarchy information is involved (indexes rapidly become obsolete).
    355                 // If remove was set, remove it. We can only remove pure file level metadata, or folder level iff we were asked for folder level.
    356                     if(remove && ((filename != null && filename.matches(filename_text) && !filename_text.equals(DIRECTORY_FILENAME)) || (filename == null && filename_text.equals(DIRECTORY_FILENAME)))) {
    357                     ///ystem.err.println("Removing " + metadata + " from " + file);
    358                     description_element.removeChild(metadata_element);
    359                     // Remove the description element if empty.
    360                     if(!description_element.hasChildNodes()) {
    361                         fileset_element.removeChild(description_element);
    362                     }
    363                     }
    364                     else {
    365                     //String current_value = metadata.getAbsoluteValue();
    366                     String current_value = Codec.transform(metadata.getValueNode().getFullPath(false), Codec.TEXT_TO_DOM);
    367                     ///ystem.err.println("Checking the current hfile: " + current_value);
    368                     ///ystem.err.println("Against whats in the hfile: " + current_value);
    369                     if(!raw_value.equals(current_value)) {
    370                         // Remove old text
    371                         while(metadata_element.hasChildNodes()) {
    372                         metadata_element.removeChild(metadata_element.getFirstChild());
    373                         }
    374                         // Add new.
    375                         metadata_element.appendChild(base_document.createTextNode(current_value));
    376                     }
    377                     }
    378                 }
    379                 metadata = null;
    380                 raw_value = null;
    381                 raw_element = null;
    382                 metadata_element = null;
    383                 }
    384                 metadata_elements = null;
    385                 description_element = null;
     397                description_element = null;
    386398            }
    387399            description_elements = null;
    388             }
    389             filename_text = null;
    390             filename_element = null;
     400            }
     401            filename_text = null;
     402            filename_element = null;
    391403        }
    392404        // If the file set no longer has any description entries, remove it entirely
    393405        NodeList description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
    394406        if(description_elements.getLength() == 0) {
    395             directorymetadata_element.removeChild(fileset_element);
     407            directorymetadata_element.removeChild(fileset_element);
    396408        }
    397409        description_elements = null;
    398410        filename_elements = null;
    399411        fileset_element = null;
    400         }
    401         fileset_elements = null;
    402         directorymetadata_element = null;
     412        }
     413        fileset_elements = null;
     414        directorymetadata_element = null;
    403415    }
    404416    catch (Exception error) {
    405         Gatherer.self.printStackTrace(error);
     417        Gatherer.self.printStackTrace(error);
    406418    }
    407419    ///ystem.err.println("Found " + metadatum.size() + " pieces of metadata.");
    408420    return metadatum;
    409     }
    410 
    411     /** Determine if this document has been saved recently, and thus xml file version is up to date. */
    412     public boolean isUpToDate() {
     421    }
     422
     423    /** Determine if this document has been saved recently, and thus xml file version is up to date. */
     424    public boolean isUpToDate() {
    413425    return false;
    414     }
    415 
    416     /** Determine is this is a valid Greenstone Directory Metadata file. It may of course just be some xml file with the name metadata.xml. */
    417     public boolean isValid() {
     426    }
     427
     428    /** Determine is this is a valid Greenstone Directory Metadata file. It may of course just be some xml file with the name metadata.xml. */
     429    public boolean isValid() {
    418430    // Just determine if the doctype is GreenstoneDirectoryMetadata and root node is called DirectoryMetadata.
    419431    String doctype_name = base_document.getDoctype().getName();
    420432    String root_name = base_document.getDocumentElement().getTagName();
    421433    return ((doctype_name.equals("GreenstoneDirectoryMetadata") && root_name.equals("GreenstoneDirectoryMetadata")) || (doctype_name.equals("DirectoryMetadata") && root_name.equals("DirectoryMetadata")));
    422     }
    423     /** Remove the given directory level metadata from this document. All directory level metadata is available under the FileSet with filename '.*'. There is at least one nasty case to consider, where the first overwriting metadata entry, of several with the same element, is removed. In this case the next entry must become overwrite to ensure proper inheritance. */
    424     public void removeMetadata(String filename, Metadata metadata) {
     434    }
     435    /** Remove the given directory level metadata from this document. All directory level metadata is available under the FileSet with filename '.*'. There is at least one nasty case to consider, where the first overwriting metadata entry, of several with the same element, is removed. In this case the next entry must become overwrite to ensure proper inheritance. */
     436    public void removeMetadata(String filename, Metadata metadata) {
     437    Gatherer.println("Remove metadata: " + metadata + "\nFrom filename: " + filename);
    425438    try {
    426         boolean found = false;
    427         boolean first_metadata_element_found = true;
    428         boolean make_next_metadata_element_overwrite = false;
    429         boolean remove_fileset = false;
    430         // Retrieve the document element.
    431         Element directorymetadata_element = base_document.getDocumentElement();
    432         // Iterate through the filesets looking for the directory level one.
    433         NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
    434         for(int i = 0; !found && i < fileset_elements.getLength(); i++) {
     439        boolean found = false;
     440        boolean first_metadata_element_found = true;
     441        boolean make_next_metadata_element_overwrite = false;
     442        boolean remove_fileset = false;
     443        // Retrieve the document element.
     444        Element directorymetadata_element = base_document.getDocumentElement();
     445        // Iterate through the filesets looking for the directory level one.
     446        NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
     447        for(int i = 0; !found && i < fileset_elements.getLength(); i++) {
    435448        Element fileset_element = (Element) fileset_elements.item(i);
    436449        NodeList filename_elements = fileset_element.getElementsByTagName(FILENAME_ELEMENT);
    437450        for(int j = 0; !found && j < filename_elements.getLength(); j++) {
    438             Element filename_element = (Element) filename_elements.item(j);
    439             String filename_text = MSMUtils.getValue(filename_element);
    440             if((filename != null && filename.matches(filename_text) && !filename.equals(DIRECTORY_FILENAME)) || (filename == null && filename_text.equals(DIRECTORY_FILENAME))) {
     451            Element filename_element = (Element) filename_elements.item(j);
     452            String filename_text = MSMUtils.getValue(filename_element);
     453            if((filename != null && filename.matches(filename_text) && !filename.equals(DIRECTORY_FILENAME)) || (filename == null && filename_text.equals(DIRECTORY_FILENAME))) {
    441454            // Retrieve the Metadata Element for this fileset, and iterate through them looking for the one which we are to remove.
    442455            NodeList description_elements = fileset_element.getElementsByTagName("Description");
    443456            for(int k = 0; !found && k < description_elements.getLength(); k++) {
    444                 Element description_element = (Element) description_elements.item(k);
    445                 NodeList metadata_elements = description_element.getElementsByTagName(StaticStrings.METADATA_ELEMENT);
    446                 for(int l = 0; (!found || !make_next_metadata_element_overwrite) && l < metadata_elements.getLength(); l++) {
    447                 Element metadata_element = (Element) metadata_elements.item(l);
    448                 String element = metadata_element.getAttribute("name");
    449                 String value = MSMUtils.getValue(metadata_element);
    450                 // See if this is the metadata we wish to remove
    451                 if(element.equals(metadata.getElement().getName())) {
    452                     if(value.equals(metadata.getAbsoluteValue())) {
    453                     // Remove it
    454                     ///ystem.err.println("Remove " + element + "-" + value);
    455                     description_element.removeChild(metadata_element);
    456                     found = true;
    457                     // If this was the first metadata with this element found, and it was set to overwrite, then we have to ensure that the next metadata with this element found (if any) is changed to be overwrite now.
    458                     if(first_metadata_element_found && !metadata.accumulates()) {
    459                         ///ystem.err.println("First of this element found!");
    460                         make_next_metadata_element_overwrite = true;
    461                     }
    462                     }
    463                     // If this was the first metadata we've found with the element of the one to be removed set first found to false.
    464                     else if(first_metadata_element_found) {
    465                     ///ystem.err.println("Found a matching element: " + element + "=" + value);
    466                     first_metadata_element_found = false;
    467                     }
    468                     // Otherwise we should make this metadata overwrite as requested.
    469                     else if(make_next_metadata_element_overwrite) {
    470                     ///ystem.err.println("Changing to overwrite: " + element + "=" + value);
    471                     metadata_element.setAttribute(MODE_ATTRIBUTE, "");
    472                     }
     457                Element description_element = (Element) description_elements.item(k);
     458                // We have to do this for each type of metadata
     459                for(int z = 0; z < ALL_METADATA_TYPES.length; z++) {
     460                     NodeList metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
     461                     for(int l = 0; (!found || !make_next_metadata_element_overwrite) && l < metadata_elements.getLength(); l++) {
     462                     Element metadata_element = (Element) metadata_elements.item(l);
     463                     String element = metadata_element.getAttribute("name");
     464                     String value = MSMUtils.getValue(metadata_element);
     465                     // See if this is the metadata we wish to remove
     466                     if(element.equals(metadata.getElement().getName())) {
     467                         if(value.equals(metadata.getAbsoluteValue())) {
     468                         // Remove it
     469                         ///ystem.err.println("Remove " + element + "-" + value);
     470                         description_element.removeChild(metadata_element);
     471                         found = true;
     472                         // If this was the first metadata with this element found, and it was set to overwrite, then we have to ensure that the next metadata with this element found (if any) is changed to be overwrite now.
     473                         if(first_metadata_element_found && !metadata.accumulates()) {
     474                             ///ystem.err.println("First of this element found!");
     475                             make_next_metadata_element_overwrite = true;
     476                         }
     477                         }
     478                         // If this was the first metadata we've found with the element of the one to be removed set first found to false.
     479                         else if(first_metadata_element_found) {
     480                         ///ystem.err.println("Found a matching element: " + element + "=" + value);
     481                         first_metadata_element_found = false;
     482                         }
     483                         // Otherwise we should make this metadata overwrite as requested.
     484                         else if(make_next_metadata_element_overwrite) {
     485                         ///ystem.err.println("Changing to overwrite: " + element + "=" + value);
     486                         metadata_element.setAttribute(MODE_ATTRIBUTE, "");
     487                         }
     488                     }
     489                     value = null;
     490                     element = null;
     491                     metadata_element = null;
     492                     }
     493                     metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
     494                     // If we found it, removed it, and now the description tag has no children, mark the fileset for removal
     495                     if(metadata_elements.getLength() == 0) {
     496                     remove_fileset = true;
     497                     }
     498                     metadata_elements = null;
    473499                }
    474                 value = null;
    475                 element = null;
    476                 metadata_element = null;
    477                 }
    478                 metadata_elements = description_element.getElementsByTagName(StaticStrings.METADATA_ELEMENT);
    479                 // If we found it, removed it, and now the description tag has no children, mark the fileset for removal
    480                 if(metadata_elements.getLength() == 0) {
    481                 remove_fileset = true;
    482                 }
    483                 metadata_elements = null;
    484                 description_element = null;
     500                description_element = null;
    485501            }
    486502            description_elements = null;
    487             }
    488             filename_text = null;
    489             filename_element = null;
     503            }
     504            filename_text = null;
     505            filename_element = null;
    490506        }
    491507        filename_elements = null;
    492508        if(found && remove_fileset) {
    493             directorymetadata_element.removeChild(fileset_element);
     509            directorymetadata_element.removeChild(fileset_element);
    494510        }
    495511        fileset_element = null;
    496         }
    497         fileset_elements = null;
    498         directorymetadata_element = null;
    499         up_to_date = false;
     512        }
     513        fileset_elements = null;
     514        directorymetadata_element = null;
     515        up_to_date = false;
    500516    }
    501517    catch (Exception error) {
    502         Gatherer.printStackTrace(error);
    503     }
    504     }
    505 
    506     /** Change the up to date flag. */
    507     public void setUpToDate(boolean up_to_date) {
     518        Gatherer.printStackTrace(error);
     519    }
     520    }
     521
     522    /** Change the up to date flag. */
     523    public void setUpToDate(boolean up_to_date) {
    508524    this.up_to_date = up_to_date;
    509     }
     525    }
    510526}
  • trunk/gli/src/org/greenstone/gatherer/msm/GreenstoneArchiveParser.java

    r6047 r6051  
    139139                for(int k = 0; !found && k < metadatum.size(); k++) {
    140140                    Metadata sibling = (Metadata) metadatum.get(k);
     141                    ///ystem.err.println("Comparing " + element + " to " + sibling.getElement());
    141142                    if(element.equals(sibling.getElement())) {
     143                          ///ystem.err.println("Removing metadata for: " + sibling);
    142144                    Gatherer.c_man.getCollection().gdm.metadataChanged(new MSMEvent(this, System.currentTimeMillis(), target_file, sibling, null));
    143145                    }
  • trunk/gli/src/org/greenstone/gatherer/shell/GShell.java

    r6049 r6051  
    108108    return process_running;
    109109    }
    110    
     110
    111111    /** Constructor gatherer all the data required to create a new process, and emit meaningfull messages.
    112112     * @param args A <strong>String[]</strong> containing the arguments to the process thread, including the name of the executable.
     
    143143    } */
    144144    /** Any threaded class must include this method to allow the thread body to be run. */
    145     public void run() {
    146     if(progress != null) {
    147         progress.start();
    148     }
    149     // Determine if the user has asked for an outfile.
    150     String out_name = null;
    151     BufferedOutputStream bos = null;
    152     if(type == IMPORT || type == BUILD) {
    153         if(type == IMPORT) {
    154         out_name = (String) Gatherer.c_man.getCollection().build_options.getImportValue("out");
    155         }
    156         else {
    157         out_name = (String) Gatherer.c_man.getCollection().build_options.getBuildValue("out");
    158         }
    159         if(out_name != null && out_name.length() > 0) {
     145    public void run() {
     146        if(progress != null) {
     147            progress.start();
     148        }
     149        // Determine if the user has asked for an outfile.
     150        String out_name = null;
     151        BufferedOutputStream bos = null;
     152        if(type == IMPORT || type == BUILD) {
     153            if(type == IMPORT) {
     154            out_name = (String) Gatherer.c_man.getCollection().build_options.getImportValue("out");
     155            }
     156            else {
     157            out_name = (String) Gatherer.c_man.getCollection().build_options.getBuildValue("out");
     158            }
     159            if(out_name != null && out_name.length() > 0) {
     160            try {
     161                bos = new BufferedOutputStream(new FileOutputStream(new File(out_name), true));
     162            }
     163            catch (Exception error) {
     164                Gatherer.printStackTrace(error);
     165            }
     166            }
     167        }
     168        // Issue a processBegun event
     169        fireProcessBegun(type, status);
    160170        try {
    161             bos = new BufferedOutputStream(new FileOutputStream(new File(out_name), true));
    162         }
    163         catch (Exception error) {
    164             Gatherer.printStackTrace(error);
    165         }
    166         }
    167     }
    168     // Issue a processBegun event
    169     fireProcessBegun(type, status);
    170     try {
    171171
    172172        String command = "";
     
    176176        ///ystem.err.println("Command: " + command);
    177177        fireMessage(type, Dictionary.get("GShell.Command") + ": " + command, status);
    178                
     178
    179179        Runtime rt = Runtime.getRuntime();
    180180        Process prcs = rt.exec(args);
     
    184184        //BufferedReader stdinbr = new BufferedReader( stdinisr );
    185185        // Captures the std err of a program and pipes it into std in of java
    186        
     186
    187187        StringBuffer eline_buffer = new StringBuffer();
    188188        StringBuffer stdline_buffer = new StringBuffer();
     
    191191        if(eisr.ready()) {
    192192            int c = eisr.read();
     193            ///atherer.println("eisr: '" + (char) c + "'");
    193194            if(c == '\n' || c == '\r') {
    194195            if(eline_buffer.length() > 0) {
    195196                String eline = eline_buffer.toString();
    196                 ///ystem.err.print("*");
     197                ///atherer.println("* " + eline + " *");
    197198                if(progress != null) {
    198199                progress.parse(eline);
     
    218219        else if(stdisr.ready()) {
    219220            int c = stdisr.read();
     221            ///atherer.println("eisr: '" + (char) c + "'");
    220222            if(c == '\n' || c == '\r') {
    221223            if(stdline_buffer.length() > 0) {
    222224                String stdline = stdline_buffer.toString();
    223                 ///ystem.err.print("+");
     225                ///atherer.println("+ " + stdline + " +");
    224226                fireMessage(type, typeAsString(type) + "> " + stdline, status);
    225227                stdline = null;
     
    240242        }
    241243
     244            // Of course, just because the process is finished doesn't mean the incoming streams are empty. Unfortunately I've got no chance of preserving order, so I'll process the error stream first, then the out stream
     245            while(eisr.ready()) {
     246                int c = eisr.read();
     247                ///atherer.println("eisr: '" + (char) c + "'");
     248                if(c == '\n' || c == '\r') {
     249                    if(eline_buffer.length() > 0) {
     250                        String eline = eline_buffer.toString();
     251                        ///atherer.println("* " + eline + " *");
     252                        if(progress != null) {
     253                            progress.parse(eline);
     254                        }
     255                        if(bos != null) {
     256                            try {
     257                                bos.write(eline.getBytes(), 0, eline.length());
     258                            }
     259                            catch(Exception error) {
     260                                Gatherer.printStackTrace(error);
     261                            }
     262                        }
     263                        fireMessage(type, typeAsString(type) + "> " + eline, status);
     264                        eline = null;
     265                        eline_buffer = new StringBuffer();
     266                    }
     267                }
     268                else {
     269                    eline_buffer.append((char)c);
     270                }
     271            }
     272            while(stdisr.ready()) {
     273                int c = stdisr.read();
     274                ///atherer.println("eisr: '" + (char) c + "'");
     275                if(c == '\n' || c == '\r') {
     276                    if(stdline_buffer.length() > 0) {
     277                        String stdline = stdline_buffer.toString();
     278                        ///atherer.println("+ " + stdline + " +");
     279                        fireMessage(type, typeAsString(type) + "> " + stdline, status);
     280                        stdline = null;
     281                        stdline_buffer = new StringBuffer();
     282                    }
     283                }
     284                else {
     285                    stdline_buffer.append((char)c);
     286                }
     287            }
     288
     289        // Ensure that any messages still remaining in the string buffers are fired off.
     290        if(eline_buffer.length() > 0) {
     291            String eline = eline_buffer.toString();
     292            if(progress != null) {
     293                progress.parse(eline);
     294            }
     295            if(bos != null) {
     296                try {
     297                    bos.write(eline.getBytes(), 0, eline.length());
     298                }
     299                catch(Exception error) {
     300                    Gatherer.printStackTrace(error);
     301                }
     302            }
     303            fireMessage(type, typeAsString(type) + "> " + eline, status);
     304            eline = null;
     305        }
     306
     307        if(stdline_buffer.length() > 0) {
     308            String stdline = stdline_buffer.toString();
     309            fireMessage(type, typeAsString(type) + "> " + stdline, status);
     310            stdline = null;
     311        }
     312
    242313        if(!hasSignalledStop()) {
    243314        // Now display final message based on exit value
    244315        prcs.waitFor();
    245                      
     316
    246317        if(prcs.exitValue() == 0) {
    247318            status = OK;
     
    332403    }
    333404
    334     /** Method to determine if the user, via the progress monitor, has signalled stop. 
     405    /** Method to determine if the user, via the progress monitor, has signalled stop.
    335406     * @return A <strong>boolean</strong> indicating if the user wanted to stop.
    336407     */
  • trunk/gli/src/org/greenstone/gatherer/util/Codec.java

    r5877 r6051  
    147147    // Transform plain html text into greenstone encoding
    148148    String[] text_to_greenstone = {
    149        
     149
    150150        "\\[", "&#091;",
    151151        "\\]", "&#093;",
    152152        "\"", "&quot;",
    153         "\'", "&apos;",
    154153        "\n", "\\\\n"
    155154    };
     155    //      "\'", "&apos;",
    156156    // removed "\\\\", "\\|",
    157157    TRANSFORMS.put(TEXT_TO_GREENSTONE, text_to_greenstone);
     
    179179    }
    180180
    181     static public String transform(String raw, String transform) {
     181    static public String transform(String raw, String transform) {
     182        if(raw == null) {
     183             return raw;
     184        }
    182185    ///ystem.err.println("Transforming by "+transform+":\n" + raw);
    183186    String processed = (String) CACHE.get(transform, raw);
  • trunk/gli/src/org/greenstone/gatherer/util/StaticStrings.java

    r6030 r6051  
    3232/** Were you to guess that this is a class object choc-a-block full of static stringy goodness, you'd be right. They come in several flavours: Those ending _STR are strings you might find as values in XML, _ELEMENT are element names, _ATTRIBUTE are attribute names, _CHAR are particular characters while _CHARACTER are also characters but expressed as strings (for regex purposes ie startsWith, endsWith, indexOf and replaceAll); _PATTERN are strings which require extra escaping to put them through regex. Finally anything else is just a static string used within GLI. */
    3333public class StaticStrings {
     34     static final public char   CLOSEBRACKET_CHAR                          = ']';
     35    static final public char   DOUBLEQUOTE_CHAR                           = '\"';
     36    static final public char   BACKSLASH_CHAR                             = '\\';
    3437    static final public char   FORWARDSLASH_CHAR                          = '/';
    3538    static final public char   NEW_LINE_CHAR                              = '\n';
     39    static final public char   OPENBRACKET_CHAR                           = '[';
    3640    static final public char   PIPE_CHAR                                  = '|';
     41    static final public char   SINGLEQUOTE_CHAR                           = '\'';
     42    static final public char   SPACE_CHAR                                 = ' ';
    3743    static final public char   STAR_CHAR                                  = '*';
    3844    static final public String ABSTRACT_ELEMENT                           = "Abstract";
     
    4147    static final public String ASSIGNED_ATTRIBUTE                         = "assigned";
    4248    static final public String AT_CHARACTER                               = "@";
     49    static final public String BUILD_TYPE_STR                             = "buildtype";
    4350    static final public String CCS_STR                                    = "ccs";
    4451    static final public String CLASSES_FOLDER                             = "classes";
     
    7683    static final public String ENGLISH_LANGUAGE_STR                       = "en";
    7784    static final public String ENUM_STR                                   = "enum";
     85    static final public String EQUALS_CHARACTER                           = "=";
    7886    static final public String ERROR_STR                                  = "Error";
    7987    static final public String ESCAPE_PATTERN                             = "\\\\";
     
    8189    static final public String EXCLAIMATION_CHARACTER                     = "!";
    8290    static final public String EXCLUDE_STR                                = "exclude";
     91    static final public String EXTRACTED_METADATA_ELEMENT                 = "XMetadata";
    8392    static final public String EXTRACTED_NAMESPACE                        = "ex.";
    8493    static final public String FALSE_STR                                  = "false";
     
    146155    static final public String PROPERTIES_FILE_EXTENSION                  = ".properties";
    147156    static final public String PSEUDO_COLLECTCONFIGURATION_XML            = "xml/CollectionConfig.xml";
    148     //static final public String QUOTE_CHARACTER                            = "\"";
    149157    static final public String RBRACKET_CHARACTER                         = "]";
    150158    static final public String RBRACKET_PATTERN                           = "\\]";
Note: See TracChangeset for help on using the changeset viewer.