Changeset 8313


Ignore:
Timestamp:
2004-10-13T14:48:20+13:00 (20 years ago)
Author:
mdewsnip
Message:

Finally committing the (many) changes to the GLI to use the new metadata code... I hope this doesn't have too many bugs in it and committing it now doesn't stuff anyone up! (Katherine said I could commit it, so blame her if anything goes wrong).

Location:
trunk/gli
Files:
1 added
2 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/clean.bat

    r8269 r8313  
    3333if exist "gui\*.class" del "gui\*.class"
    3434if exist "help\*.class" del "help\*.class"
    35 if exist "mem\*.class" del "mem\*.class"
    3635if exist "metadata\*.class" del "metadata\*.class"
    37 if exist "msm\*.class" del "msm\*.class"
    3836if exist "shell\*.class" del "shell\*.class"
    3937if exist "util\*.class" del "util\*.class"
    40 if exist "valuetree\*.class" del "valuetree\*.class"
    4138cd ..\..\..\..
    4239
  • trunk/gli/clean.sh

    r8269 r8313  
    2626rm -rf gui
    2727rm -rf help
    28 rm -rf mem
    2928rm -rf metadata
    30 rm -rf msm
    3129rm -rf shell
    3230rm -rf util
    33 rm -rf valuetree
    3431cd ../../../..
    3532
  • trunk/gli/makegli.bat

    r8271 r8313  
    173173"%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/gui/tree/*.java
    174174"%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/help/*.java
    175 "%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/mem/*.java
    176175"%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/metadata/*.java
    177 "%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/msm/*.java
    178 "%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/msm/parsers/*.java
    179176"%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/shell/*.java
    180177"%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/util/*.java
    181 "%JAVACPATH%\javac.exe" -d classes/ -sourcepath src/ -classpath classes/;lib/apache.jar;lib/qfslib.jar;lib/mail.jar;lib/activation.jar src/org/greenstone/gatherer/valuetree/*.java
    182178
    183179if "%GLILANG%" == "en" echo Done!
  • trunk/gli/makegli.sh

    r8271 r8313  
    164164$javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/gui/tree/*.java
    165165$javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/help/*.java
    166 $javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/mem/*.java
    167166$javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/metadata/*.java
    168 $javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/msm/*.java
    169 $javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/msm/parsers/*.java
    170167$javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/shell/*.java
    171168$javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/util/*.java
    172 $javacpath -deprecation -d classes/ -sourcepath src/ -classpath classes/:lib/apache.jar:lib/qfslib.jar:lib/mail.jar:lib/activation.jar src/org/greenstone/gatherer/valuetree/*.java
    173169
    174170if [ "$glilang" == "es" ]; then
  • trunk/gli/src/org/greenstone/gatherer/cdm/Argument.java

    r8243 r8313  
    3939import org.greenstone.gatherer.collection.Collection;
    4040import org.greenstone.gatherer.collection.CollectionManager;
    41 import org.greenstone.gatherer.msm.ElementWrapper;
     41import org.greenstone.gatherer.metadata.MetadataElement;
     42import org.greenstone.gatherer.metadata.MetadataTools;
    4243import org.greenstone.gatherer.util.StaticStrings;
    4344import org.greenstone.gatherer.util.Utility;
     
    246247     * @see org.greenstone.gatherer.collection.CollectionManager#getCollection
    247248     */
    248     public String getValue() {
    249     String value = null;
    250     // Only assigned arguments have values.
    251     if(element != null) {
    252         value = XMLTools.getValue(element);
    253         // We may have to retrieve the language dependant string for a metadata element
    254         if(type == METADATUM) {
    255         ElementWrapper element_wrapper = Gatherer.c_man.getCollection().msm.getElement(value);
    256         if(element_wrapper != null) {
    257             value = element_wrapper.getName();
    258         }
    259         }
    260     }
    261     return value;
    262     }
    263 
    264     /** Retrieve the vector of values.
    265      * @return an ArrayList of values
    266      * @see org.greenstone.gatherer.Gatherer#c_man
    267      * @see org.greenstone.gatherer.collection.CollectionManager#getCollection
    268      */
    269     public ArrayList getValues() {
    270     ArrayList values = new ArrayList();
    271     // Only assigned arguments have values.
    272     if(element != null) {
    273         String value = XMLTools.getValue(element);
    274         StringTokenizer tokenizer = new StringTokenizer(value, ",");
    275         while(tokenizer.hasMoreTokens()) {
    276         String token = tokenizer.nextToken();
    277         if(type == METADATA) {
    278             ElementWrapper element_wrapper = Gatherer.c_man.getCollection().msm.getElement(token);
    279             if(element_wrapper != null) {
    280             token = element_wrapper.toString();
    281             }
    282         }
    283         values.add(token);
    284         }
    285     }
    286     return values;
    287     }
     249    public String getValue()
     250    {
     251    // Only assigned arguments have values.
     252    if (element == null) {
     253        return null;
     254    }
     255
     256    return XMLTools.getValue(element);
     257    }
     258
    288259
    289260    /** Method to determine if this argument has been assigned.
     
    509480     * @see org.greenstone.gatherer.util.StaticStrings#SPEECH_CHARACTER
    510481     */
    511     public String toString() {
     482    public String toString()
     483    {
    512484    StringBuffer text = new StringBuffer("-");
    513     if(element != null) {
    514         if(name == null) {
    515         name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
    516         }
    517         text.append(name);
    518         String value = XMLTools.getValue(element);
    519         if(value.length() > 0) {
    520         text.append(StaticStrings.SPACE_CHARACTER);
    521         // If the value contains a space, add speech marks
    522         if(value.indexOf(StaticStrings.SPACE_CHARACTER) != -1) {
    523             value = StaticStrings.SPEECH_CHARACTER + value + StaticStrings.SPEECH_CHARACTER;
    524         }
    525         // Tokenize the string
    526         StringTokenizer tokenizer = new StringTokenizer(value, ",");
    527         while(tokenizer.hasMoreTokens()) {
    528             String token = tokenizer.nextToken();
    529             if(type == METADATA || type == METADATUM) {
    530             ElementWrapper element_wrapper = null;
    531             // if you click on exit before saving and format statements have changed, this could be null
    532             if (Gatherer.c_man.getCollection() != null) {
    533                 element_wrapper = Gatherer.c_man.getCollection().msm.getElement(token);
    534             }
    535             if(element_wrapper != null) {
    536                 text.append(element_wrapper.toString());
    537                 element_wrapper = null;
    538             }
    539             else {
    540                 text.append(token);
    541             }
    542             }
    543             else {
    544             text.append(token);
    545             }
    546             token = null;
    547             text.append(StaticStrings.COMMA_CHARACTER);
    548         }
    549         tokenizer = null;
    550         text.deleteCharAt(text.length() - 1);
    551         }
    552         value = null;
    553     }
     485
     486    if (element == null) {
     487        return text.toString();
     488    }
     489
     490    if (name == null) {
     491        name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
     492    }
     493    text.append(name);
     494
     495    String value = XMLTools.getValue(element);
     496    if (value.length() == 0) {
     497        return text.toString();
     498    }
     499
     500    text.append(StaticStrings.SPACE_CHARACTER);
     501
     502//  // Handle metadata elements specially
     503//  if (type == METADATA || type == METADATUM) {
     504//      // Tokenize the string
     505//      StringTokenizer tokenizer = new StringTokenizer(value, ",");
     506//      while (tokenizer.hasMoreTokens()) {
     507//      String token = tokenizer.nextToken();
     508
     509//      MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(token);
     510//      if (metadata_element != null) {
     511//          text.append(metadata_element.getFullName());
     512//      }
     513//      else {
     514//          text.append(token);
     515//      }
     516
     517//      if (tokenizer.hasMoreTokens()) {
     518//          text.append(StaticStrings.COMMA_CHARACTER);
     519//      }
     520//      }
     521//      return text.toString();
     522//  }
     523
     524    // If the value contains a space, add speech marks
     525    //   (Except for metadata elements, which won't have spaces when written out to collect.cfg)
     526    if (value.indexOf(StaticStrings.SPACE_CHARACTER) != -1 && !(type == METADATUM || type == METADATA)) {
     527        value = StaticStrings.SPEECH_CHARACTER + value + StaticStrings.SPEECH_CHARACTER;
     528    }
     529
     530    text.append(value);
    554531    return text.toString();
    555532    }   
  • trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentConfiguration.java

    r8243 r8313  
    3939import org.greenstone.gatherer.gui.ModalDialog;
    4040import org.greenstone.gatherer.gui.SimpleMenuBar;
    41 import org.greenstone.gatherer.msm.ElementWrapper;
     41import org.greenstone.gatherer.metadata.MetadataElement;
     42import org.greenstone.gatherer.metadata.MetadataSetManager;
    4243import org.greenstone.gatherer.util.StaticStrings;
    4344import org.greenstone.gatherer.util.Utility;
     
    321322        String existing_value = argument.getValue();
    322323        String default_value = argument.getDefaultValue();
     324
    323325        switch(argument.getType()) {
    324326        case Argument.ENUM:
     
    333335        Collections.sort(options_model);
    334336        value = new GComboBox(options_model.toArray(), false);
    335         //((JComboBox)value).setEditable(false);
    336337        ((JComboBox)value).addActionListener(new ToolTipUpdater());
    337338        if(existing_value != null && existing_value.length() > 0) {
     
    345346        }
    346347        break;
     348
    347349        case Argument.FLAG:
    348350        // Only need the check box.
    349351        break;
     352
    350353        case Argument.HIERARCHY:
    351         value = new GComboBox(Gatherer.c_man.getCollection().msm.getAssignedElements(true), false);
    352         /** @TODO - figure out a smarter way of allowing Greenstone extracted metadata to be selected. */
    353         //((JComboBox)value).setEditable(false);
    354         ((JComboBox)value).addItemListener(new HierarchyListener());
    355         // Now ensure we have the existing value or default value selected if either exist.
    356         if(existing_value != null && existing_value.length() > 0) {
    357             selectValue((JComboBox)value, existing_value);
    358         }
    359         else if(default_value != null) {
    360             selectValue((JComboBox)value, default_value);
    361         }
     354        // I don't think these are used any more...
    362355        break;
     356
    363357        case Argument.INTEGER:
    364358        // Build a spinner
     
    393387        value = spinner;
    394388        break;
     389
    395390        case Argument.REGEXP:
    396391        case Argument.STRING:
    397         // Use a standard text field
    398         if(existing_value != null && existing_value.length() > 0) {
     392        // If there is already a value set for this argument, use it
     393        if (existing_value != null && !existing_value.equals("")) {
    399394            value = new JTextField(existing_value);
    400         }
    401         else {
    402             if(default_value != null) {
    403             value = new JTextField(default_value);
    404             }
    405             // Special test just for the hfile field.
    406             else if(argument.getName().equals("hfile")) {
    407             // Work through previous controls looking for the metadata one.
    408             for(int i = 0; i < central_pane.getComponentCount(); i++) {
    409                 Object object = central_pane.getComponent(i);
    410                 if(object instanceof ArgumentControl) {
    411                 ArgumentControl control = (ArgumentControl) object;
    412                 if(control.toString().equals("metadata")) {
    413                     Object temp = control.getValue();
    414                     if(temp != null) {
    415                     value = new JTextField(temp.toString() + ".txt");
    416                     }
    417                 }
    418 
    419                 }
    420             }
    421             }
    422             else {
    423             value = new JTextField();
    424             }
    425         }
     395            break;
     396        }
     397
     398        // Use the default value, if there is one
     399        if (default_value != null && !default_value.equals("")) {
     400            value = new JTextField(default_value);
     401            break;
     402        }
     403
     404//      // Special test just for the hfile field.
     405//      if (argument.getName().equals("hfile")) {
     406//          // Work through previous controls looking for the metadata one.
     407//          for (int i = 0; i < central_pane.getComponentCount(); i++) {
     408//          Object object = central_pane.getComponent(i);
     409//          if (object instanceof ArgumentControl) {
     410//              ArgumentControl control = (ArgumentControl) object;
     411//              if (control.toString().equals("metadata")) {
     412//              Object temp = control.getValue();
     413//              if (temp != null) {
     414//                  value = new JTextField(temp.toString() + ".txt");
     415//                                  break;
     416//              }
     417//              }
     418//          }
     419//          }
     420//      }
     421
     422        // Blank field
     423        value = new JTextField();
    426424        break;
     425
    427426        case Argument.LANGUAGE:
    428427        value = new GComboBox(CollectionDesignManager.language_manager.getLanguageCodes().toArray(), false);
    429         //((JComboBox)value).setEditable(false);
     428
    430429        // Now ensure we have the existing value or default value selected if either exist.
    431430        Language selected = null;
     
    440439        }
    441440        break;
     441
    442442        case Argument.METADATUM:
    443443        case Argument.METADATA:
    444         value = new GComboBox(Gatherer.c_man.getCollection().msm.getAssignedElements(), false);
     444        value = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
    445445
    446446        // Editable for advanced modes (allows things like dc.Title,ex.Title)
     
    450450
    451451        // Now ensure we have the existing value or default value selected if either exist.
    452         if(existing_value != null && existing_value.length() > 0) {
    453             boolean found = selectValue((JComboBox)value, existing_value);
    454             // Its possible that this is a custom value and so doesn't exist in the combobox. If so add it and then select it
    455             if(!found) {
    456             ((JComboBox)value).addItem(existing_value);
    457             ((JComboBox)value).setSelectedItem(existing_value);
    458             }
    459         }
    460         else if(default_value != null) {
    461             selectValue((JComboBox)value, default_value);
     452        if (existing_value != null && existing_value.length() > 0) {
     453            boolean found = selectValue((JComboBox) value, existing_value);
     454            // It's possible that this is a custom value and so doesn't exist in the combobox
     455            if (!found) {
     456            // If so, add it then select it
     457            ((JComboBox) value).addItem(existing_value);
     458            ((JComboBox) value).setSelectedItem(existing_value);
     459            }
     460        }
     461        else if (default_value != null) {
     462            selectValue((JComboBox) value, default_value);
    462463        }
    463464        break;
     465
    464466// ---- Special interface for adding and ordering multiple metadata items ----
    465467// Turned off at Ian's request!
     
    467469//          // Comma separated metadata values.
    468470//          ArrayList values = argument.getValues();
    469 //          value = new GComboBox(Gatherer.c_man.getCollection().msm.getAssignedElements(), false);
     471//          value = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
    470472//          //((JComboBox)value).setEditable(false);
    471473//          DefaultListModel model = new DefaultListModel();
     
    680682        case Argument.METADATUM:
    681683        case Argument.METADATA:
    682             Object new_value_raw = ((JComboBox)value).getSelectedItem();
    683             if(new_value_raw instanceof ElementWrapper) {
    684             // Element wrappers are guaranteed to be non-zero length
    685             argument.setValue(((ElementWrapper)new_value_raw).getName());
     684            Object new_value_raw = ((JComboBox) value).getSelectedItem();
     685            if (new_value_raw instanceof MetadataElement) {
     686            argument.setValue(((MetadataElement) new_value_raw).getFullName());
    686687            }
    687688            else {
     
    719720//              return true;
    720721        case Argument.HIERARCHY:
    721             argument.setValue(((JComboBox)value).getSelectedItem().toString());
    722             // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
    723             argument.setAssigned(true);
     722//          argument.setValue(((JComboBox)value).getSelectedItem().toString());
     723//          // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
     724//          argument.setAssigned(true);
    724725            return true;
    725726        case Argument.REGEXP:
     
    777778            */
    778779        }
    779         else if(object instanceof ElementWrapper) {
     780        else if (object instanceof MetadataElement) {
    780781            if(object.toString().equals(target)) {
    781782            combobox.setSelectedIndex(i);
     
    796797        ((JTextField)value).setText(value_str);
    797798    }
    798     /** Listener which adds entries to a list from a combobox when fired. */
    799     private class AddListener
    800         implements ActionListener {
    801         /** The model behind the target list. */
    802         private DefaultListModel model = null;
    803             /** The source for data to be added to the list. */
    804         private JComboBox source = null;
    805         /** The list to add data to. */
    806         private JList target = null;
    807         /** Constructor.
    808          * @param source A <strong>JComboBox</strong> which serves as the source for data.
    809          * @param target A <strong>JList</strong> which serves as the target for data.
    810          */
    811         public AddListener(JComboBox source, JList target) {
    812         this.model = (DefaultListModel) target.getModel();
    813         this.source = source;
    814         this.target = target;
    815         }
    816         /** When the add button is clicked, we attempt to add the selected metadata from the source into the target.
    817          * @param event An <strong>ActionEvent</strong> containing information about the event.
    818          */
    819         public void actionPerformed(ActionEvent event) {
    820         ElementWrapper element = (ElementWrapper) source.getSelectedItem();
    821         String name = element.toString();
    822         if (!model.contains(name)) {
    823             model.addElement(name);
    824         }
    825         }
    826     }
     799// /** Listener which adds entries to a list from a combobox when fired. */
     800// private class AddListener
     801//      implements ActionListener {
     802//      /** The model behind the target list. */
     803//      private DefaultListModel model = null;
     804//              /** The source for data to be added to the list. */
     805//      private JComboBox source = null;
     806//      /** The list to add data to. */
     807//      private JList target = null;
     808//      /** Constructor.
     809//       * @param source A <strong>JComboBox</strong> which serves as the source for data.
     810//       * @param target A <strong>JList</strong> which serves as the target for data.
     811//       */
     812//      public AddListener(JComboBox source, JList target) {
     813//      this.model = (DefaultListModel) target.getModel();
     814//      this.source = source;
     815//      this.target = target;
     816//      }
     817//      /** When the add button is clicked, we attempt to add the selected metadata from the source into the target.
     818//       * @param event An <strong>ActionEvent</strong> containing information about the event.
     819//       */
     820//      public void actionPerformed(ActionEvent event) {
     821//      ElementWrapper element = (ElementWrapper) source.getSelectedItem();
     822//      String name = element.toString();
     823//      if (!model.contains(name)) {
     824//          model.addElement(name);
     825//      }
     826//      }
     827// }
    827828    /** Listens for actions apon the enable checkbox, and if detected enables or diables control appropriately. */
    828829    private class EnabledListener
     
    896897    }
    897898    /** If a metadata element is selected that requires an hfile, then this listener defaults that hfile. */
    898     private class HierarchyListener
    899         implements ItemListener {
    900         /** Any implementation of ItemListener must include this method so that we can be informed when an item from the list is selected, and generate a predetermined hfile for that selection.
    901          * @param event An <strong>ItemEvent</strong> containing information about the selection.
    902          * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl
    903          */
    904         public void itemStateChanged(ItemEvent event) {
    905         // Determine if the selected element represents a hierarchy.
    906         Object temp = ((JComboBox)value).getSelectedItem();
    907         String filename = temp.toString();
    908         // Search for a argument control called hfile and enable and set value.
    909         for(int i = 0; i < central_pane.getComponentCount(); i++) {
    910             Object object = central_pane.getComponent(i);
    911             if(object instanceof ArgumentControl) {
    912             ArgumentControl control = (ArgumentControl) object;
    913             if(control.toString().equals("hfile")) {
    914                 control.setValue(filename + ".txt");
    915                 control.setEnabled(true);
    916             }
    917             }
    918         }
    919         }
    920     }
     899// private class HierarchyListener
     900//      implements ItemListener {
     901//      /** Any implementation of ItemListener must include this method so that we can be informed when an item from the list is selected, and generate a predetermined hfile for that selection.
     902//       * @param event An <strong>ItemEvent</strong> containing information about the selection.
     903//       * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl
     904//       */
     905//      public void itemStateChanged(ItemEvent event) {
     906//      // Determine if the selected element represents a hierarchy.
     907//      Object temp = ((JComboBox)value).getSelectedItem();
     908//      String filename = temp.toString();
     909//      // Search for a argument control called hfile and enable and set value.
     910//      for(int i = 0; i < central_pane.getComponentCount(); i++) {
     911//          Object object = central_pane.getComponent(i);
     912//          if(object instanceof ArgumentControl) {
     913//          ArgumentControl control = (ArgumentControl) object;
     914//          if(control.toString().equals("hfile")) {
     915//              control.setValue(filename + ".txt");
     916//              control.setEnabled(true);
     917//          }
     918//          }
     919//      }
     920//      }
     921// }
    921922    /** A ListOption is a compound item which is constructed from several Strings. That magic part is that the length of screen real-estate used by the text version of this item is limited. */
    922923    private class ListOption
  • trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfiguration.java

    r8243 r8313  
    3636import org.greenstone.gatherer.Gatherer;
    3737import org.greenstone.gatherer.gui.GLIButton;
     38import org.greenstone.gatherer.metadata.MetadataElement;
     39import org.greenstone.gatherer.metadata.MetadataTools;
    3840import org.greenstone.gatherer.util.DOMTree;
    3941import org.greenstone.gatherer.util.Codec;
     
    538540
    539541        // Remove the extracted metadata namespaces if required
    540         if (!show_extracted_namespace && value_str.length() > 0) {
     542        if (value_str.length() > 0) {
    541543            StringTokenizer string_tokenizer = new StringTokenizer(value_str, ",");
    542544            value_str = "";
    543545            while (string_tokenizer.hasMoreElements()) {
    544546            String token = (String) string_tokenizer.nextElement();
     547            MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(token);
     548            if (metadata_element != null) {
     549                token = metadata_element.getFullName();
     550            }
     551
    545552            if (token.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
    546553                token = token.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
    547554            }
    548555
    549             if (!value_str.equals("")) {
     556            value_str = value_str + token;
     557            if (string_tokenizer.hasMoreElements()) {
    550558                value_str = value_str + ",";
    551559            }
    552             value_str = value_str + token;
    553560            }
    554561        }
     
    11381145            while (string_tokenizer.hasMoreElements()) {
    11391146                String token = (String) string_tokenizer.nextElement();
     1147
    11401148                if (token.indexOf(StaticStrings.NS_SEP) == -1) {
    11411149                token = StaticStrings.EXTRACTED_NAMESPACE + token;
     1150                }
     1151                else {
     1152                MetadataElement metadata_element = MetadataTools.getMetadataElementWithName(token);
     1153                if (metadata_element != null) {
     1154                    token = metadata_element.getDisplayName();
     1155                }
    11421156                }
    11431157
     
    14721486            }
    14731487            if(name.equals(METADATA_ARGUMENT)) {
    1474                 // 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.
     1488                // 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.
    14751489                if(value.indexOf(StaticStrings.NS_SEP) == -1) {
    14761490                value = StaticStrings.EXTRACTED_NAMESPACE + value;
  • trunk/gli/src/org/greenstone/gatherer/cdm/FormatManager.java

    r8243 r8313  
    2727package org.greenstone.gatherer.cdm;
    2828
    29 /**************************************************************************************
    30  * Written:     06/05/02
    31  * Revised:     04/10/02 - Commented
    32  *              14/07/03 - DOM support
    33  **************************************************************************************/
     29
    3430import java.awt.*;
    3531import java.awt.event.*;
     
    4238import org.greenstone.gatherer.Gatherer;
    4339import org.greenstone.gatherer.gui.GLIButton;
    44 import org.greenstone.gatherer.msm.ElementWrapper;
     40import org.greenstone.gatherer.metadata.MetadataElement;
     41import org.greenstone.gatherer.metadata.MetadataSetManager;
    4542import org.greenstone.gatherer.util.StaticStrings;
    4643import org.greenstone.gatherer.util.Utility;
     
    208205    ArrayList variable_model = new ArrayList();
    209206    variable_model.add("[Text]");
     207    ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
     208    for (int i = 0; i < every_metadata_set_element.size(); i++) {
     209        variable_model.add("[" + ((MetadataElement) every_metadata_set_element.get(i)).getFullName() + "]");
     210    }
    210211    variable_model.add("[link]");
    211212    variable_model.add("[/link]");
     
    216217    variable_model.add("[parent(Top):_]");
    217218    variable_model.add("[parent(All'_'):_]");
    218     Vector elements = Gatherer.c_man.getCollection().msm.getAssignedElements();
    219     for(int i = 0; i < elements.size(); i++) {
    220         variable_model.add("[" + ((ElementWrapper)elements.get(i)).getName() + "]");
    221     }
    222     Collections.sort(variable_model);
    223219    return variable_model;
    224220    }
     
    236232    private HashMap default_mappings;
    237233    private JButton add_button;
    238     //private JButton default_button;
    239234    private JButton insert_button;
    240235    private JButton remove_button;
     
    311306        Dictionary.registerText(editor_label, "CDM.FormatManager.Editor");
    312307
    313         //default_button = new GLIButton();
    314         //default_button.setEnabled(false);
    315         //default_button.setMnemonic(KeyEvent.VK_D);
    316         //Dictionary.registerBoth(default_button, "CDM.FormatManager.Default_Format", "CDM.FormatManager.Default_Format_Tooltip");
    317        
    318308        editor_textarea = new JTextArea();
    319309        editor_textarea.setBackground(Configuration.getColor("coloring.editable_background", false));
  • trunk/gli/src/org/greenstone/gatherer/cdm/Index.java

    r8243 r8313  
    3030import org.greenstone.gatherer.DebugStream;
    3131import org.greenstone.gatherer.Gatherer;
    32 import org.greenstone.gatherer.msm.ElementWrapper;
     32import org.greenstone.gatherer.metadata.MetadataElement;
     33import org.greenstone.gatherer.metadata.MetadataSet;
     34import org.greenstone.gatherer.metadata.MetadataSetManager;
     35import org.greenstone.gatherer.metadata.MetadataTools;
    3336import org.greenstone.gatherer.util.StaticStrings;
    3437import org.greenstone.gatherer.util.Utility;
     
    7376        Element content_element = document.createElement(CollectionConfiguration.CONTENT_ELEMENT);
    7477        Object source_object = sources.get(i);
    75         if(source_object instanceof ElementWrapper) {
    76         ///DebugStream.println("Found ElementWrapper as source: " + ((ElementWrapper)source_object).getName());
    77         content_element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, ((ElementWrapper)source_object).getName());
     78        if (source_object instanceof MetadataElement) {
     79        // System.err.println("Constructing new Index with MetadataElement source...");
     80        content_element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, ((MetadataElement) source_object).getFullName());
    7881        }
    7982        else {
    80         ///DebugStream.println("Found String as source: " + source_object.toString());
     83        // System.err.println("Constructing new Index with String source...");
    8184        content_element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, source_object.toString());
    8285        }
     
    166169        for(int i = 0; i < sources_size; i++) {
    167170        Object source_object = sources.get(i);
    168         // If its an element wrapper use the unique name rather than the
    169         if(source_object instanceof ElementWrapper) {
    170             String full_element_name = ((ElementWrapper)source_object).getName();
     171        if (source_object instanceof MetadataElement) {
     172            String full_element_name = ((MetadataElement)source_object).getFullName();
    171173            if(full_element_name.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
    172174               id_buffer.append(full_element_name.substring(StaticStrings.EXTRACTED_NAMESPACE.length()));
     
    206208        for(int i = 0; i < content_elements_length; i++) {
    207209        Element content_element = (Element) content_elements.item(i);
    208         String source_str = (String) content_element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE);
    209         ElementWrapper element_wrapper = Gatherer.c_man.getCollection().msm.getElement(source_str);
    210         if(element_wrapper != null) {
    211             sources.add(element_wrapper);
     210        String metadata_element_name_full = (String) content_element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE);
     211        MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(metadata_element_name_full);
     212        if (metadata_element != null) {
     213            sources.add(metadata_element);
    212214        }
    213215        else {
    214             sources.add(source_str);
     216            sources.add(metadata_element_name_full);
    215217        }
    216218        }
     
    267269        Element content_element = element.getOwnerDocument().createElement(CollectionConfiguration.CONTENT_ELEMENT);
    268270        Object source_object = sources.get(i);
    269         if(source_object instanceof ElementWrapper) {
    270             //DebugStream.println("Found ElementWrapper as source: " + ((ElementWrapper)source_object).getName());
    271             String name = ((ElementWrapper)source_object).getName();
     271        if (source_object instanceof MetadataElement) {
     272            String name = ((MetadataElement) source_object).getFullName();
    272273            content_element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, name);
    273274            name = null;
  • trunk/gli/src/org/greenstone/gatherer/cdm/IndexManager.java

    r8243 r8313  
    3939import org.greenstone.gatherer.gui.GComboBox;
    4040import org.greenstone.gatherer.gui.GLIButton;
    41 import org.greenstone.gatherer.msm.ElementWrapper;
     41import org.greenstone.gatherer.metadata.MetadataElement;
     42import org.greenstone.gatherer.metadata.MetadataSetManager;
    4243import org.greenstone.gatherer.util.ExclusiveListSelectionListener;
    4344import org.greenstone.gatherer.util.StaticStrings;
     
    383384            Object source_object = sources_list.get(j);
    384385            String source_str = null;
    385             if(source_object instanceof ElementWrapper) {
    386                 source_str = ((ElementWrapper)source_object).getName();
     386            if(source_object instanceof MetadataElement) {
     387                source_str = ((MetadataElement) source_object).getFullName();
    387388            }
    388389            else {
     
    519520        ArrayList new_data = new ArrayList();
    520521        new_data.add(CollectionConfiguration.TEXT_STR);
    521         new_data.addAll(Gatherer.c_man.getCollection().msm.getAssignedElements());
    522 
     522        new_data.addAll(MetadataSetManager.getEveryMetadataSetElement());
    523523        // Creation
    524524        JPanel mgindexes_panel = new JPanel();
     
    688688        ArrayList new_data = new ArrayList();
    689689        new_data.add(CollectionConfiguration.TEXT_STR);
    690         new_data.addAll(Gatherer.c_man.getCollection().msm.getAssignedElements());
     690        new_data.addAll(MetadataSetManager.getEveryMetadataSetElement());
    691691        // reset the model in the list and combobox
    692692        source_list.setListData(new_data.toArray());
     
    772772         * @param event A <strong>ListSelectionEvent</strong> containing further information about the list selection.
    773773         */
    774         public void valueChanged(ListSelectionEvent event) {
     774        public void valueChanged(ListSelectionEvent event)
     775        {
     776        if (event.getValueIsAdjusting()) {
     777            return;
     778        }
     779
    775780        Object value = index_list.getSelectedValue();
    776781        move_down_button.setEnabled(value != null);
     
    12001205        index_combobox.addItem(CollectionConfiguration.METADATA_STR);
    12011206        index_combobox.addItem(CollectionConfiguration.TEXT_STR);
    1202         java.util.List assigned_elements = Gatherer.c_man.getCollection().msm.getAssignedElements();
    1203         int assigned_elements_size = assigned_elements.size();
    1204         for(int i = 0; i < assigned_elements_size; i++) {
    1205         index_combobox.addItem(assigned_elements.get(i));
    1206         }
    1207         assigned_elements = null;
     1207        ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
     1208        for(int i = 0; i < every_metadata_set_element.size(); i++) {
     1209        index_combobox.addItem(every_metadata_set_element.get(i));
     1210        }
    12081211        // Ensure the level manager has at least documents assigned
    12091212        if(levels_model.getSize() == 0) {
     
    13831386            // Unfortunately we have to generate a valid id
    13841387            String id = null;
    1385             if(selected_object instanceof ElementWrapper) {
    1386             id = ((ElementWrapper)selected_object).getName();
     1388            if (selected_object instanceof MetadataElement) {
     1389            id = ((MetadataElement) selected_object).getFullName();
    13871390            }
    13881391            else {
  • trunk/gli/src/org/greenstone/gatherer/cdm/MetadataSetView.java

    r8243 r8313  
    2929import java.awt.*;
    3030import java.awt.event.*;
     31import java.io.File;
    3132import java.util.*;
    3233import javax.swing.*;
    3334import javax.swing.event.*;
     35import javax.swing.filechooser.*;
    3436import org.greenstone.gatherer.Configuration;
    3537import org.greenstone.gatherer.DebugStream;
     
    3739import org.greenstone.gatherer.Gatherer;
    3840import org.greenstone.gatherer.gui.GLIButton;
    39 import org.greenstone.gatherer.mem.MetadataEditorManager;
    40 import org.greenstone.gatherer.msm.MetadataSet;
    41 import org.greenstone.gatherer.msm.MSMEvent;
    42 import org.greenstone.gatherer.msm.MSMListener;
    43 import org.w3c.dom.*;
     41import org.greenstone.gatherer.gui.MetadataElementListCellRenderer;
     42import org.greenstone.gatherer.metadata.MetadataElement;
     43import org.greenstone.gatherer.metadata.MetadataSet;
     44import org.greenstone.gatherer.metadata.MetadataSetManager;
     45import org.greenstone.gatherer.metadata.MetadataTools;
     46import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
     47import org.greenstone.gatherer.util.Utility;
     48
    4449
    4550/** This class only knows how to produce a simple visual representation of the currently imported metadata sets. It is also read-only, so should be fairly straight forward.
     
    4853 */
    4954public class MetadataSetView
    50     extends DynamicListModel
    51     implements MSMListener {
     55    extends DynamicListModel {
     56
    5257    /** The visual contols used to review the metadata sets. */
    5358    private Control controls = null;
     
    5560    private DynamicListModel model = null;
    5661
    57     /** Constructor.
    58      */
    59     public MetadataSetView() {
    60     DebugStream.println("MetadataSetView: Initialized.");
     62
     63    public MetadataSetView()
     64    {
    6165    model = this;
    62     Gatherer.c_man.getCollection().msm.addMSMListener(this);
    63     loadMetadataSets();
     66
     67    // Initialise the model
     68    refreshModel();
     69
    6470    // Build the controls
    65     controls = new MetadataSetControl();
    66     }
    67 
    68     /** Destructor. Remove any references of this class from persistant objects.
    69      * @see org.greenstone.gatherer.Gatherer
    70      * @see org.greenstone.gatherer.collection.CollectionManager
    71      */
    72     public void destroy() {
     71    controls = new MetadataSetViewControls();
     72    }
     73
     74
     75    public void destroy()
     76    {
    7377    controls.destroy();
    7478    controls = null;
    75     Gatherer.c_man.msm.removeMSMListener(this);
    7679    model = null;
    7780    }
    7881
    79     /** Called when an element is changed within a set in the MSM, prompting us to refresh our list of elements being shown.
    80      * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change.
    81      * @see org.greenstone.gatherer.cdm.MetadataSetView.MetadataSetControl
    82      */
    83     public void elementChanged(MSMEvent event) {
    84     // Get the controls to refresh element list.
    85     ((MetadataSetControl)controls).refreshElementList();
    86     }
    8782
    8883    /** A method for retrieve the controls for this manager.
    89      * @see org.greenstone.gatherer.Dictionary
    90      * @see org.greenstone.gatherer.gui.Coloring
    9184     */
    9285    public Control getControls() {
     
    9487    }
    9588
    96     /** Called when a metadata value has undergone significant change.
    97      * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change.
    98      */
    99     public void metadataChanged(MSMEvent event) {
    100     // Couldn't care less.
    101     }
    102 
    103     /** Called when a set is added or removed from the MSM.
    104      * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change.
    105      */
    106     public void setChanged(MSMEvent event) {
    107     // Reload model.
    108     clear();
    109     loadMetadataSets();
    110     }
    111 
    112 
    113     /** Prints out the contents of this manager, as they would appear in the collection configuration file.
    114      * @return A <strong>String</strong> containing a block of commands.
    115      * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper
    116      */
    117     public String toString() {
    118     String text = "";
    119     for(int i = 0; i < size(); i++) {
    120         SetWrapper set = (SetWrapper)get(i);
    121         text = text + set.toString() + "\n";
    122     }
    123     text = text + "\n";
    124     return text;
    125     }
    126 
    127     /** Called when a significant change has occured to a value tree for a certain element, however we take no further action.
    128      * @param event A <strong>MSMEvent</strong> containing information relevant to the event.
    129      */
    130     public void valueChanged(MSMEvent event) {
    131     }
    132 
    133     /** Retrieves the current list of loaded metadata sets, and builds a list model around them.
    134      * @see org.greenstone.gatherer.Gatherer
    135      * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper
    136      * @see org.greenstone.gatherer.collection.CollectionManager
    137      */
    138     private void loadMetadataSets() {
    139     // We initialize the set_model with wrapped metadata sets. Note that when we call getSets() we also end up adding ourselves as a listener to the metadata set manager.
    140     Vector sets = Gatherer.c_man.getCollection().msm.getSets();
    141     for(int i = 0; i < sets.size(); i++) {
    142         addElement(new SetWrapper((MetadataSet)sets.get(i)));
    143     }
    144     }
     89
     90    public void refreshModel()
     91    {
     92    // Remove any metadata sets from the model that are no longer loaded
     93    ArrayList loaded_metadata_sets = MetadataSetManager.getMetadataSets();
     94    for (int i = size() - 1; i >= 0; i--) {
     95        MetadataSet metadata_set = (MetadataSet) get(i);
     96        if (loaded_metadata_sets.contains(metadata_set) == false) {
     97        // System.err.println("Metadata set in list no longer loaded...removing.");
     98        remove(i);
     99        }
     100    }
     101
     102    // Add any metadata sets that are loaded but not in the model
     103    for (int i = 0; i < loaded_metadata_sets.size(); i++) {
     104        MetadataSet loaded_metadata_set = (MetadataSet) loaded_metadata_sets.get(i);
     105        boolean in_model = false;
     106        for (int j = 0; j < size(); j++) {
     107        MetadataSet metadata_set = (MetadataSet) get(j);
     108        if (metadata_set.equals(loaded_metadata_set)) {
     109            in_model = true;
     110            break;
     111        }
     112        }
     113
     114        if (in_model == false) {
     115        // System.err.println("Metadata set loaded but not in list...adding.");
     116        addElement(loaded_metadata_set);
     117        }
     118    }
     119    }
     120
    145121
    146122    /** 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. */
    147     private class MetadataSetControl
     123    private class MetadataSetViewControls
    148124    extends JPanel
    149125    implements Control {
    150     /** Listens for clicks upon the configure button, or double clicks from the metadata set list. */
    151     private ConfigureActionListener configure_action_listener;
    152126    /** Opens the MEM and systematically performs as if the add set button were clicked. */
    153127    private JButton add_button;
    154     /** Opens the MEM with the appropriate set open for editing. */
    155     private JButton configure_button;
    156128    /** Opens the MEM and systematically performs as if the remove set button were clicked. */
    157129    private JButton remove_button;
     
    179151    private JTextArea instructions = null;
    180152
    181     private ListListener list_listener;
    182 
    183     private MultilingualListCellRenderer element_list_cell_renderer;
    184 
    185     /** The element model for the currently selected set. */
    186     private Vector element_model = null;
     153    private MetadataElementListCellRenderer element_list_cell_renderer;
     154    private MetadataSetListSelectionListener list_listener;
    187155
    188156    /* Constructor.
     
    191159     * @see org.greenstone.gatherer.cdm.MetadataSetView.ListListener
    192160     */
    193     public MetadataSetControl() {
     161    public MetadataSetViewControls()
     162    {
    194163        // Create visual components
    195164        central_pane = new JPanel();
     
    198167        element_label.setOpaque(true);
    199168        Dictionary.registerText(element_label, "CDM.MetadataSetManager.Elements");
     169        element_list = new JList();
    200170        element_list_scroll_pane = new JScrollPane();
    201         element_list_cell_renderer = new MultilingualListCellRenderer(element_list_scroll_pane);
    202         element_list = new JList();
    203171        element_list_scroll_pane.setViewportView(element_list);
     172        element_list_cell_renderer = new MetadataElementListCellRenderer();
    204173        element_list.setCellRenderer(element_list_cell_renderer);
    205174        element_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     
    218187        Dictionary.registerText(set_label, "CDM.MetadataSetManager.Sets");
    219188        set_list = new JList(model);
     189        set_list.setCellRenderer(new MetadataSetListCellRenderer());
    220190        set_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    221         if(model.size() > 0) {
    222         set_list.setSelectedIndex(0);
    223         }
    224191
    225192        set_pane = new JPanel();
     
    234201        add_button.setMnemonic(KeyEvent.VK_A);
    235202        Dictionary.registerBoth(add_button, "CDM.MetadataSetManager.Add", "CDM.MetadataSetManager.Add_Tooltip");
    236         configure_button = new GLIButton();
    237         configure_button.setEnabled(false);
    238         configure_button.setMnemonic(KeyEvent.VK_C);
    239         Dictionary.registerBoth(configure_button, "CDM.MetadataSetManager.Configure", "CDM.MetadataSetManager.Configure_Tooltip");
    240203        remove_button = new GLIButton();
    241204        remove_button.setEnabled(false);
    242205        remove_button.setMnemonic(KeyEvent.VK_R);
    243206        Dictionary.registerBoth(remove_button, "CDM.MetadataSetManager.Remove", "CDM.MetadataSetManager.Remove_Tooltip");
    244         configure_action_listener = new ConfigureActionListener();
    245         list_listener = new ListListener();
     207        list_listener = new MetadataSetListSelectionListener();
    246208
    247209        // Add listeners
    248210        add_button.addActionListener(new AddButtonListener());
    249         configure_button.addActionListener(configure_action_listener);
    250211        remove_button.addActionListener(new RemoveButtonListener());
    251212        set_list.addListSelectionListener(list_listener);
    252         set_list.addMouseListener(configure_action_listener);
    253213        // Layout
    254214        instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
     
    273233        button_pane.setLayout(new GridLayout(1,3,0,0));
    274234        button_pane.add(add_button);
    275         button_pane.add(configure_button);
    276235        button_pane.add(remove_button);
    277236
     
    282241        add(button_pane, BorderLayout.SOUTH);
    283242    }
    284     /** Destructor. */
    285     public void destroy() {
    286     }
    287     /** Update the element list. */
    288     public void refreshElementList() {
    289         element_list.updateUI();
    290     }
    291 
    292     /** Overriden to ensure the instruction area is scrolled to top.
    293      */
    294     public void gainFocus() {
    295         if(instructions != null) {
     243
     244
     245    public void destroy() { }
     246
     247
     248    public void gainFocus()
     249    {
     250        // Ensure the instructions area is scrolled to the top
     251        if (instructions != null) {
    296252        instructions.setCaretPosition(0);
    297253        }
     254
    298255        // If no current selection, select first available set
    299         if(set_list.isSelectionEmpty() && set_list.getModel().getSize() > 0) {
     256        if (set_list.isSelectionEmpty() && set_list.getModel().getSize() > 0) {
    300257        set_list.setSelectedIndex(0);
    301258        list_listener.valueChanged(new ListSelectionEvent(set_list, 0, 0, true));
     
    303260    }
    304261
    305     public void loseFocus() {
    306     }
    307 
    308     /** Listens for clicks on the add button, and actions them accordingly by opening the MEM and clicking add set. */
     262
     263    public void loseFocus() { }
     264
     265
     266    /** Listens for clicks on the add button. */
    309267    private class AddButtonListener
    310268        implements ActionListener {
     269
    311270        /** Called when the add button is clicked.
    312271         * @param event an ActionEvent containing information about the mouse click
    313          * @see org.greenstone.gatherer.Gatherer
    314          * @see org.greenstone.gatherer.collection.Collection
    315          * @see org.greenstone.gatherer.collection.CollectionManager
    316          * @see org.greenstone.gatherer.mem.MetadataEditorManager
    317272         */
    318         public void actionPerformed(ActionEvent event) {
    319         Gatherer.c_man.getCollection().msm.editMDS(null, MetadataEditorManager.ADD_SET);
    320         }
    321     }
    322 
    323     /** Listens for clicks on the configure button or double clicks upon the metadata set list and chains to the MEM as appropriate. */
    324     private class ConfigureActionListener
    325         extends MouseAdapter
     273        public void actionPerformed(ActionEvent event)
     274        {
     275        JFileChooser chooser = new JFileChooser(new File(Utility.METADATA_DIR));
     276        chooser.setFileFilter(new MetadataSet.MetadataSetFileFilter());
     277        int return_val = chooser.showDialog(Gatherer.g_man, Dictionary.get("MSMPrompt.File_Import"));
     278        if (return_val == JFileChooser.APPROVE_OPTION) {
     279            Gatherer.c_man.importMetadataSet(new MetadataSet(chooser.getSelectedFile()));
     280            refreshModel();
     281
     282            // The metadata.xml files may possibly contain metadata for this newly added metadata set
     283            // Re-read all the metadata.xml files to account for this case
     284            MetadataXMLFileManager.clearMetadataXMLFiles();
     285            MetadataXMLFileManager.loadMetadataXMLFiles(new File(Gatherer.c_man.getCollectionImport()));
     286        }
     287        }
     288    }
     289
     290
     291    private class MetadataSetListCellRenderer
     292        implements ListCellRenderer
     293    {
     294        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
     295        {
     296        DefaultListCellRenderer default_list_cell_renderer = new DefaultListCellRenderer();
     297        JLabel list_cell_label = (JLabel) default_list_cell_renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     298
     299        if (value instanceof MetadataSet) {
     300            MetadataSet metadata_set = (MetadataSet) value;
     301            String metadata_set_name = MetadataTools.getMetadataSetAttribute(metadata_set, "Name", Configuration.getLanguage(), "en");
     302            list_cell_label.setText("metadataset " + metadata_set.getNamespace() + " \"" + metadata_set_name + "\"");
     303        }
     304
     305        return list_cell_label;
     306        }
     307    }
     308
     309
     310    private class MetadataSetListSelectionListener
     311        implements ListSelectionListener {
     312
     313        public void valueChanged(ListSelectionEvent event)
     314        {
     315        // Wait until we get a stable event
     316        if (event.getValueIsAdjusting()) {
     317            return;
     318        }
     319
     320        // Now we can process it
     321        if (!set_list.isSelectionEmpty()) {
     322            MetadataSet metadata_set = (MetadataSet) set_list.getSelectedValue();
     323            element_list.setListData(new Vector(metadata_set.getMetadataSetElements()));
     324            remove_button.setEnabled(true);
     325
     326            // Finally check the directionality and scroll as necessary
     327            JScrollBar scroll_bar = element_list_scroll_pane.getHorizontalScrollBar();
     328            if (element_list_cell_renderer.getDirectionality() == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
     329            scroll_bar.setValue(scroll_bar.getMaximum());
     330            }
     331            else {
     332            scroll_bar.setValue(scroll_bar.getMinimum());
     333            }
     334        }
     335        else {
     336            remove_button.setEnabled(false);
     337        }
     338        }
     339    }
     340
     341
     342    /** Listens for clicks on the remove button. */
     343    private class RemoveButtonListener
    326344        implements ActionListener {
    327         /** Called when the configure button is clicked.
     345
     346        /** Called when the remove button is clicked.
    328347         * @param event an ActionEvent containing information about the mouse click
    329348         */
    330         public void actionPerformed(ActionEvent event) {
    331         configureSet();
    332         }
    333 
    334         /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt.
    335          * @param event a MouseEvent containing information about the mouse click
    336         */
    337         public void mouseClicked(MouseEvent event) {
    338         if(event.getClickCount() == 2 ) {
    339             configureSet();
    340         }
    341         }
    342         /** If some set is selected, then open the metadata set manager with the current set selected and expanded
    343          * @see org.greenstone.gatherer.Gatherer
    344          * @see org.greenstone.gatherer.collection.Collection
    345          * @see org.greenstone.gatherer.collection.CollectionManager
    346          * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper
    347          * @see org.greenstone.gatherer.mem.MetadataEditorManager
    348          */
    349         private void configureSet() {
    350         if(!set_list.isSelectionEmpty()) {
    351             MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet();
    352             Gatherer.c_man.getCollection().msm.editMDS(set, MetadataEditorManager.NORMAL);
    353         }
    354         else {
    355             configure_button.setEnabled(false);
    356         }
    357         }
    358     }
    359 
    360     private class ListListener
    361         implements ListSelectionListener {
    362         public void valueChanged(ListSelectionEvent event) {
    363         // Wait until we get a stable event
    364         if(event.getValueIsAdjusting()) {
    365             return;
    366         }
    367         // Now we can process it
    368         if(!set_list.isSelectionEmpty()) {
    369             MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet();
    370             NodeList elements = set.getElements();
    371             element_model = new Vector();
    372             for(int i = 0; i < elements.getLength(); i++) {
    373             element_model.add(new ElementWrapper(elements.item(i)));
    374             }
    375             //Collections.sort(element_model);
    376             element_list.setListData(element_model);
    377             configure_button.setEnabled(true);
    378             remove_button.setEnabled(true);
    379 
    380             // Finally check the directionality and scroll as necessary
    381             JScrollBar scroll_bar = element_list_scroll_pane.getHorizontalScrollBar();
    382             if(element_list_cell_renderer.getDirectionality() == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
    383             scroll_bar.setValue(scroll_bar.getMaximum());
    384             }
    385             else {
    386             scroll_bar.setValue(scroll_bar.getMinimum());
    387             }
    388 
    389         }
    390         else {
    391             configure_button.setEnabled(false);
    392             remove_button.setEnabled(false);
    393         }
    394         }
    395     }
    396 
    397     /** Listens for clicks on the remove button, and actions them accordingly by opening the MEM and clicking remove set. */
    398     private class RemoveButtonListener
    399         implements ActionListener {
    400         /** Called when the remove button is clicked.
    401          * @param event an ActionEvent containing information about the mouse click
    402          * @see org.greenstone.gatherer.Gatherer
    403          * @see org.greenstone.gatherer.collection.Collection
    404          * @see org.greenstone.gatherer.collection.CollectionManager
    405          * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper
    406          * @see org.greenstone.gatherer.mem.MetadataEditorManager
    407          */
    408         public void actionPerformed(ActionEvent event) {
    409         if(!set_list.isSelectionEmpty()) {
    410             MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet();
    411             Gatherer.c_man.getCollection().msm.editMDS(set, MetadataEditorManager.REMOVE_SET);
    412         }
    413         else {
    414             remove_button.setEnabled(false);
    415         }
    416         }
    417     }
    418 
    419     private class MultilingualListCellRenderer
    420         extends DefaultListCellRenderer {
    421         private byte previous_directionality = Character.DIRECTIONALITY_UNDEFINED;
    422         private JScrollPane scroll_pane;
    423         public MultilingualListCellRenderer(JScrollPane scroll_pane) {
    424         super();
    425         this.scroll_pane = scroll_pane;
    426         }
    427 
    428         public byte getDirectionality() {
    429         if(previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE) {
    430             return Character.DIRECTIONALITY_RIGHT_TO_LEFT;
    431         }
    432         else {
    433             return Character.DIRECTIONALITY_LEFT_TO_RIGHT;
    434         }
    435         }
    436        
    437         public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    438         JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    439         // Determine if the text should be left aligned or right aligned
    440         String text = value.toString();
    441         int text_index = 0;
    442         byte directionality = Character.DIRECTIONALITY_UNDEFINED;
    443         while(directionality == Character.DIRECTIONALITY_UNDEFINED && text_index < text.length()) {
    444             directionality = Character.getDirectionality(text.charAt(text_index));
    445             text_index++;
    446         }
    447         if(directionality != previous_directionality) {
    448             previous_directionality = directionality;
    449             if(directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE) {
    450             ///ystem.err.println("R2L for: " + text);
    451             component.setHorizontalAlignment(JLabel.TRAILING);
    452             component.setHorizontalTextPosition(JLabel.TRAILING);
    453             component.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    454             //scroll_pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    455             }
    456             else {
    457             component.setHorizontalAlignment(JLabel.LEADING);
    458             component.setHorizontalTextPosition(JLabel.LEADING);
    459             ///ystem.err.println("L2R for: " + text);
    460             component.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    461             //scroll_pane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    462             }
    463         }
    464 
    465         text = null;
    466         return component;
    467         }
    468 
    469     }
    470    
    471     }
    472 
    473     /** Provides a convience wrapper around a metadata set, that allows it to appear in the <strong>JList</strong> the same way it would in the collection configuration file. */
    474     private class SetWrapper {
    475     private MetadataSet set = null;
    476     public SetWrapper(MetadataSet set) {
    477         this.set = set;
    478     }
    479     public MetadataSet getSet() {
    480         return set;
    481     }
    482     public String toString() {
    483         String namespace = set.getNamespace();
    484         // Watch out for the greenstone set, with its namespace of ""
    485         return "metadataset " + namespace + " \"" + set.getName() + "\"";
     349        public void actionPerformed(ActionEvent event)
     350        {
     351        MetadataSet metadata_set = (MetadataSet) set_list.getSelectedValue();
     352        Gatherer.c_man.removeMetadataSet(metadata_set);
     353        refreshModel();
     354        element_list.setListData(new Vector());
     355        }
    486356    }
    487357    }
  • trunk/gli/src/org/greenstone/gatherer/cdm/Subcollection.java

    r8243 r8313  
    2828
    2929import org.greenstone.gatherer.Gatherer;
    30 import org.greenstone.gatherer.msm.ElementWrapper;
    3130import org.greenstone.gatherer.util.StaticStrings;
    3231import org.greenstone.gatherer.util.Troolean;
     
    154153     * @return a String which is either the fully qualified name of a metadata element, or filename
    155154     */
    156     public String getSource() {
    157     if(source == null &&element != null) {
     155    public String getSource()
     156    {
     157    if (source == null && element != null) {
    158158        source = element.getAttribute(StaticStrings.CONTENT_ATTRIBUTE);
    159         // If this is a metadata element then retrieve the appropriate ElementWrapper and use the language specific name
    160         if(!source.equals(StaticStrings.FILENAME_STR)) {
    161         ElementWrapper element_wrapper = Gatherer.c_man.getCollection().msm.getElement(source);
    162         if(element_wrapper != null) {
    163             source = element_wrapper.toString();
    164         }
    165         }
    166     }
     159    }
     160
    167161    return source;
    168162    }
  • trunk/gli/src/org/greenstone/gatherer/cdm/SubcollectionManager.java

    r8243 r8313  
    2727package org.greenstone.gatherer.cdm;
    2828
    29 /**************************************************************************************
    30  * Written:      ??/??/02
    31  * Revised:      04/07/03 - DOM support
    32  **************************************************************************************/
     29
    3330import java.awt.*;
    3431import java.awt.event.*;
     
    4239import org.greenstone.gatherer.gui.GLIButton;
    4340import org.greenstone.gatherer.gui.NonWhitespaceField;
    44 import org.greenstone.gatherer.msm.ElementWrapper;
     41import org.greenstone.gatherer.metadata.MetadataElement;
     42import org.greenstone.gatherer.metadata.MetadataSetManager;
    4543import org.greenstone.gatherer.util.ExclusiveListSelectionListener;
    4644import org.greenstone.gatherer.util.StaticStrings;
     
    245243        JLabel source_label = new JLabel();
    246244        Dictionary.registerText(source_label, "CDM.SubcollectionManager.Source");
    247         Vector source_model = Gatherer.c_man.getCollection().msm.getAssignedElements();
     245        ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
     246        Vector source_model = new Vector(every_metadata_set_element);
    248247        source_model.add(0, StaticStrings.FILENAME_STR);
    249248        source_combobox = new JComboBox(source_model);
     
    364363    public void gainFocus() {
    365364        // Rebuild the sources combobox
    366         Vector source_model = Gatherer.c_man.getCollection().msm.getAssignedElements();
     365        ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
     366        Vector source_model = new Vector(every_metadata_set_element);
    367367        source_model.add(0, "Filename"); // Add filename as a possible source.
    368368        source_combobox.setModel(new DefaultComboBoxModel(source_model));
     
    395395        String source = null;
    396396        Object object = source_combobox.getSelectedItem();
    397         if(object instanceof ElementWrapper) {
    398             ElementWrapper element_wrapper = (ElementWrapper)object;
    399             source = element_wrapper.getName();
    400             if(source.indexOf(StaticStrings.NS_SEP) == -1) {
    401             source = StaticStrings.EXTRACTED_NAMESPACE + source;
    402             }
     397        if (object instanceof MetadataElement) {
     398            MetadataElement metadata_element = (MetadataElement) object;
     399            source = metadata_element.getFullName();
    403400        }
    404401        else {
     
    481478            String source = null;
    482479            Object object = source_combobox.getSelectedItem();
    483             if(object instanceof ElementWrapper) {
    484             ElementWrapper element_wrapper = (ElementWrapper)object;
    485             source = element_wrapper.getName();
    486             if(source.indexOf(StaticStrings.NS_SEP) == -1) {
    487                 source = StaticStrings.EXTRACTED_NAMESPACE + source;
    488             }
     480            if (object instanceof MetadataElement) {
     481            MetadataElement metadata_element = (MetadataElement) object;
     482            source = metadata_element.getFullName();
    489483            }
    490484            else {
     
    508502         */
    509503        public void valueChanged(ListSelectionEvent event) {
     504        // Wait until the event stabilises to avoid processing it multiple times
     505        if (event.getValueIsAdjusting() == true) {
     506            return;
     507        }
    510508        // Now the entry
    511509        if(!subcollection_list.isSelectionEmpty()) {
     
    520518            Object value = source_combobox.getItemAt(pos);
    521519            //ystem.err.println("Search for: " + s);
    522             while(value != null) {
    523             if(value instanceof ElementWrapper) {
    524                 ElementWrapper e = (ElementWrapper) value;
    525                 String e_name = e.getName();
    526                 if(e_name.indexOf(StaticStrings.NS_SEP) == -1) {
    527                 e_name = StaticStrings.EXTRACTED_NAMESPACE + e_name;
    528                 }
     520            while (value != null) {
     521            if (value instanceof MetadataElement) {
     522                MetadataElement metadata_element = (MetadataElement) value;
     523                String metadata_element_name = metadata_element.getFullName();
    529524                //ystem.err.print("Compare to: " + e_name);
    530                 if(e_name.equals(s)) {
     525                if (metadata_element_name.equals(s)) {
    531526                source_combobox.setSelectedIndex(pos);
    532527                value = null;
  • trunk/gli/src/org/greenstone/gatherer/collection/Collection.java

    r8253 r8313  
    4848import org.greenstone.gatherer.cdm.CollectionMetaManager;
    4949import org.greenstone.gatherer.file.FileNode;
    50 import org.greenstone.gatherer.msm.MetadataXMLFileManager;
    51 import org.greenstone.gatherer.msm.MetadataSetManager;
    5250import org.greenstone.gatherer.util.StaticStrings;
    5351import org.greenstone.gatherer.util.Utility;
     
    6462    /** A reference to the Collection Design Manager. */
    6563    public CollectionDesignManager cdm;
    66     /** A reference to the Greenstone Directory Metadata Manager. */
    67     public MetadataXMLFileManager gdm;
    68     /** A reference to the Metadata Set Manager. */
    69     public MetadataSetManager msm;
    7064    /** true if an error has occurred during construction */
    7165    public boolean error = false;
     
    119113    public void destroy() {
    120114    cdm.destroy();
    121     gdm.destroy();
    122     msm.destroy();
    123115    Configuration.setCollectionConfiguration(null);
    124116    if (Gatherer.g_man != null) {
     
    127119    cdm = null;
    128120    document = null;
    129     gdm = null;
    130     msm = null;
    131121    }
    132122   
     
    170160    }
    171161
    172     public MetadataXMLFileManager getGDM() {
    173     return gdm;
    174     }
    175    
    176162    /** Retrieve the short name for this collection.
    177163     * @return The name as a <strong>String</strong>.
  • trunk/gli/src/org/greenstone/gatherer/collection/CollectionManager.java

    r8253 r8313  
    6262import org.greenstone.gatherer.gui.WarningDialog;
    6363import org.greenstone.gatherer.gui.tree.WorkspaceTree;
    64 import org.greenstone.gatherer.msm.ElementWrapper;
    65 import org.greenstone.gatherer.msm.MetadataXMLFileManager;
    66 import org.greenstone.gatherer.msm.GreenstoneArchiveParser;
    67 import org.greenstone.gatherer.msm.LegacyCollectionImporter;
    68 import org.greenstone.gatherer.msm.MetadataSet;
    69 import org.greenstone.gatherer.msm.MetadataSetManager;
    70 import org.greenstone.gatherer.msm.MSMEvent;
    71 import org.greenstone.gatherer.msm.MSMListener;
    72 import org.greenstone.gatherer.msm.MSMProfiler;
     64import org.greenstone.gatherer.metadata.DocXMLFileManager;
     65import org.greenstone.gatherer.metadata.MetadataSet;
     66import org.greenstone.gatherer.metadata.MetadataSetManager;
     67import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
     68import org.greenstone.gatherer.metadata.ProfileXMLFileManager;
    7369import org.greenstone.gatherer.shell.GShell;
    7470import org.greenstone.gatherer.shell.GShellEvent;
     
    8985 */
    9086public class CollectionManager
    91     implements GShellListener, MSMListener {
    92     /** A reference to the metadata set manager. */
    93     public MetadataSetManager msm;
     87    implements GShellListener {
     88
    9489    /** Are we currently in the process of building? */
    9590    private boolean building = false;
     
    10095    /** The collection_model. */
    10196    private FileSystemModel collection_model = null;
    102     /** The workspace model. This becomes invalid on a collection change. */
    103     // private FileSystemModel workspace_model = null;
    10497    /** An inner class listener responsible for noting tree changes and resetting saved when they occur. */
    10598    private FMTreeModelListener fm_tree_model_listener = null;
     
    127120    this.collection = null;
    128121    }
     122
     123
    129124    /** Add a special directory mapping.
    130125     * @param name The name for this directory mapping as a <strong>String</strong>.
    131126     * @param file The directory this mapping maps to as a <strong>File</strong>.
    132127     */
    133     public void addDirectoryMapping(String name, File file) {
     128    public void addDirectoryMapping(String name, File file)
     129    {
    134130    // Update the information stored in the Gatherer config
    135131    Configuration.addDirectoryMapping(name, file);
     
    137133    Gatherer.g_man.refreshWorkspaceTree(WorkspaceTree.FOLDER_SHORTCUTS_CHANGED);
    138134    }
     135
     136
    139137    /** This method calls the builcol.pl scripts via a GShell so as to not lock up the processor.
    140138     * @see org.greenstone.gatherer.Configuration
     
    147145     * @see org.greenstone.gatherer.util.Utility
    148146     */
    149     public void buildCollection() {
     147    private void buildCollection() {
    150148    DebugStream.println("CollectionManager.buildCollection()");
    151149    building = true;
     
    227225    lock_file.delete();
    228226    if(lock_file.exists()) {
    229        System.err.println("Lockfile was not successfully deleted.");
    230     }
    231     collection.msm.destroy();
     227        System.err.println("Lockfile was not successfully deleted.");
     228    }
     229
     230    MetadataSetManager.clearMetadataSets();
     231    MetadataXMLFileManager.clearMetadataXMLFiles();
     232    DocXMLFileManager.clearDocXMLFiles();
     233    ProfileXMLFileManager.clearProfileXMLFile();
     234
    232235    collection = null;
    233236    collection_model = null;
     
    324327     * @param metadata_sets if the user has decided to select several metadata sets with which to initially populate the GLI then this is an ArrayList of metadata set file names, otherwise its null
    325328     */
    326     public void createCollection(String description, String email, String name, String title, File base_collection_directory, ArrayList metadata_sets) {
    327     boolean cancelled = false;
    328 
     329    public void createCollection(String description, String email, String name, String title, File base_collection_directory, ArrayList metadata_sets)
     330    {
    329331    try {
    330332        // first make sure that the collect directory exists
     
    340342        // *******************
    341343        //check that this creation has worked - simply by checking for the existence of the collect.cfg file
    342         String a_dir;
     344        String collection_dir;
    343345        if (Gatherer.GS3) {
    344         a_dir = Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, name);
     346        collection_dir = Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, name);
    345347        } else {
    346         a_dir = Utility.getCollectionDir(Configuration.gsdl_path, name);
    347         }
    348         File config_file = new File(Utility.getConfigFile(a_dir));
     348        collection_dir = Utility.getCollectionDir(Configuration.gsdl_path, name);
     349        }
     350        File config_file = new File(Utility.getConfigFile(collection_dir));
    349351        if (!config_file.exists()) {
    350352        // no point continuing
     
    356358       
    357359        // ACTIVE_DIR/log/
    358         File log_dir_temp = new File(Utility.getLogDir(a_dir)+"temp.dat");
     360        File log_dir_temp = new File(Utility.getLogDir(collection_dir)+"temp.dat");
    359361        File log_dir = log_dir_temp.getParentFile();
    360362        log_dir.mkdirs();
     
    364366
    365367        // Make sure an import folder exists
    366         File import_directory = new File(Utility.getImportDir(a_dir));
     368        File import_directory = new File(Utility.getImportDir(collection_dir));
    367369        if (!import_directory.exists()) {
    368370        import_directory.mkdirs();
     
    372374
    373375        // Now create the collection object around the directory.
    374         collection = new Collection(new File(a_dir, name + ".col"));
    375         collection.msm = new MetadataSetManager();
    376         msm = collection.msm; // Legacy
    377         collection.msm.load();
    378 
    379         // Import default metadata sets if any.
    380         for(int i = 0; metadata_sets != null && i < metadata_sets.size(); i++) {
    381         MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
    382         collection.msm.importMDS(metadata_set.getFile(), false);
    383         }
    384 
    385         boolean skip_import_phase = false;
     376        collection = new Collection(new File(collection_dir, name + ".col"));
     377
     378        MetadataSetManager.clearMetadataSets();
     379        MetadataXMLFileManager.clearMetadataXMLFiles();
     380        DocXMLFileManager.clearDocXMLFiles();
     381
     382        // Import default metadata sets, if any
     383        for (int i = 0; metadata_sets != null && i < metadata_sets.size(); i++) {
     384        importMetadataSet((MetadataSet) metadata_sets.get(i));
     385        }
     386
     387        ProfileXMLFileManager.loadProfileXMLFile(new File(collection_dir, Utility.META_DIR));
    386388
    387389        // Before we create the CollectionDesignManager we have to check if we are basing it upon some other collection.
    388         if(base_collection_directory != null) {
    389            DebugStream.println("Basing new collection on existing one: " + base_collection_directory);
    390            collection.setBaseCollection(base_collection_directory.getAbsolutePath());
    391            // copy over other needed directories
    392            copyExtraBaseCollStuff(new File(a_dir), base_collection_directory);
    393         // Try to import any existing metadata sets for this collection. Look in base_collection_directory/metadata and import any metadata sets found.
    394         File base_metadata = new File(base_collection_directory, Utility.META_DIR);
    395         if(base_metadata.exists()) {
    396             DebugStream.println("Found the metadata directory.");
    397             File[] possible_metadata_sets = base_metadata.listFiles();
    398             for(int i = 0; possible_metadata_sets != null && i < possible_metadata_sets.length; i++) {
    399             String filename = possible_metadata_sets[i].getName();
    400             if(filename.endsWith(".mds")) {
    401                 DebugStream.println("+ Found a metadata set. Importing: " + possible_metadata_sets[i].getAbsolutePath());
    402                 collection.msm.importMDS(possible_metadata_sets[i], false);
    403                 skip_import_phase = true;
    404             }
     390        if (base_collection_directory != null) {
     391        DebugStream.println("Basing new collection on existing one: " + base_collection_directory);
     392        collection.setBaseCollection(base_collection_directory.getAbsolutePath());
     393        // copy over other needed directories
     394        copyExtraBaseCollStuff(new File(collection_dir), base_collection_directory);
     395        // Try to import any existing metadata sets for this collection
     396        // Look in base_collection_directory/metadata and import any metadata sets found.
     397        File base_metadata_directory = new File(base_collection_directory, Utility.META_DIR);
     398        ArrayList base_metadata_sets = MetadataSetManager.listMetadataSets(base_metadata_directory);
     399        if (base_metadata_sets != null) {
     400            for (int i = 0; i < base_metadata_sets.size(); i++) {
     401            importMetadataSet((MetadataSet) base_metadata_sets.get(i));
    405402            }
    406403        }
     
    408405            DebugStream.println("This base collection has no metadata directory.");
    409406        }
    410         // If no sets were imported, then create a new metadata with this new collections name.
    411         if(collection.msm.getSets().size() == 0) {
     407
     408        // If no sets were imported...
     409        if (MetadataSetManager.getMetadataSets().size() == 0) {
    412410            // Prompt the user so that they can choose at least one initial metadata set. We're sneaky here and just create a ncm_prompt
    413411            DebugStream.println("This collection has no metadata sets. Present the user with the metadata set selection prompt.");
    414412            NewCollectionMetadataPrompt ncm_prompt = new NewCollectionMetadataPrompt();
    415413            // If cancelled then they really do mean to start a collection with no metadata sets.
    416             if(!ncm_prompt.isCancelled()) {
     414            if (!ncm_prompt.isCancelled()) {
    417415            ArrayList initial_sets = ncm_prompt.getSets();
    418             for(int i = 0; initial_sets != null && i < initial_sets.size(); i++) {
    419                 MetadataSet metadata_set = (MetadataSet) initial_sets.get(i);
    420                 collection.msm.importMDS(metadata_set.getFile(), false);
    421                 metadata_set = null;
     416            for (int i = 0; initial_sets != null && i < initial_sets.size(); i++) {
     417                importMetadataSet((MetadataSet) initial_sets.get(i));
    422418            }
    423             initial_sets = null;
    424419            }
    425420            ncm_prompt.dispose();
    426421            ncm_prompt = null;
    427422        }
    428         // Do a dry metadata import run over the entire base collection, recording profile mappings. We do this by finding the archive files, and then iterating over them using the GreenstoneArchiveParser to retrieve metadata from them. We then process the importing of new metadata elements using the selectElement prompt used in a file action metadata import. However the big change is that we don't actually import any metadata, just create importing profiles.
    429         if(!skip_import_phase) {
    430             File base_archive = new File(base_collection_directory, Utility.ARCHIVES_DIR);
    431             if(base_archive.exists()) {
    432             DebugStream.println("+ Archive directory found. Inspecting archives for metadata information.");
    433             ArrayList metadata_elements = GreenstoneArchiveParser.extractMetadataElements(base_archive);
    434             for(int i = 0; !cancelled && i < metadata_elements.size(); i++) {
    435                 String metadata_name = (String) metadata_elements.get(i);
    436                 ElementWrapper target = collection.msm.prompt.selectElement(metadata_name);
    437                 cancelled = Gatherer.c_man.getCollection().msm.prompt.wasDialogCancelled();
    438                 if(!cancelled) {
    439                 if(target != null) {
    440                     collection.msm.profiler.addAction(base_collection_directory.getAbsolutePath(), metadata_name, target.getName());
    441                 }
    442                 else {
    443                     collection.msm.profiler.addAction(base_collection_directory.getAbsolutePath(), metadata_name, null);
    444                 }
    445                 }
    446             }
    447             // Hopefully mappings should now be in place for metadata extracted from this collection.
    448             }
    449             else {
    450             DebugStream.println("+ Searching files for metadata.xml information.");
    451             // Find the import directory
    452             File base_import = new File(base_collection_directory, Utility.IMPORT_DIR);
    453             if(base_import.exists()) {
    454                 searchForMetadata(base_import);
    455             }
    456             }
    457         }
    458         // And if that fails then we must have been asked by Satan himself to build the very digital collections of hell, because they don't match any goodly greenstone collection I have ever seen, so you can't blame me if I can't import them.
    459423
    460424        // Now we update our collect.cfg
    461425        DebugStream.println("Copy and update collect.cfg from base collection.");
    462         updateCollectionCFG(new File(base_collection_directory, Utility.CONFIG_FILE), new File(a_dir, Utility.CONFIG_FILE), description, email, title);
     426        updateCollectionCFG(new File(base_collection_directory, Utility.CONFIG_FILE), new File(collection_dir, Utility.CONFIG_FILE), description, email, title);
    463427        }
    464428
    465429        // Always import the extracted metadata set if we didn't already
    466         if(collection.msm.getSet(Utility.EXTRACTED_METADATA_NAMESPACE) == null) {
    467            collection.msm.importMDS(new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION), false);
     430        if (MetadataSetManager.getMetadataSet(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE) == null) {
     431        File extracted_metadata_set_file = new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION);
     432        importMetadataSet(new MetadataSet(extracted_metadata_set_file));
    468433        }
    469434
    470435        collection.cdm = new CollectionDesignManager(new File(getCollectionConfig()));
    471        
     436
    472437        // 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
    473         if(base_collection_directory != null) {
     438        if (base_collection_directory != null) {
    474439        // Update the creator and maintainer
    475440        CollectionMeta creator_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getCreator());
     
    479444        maintainer_collectionmeta.setValue(email);
    480445        maintainer_collectionmeta = null;
     446
    481447        // Update the collection title
    482448        CollectionMeta collection_name_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONNAME_STR);
    483449        collection_name_collectionmeta.setValue(title);
    484450        collection_name_collectionmeta = null;
     451
    485452        // And now the description
    486453        CollectionMeta collection_extra_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_COLLECTIONEXTRA_STR);
    487454        collection_extra_collectionmeta.setValue(description);
    488455        collection_extra_collectionmeta = null;
     456
    489457        // All collections based on others are automatically public
    490458        CollectionMeta public_collectionmeta = new CollectionMeta(collection.cdm.collect_config.getPublic());
    491459        public_collectionmeta.setValue(StaticStrings.TRUE_STR);
    492460        public_collectionmeta = null;
     461
    493462        // Finally reset the icons
    494463        CollectionMeta icon_collection_collectionmeta = collection.cdm.collectionmeta_manager.getMetadatum(StaticStrings.COLLECTIONMETADATA_ICONCOLLECTION_STR);
     
    499468        icon_collection_small_collectionmeta = null;
    500469        }
    501        
    502         collection.gdm = new MetadataXMLFileManager();
    503470
    504471        progress.setProgress(3);
    505472
    506         // Has to be done after creating metadata set manager.
    507         File gmeta_dir_temp = new File(getCollectionMetadata()+"temp.dat");
    508         File gmeta_dir = gmeta_dir_temp.getParentFile();
    509         gmeta_dir.mkdirs();
    510         if(progress != null) {
    511         progress.setNote("GMeta created");
    512         }
    513         progress.setProgress(4);
    514 
    515         progress.setProgress(6);
    516         // Register ourselves as being interested in what the msm has to say.
    517         collection.msm.addMSMListener(this);
    518473        // Create a lock file.
    519         File lock_file = new File(a_dir, LOCK_FILE);
     474        File lock_file = new File(collection_dir, LOCK_FILE);
    520475        FileOutputStream out = new FileOutputStream(lock_file);
    521476        out.write(LOCK_FILE.getBytes());
    522477        out.close();
    523478        out = null;
     479
    524480        progress.setProgress(7);
    525         String args[] = new String[1];
    526         args[0] = name;
    527         progress.setNote(Dictionary.get("CollectionManager.Session_Ready", args));
     481        progress.setNote(Dictionary.get("CollectionManager.Session_Ready", name));
    528482        progress.close();
    529483    }
     
    543497    }
    544498    }
     499
    545500
    546501    public void createLockFile(File destination) {
     
    569524    }
    570525
    571     /** Method that is called whenever an element within a set is changed or modified. We want to mark the collection so that it needs saving again.
    572      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    573      * @see org.greenstone.gatherer.collection.Collection
    574      */
    575     public void elementChanged(MSMEvent event) {
    576     // This means the state of the collections has changed, so we should set saved to false.
    577     collection.setSaved(false);
    578     }
    579     /** Used to retrieve the build options associated with the currently loaded collection. If none yet exist, default ones are created.
    580      * @return A <strong>BuildOptions</strong> object containing the build options for the current collection.
    581      * @see org.greenstone.gatherer.collection.Collection
    582      */
    583     /* private BuildOptions getBuildOptions() {
    584     return collection.build_options;
    585     } */
    586526
    587527    /** Retrieve the current collection.
     
    591531    return collection;
    592532    }
     533
     534
    593535    /** Constructs the absolute filename of the collection archive directory, which should resemble "$GSDLHOME/collect/&lt;col_name&gt;/archive/"
    594536     * @return A <strong>String</strong> containing the filename.
     
    630572        return Utility.getConfigFile(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()));
    631573    } else {
    632     return Utility.getConfigFile(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
     574        return Utility.getConfigFile(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
    633575    }
    634576    }
     
    660602        return Utility.getEtcDir(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()));
    661603    } else {
    662     return Utility.getEtcDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
     604        return Utility.getEtcDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
    663605    }
    664606    }
     
    674616        return Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()) + collection.getName() + ".col";
    675617    } else {
    676     return Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()) + collection.getName() + ".col";
     618        return Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()) + collection.getName() + ".col";
    677619    }
    678620    }
     
    688630        return Utility.getImagesDir(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()));
    689631    } else {
    690     return Utility.getImagesDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
     632        return Utility.getImagesDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
    691633    }
    692634    }
     
    748690    }
    749691
    750     /** This method either returns the title of the current collection, or a placeholder string of 'No Collection'.
    751      * @return A <strong>String</strong> which represents what we wish to display for a collection title.
    752      * @see org.greenstone.gatherer.collection.Collection
    753      */
    754     /* private String getCollectionTitle() {
    755     if(collection != null) {
    756         return collection.getTitle();
    757     }
    758     return Dictionary.get("Collection.No_Collection");
    759     } */
     692
     693    static public String getCollectionMetadataDirectory()
     694    {
     695    if (Gatherer.GS3) {
     696        return Utility.getMetadataDir(Utility.getCollectionDir(Configuration.gsdl3_path, Configuration.site_name, collection.getName()));
     697    } else {
     698        return Utility.getMetadataDir(Utility.getCollectionDir(Configuration.gsdl_path, collection.getName()));
     699    }
     700    }
     701   
    760702
    761703    /** Retrieve the record set (tree model) associated with the current collection. */
     
    827769        index_dir = index_dir.getParentFile();
    828770        if(index_dir.exists()) {
    829            DebugStream.println("Old Index = " + index_dir.getAbsolutePath()+", testing for deletability");
    830            if (!canDelete(index_dir)) {
    831            // tell the user
    832            JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Delete_Index"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    833            // tell the gui manager
    834            // a message for the building log
    835            GShellEvent event = new GShellEvent(this, 0, GShell.IMPORT, Dictionary.get("CollectionManager.Cannot_Delete_Index_Log"), GShell.ERROR);
    836            Gatherer.g_man.create_pane.message(event);
    837            event = new GShellEvent(this, 0, GShell.IMPORT, "", GShell.ERROR);
    838            Gatherer.g_man.create_pane.processComplete(event);
    839            importing = false;
    840            return;
    841            }
    842            
     771        DebugStream.println("Old Index = " + index_dir.getAbsolutePath()+", testing for deletability");
     772        if (!canDelete(index_dir)) {
     773            // tell the user
     774            JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Delete_Index"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     775            // tell the gui manager
     776            // a message for the building log
     777            GShellEvent event = new GShellEvent(this, 0, GShell.IMPORT, Dictionary.get("CollectionManager.Cannot_Delete_Index_Log"), GShell.ERROR);
     778            Gatherer.g_man.create_pane.message(event);
     779            event = new GShellEvent(this, 0, GShell.IMPORT, "", GShell.ERROR);
     780            Gatherer.g_man.create_pane.processComplete(event);
     781            importing = false;
     782            return;
     783        }
    843784        }
    844785
     
    879820    }
    880821
     822
     823    public void importMetadataSet(MetadataSet external_metadata_set)
     824    {
     825    // Copy the .mds file into the collection's "metadata" folder...
     826    File external_metadata_set_file = external_metadata_set.getMetadataSetFile();
     827
     828    // ...but not if it is the redundant "hidden.mds" file
     829    if (external_metadata_set_file.getName().equals("hidden.mds")) {
     830        return;
     831    }
     832
     833    // ...and only if it doesn't already exist
     834    File metadata_set_file = new File(getCollectionMetadata(), external_metadata_set_file.getName());
     835    if (!metadata_set_file.exists()) {
     836        try {
     837        Gatherer.f_man.getQueue().copyFile(external_metadata_set_file, metadata_set_file, null);
     838        }
     839        catch (Exception ex) {
     840        ex.printStackTrace();
     841        }
     842
     843        // Load it into the MetadataSetManager
     844        MetadataSetManager.loadMetadataSet(metadata_set_file);
     845    }
     846    }
     847
     848
    881849    /** Determine if we are currently in the middle of importing (and thus, in this case, we can't allow the log writer to exit). Boy was this a mission to track down. The cascade of crap rolls out something like this: Joe Schmo clicks 'Build Collection', which calls the importCollection() method above, which in turn saves the collection with a saveTask, which fires a collectionChanged message once its finished, which drives the list of logs shown on the create pane to update, which fires a itemChanged() event to the OptionsPane who dutifully tells the current log writer thread to finish up writing (all zero lines its been asked to write) and then die. Wereapon Joe Schmo gets a pretty log to look at, but it isn't actually being written to file so the next time he tries to view it faeces hits the air motion cooling device. Joy.
    882850     * @return true if the gli is currently importing
     
    891859     * @see org.greenstone.gatherer.Gatherer
    892860     * @see org.greenstone.gatherer.collection.Collection
    893      * @see org.greenstone.gatherer.msm.MetadataSetManager
    894      * @see org.greenstone.gatherer.msm.MSMListener
    895861     * @see org.greenstone.gatherer.util.Utility
    896862     */
    897     public boolean loadCollection(String location) {
    898     DebugStream.println("Load Collection '" + location + "'");
    899     String[] args2 = new String[1];
    900     args2[0] = location;
    901     boolean result = false;
     863    public boolean loadCollection(String location)
     864    {
     865    DebugStream.println("Loading collection " + location + "...");
    902866    boolean non_gatherer_collection = false;
     867
    903868    // Check we have actually been given a .col file.
    904     if(!location.endsWith(".col")) {
    905         JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Not_Col_File", args2), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     869    if (!location.endsWith(".col")) {
     870        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Not_Col_File", location), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    906871        DebugStream.println("CollectionManager.loadCollection: Haven't been given a .col file.");
    907872        return false;
    908873    }
     874
    909875    // Check that there is the collection configuration file available
    910 
    911876    File collection_file = new File(location);
    912877    // Ensure that the directory exists.
    913878    File collection_directory = collection_file.getParentFile();
    914     if(!collection_directory.exists()) {
     879    if (!collection_directory.exists()) {
    915880        // we cant open this
    916881        collection_directory = null;
     
    926891
    927892    // Special case of a user trying to open an old greenstone collection.
    928     File metadata_directory = new File(collection_directory, Utility.META_DIR);
    929     if(!metadata_directory.exists()) {
    930 
    931         DebugStream.println("CollectionManager.loadCollection: trying to load up a non-gatherer collection");
     893    File collection_metadata_directory = new File(collection_directory, Utility.META_DIR);
     894    if (!collection_metadata_directory.exists()) {
     895        DebugStream.println("Loading non-gatherer collection...");
    932896        non_gatherer_collection = true;
    933897    }
    934898
     899    // Now determine if a lock already exists on this collection.
    935900    String name = collection_directory.getName();
    936901    File lock_file = new File(collection_file.getParentFile(), LOCK_FILE);
    937     // Now determine if a lock already exists on this collection.
    938     int choice = LockFileDialog.YES_OPTION;
    939     if(lock_file.exists()) {
     902    if (lock_file.exists()) {
    940903        LockFileDialog dialog = new LockFileDialog(Gatherer.g_man, name, lock_file);
    941         choice = dialog.getChoice();
     904        int choice = dialog.getChoice();
    942905        dialog.dispose();
    943906        dialog = null;
    944     }
    945 
    946     if(choice != LockFileDialog.YES_OPTION) {
    947         // user has cancelled
    948         lock_file = null;
    949         collection_directory = null;
    950         collection_config_file = null;
    951         return false;
    952     }
    953 
    954 
     907
     908        if (choice != LockFileDialog.YES_OPTION) {
     909        // user has cancelled
     910        lock_file = null;
     911        collection_directory = null;
     912        collection_config_file = null;
     913        return false;
     914        }
     915
     916        lock_file.delete();
     917    }
     918
     919    boolean result = false;
    955920    try {
    956         if(lock_file.exists()) {
    957         lock_file.delete();
    958         }
    959921        // Create a lock file.
    960922        createLockFile(lock_file);
     
    964926        System.err.println("Cannot write lock file!");
    965927        String args[] = new String[2];
    966         args[0] = args2[0];
     928        args[0] = location;
    967929        args[1] = Dictionary.get("FileActions.Write_Not_Permitted_Title");
    968930        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open_With_Reason", args), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     
    970932        return false;
    971933        }
     934
    972935        // Open the collection file
    973936        this.collection = new Collection(collection_file);
     
    975938        collection = null;
    976939        // Remove lock file
    977         if(lock_file.exists()) {
     940        if (lock_file.exists()) {
    978941            lock_file.delete();
    979942        }
     
    981944        }
    982945
    983         collection.msm = new MetadataSetManager();
    984         msm = collection.msm; // Legacy
    985         collection.msm.load();
    986         // if non-gatherer collection, need to add some metadata sets
     946        MetadataSetManager.clearMetadataSets();
     947        MetadataSetManager.loadMetadataSets(collection_metadata_directory);
     948
     949        ProfileXMLFileManager.loadProfileXMLFile(collection_metadata_directory);
     950 
     951        // If this is a non-GLI (legacy) collection, ask the user to choose some metadata sets
    987952        if (non_gatherer_collection) {
    988953        if (!addSomeMetadataSets(collection_directory)) {
    989             // for now - return of false means its been cancelled. Any error messages should be sent from the function itself
    990954            lock_file = null;
    991955            collection_directory = null;
     
    993957            return false;
    994958        }
    995         }
     959
     960        // Recurse the import folder tree, backing up the metadata.xml files before they are edited
     961        LegacyCollectionImporter.backupMetadataXMLFiles(collection_directory);
     962        }
     963
     964        // Read through the metadata.xml files in the import directory, building up the metadata value trees
     965        File collection_import_directory = new File(collection_directory, Utility.IMPORT_DIR);
     966        MetadataXMLFileManager.clearMetadataXMLFiles();
     967        MetadataXMLFileManager.loadMetadataXMLFiles(collection_import_directory);
     968
     969        // Read through the doc.xml files in the archives directory
     970        File collection_archives_directory = new File(collection_directory, Utility.ARCHIVES_DIR);
     971        DocXMLFileManager.clearDocXMLFiles();
     972        DocXMLFileManager.loadDocXMLFiles(collection_archives_directory);
    996973
    997974        collection.cdm = new CollectionDesignManager(collection_config_file);
    998975        if (non_gatherer_collection) {
    999         // We first recurse the Import folder tree, reading in any metadata.xml files, and then altering the non-namespaced element names to be valid GLI names
    1000         LegacyCollectionImporter lci = new LegacyCollectionImporter(collection_directory, collection.cdm);
    1001         lci.backupMetadataXMLFiles(collection_directory);
    1002         lci.importMetadata();
    1003         lci.updateClassifiers();
    1004         lci = null;
    1005         }
    1006         // Whether the collection is legacy or not, we should now be able to prepare the MetadataXMLFileManager
    1007         collection.gdm = new MetadataXMLFileManager();
     976        // Change the classifiers to use the namespaced element names
     977        LegacyCollectionImporter.updateClassifiers(collection.cdm);
     978        }
    1008979
    1009980        // Tell everyone that it worked.
    1010         String[] args = new String[1];
    1011         args[0] = name;
    1012         DebugStream.println(Dictionary.get("CollectionManager.Loading_Successful", args));
    1013         // Now we need to hook up classes that depend on messages from the metadata set manager to keep their content fresh.
    1014         collection.msm.addMSMListener(this);
     981        DebugStream.println(Dictionary.get("CollectionManager.Loading_Successful", name));
     982
    1015983        // We're done. Let everyone know.
    1016         if(Gatherer.g_man != null) {
    1017         // workspace_model = null;
     984        if (Gatherer.g_man != null) {
    1018985        Gatherer.g_man.collectionChanged(ready());
    1019986        }
    1020987        result = true;
    1021     } catch (Exception error) {
     988    }
     989    catch (Exception error) {
    1022990        // There is obviously no existing collection present.
    1023991        DebugStream.printStackTrace(error);
    1024992        if(error.getMessage() != null) {
    1025993        String[] args = new String[2];
    1026         args[0] = args2[0];
     994        args[0] = location;
    1027995        args[1] = error.getMessage();
    1028996        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open_With_Reason", args), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    1029997        }
    1030998        else {
    1031         JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open", args2), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
     999        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Cannot_Open", location), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
    10321000        }
    10331001    }
     
    10371005    collection_config_file = null;
    10381006
    1039     args2 = null;
    10401007    return result;
    10411008    }
     
    11471114    public synchronized void message(GShellEvent event) {
    11481115    }
    1149     /** Called whenever the metadata value changes in some way, such as the addition of a new value. We want to mark the collection so that it needs saving again.
    1150      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    1151      * @see org.greenstone.gatherer.collection.Collection
    1152      */
    1153     public void metadataChanged(MSMEvent event) {
    1154     // Again this change means we need to save the collection again.
    1155     collection.setSaved(false);
    1156     }
     1116
    11571117    /** This call is fired whenever a process within a GShell created by this class begins.
    11581118     * @param event A <strong>GShellEvent</strong> containing information about the GShell process.
     
    12821242    return file;
    12831243    }
     1244
     1245
     1246    public void removeMetadataSet(MetadataSet metadata_set)
     1247    {
     1248    System.err.println("Removing metadata set...");
     1249
     1250    // Delete the .mds file from the collection's "metadata" folder...
     1251    File metadata_set_file = metadata_set.getMetadataSetFile();
     1252
     1253    // ...but not if it is the "ex.mds" file
     1254    if (metadata_set_file.getName().equals("ex.mds")) {
     1255        return;
     1256    }
     1257
     1258    // ...and only if it exists
     1259    if (metadata_set_file.exists()) {
     1260        metadata_set_file.delete();
     1261
     1262        // Unload it from the MetadataSetManager
     1263        MetadataSetManager.unloadMetadataSet(metadata_set);
     1264    }
     1265    }
     1266
     1267
    12841268    /** Used to check whether all open collections have a 'saved' state.
    12851269     * @return A <i>boolean</i> which is <i>true</i> if the collection has been saved.
     
    13131297    }
    13141298
    1315     /** Method that is called whenever the metadata set collection changes in some way, such as the addition of a new set or the merging of two sets. We want to mark the collection so that it needs saving again.
    1316      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    1317      * @see org.greenstone.gatherer.collection.Collection
    1318      */
    1319     public void setChanged(MSMEvent event) {
    1320     // Invalidate saved
    1321     collection.setSaved(false);
    1322     }
    1323 
    13241299    public void setClosingThread(boolean set) {
    13251300    if(set) {
     
    13311306    }
    13321307
    1333     /** Updates the given workspace tree model to reference the private cache of the currently loaded collection. */
    1334     /* private void updatePrivateWorkspace(DefaultTreeModel model) {
    1335     // Add Private workspace if a collection has been loaded.
    1336     if(ready() && !Configuration.get("workflow.mirror", true)) {
    1337         FileNode root = (FileNode)model.getRoot();
    1338                 // Remove old private workspace
    1339         FileNode old = (FileNode)model.getChild(root, 2);
    1340         model.removeNodeFromParent(old);
    1341                 // Create and insert new.
    1342         FileNode private_workspace = new FileNode(new File(getCollectionCache()), Dictionary.get("Tree.Private"));
    1343         model.insertNodeInto(private_workspace, root, 2);
    1344     }
    1345     } */
    1346     /** Called whenever the value tree of an metadata element changes in some way, such as the addition of a new value. We want to mark the collection so that it needs saving again.
    1347      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    1348      * @see org.greenstone.gatherer.collection.Collection
    1349      */
    1350     public void valueChanged(MSMEvent event) {
    1351     collection.setSaved(false);
    1352     }
    13531308
    13541309    /** 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 should be added back in and finished. [kjdon] */
     
    13641319
    13651320    /*if (meta_choice == ExternalCollectionPrompt.NEW_META_SET) {
    1366         NewMetaSetPrompt nmsp = new NewMetaSetPrompt();
    1367         if (nmsp.isCancelled()) {
    1368         return false;
    1369 }
    1370         String namespace_str = nmsp.getNamespace();
    1371         String name_str = nmsp.getName();
    1372         MetadataSet set = Gatherer.c_man.msm.addSet(namespace_str, name_str);
    1373     } else if (meta_choice == ExternalCollectionPrompt.EXISTING_META_SET) {
     1321      NewMetaSetPrompt nmsp = new NewMetaSetPrompt();
     1322      if (nmsp.isCancelled()) {
     1323      return false;
     1324      }
     1325      String namespace_str = nmsp.getNamespace();
     1326      String name_str = nmsp.getName();
     1327      // MetadataSet set = Gatherer.c_man.msm.addSet(namespace_str, name_str);
     1328      } else if (meta_choice == ExternalCollectionPrompt.EXISTING_META_SET) {
    13741329    */
    13751330    // now we reuse the newcoll metadata prompt for the user to select metadata sets
     
    13811336    // Import default metadata sets if any.
    13821337    for(int i = 0; metadata_sets != null && i < metadata_sets.size(); i++) {
    1383         MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
    1384         collection.msm.importMDS(metadata_set.getFile(), false);
    1385     }
    1386     /*} else {
    1387       return false;
    1388       }*/
     1338        importMetadataSet((MetadataSet) metadata_sets.get(i));
     1339    }
     1340
    13891341    // Always import the extracted metadata set
    1390     collection.msm.importMDS(new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION), false);
     1342    File extracted_metadata_set_file = new File(Utility.METADATA_DIR + Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION);
     1343    importMetadataSet(new MetadataSet(extracted_metadata_set_file));
    13911344
    13921345    return true;
    13931346    }
    13941347
    1395 
    1396 //      // now try to load in existing metadata, delete the existing metadata.xml files, then save the new ones.
    1397 //      private boolean findAndLoadExistingMetadata(File collection_dir)
    1398 //      {
    1399 //      TreeModel collection_tree = getRecordSet();
    1400 //      FileNode root_node = (FileNode) collection_tree.getRoot();
    1401 //      if (searchForMetadata(collection_tree, root_node) == false) {
    1402 //          return false;
    1403 //      }
    1404 //      collection.gdm.save(root_node);
    1405 //      return true;
    1406 //      }
    14071348
    14081349    // used as arg in the perl scripts
     
    14231364    }
    14241365
     1366
    14251367    /** Install collection by moving its files from building to index after a successful build.
    14261368     * @see org.greenstone.gatherer.Gatherer
    14271369     * @see org.greenstone.gatherer.util.Utility
    14281370     */
    1429     private boolean installCollection() {
     1371    private boolean installCollection()
     1372    {
    14301373    DebugStream.println("Build complete. Moving files.");
    14311374
     
    15061449
    15071450
    1508     private boolean searchArchivesForMetadata(File archive_directory) {
    1509     /** @todo - ensure GreenstoneArchiveParser works as expected. */
    1510     return true;
    1511     }
    1512 
    1513     /** now this returns true if successful, false if unsuccessful or cancelled */
    1514     private boolean searchForMetadata(File current_file) {
    1515     boolean success = true;
    1516        if(current_file.isFile() && current_file.getName().equals(Utility.METADATA_XML)) {
    1517            success = collection.msm.searchForMetadata(null, new FileNode(current_file), false, true); // A dummy run only.
    1518        }
    1519        else {
    1520            File[] children_files = current_file.listFiles();
    1521            for(int i = 0; success && children_files != null && i < children_files.length; i++) {
    1522                success = searchForMetadata(children_files[i]);
    1523            }
    1524        }
    1525        return success;
    1526      }
    1527    
    1528     private boolean searchForMetadata(TreeModel collection_tree, FileNode current_node) {
    1529     File source_file = current_node.getFile();
    1530     String source_file_name = source_file.getName();
    1531     if (source_file_name.equals(Utility.METADATA_XML) || source_file_name.equals("CVS")) {
    1532         return true;
    1533     }
    1534     if (collection.msm.searchForMetadata(current_node, current_node, false)== false) {
    1535         return false;
    1536     }
    1537     int num_children = collection_tree.getChildCount(current_node);
    1538     for (int i=0; i<num_children; i++) {
    1539         FileNode child = (FileNode)collection_tree.getChild(current_node, i);
    1540         if (searchForMetadata(collection_tree, child)==false) {
    1541         return false;
    1542         }
    1543     }
    1544     return true;
    1545     }
    1546 
    1547     private void updateCollectionCFG(File base_cfg, File new_cfg, String description, String email, String title) {
     1451    private void updateCollectionCFG(File base_cfg, File new_cfg, String description, String email, String title)
     1452    {
    15481453    boolean first_name = true;
    15491454    boolean first_extra = true;
    15501455    String collection_path = (base_cfg.getParentFile().getParentFile()).getAbsolutePath();
    1551    
    1552     HashMap mappings = collection.msm.profiler.getActions(collection_path);
    1553     if(mappings == null) {
    1554         DebugStream.println("Mappings is null, which is odd. Leaving all configuration commands which use metadata as they are.");
    1555     }
    1556    
     1456
    15571457    // 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.
    15581458    try {
     
    16201520                text.append(token);
    16211521                String temp_metadata = tokenizer.nextToken();
    1622                 String replacement = null;
    1623                 if(mappings != null) {
    1624                     replacement = (String) mappings.get(temp_metadata);
    1625                 }
    1626                 if(replacement != null) {
     1522                String replacement = ProfileXMLFileManager.getMetadataElementFor(temp_metadata);
     1523                if (replacement != null && !replacement.equals("")) {
    16271524                    token = replacement;
    16281525                    old_metadata = temp_metadata;
     
    16411538                text.append(token);
    16421539                String temp_metadata = tokenizer.nextToken();
    1643                 String replacement = null;
    1644                 if(mappings != null) {
    1645                     replacement = (String) mappings.get(temp_metadata);
    1646                 }
    1647                 if(replacement != null) {
     1540                String replacement = ProfileXMLFileManager.getMetadataElementFor(temp_metadata);
     1541                if (replacement != null && !replacement.equals("")) {
    16481542                    token = replacement;
    16491543                }
     
    16811575            old_metadata = null;
    16821576            write(out, command);
    1683          } else {
    1684              // the rest of the commands just want a string - we read in all the tokens from the tokeniser and get rid of it.
     1577        } else {
     1578            // the rest of the commands just want a string - we read in all the tokens from the tokeniser and get rid of it.
    16851579            StringBuffer new_command = new StringBuffer(command_type_str);
    16861580            while (tokenizer.hasMoreTokens()) {
     
    16941588            // we really want to build up the whole command here
    16951589            boolean format_command = command_type_str.equals(Utility.CFG_FORMAT);
    1696             // Replace mapping strings
    1697             if(mappings != null) {
    1698             for(Iterator keys = mappings.keySet().iterator(); keys.hasNext(); ) {
     1590            HashMap metadata_mapping = ProfileXMLFileManager.getMetadataMapping();
     1591            if (metadata_mapping != null) {
     1592            Iterator keys = metadata_mapping.keySet().iterator();
     1593            while (keys.hasNext()) {
    16991594                String target = (String) keys.next();
    1700                 String replacement = (String) mappings.get(target);
    1701                 if(format_command) {
    1702                 target = "\\[" + target + "\\]";
    1703                 replacement = "{Or}{[" + replacement + "]," + target + "}";
     1595                String replacement = (String) metadata_mapping.get(target);
     1596                if (replacement != null && !replacement.equals("")) {
     1597                if (format_command) {
     1598                    target = "\\[" + target + "\\]";
     1599                    replacement = "{Or}{[" + replacement + "]," + target + "}";
     1600                }
     1601                command = command.replaceAll(target, replacement);
    17041602                }
    1705                 command = command.replaceAll(target, replacement);
    17061603            }
    17071604            }
     1605
    17081606            write(out, command);
    1709          }
     1607        }
    17101608        tokenizer = null;
    17111609        }
     
    17271625    out.newLine();
    17281626    }
     1627
    17291628
    17301629    /** The CollectionManager class is getting too confusing by half so I'll implement this TreeModelListener in a private class to make responsibility clear. */
  • trunk/gli/src/org/greenstone/gatherer/collection/SaveCollectionTask.java

    r8243 r8313  
    4343import org.greenstone.gatherer.DebugStream;
    4444import org.greenstone.gatherer.Gatherer;
     45import org.greenstone.gatherer.metadata.MetadataSetManager;
    4546import org.greenstone.gatherer.util.Utility;
    4647
     
    6667    static final private int COPY_COLLECTION      = 4;
    6768    static final private int MAKE_COLLECTION      = 5;
    68     static final private int METADATA_SAVED       = 6;
    69     static final private int METADATA_XML_SAVED   = 7;
    7069    static final private int OPEN_COLLECTION      = 8;
    7170    static final private int RESTORE_COLLECTION   = 9;
     
    112111    // spd.setMillisToDecideToPopup(100);
    113112    // spd.setMillisToPopup(100);
    114     // 0. Force all remaining metadata.xml files to load.
     113
    115114    // 1. Perform a regular collection save on what we will later refer to as the origin collection.
    116115    ///ystem.err.println("1. Save origin.");
     
    119118    args[0] = collection.getName() + ".col";
    120119    try {
    121         // Block until all of the metadata files have been read in.
    122         collection.gdm.waitUntilComplete();
    123         // Write out the metadata xml files. The destroy below is meant to do this, but never does.
    124         collection.gdm.save();
    125         // spd.setProgress(getValue(METADATA_XML_SAVED));
    126 
    127120        File file = new File(tmp_loc);
    128121        // Create backup
     
    131124        backup.deleteOnExit();
    132125        if(!file.renameTo(backup)) {
    133             DebugStream.println("Error in CollectionManager.load(): FileRenamedException");
     126            DebugStream.println("Error in SaveCollectionTask.run(): FileRenamedException");
    134127        }
    135128        }
     
    143136        // spd.setProgress(getValue(COLLECTION_CFG_SAVED));
    144137
    145         // Write out the metadata files.
    146         Gatherer.c_man.msm.save();
    147         // spd.setProgress(getValue(METADATA_SAVED));
     138        // Write hfiles for the loaded metadata elements into the collection "etc" directory
     139        MetadataSetManager.writeHierarchyFiles(new File(Gatherer.c_man.getCollectionEtc()));
    148140
    149141        collection.setSaved(true);
     
    307299        return (int)((double)70 * multiplier);
    308300    case COLLECTION_CFG_SAVED:
    309     case METADATA_SAVED:
    310     case METADATA_XML_SAVED:
    311301        return (int)((double)10 * multiplier);
    312302        // Save As
     
    325315    }
    326316}
    327 
    328 
    329 
    330 
    331 
  • trunk/gli/src/org/greenstone/gatherer/file/FileQueue.java

    r8243 r8313  
    3838import org.greenstone.gatherer.gui.LongProgressBar;
    3939import org.greenstone.gatherer.gui.tree.DragTree;
     40import org.greenstone.gatherer.metadata.MetadataValue;
     41import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
    4042import org.greenstone.gatherer.util.ArrayTools;
    4143import org.greenstone.gatherer.util.DragComponent;
     
    397399                        if(job.type == FileJob.COPY) {
    398400                        // A copy is undone with a delete, so it doesn't really matter where the file originally came from (we're not moving it back there, but into the recycle bin). You may also notice we don't make use of the target parent record. This is because no undo action needs this information, and even if it did it could simply ask for records parent!
    399                         // Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_COPY, null, null, job.target, directory_record, job.undo);
    400401                        }
    401402                        else {
    402403                        // Movements however do need a source and source parent so the file can be moved back to the correct place.
    403                         // Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_MOVE, job.source, (FileNode)origin_node.getParent(), job.target, directory_record, job.undo);
    404404                        }
    405405                    }
     
    431431                    // Show warning.
    432432                    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Not_Found_Message", source_file.getName()), Dictionary.get("FileActions.File_Not_Found_Title"), JOptionPane.ERROR_MESSAGE);
    433                 // Force refresh of source folder.
     433                    // Force refresh of source folder.
    434434                    source_model.refresh(new TreePath(((FileNode)origin_node.getParent()).getPath()));
    435435                }
    436436               
    437437                // We can't have been cancelled, and we must have created a new FileNode during the above phase, before we can handle metadata.
    438                 if(!cancel_action && new_node != null) {
    439                 /* Time to handle any existing metadata. */
    440                 // If the directory came from inside our collection...
     438                if (!cancel_action && new_node != null) {
     439                    /* Time to handle any existing metadata. */
     440                    // If the directory came from inside our collection...
    441441                    if (job.source.toString().equals("Collection")) {
    442                     ///ystem.err.println("Move within collection...");
    443                     // we just retrieve the metadata attached to the origin node...
    444                     ArrayList existing_metadata = Gatherer.c_man.getCollection().gdm.getMetadataOnly(source_file);
    445                     ///atherer.println("Existing metadata for " + origin_node + ": " + gdm.toString(existing_metadata));
    446                     // then assign this remainder to the new folder.
    447                     ///ystem.err.println("New metadata: " + gdm.toString(existing_metadata));
    448                     Gatherer.c_man.getCollection().gdm.addMetadata(new_node, existing_metadata);
    449                     existing_metadata = null;
    450                     }
    451                 // If it came from the recycle bin retrieve the metadata from there, once again remembering to account for inherited metadata
    452 //                      else if (job.source.toString().equals("Undo")) {
    453 //                      // Retrieve metadata from the recycle bin
    454 //                      ArrayList existing_metadata = Gatherer.c_man.undo.getMetadata(source_file);
    455 //                      // then assign this remainder to the new folder.
    456 //                      Gatherer.c_man.getCollection().gdm.addMetadata(new_node, existing_metadata);
    457 //                      existing_metadata = null;
    458 //                      }
    459                 // Otherwise if it came from the workspace use the MSMs parsers to search for folder level metadata (such as metadata.xml or marc records).
     442                    // System.err.println("Move within collection...");
     443
     444                    // Get the non-folder level metadata assigned to the origin node...
     445                    ArrayList assigned_metadata = MetadataXMLFileManager.getMetadataAssignedDirectlyToFile(source_file);
     446                    // ...and remove it from the original node and assign it to the new folder
     447                    for (int i = 0; i < assigned_metadata.size(); i++) {
     448                        MetadataValue metadata_value = (MetadataValue) assigned_metadata.get(i);
     449                        MetadataXMLFileManager.removeMetadata(origin_node, metadata_value);
     450                        MetadataXMLFileManager.addMetadata(new_node, metadata_value);
     451                    }
     452                    }
     453                    // If it came from the workspace search for metadata assigned to the file
    460454                    else if (job.source.toString().equals("Workspace")) {
    461                     cancel_action = !Gatherer.c_man.getCollection().msm.searchForMetadata(new_node, origin_node, job.folder_level);
     455                    ArrayList assigned_metadata = MetadataXMLFileManager.getMetadataAssignedDirectlyToExternalFile(origin_node.getFile());
     456                    for (int i = 0; i < assigned_metadata.size(); i++) {
     457                        MetadataValue metadata_value = (MetadataValue) assigned_metadata.get(i);
     458                        MetadataXMLFileManager.addMetadata(new_node, metadata_value);
     459                    }   
    462460                    }
    463461                }
     
    475473            }
    476474
    477             // If the source is an empty directory or a file. Don't do anything to the root node of a tree.
     475            // If the source is a file or an empty directory (but not the root node of a tree)
    478476            File[] child_list = source_file.listFiles();
    479             if(source_file.isFile() || (child_list != null && (child_list.length == 0 || (child_list.length == 1 && child_list[0].getName().equals(Utility.METADATA_XML))) && origin_node.getParent() != null)) {
    480                 ///atherer.println("File or empty directory.");
    481                 // Delete any metadata.xml still in the directory.
    482                 if(child_list != null && child_list.length == 1) {
    483                 child_list[0].delete();
    484                 }
    485 
    486                 ///atherer.println("Origin is file or is directory and is empty.");
    487                 // update status area
     477            if (source_file.isFile() || (child_list != null && child_list.length == 0 && origin_node.getParent() != null)) {
     478                // System.err.println("Deleting file: " + source_file.getAbsolutePath());
     479
     480                // Update status area
    488481                String args[] = new String[1];
    489                 // args[0] = "" + (queue.size() + 1) + "";
    490482                args[0] = Utility.formatPath("FileActions.Deleting", source_file.getAbsolutePath(), file_status.getSize().width);
    491483                file_status.setText(Dictionary.get("FileActions.Deleting", args));
    492                 args = null;
    493 
    494                 // Remove its metadata
    495                 ArrayList metadatum = null;
    496 //                  if(job.source == Gatherer.c_man.undo) {
    497 //                  Gatherer.c_man.undo.addMetadata(target_file, metadatum);
    498 //                  }
    499 //                  else {
    500                 metadatum = Gatherer.c_man.getCollection().gdm.removeMetadata(origin_node.getFile());
    501                 // }
    502                 // determine its parent node
    503                 FileNode parent_record = (FileNode)origin_node.getParent();
     484
     485                // If it is a metadata.xml file, we must unload it
     486                if (source_file.getName().equals(Utility.METADATA_XML)) {
     487                MetadataXMLFileManager.unloadMetadataXMLFile(source_file);
     488                }
     489
     490                // Remove the metadata assigned directly to the file
     491                ArrayList assigned_metadata = MetadataXMLFileManager.getMetadataAssignedDirectlyToFile(origin_node.getFile());
     492                for (int i = 0; i < assigned_metadata.size(); i++) {
     493                MetadataValue metadata_value = (MetadataValue) assigned_metadata.get(i);
     494                MetadataXMLFileManager.removeMetadata(origin_node, metadata_value);
     495                }
     496
    504497                // Remove from model
    505                 if(parent_record != null) {
     498                FileNode parent_record = (FileNode) origin_node.getParent();
     499                if (parent_record != null) {
    506500                SynchronizedTreeModelTools.removeNodeFromParent(source_model, origin_node);
    507501                }
    508                 // If we are deleting
    509                 File recycled_file = null;
    510                 FileNode recycled_parent = null;
    511                 // delete the source file
     502
     503                // Delete the source file
    512504                Utility.delete(source_file);
    513505            }
  • trunk/gli/src/org/greenstone/gatherer/gui/EnrichPane.java

    r8262 r8313  
    3737package org.greenstone.gatherer.gui;
    3838
     39
    3940import java.awt.*;
    4041import java.awt.event.*;
     
    4243import java.util.*;
    4344import javax.swing.*;
    44 import javax.swing.border.*;
    4545import javax.swing.event.*;
    4646import javax.swing.table.*;
     
    5151import org.greenstone.gatherer.Gatherer;
    5252import org.greenstone.gatherer.file.FileNode;
    53 import org.greenstone.gatherer.gui.table.GTableModel;
    54 import org.greenstone.gatherer.gui.table.TableCellRenderer;
    5553import org.greenstone.gatherer.gui.tree.DragTree;
    56 import org.greenstone.gatherer.msm.ElementWrapper;
    57 import org.greenstone.gatherer.msm.Metadata;
    58 import org.greenstone.gatherer.msm.MSMEvent;
    59 import org.greenstone.gatherer.msm.MSMListener;
    60 import org.greenstone.gatherer.util.Codec;
     54import org.greenstone.gatherer.metadata.MetadataElement;
     55import org.greenstone.gatherer.metadata.MetadataValue;
     56import org.greenstone.gatherer.metadata.MetadataValueTableEntry;
     57import org.greenstone.gatherer.metadata.MetadataValueTableModel;
     58import org.greenstone.gatherer.metadata.MetadataValueTreeModel;
     59import org.greenstone.gatherer.metadata.MetadataValueTreeNode;
     60import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
    6161import org.greenstone.gatherer.util.DragGroup;
    6262import org.greenstone.gatherer.util.PatternTokenizer;
    63 import org.greenstone.gatherer.util.StaticStrings;
    6463import org.greenstone.gatherer.util.TreeSynchronizer;
    6564import org.greenstone.gatherer.util.Utility;
    66 import org.greenstone.gatherer.valuetree.GValueModel;
    67 import org.greenstone.gatherer.valuetree.GValueNode;
    68 /** Provides a view of controls for the editing of metadata. It makes use of several other important components such as a GTree, GTable and GValueTree. While much of the gui content is left to these components, the EnrichPane is resposible for actioning metadata edit requests, listing for mouse clicks within its scope and other data functionality (such as providing a list of the selected files).
    69 * @author John Thompson, Greenstone Digital Libraries, University of Waikato
    70 * @version 2.3b
    71 */
     65
     66
     67/** Provides a view of controls for the editing of metadata. It makes use of several other important components such as a GTree, GTable and MetadataValueTree. While much of the gui content is left to these components, the EnrichPane is resposible for actioning metadata edit requests, listing for mouse clicks within its scope and other data functionality (such as providing a list of the selected files).
     68 */
    7269public class EnrichPane
    7370    extends JPanel
    74     implements ActionListener, ListSelectionListener, TreeSelectionListener, MSMListener {
     71    implements ActionListener, TreeSelectionListener {
    7572
    7673    static private Dimension BUTTON_SIZE = new Dimension(190, 25);
     
    8077    static private Dimension TREE_SIZE = new Dimension(250, 500);
    8178    static private int MINIMUM_TABLE_HEADER_SIZE = 15;
    82     /** The name of the panel containing the metadata table. */
    83     static final private String CARD_ONE  = "Card One";
    84     /** The name of the panel containing the 'no file' placeholder for the metadata table. */
    85     static final private String CARD_TWO = "Card Two";
    86     /** The name of the panel containing the 'no metadata' placeholder for the metadata table. */
    87     static final private String CARD_ZERO = "Card Zero";
    88     /** The name of the panel containing the placeholder for the value tree. */
    89     static final private String TOOLS_OFF = "Tools Off";
    90     /** The name of the panel containing the value tree. */
    91     static final private String TOOLS_ON  = "Tools On";
    92 
    93     /** The GValueTree graphically shows the available metadata that has been previously assigned, and provides controls for adding, updating and removing metadata, depending on the users selections in the other important components. */
    94     private GValueTree tree = null;
    95     /** The layout manager used to display either the GTable (when records are selected) or a placeholder panel with the immortal words 'No Record Selected'. */
    96     private CardLayout card_layout = null;
    97     /** The layout manager used to display either the GValueTree (when records are selected) or a placeholder panel with the immortal words 'No Record Selected'. */
    98     private CardLayout card_layout2 = null;
     79
     80    private MetadataValueTable metadata_value_table = null;
     81    /** The layout manager used to display either the MetadataValueTable (when files are selected) or a placeholder panel */
     82    private CardLayout metadata_value_table_card_layout = null;
     83    /** The name of the panel containing the metadata table */
     84    static final private String TABLE_CARD = "";
     85    /** The name of the panel containing the "no files selected" placeholder for the metadata table */
     86    static final private String TABLE_CARD_NO_FILES_SELECTED = "No files selected";
     87    /** The name of the panel containing the "no metadata available" placeholder for the metadata table */
     88    static final private String TABLE_CARD_NO_METADATA_AVAILABLE = "No metadata available";
     89
     90    /** The MetadataValueTree graphically shows the available metadata that has been previously assigned, and provides controls for adding, updating and removing metadata, depending on the user's selections in the other important components. */
     91    private MetadataValueTree metadata_value_tree = null;
     92    /** The layout manager used to display either the MetadataValueTree (when metadata is selected) or a placeholder panel */
     93    private CardLayout metadata_value_tree_card_layout = null;
     94    /** The name of the panel containing the metadata value tree */
     95    static final private String TREE_CARD = "";
     96    /** The name of the panel containing the "no metadata element selected" placeholder for the metadata table */
     97    static final private String TREE_CARD_NO_METADATA_ELEMENT_SELECTED  = "No metadata element selected";
     98
    9999    /** Used to dynamically filter the collection tree at user request. Note that this is synchronized with the collection tree filter in the Gather view. */
    100100    private Filter filter = null;
    101     /** The data model behind the GTable, to which we hold a reference for convenient access. */
    102     private GTableModel model = null;
    103     /** The currently reported selection. Note that this may actually be incorrect, but if so the changed flag will be set, and the selection will be updated the next time it is needed. */
    104     private FileNode records[] = null;
     101    /** The currently reported selection. */
     102    private FileNode[] file_nodes = null;
    105103    /** The button, which when clicked, adds metadata to the selected records. */
    106104    private JButton add;
     
    120118    /** The splitpane dividing the collection tree and the metadata based controls. */
    121119    private JSplitPane external_split;
    122     /** A reference to the metadata table, via its superclass. */
    123     private JTable table;
    124120    /** The label shown at the top of the metadata table detailing the current selection statistics. */
    125121    private JTextField table_label;
    126122    /** A reference to the collection tree. */
    127123    private DragTree collection_tree;
    128     /** The currently selected metadata determined by listening to every second list selection event from the metadata table. */
    129     private Metadata selected_metadata;
    130124    /** Provide synchronization between the collection trees in this view and the collection pane view. */
    131125    private TreeSynchronizer tree_sync = null;
     126    private boolean metadata_edit_event = false;
     127
    132128
    133129    /** Constructor.
    134130     * @param tree_sync The <strong>TreeSynchronizer</strong> to be used on the collection tree
    135      * @see org.greenstone.gatherer.Configuration
    136      * @see org.greenstone.gatherer.gui.EnrichPane.GValueTree
    137131     */
    138132    public EnrichPane(TreeSynchronizer tree_sync)
    139133    {
    140     this.tree = null;
    141134    this.tree_sync = tree_sync;
    142135
     
    176169    Dictionary.registerBoth(expand_for_extracted, "MetaEdit.Expand", "MetaEdit.Expand_Tooltip");
    177170
    178     tree = new GValueTree(CONTROL_SIZE.width, CONTROL_SIZE.height);
     171    metadata_value_table = new MetadataValueTable();
     172    metadata_value_tree = new MetadataValueTree(CONTROL_SIZE.width, CONTROL_SIZE.height);
    179173    }
    180174
     
    182176    /** Called whenever an action occurs on one of our registered buttons.
    183177     * @param event An <strong>ActionEvent</strong> containing information about the event.
    184      * @see org.greenstone.gatherer.collection.CollectionManager
    185      * @see org.greenstone.gatherer.gui.EnrichPane.GValueTree
    186      * @see org.greenstone.gatherer.gui.table.GTableModel
    187      * @see org.greenstone.gatherer.msm.ElementWrapper
    188      * @see org.greenstone.gatherer.msm.MetadataSetManager
    189      * @see org.greenstone.gatherer.msm.MSMEvent
    190178     */
    191     public void actionPerformed(ActionEvent event) {
     179    public void actionPerformed(ActionEvent event)
     180    {
    192181    Object esrc = event.getSource();
     182
     183    // Add button pressed
    193184    if (esrc == add) {
    194         ElementWrapper element = tree.getSelectedMetadataElement();
    195         String value = tree.getSelectedValue();
    196         (new AppendMetadataTask(element, value)).start();
    197         value = null;
    198         element = null;
    199     }
     185        MetadataElement metadata_element = metadata_value_table.getSelectedMetadataElement();
     186        MetadataValueTreeNode metadata_value_tree_node = metadata_element.addMetadataValue(metadata_value_tree.getSelectedValue());
     187        MetadataValue metadata_value = new MetadataValue(metadata_element, metadata_value_tree_node);
     188        metadata_value.setIsAccumulatingMetadata(true);
     189        (new AppendMetadataTask(metadata_value)).start();
     190    }
     191
     192    // Replace button pressed
    200193    else if (esrc == update) {
    201         ElementWrapper element = tree.getSelectedMetadataElement();
    202         String value = tree.getSelectedValue();
    203         (new UpdateMetadataTask(element, value)).start();
    204         value = null;
    205         element = null;
    206     }
     194        MetadataElement metadata_element = metadata_value_table.getSelectedMetadataElement();
     195        MetadataValueTreeNode metadata_value_tree_node = metadata_element.addMetadataValue(metadata_value_tree.getSelectedValue());
     196        MetadataValue metadata_value = new MetadataValue(metadata_element, metadata_value_tree_node);
     197        metadata_value.setIsAccumulatingMetadata(!metadata_value_table.getSelectedMetadataValueTableEntry().isInheritedMetadata());
     198        (new UpdateMetadataTask(metadata_value)).start();
     199    }
     200
     201    // Remove button pressed
    207202    else if (esrc == remove) {
    208203        (new RemoveMetadataTask()).start();
    209204    }
     205
     206    // Expand button pressed
    210207    else if (esrc == expand) {
    211208        EditorDialog ed = new EditorDialog();
    212         String temp = ed.display(tree.getSelectedValue());
    213         if (temp != null) {
    214         tree.setSelectedValue(temp);
    215         }
    216     }
     209        String new_metadata_value = ed.display(metadata_value_tree.getSelectedValue());
     210        if (new_metadata_value != null) {
     211        metadata_value_tree.setSelectedValue(new_metadata_value);
     212        }
     213    }
     214
     215    // Expand button for extracted metadata pressed
    217216    else if (esrc == expand_for_extracted) {
    218217        EditorDialog ed = new EditorDialog();
    219218        ed.setEditable(false);
    220         String temp = ed.display(selected_metadata.getValue());
    221     }
    222     validateControls();
    223     }
    224 
    225     private class AppendMetadataTask
    226     extends Thread {
    227 
    228     private ElementWrapper element = null;
    229     private String value = null;
    230 
    231     private AppendMetadataTask(ElementWrapper element, String raw_value) {
    232         this.element = element;
    233         this.value = raw_value;
    234         // 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
    235         //this.value = /odec.transform(value, /odec.ENCODE_PATH);
    236         //this.value = /odec.transform(this.value, /odec.REMOVE_SQUARE_BRACKET);
    237         //this.value = /odec.transform(this.value, /odec.TEXT_TO_DOM);
    238     }
    239 
    240     public void run() {
    241         // System.err.println("Add metadata - '" + value + "'");
    242         // Check the new metadata is valid
    243         if (records != null && element != null && value != null) {
    244         // Check the records, and if they are folders then display the warning.
    245         Metadata added_metadata = null;
    246         if (!records[0].isLeaf()) {
    247             WarningDialog dialog = new WarningDialog("warning.DirectoryLevelMetadata", true);
    248             if (dialog.display() == JOptionPane.OK_OPTION) {
    249             added_metadata = Gatherer.c_man.getCollection().msm.addMetadata(System.currentTimeMillis(), records, element, value);
    250             }
    251             dialog.dispose();
    252             dialog = null;
    253         }
    254         else {
    255             added_metadata = Gatherer.c_man.getCollection().msm.addMetadata(System.currentTimeMillis(), records, element, value);
    256         }
    257         model.selectMetadataWhenBuildingComplete(added_metadata);
    258         }
    259     }
    260     }
    261 
    262     private class UpdateMetadataTask
    263     extends Thread {
    264 
    265     private ElementWrapper element;
    266     private String value;
    267 
    268     private UpdateMetadataTask(ElementWrapper element, String raw_value) {
    269         this.element = element;
    270         this.value = raw_value;
    271         // Transform the raw text to be DOM compatible - as that will be its next destination immediately after being added to the value model
    272         //this.value = /odec.transform(value, /odec.REMOVE_SQUARE_BRACKET);
    273         //this.value = /odec.transform(this.value, /odec.TEXT_TO_DOM);
    274     }
    275 
    276     public void run() {
    277         // You can only update if there is a selected_metadata and
    278         // you have valid values in all fields.
    279         DebugStream.println("Replacing value:");
    280         if (selected_metadata != null && records != null && element != null && value != null) {
    281         selected_metadata = Gatherer.c_man.getCollection().msm.updateMetadata(System.currentTimeMillis(), selected_metadata, records, value, MetaEditPrompt.CONFIRM, selected_metadata.isFileLevel());
    282         }
    283         model.selectMetadataWhenBuildingComplete(selected_metadata);
    284     }
    285     }
    286 
    287     private class RemoveMetadataTask
    288     extends Thread {
    289 
    290     private RemoveMetadataTask() {}
    291 
    292     public void run() {
    293         DebugStream.println("Removing value:");
    294         if (selected_metadata != null && records != null) {
    295         Gatherer.c_man.getCollection().msm.removeMetadata(System.currentTimeMillis(), selected_metadata, records);
    296         }
    297 
    298         // Select the closest piece of metadata with the same element name
    299         model.selectClosestMetadataWhenBuildingComplete(selected_metadata);
    300     }
    301     }
     219        ed.display(metadata_value_table.getSelectedMetadataValueTableEntry().getFullValue());
     220    }
     221    }
     222
    302223
    303224    /** Some actions can only occur after this panel has been displayed on-screen, so this method is provided to do exactly that. Such actions include the proportioning of the split panes and the setting of table column widths.
    304      * @see org.greenstone.gatherer.gui.table.GTableModel
    305225     */
    306     public void afterDisplay() {
     226    public void afterDisplay()
     227    {
    307228    external_split.setDividerLocation(0.3);
    308229    }
     230
     231
    309232    /** Called whenever a significant change has occured in the state of the currently loaded collection.
    310233     * @param ready <i>true</i> if there is a collection currently ready to be editing, <i>false</i> otherwise.
     
    312235     * @see org.greenstone.gatherer.util.TreeSynchronizer
    313236     */
    314     public void collectionChanged(boolean ready) {
     237    public void collectionChanged(boolean ready)
     238    {
    315239    if (ready) {
     240        // System.err.println("In collectionChanged(true).");
    316241        TreeModel collection_model = Gatherer.c_man.getRecordSet();
    317         //String[] args = new String[1];
    318         //args[0] = Gatherer.c_man.getCollection().getName();
    319242        Dictionary.registerText(collection_label, "Collection.Collection");
     243
    320244        // Update label coloring.
    321245        collection_label.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
    322246        collection_label.setForeground(Configuration.getColor("coloring.collection_heading_foreground", false));
    323247        collection_tree.setModel(collection_model);
     248
    324249        // Update tree coloring.
    325250        collection_tree.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
    326251        collection_tree.setForeground(Configuration.getColor("coloring.collection_tree_foreground", false));
    327         // Register our msm dependant components (or correctly their models) with msm.
    328         if (model != null) {
    329         // remove the listener first - in case its already present
    330         Gatherer.c_man.getCollection().msm.removeMSMListener(model);
    331         Gatherer.c_man.getCollection().msm.addMSMListener(model);
    332         }
    333         // register the pane itself as an MSMListener, so if we add a new metadata set, it will immediately show up. - remove itself first just in case
    334         Gatherer.c_man.getCollection().msm.removeMSMListener(this);
    335         Gatherer.c_man.getCollection().msm.addMSMListener(this);
    336 
    337         // Clear the currently selected metadata element in the table
    338         // This is important so the value tree is refreshed when the collection changes
    339         tree.setSelectedMetadataElement(null);
    340252    }
    341253    else {
     
    350262    tree_sync.add(collection_tree);
    351263    }
     264
     265
    352266    /** Used to create, connect and layout the components to be shown on this control panel.
    353267     * @see org.greenstone.gatherer.Gatherer
     
    355269     * @see org.greenstone.gatherer.file.FileOpenActionListener
    356270     * @see org.greenstone.gatherer.gui.Filter
    357      * @see org.greenstone.gatherer.gui.GComboBox
    358      * @see org.greenstone.gatherer.gui.table.GTableModel
    359271     */
    360     public void display() {
    361     RightButtonListener right_button_listener = new RightButtonListener();
     272    public void display()
     273    {
    362274    // Creation
    363275    JPanel collection_pane = new JPanel(new BorderLayout());
     
    367279    external_split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
    368280
    369     ///atherer.println("\tCreating collection_label");
    370281    collection_label = new JLabel();
    371282    Dictionary.registerText(collection_label, "Collection.No_Collection");
     
    375286    TreeModel collection_model = Gatherer.c_man.getRecordSet();
    376287    if (collection_model != null) {
    377         collection_tree = new DragTree("MetaEdit", collection_model, null, false);
     288        collection_tree = new DragTree("Enrich", collection_model, null, false);
    378289    }
    379290    else {
    380         collection_tree = new DragTree("MetaEdit", null, false);
     291        collection_tree = new DragTree("Enrich", null, false);
    381292    }
    382293    group.add(collection_tree);
     
    384295    collection_tree.putClientProperty("JTree.lineStyle", "Angled");
    385296    collection_tree.addMouseListener(Gatherer.g_man.foa_listener);
    386     collection_tree.addMouseListener(right_button_listener);
     297    collection_tree.addMouseListener(new RightButtonListener());
    387298    collection_tree.addTreeSelectionListener(this);
    388299    collection_tree.addTreeExpansionListener(Gatherer.g_man.foa_listener);
    389300    collection_tree.setLargeModel(true);
    390301    collection_tree.setRootVisible(false);
    391    
     302
    392303    KeyListenerImpl key_listener = new KeyListenerImpl();
    393304    collection_tree.addKeyListener(key_listener);
     
    398309    filter.setEditable(Configuration.getMode() > Configuration.LIBRARIAN_MODE);
    399310    Dictionary.registerTooltip(filter.getComboBox(), "Collection.Filter_Tooltip");
    400 
    401     // Connection
    402311
    403312    // Layout
     
    432341    Dictionary.registerText(table_label, "MetaEdit.No_File");
    433342
    434     card_layout = new CardLayout();
    435 
    436343    table_card_pane = new JPanel();
    437344
     
    456363    JPanel table_pane_one = new JPanel();
    457364
    458     ///atherer.println("\tCreating metadata_table");
    459     table = new JTable();
    460     model = new GTableModel(table);
    461     table.setModel(model);
    462     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    463     table.getSelectionModel().addListSelectionListener(this);
    464     table.setColumnSelectionAllowed(false);
    465 
    466     // The default JTable doesn't quite have the desired properties - when a
    467     // table cell is clicked on, the table is scrolled so the cell is as
    468     // visible as possible. This means that the left-most cells can become
    469     // hidden. To fix this, the MouseInputHandler in BasicTableUI is removed
    470     // as a MouseListener on the table, and a very slightly altered copy is
    471     // added in its place (TableMouseInputHandler).
    472     MouseListener[] mls = table.getMouseListeners();
    473     for (int i = 0; i < mls.length; i++) {
    474         // Remove the instances of MouseInputHandler
    475         if (mls[i].toString().startsWith("javax.swing.plaf.basic.BasicTableUI$MouseInputHandler@")) {
    476         table.removeMouseListener(mls[i]);
    477         }
    478     }
    479     // Add the slightly-altered mouse listener
    480     table.addMouseListener(new TableMouseInputHandler());
    481 
    482     // We also have to ensure that the table column header hasn't gone on a severe Jenny Craig binge and has somehow lost 7/8th of its component size (15 -> 2 pixels high).
    483     JTableHeader table_header = table.getTableHeader();
    484     Dimension table_header_preferred_size = table_header.getPreferredSize();
    485     if (table_header_preferred_size.height < MINIMUM_TABLE_HEADER_SIZE) {
    486         table_header_preferred_size.setSize(table_header_preferred_size.width, MINIMUM_TABLE_HEADER_SIZE);
    487         table_header.setPreferredSize(table_header_preferred_size);
    488     }
    489 
    490     JScrollPane table_scroll = new JScrollPane(table);
     365    JScrollPane table_scroll = new JScrollPane(metadata_value_table);
    491366    table_scroll.getViewport().setBackground(Configuration.getColor("coloring.collection_tree_background", false));
    492367    table_scroll.setOpaque(true);
    493368
     369    // Create the cards for the metadata value table
     370    metadata_value_table_card_layout = new CardLayout();
     371
     372    table_pane_zero.setLayout(new BorderLayout());
     373    table_pane_zero.add(no_file_message, BorderLayout.CENTER);
     374
     375    table_pane_one.setLayout(new BorderLayout());
     376    table_pane_one.add(table_scroll, BorderLayout.CENTER);
     377
     378    table_pane_two.setLayout(new BorderLayout());
     379    table_pane_two.add(no_metadata_message, BorderLayout.CENTER);
     380
     381    table_card_pane.setLayout(metadata_value_table_card_layout);
     382    table_card_pane.add(table_pane_zero, TABLE_CARD_NO_FILES_SELECTED);
     383    table_card_pane.add(table_pane_one, TABLE_CARD);
     384    table_card_pane.add(table_pane_two, TABLE_CARD_NO_METADATA_AVAILABLE);
     385
     386    // Create the cards for the metadata value tree
     387    metadata_value_tree_card_layout = new CardLayout();
     388
    494389    // Control pane
    495     ///atherer.println("\tCreating Metadata Controls");
    496 
    497390    control_pane = new JPanel();
    498391    control_pane.setBorder(BorderFactory.createLoweredBevelBorder());
     
    501394    control_pane.setPreferredSize(CONTROL_SIZE);
    502395
    503     card_layout2 = new CardLayout();
    504 
    505396    JPanel tools_off_pane = new JPanel();
    506397
     
    523414
    524415    tools_on_pane.setLayout(new BorderLayout());
    525     tools_on_pane.add(tree, BorderLayout.CENTER);
    526 
    527     control_pane.setLayout(card_layout2);
    528     control_pane.add(tools_off_pane, TOOLS_OFF);
    529     control_pane.add(tools_on_pane, TOOLS_ON);
     416    tools_on_pane.add(metadata_value_tree, BorderLayout.CENTER);
     417
     418    control_pane.setLayout(metadata_value_tree_card_layout);
     419    control_pane.add(tools_off_pane, TREE_CARD_NO_METADATA_ELEMENT_SELECTED);
     420    control_pane.add(tools_on_pane, TREE_CARD);
    530421
    531422    // Table components
     
    534425    table_title_pane.add(table_label, BorderLayout.CENTER);
    535426
    536     table_pane_zero.setLayout(new BorderLayout());
    537     table_pane_zero.add(no_file_message, BorderLayout.CENTER);
    538 
    539     table_pane_one.setLayout(new BorderLayout());
    540     table_pane_one.add(table_scroll, BorderLayout.CENTER);
    541 
    542     table_pane_two.setLayout(new BorderLayout());
    543     table_pane_two.add(no_metadata_message, BorderLayout.CENTER);
    544 
    545     table_card_pane.setLayout(card_layout);
    546     table_card_pane.add(table_pane_zero, CARD_ZERO);
    547     table_card_pane.add(table_pane_one, CARD_ONE);
    548     table_card_pane.add(table_pane_two, CARD_TWO);
    549 
    550427    table_pane.setLayout(new BorderLayout());
    551428    table_pane.add(table_title_pane, BorderLayout.NORTH);
     
    563440    }
    564441
    565     /** Method that is called whenever an element within a set is changed or modified. - needed for MSMListener
    566      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
     442
     443    /** Called to inform this control panel that it has just gained focus as an effect of the user clicking on its tab.
    567444     */
    568     public void elementChanged(MSMEvent event) {}
    569 
    570     /** Ensures a certain tree path is expanded, visible and selected within the collection tree.
    571      * @param path The <strong>TreePath</strong> to make visible.
    572      * @see org.greenstone.gatherer.gui.tree.DragTree
    573      */
    574     private void expandPath(TreePath path) {
    575     collection_tree.expandPath(path);
    576     collection_tree.setSelectionPath(path);
    577     }
    578     /** Called to inform this control panel that it has just gained focus as an effect of the user clicking on its tab.
    579      * @see org.greenstone.gatherer.gui.tree.DragTree
    580      */
    581     public void gainFocus() {
    582     // Use this opportunity to update the table model etc.
    583     // Select the first file (if any)
    584     if (collection_tree != null && collection_tree.getRowCount() > 0) {
    585         collection_tree.setImmediate(true);
    586         collection_tree.setSelectionRow(0);
    587         collection_tree.setImmediate(false);
    588     }
    589     else {
    590         // No selection. Reset other components
    591         valueChanged(new TreeSelectionEvent(this, null, false, null, null));
    592     }
    593 
    594     // Update the menubars idea of whats been selected
    595     if (collection_tree != null) {
    596         if (collection_tree.isSelectionEmpty()) {
    597         Gatherer.g_man.menu_bar.setMetaAuditSuffix(null);
    598         }
    599         else {
    600         Gatherer.g_man.menu_bar.setMetaAuditSuffix(collection_tree.getSelectionDetails());
    601         }
    602     }
    603     // Update the meta-audit view to show the current selection, if any.
    604     Gatherer.g_man.meta_audit.setRecords(records);
    605     }
    606 
    607     /** Retrieve the currently selected records.
    608      * @return A <strong>FileNode[]</strong> containing the current, and up to date, selection.
    609      */
    610     public FileNode[] getSelectedNode() {
    611     return records;
    612     }
    613 
    614     /** Called whenever the metadata value changes in some way, such as the addition of a new value. - needed for MSMListener
    615      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    616      */
    617     public void metadataChanged(MSMEvent event) {}
     445    public void gainFocus()
     446    {
     447    // If there is nothing in the collection tree there is nothing to do
     448    if (collection_tree == null || collection_tree.getRowCount() == 0) {
     449        System.err.println("No/empty collection tree... nothing to do.");
     450        return;
     451    }
     452
     453    // Select the first node in the tree if nothing is already selected
     454    if (collection_tree.getSelectionPaths() == null) {
     455        System.err.println("Nothing selected... selecting first tree node.");
     456        collection_tree.setImmediate(true);
     457        collection_tree.setSelectionRow(0);
     458        collection_tree.setImmediate(false);
     459    }
     460
     461    // Force all of the controls to be updated
     462    valueChanged(new TreeSelectionEvent(this, null, false, null, null));
     463    }
     464
    618465
    619466    /** Called whenever the detail mode changes to ensure the filters are at an appropriate level (ie only editable by those that understand regular expression matching)
    620467     * @param mode the mode level as an int
    621468     */
    622     public void modeChanged(int mode) {
     469    public void modeChanged(int mode)
     470    {
    623471    filter.setEditable(mode > Configuration.LIBRARIAN_MODE);
    624472    }
    625473
    626     /** Method that is called whenever the metadata set collection changes in some way, such as the addition of a new set or the merging of two sets. - needed for MSMListener
    627      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
     474
     475    /** This method is called whenever the selection within the collection
     476     * tree changes. This causes the table to be rebuilt with a new model.
    628477     */
    629     public void setChanged(MSMEvent event){
    630     // call the collection tree value changed - we need to do the same stuff here
    631     valueChanged((TreeSelectionEvent) null);
    632     }
    633 
    634     /** This method enables or diables the various controls based upon the state of the system. This method should be called after every change which could affect the GUI.
    635      */
    636     private void validateControls() {
    637     validateControls(false);
    638     }
    639 
    640     private void validateControls(boolean update_card) {
    641     validateMetadataTable();
    642     // Validate card_layout_2
    643     // We only ever change tools if the metadata table has finished building or is empty.
    644     if (update_card) {
    645         if (selected_metadata == null && model.isBuildingComplete() && model.getRowCount() == 0) {
    646         card_layout2.show(control_pane, TOOLS_OFF);
    647         }
    648         else {
    649         card_layout2.show(control_pane, TOOLS_ON);
    650         }
    651     }
    652 
    653     // Validate the buttons in the lower pane
    654     if (selected_metadata == null) {
    655         // Nothing selected
    656         return;
    657     }
    658 
    659     // Does the metadata element have no current value?
    660     GValueNode value_node = selected_metadata.getValueNode();
    661     if (value_node == null) {
    662         // Can only append if something has been entered
    663         add.setEnabled((tree.getSelectedValue().length() > 0));
    664         // Nothing to replace or remove
    665         update.setEnabled(false);
    666         remove.setEnabled(false);
    667     }
    668 
     478    public void valueChanged(TreeSelectionEvent event)
     479    {
     480    // Nothing selected in the collection tree
     481    if (collection_tree.getSelectionCount() == 0) {
     482        file_nodes = null;
     483
     484        // Update the label to show nothing is selected in the collection tree
     485        Dictionary.registerText(table_label, "MetaEdit.No_File");
     486
     487        // Display the "no file selected" card
     488        metadata_value_table_card_layout.show(table_card_pane, TABLE_CARD_NO_FILES_SELECTED);
     489    }
     490
     491    // Some files selected in the collection tree
    669492    else {
    670         // Check if the text in the value field is the same as the metadata value
    671         if (tree.getSelectedValue().equals(value_node.getFullPath(false))) {
    672         // Can't replace
    673         update.setEnabled(false);
    674         // Adding, however, is dependant on whether the metadata is common or uncommon. If the later then you can append so as to make it common.
    675         add.setEnabled(!model.isCommon(selected_metadata));
    676         }
    677         else {
    678         // Can append or replace, if something has been entered
    679         add.setEnabled((tree.getSelectedValue().length() > 0));
    680         update.setEnabled((tree.getSelectedValue().length() > 0));
    681         }
    682 
    683         // Can only remove if the metadata is file level
    684         if (selected_metadata != null) {  // Shouldn't be necessary, but is
    685         remove.setEnabled(selected_metadata.isFileLevel());
    686         }
    687     }
    688     }
    689 
    690     /** Validate the metadata table area, and if no metadata is available display the no metadata panel. */
    691     public void validateMetadataTable() {
    692     // Validate card_layout
    693     if (records == null) {
    694         card_layout.show(table_card_pane, CARD_ZERO);
    695     } else if (model.getRowCount() == 0) {
    696         card_layout.show(table_card_pane, CARD_TWO);
    697     } else {
    698         card_layout.show(table_card_pane, CARD_ONE);
    699     }
    700     }
    701 
    702     /** Another in a long list of listeners, this one is called whenever the
    703      * selection within the JTable changes. When it does we load the new data
    704      * and set the selected_metadata if applicable (ie the metadata is non-
    705      * empty).
    706      * @param event The <strong>ListSelectionEvent</strong> which contains all the information about the event that has been fired.
    707      * @see org.greenstone.gatherer.gui.table.GTableModel
    708      * @see org.greenstone.gatherer.gui.EnrichPane.GValueTree
    709      */
    710     public void valueChanged(ListSelectionEvent event) {
    711     // We only want to handle one event per selection, so wait for the value to stabilise
    712     ListSelectionModel lsm = table.getSelectionModel();
    713     if (lsm.getValueIsAdjusting() == false) {
    714         // We have a SINGLE_SELECTION model set so there is at most one
    715         // selection. Get the offending row.
    716         int selected = table.getSelectedRow();
    717         selected_metadata = model.getMetadataAtRow(selected);
    718         if (selected_metadata != null) { // Check something is selected.
    719         tree.setSelectedMetadataElement(selected_metadata.getElement());
    720         GValueNode value_node = selected_metadata.getValueNode();
    721         if (value_node != null) {
    722             tree.setSelectedValue(value_node.getFullPath(true));
    723         }
    724         else {
    725             tree.setSelectedValue("");
    726         }
    727         }
    728         validateControls(true);
    729     }
    730     }
    731 
    732     /** Called whenever the value tree of an metadata element changes in some way, such as the addition of a new value. - needed for MSMListener
    733      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
    734      */
    735     public void valueChanged(MSMEvent event) {}
    736 
    737     /** This method is called whenever the selection within the collection
    738      * tree changes. This causes the table to be rebuilt with a new model
    739      * @param event A <strong>TreeSelectionEvent</strong> containing information about the event.
    740      * @see org.greenstone.gatherer.Gatherer
    741      * @see org.greenstone.gatherer.file.FileNode
    742      * @see org.greenstone.gatherer.gui.GUIManager
    743      * @see org.greenstone.gatherer.gui.MenuBar
    744      * @see org.greenstone.gatherer.gui.table.GTableModel
    745      * @see org.greenstone.gatherer.msm.MetadataSetManager
    746      * @see org.greenstone.gatherer.gui.tree.DragTree
    747      * @see org.greenstone.gatherer.util.ArrayTools
    748      */
    749     public void valueChanged(TreeSelectionEvent event) {
    750     ///ystem.err.println("\n(MEP) valueChanged(TreeSelectionEvent)...");
    751 
    752     // Don't bother if this isn't the selected view
    753     // if (Gatherer.g_man.getSelectedView() != this) {
    754     //     return;
    755     // }
    756 
    757     if (collection_tree.getSelectionCount() > 0) {
    758         records = null;
    759493        TreePath paths[] = collection_tree.getSelectionPaths();
    760         records = new FileNode[paths.length];
     494        file_nodes = new FileNode[paths.length];
    761495        for (int i = 0; i < paths.length; i++) {
    762         FileNode record = (FileNode) paths[i].getLastPathComponent();
    763         records[i] = record;
    764         }
    765 
    766         // Remember the previous selection so we can select it again later
    767         Metadata previous_selection = selected_metadata;
    768 
     496        file_nodes[i] = (FileNode) paths[i].getLastPathComponent();
     497        }
     498
     499        // Update the label to show what is selected in the collection tree
    769500        table_label.setText(collection_tree.getSelectionDetails());
    770 
    771         // Remove old model from msm
    772         Gatherer.c_man.getCollection().msm.removeMSMListener(model);
    773         // Create new model
    774         model = new GTableModel(table, records);
    775         table.setModel(model);
    776 
    777         // Select the closest piece of metadata in the new file
    778         model.selectClosestMetadataWhenBuildingComplete(previous_selection);
    779     }
    780     else {
    781         records = null;
    782         Dictionary.registerText(table_label, "MetaEdit.No_File");
    783 
    784         // Remove old model from msm
    785         if (Gatherer.c_man.ready()) {
    786         Gatherer.c_man.getCollection().msm.removeMSMListener(model);
    787         }
    788         // Create new model
    789         model = new GTableModel(table);
    790         table.setModel(model);
    791     }
    792 
    793     if (table != null) {
    794         table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    795         Dimension table_size = table.getPreferredSize();
    796         TableColumnModel column_model = table.getColumnModel();
     501    }
     502
     503    // Update the metadata value table (and consequently, the metadata value tree)
     504    metadata_value_table.rebuild();
     505
     506//  // Update the meta-audit view to show the current selection, if any.
     507//  Gatherer.g_man.meta_audit.setRecords(file_nodes);
     508    }
     509
     510
     511    private class AppendMetadataTask
     512    extends Thread
     513    {
     514    private MetadataValue metadata_value = null;
     515
     516    private AppendMetadataTask(MetadataValue metadata_value)
     517    {
     518        this.metadata_value = metadata_value;
     519    }
     520
     521    public void run()
     522    {
     523        if (file_nodes == null || metadata_value == null) {
     524        return;
     525        }
     526
     527        // If we're adding metadata to folders display the warning
     528        if (!file_nodes[0].isLeaf()) {
     529        WarningDialog dialog = new WarningDialog("warning.DirectoryLevelMetadata", true);
     530        int dialog_result = dialog.display();
     531        dialog.dispose();
     532
     533        if (dialog_result != JOptionPane.OK_OPTION) {
     534            return;
     535        }
     536        }
     537
     538        // Edit metadata.xml files to add the metadata
     539        MetadataXMLFileManager.addMetadata(file_nodes, metadata_value);
     540
     541        // Update the metadata value table and tree
     542        metadata_edit_event = true;
     543        metadata_value_table.rebuild();
     544        metadata_edit_event = false;
     545    }
     546    }
     547
     548
     549    private class UpdateMetadataTask
     550    extends Thread
     551    {
     552    private MetadataValue metadata_value = null;
     553
     554    private UpdateMetadataTask(MetadataValue metadata_value)
     555    {
     556        this.metadata_value = metadata_value;
     557    }
     558
     559    public void run()
     560    {
     561        MetadataValueTableEntry selected_metadata_value_table_entry = metadata_value_table.getSelectedMetadataValueTableEntry();
     562        if (selected_metadata_value_table_entry == null || file_nodes == null || metadata_value == null) {
     563        return;
     564        }
     565
     566        // Edit metadata.xml files to replace the metadata
     567        MetadataXMLFileManager.removeMetadata(file_nodes, selected_metadata_value_table_entry);
     568        MetadataXMLFileManager.addMetadata(file_nodes, metadata_value);
     569
     570        // Update the metadata value table and tree
     571        metadata_edit_event = true;
     572        metadata_value_table.rebuild();
     573        metadata_edit_event = false;
     574    }
     575    }
     576
     577
     578    private class RemoveMetadataTask
     579    extends Thread
     580    {
     581    public void run()
     582    {
     583        MetadataValueTableEntry selected_metadata_value_table_entry = metadata_value_table.getSelectedMetadataValueTableEntry();
     584        if (selected_metadata_value_table_entry == null || file_nodes == null) {
     585        return;
     586        }
     587
     588        // Edit metadata.xml files to remove the metadata
     589        MetadataXMLFileManager.removeMetadata(file_nodes, selected_metadata_value_table_entry);
     590
     591        // Update the metadata value table and tree
     592        metadata_edit_event = true;
     593        metadata_value_table.rebuild();
     594        metadata_edit_event = false;
     595    }
     596    }
     597
     598
     599    private class MetadataValueTable
     600    extends JTable
     601    {
     602    private MetadataValueTableModel metadata_value_table_model = null;
     603    /** The currently selected metadata value table entry */
     604    private MetadataValueTableEntry selected_metadata_value_table_entry = null;
     605
     606
     607    public MetadataValueTable()
     608    {
     609        metadata_value_table_model = new MetadataValueTableModel();
     610        setModel(metadata_value_table_model);
     611
     612        // We allow only one row to be selected at a time
     613        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     614        getSelectionModel().addListSelectionListener(new MetadataValueTableListSelectionListener());
     615
     616        // The default JTable doesn't quite have the desired properties - when a
     617        // table cell is clicked on, the table is scrolled so the cell is as
     618        // visible as possible. This means that the left-most cells can become
     619        // hidden. To fix this, the MouseInputHandler in BasicTableUI is removed
     620        // as a MouseListener on the table, and a very slightly altered copy is
     621        // added in its place (TableMouseInputHandler).
     622        MouseListener[] mls = getMouseListeners();
     623        for (int i = 0; i < mls.length; i++) {
     624        // Remove the instances of MouseInputHandler
     625        if (mls[i].toString().startsWith("javax.swing.plaf.basic.BasicTableUI$MouseInputHandler@")) {
     626            removeMouseListener(mls[i]);
     627        }
     628        }
     629        // Add the slightly-altered mouse listener
     630        addMouseListener(new TableMouseInputHandler());
     631
     632        // We also have to ensure that the table column header hasn't gone on a severe Jenny Craig binge and has somehow lost 7/8th of its component size
     633        JTableHeader table_header = getTableHeader();
     634        Dimension table_header_preferred_size = table_header.getPreferredSize();
     635        if (table_header_preferred_size.height < MINIMUM_TABLE_HEADER_SIZE) {
     636        table_header_preferred_size.setSize(table_header_preferred_size.width, MINIMUM_TABLE_HEADER_SIZE);
     637        table_header.setPreferredSize(table_header_preferred_size);
     638        }
     639
     640        // Set the table columns as we want them
     641        setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
     642        Dimension table_size = getPreferredSize();
     643        TableColumnModel column_model = getColumnModel();
    797644
    798645        TableColumn inherited_column = column_model.getColumn(0);
    799646        inherited_column.setPreferredWidth(20);
    800         inherited_column.setCellRenderer(new TableCellRenderer(model));
     647        inherited_column.setCellRenderer(new MetadataValueTableCellRenderer(metadata_value_table_model));
    801648
    802649        TableColumn element_column = column_model.getColumn(1);
    803650        element_column.setPreferredWidth((TABLE_SIZE.width / 4) - 15);
    804         element_column.setCellRenderer(new TableCellRenderer(model));
     651        element_column.setCellRenderer(new MetadataValueTableCellRenderer(metadata_value_table_model));
    805652
    806653        TableColumn value_column = column_model.getColumn(2);
    807654        value_column.setPreferredWidth(((3 * TABLE_SIZE.width) / 4) - 30);
    808         value_column.setCellRenderer(new TableCellRenderer(model));
    809     }
    810     table.doLayout();
    811     validateControls();
    812     }
    813 
    814 
    815     /** A direct copy of javax.swing.plaf.basic.BasicTableUI$MouseInputHandler, except for one change in adjustFocusAndSelection(). The purpose of this change is to always keep the left-most cells of the table row selected visible. */
    816     private class TableMouseInputHandler implements MouseInputListener
     655        value_column.setCellRenderer(new MetadataValueTableCellRenderer(metadata_value_table_model));
     656    }
     657
     658
     659    public MetadataElement getSelectedMetadataElement()
     660    {
     661        return selected_metadata_value_table_entry.getMetadataElement();
     662    }
     663
     664
     665    public MetadataValueTableEntry getSelectedMetadataValueTableEntry()
     666    {
     667        return selected_metadata_value_table_entry;
     668    }
     669
     670
     671    public boolean isSelectedMetadataValueTableEntryCommon()
     672    {
     673        return metadata_value_table_model.isCommon(selected_metadata_value_table_entry);
     674    }
     675
     676
     677    public void rebuild()
     678    {
     679        // Remember the current metadata element selection so we can select it again later
     680        MetadataValueTableEntry previously_selected_metadata_value_table_entry = selected_metadata_value_table_entry;
     681
     682        // We don't want a lot of ListSelectionEvents while the table is rebuilding
     683        clearSelection();
     684
     685        // Rebuild the metadata value table model
     686        metadata_value_table_model.rebuild(file_nodes);
     687
     688        // If the metadata value table is empty there isn't much to do
     689        if (metadata_value_table_model.getRowCount() == 0) {
     690        // ...except display the "no metadata available" card, unless no files are selected
     691        if (file_nodes != null) {
     692            metadata_value_table_card_layout.show(table_card_pane, TABLE_CARD_NO_METADATA_AVAILABLE);
     693        }
     694        return;
     695        }
     696
     697        // Display the card with the metadata value table
     698        metadata_value_table_card_layout.show(table_card_pane, TABLE_CARD);
     699
     700        // If there was no previous selection then we're done
     701        if (previously_selected_metadata_value_table_entry == null) {
     702        return;
     703        }
     704
     705        // Look for an exact match
     706        for (int i = 0; i < metadata_value_table_model.getRowCount(); i++) {
     707        MetadataValueTableEntry metadata_value_table_entry = metadata_value_table_model.getMetadataValueTableEntry(i);
     708        int c = metadata_value_table_entry.compareTo(previously_selected_metadata_value_table_entry);
     709
     710        if (c == 0) {
     711            // Select this row and we're done
     712            addRowSelectionInterval(i, i);
     713            return;
     714        }
     715
     716        if (c < 0) {
     717            // Not in the list
     718            break;
     719        }
     720        }
     721
     722        // Select the first entry with the same metadata element
     723        MetadataElement previously_selected_metadata_element = previously_selected_metadata_value_table_entry.getMetadataElement();
     724        for (int i = 0; i < metadata_value_table_model.getRowCount(); i++) {
     725        MetadataElement metadata_element = metadata_value_table_model.getMetadataValueTableEntry(i).getMetadataElement();
     726        if (metadata_element.equals(previously_selected_metadata_element)) {
     727            // Select this row and we're done
     728            addRowSelectionInterval(i, i);
     729            return;
     730        }
     731        }
     732
     733        // All else has failed, so just select the first row in the table
     734        addRowSelectionInterval(0, 0);
     735    }
     736
     737
     738    private class MetadataValueTableListSelectionListener
     739        implements ListSelectionListener
     740    {
     741        public void valueChanged(ListSelectionEvent event)
     742        {
     743        // We only want to handle one event per selection, so wait for the value to stabilise
     744        if (getSelectionModel().getValueIsAdjusting() == true) {
     745            return;
     746        }
     747
     748        // System.err.println("In MetadataValueTableListSelectionListener.valueChanged()...");
     749
     750        selected_metadata_value_table_entry = null;
     751        MetadataElement selected_metadata_element = null;
     752        String selected_metadata_value = "";
     753
     754        // We have a SINGLE_SELECTION model set so there is at most one selection
     755        int selected_row = getSelectedRow();
     756        if (selected_row >= 0) {
     757            selected_metadata_value_table_entry = metadata_value_table_model.getMetadataValueTableEntry(selected_row);
     758            selected_metadata_element = selected_metadata_value_table_entry.getMetadataElement();
     759            MetadataValueTreeNode metadata_value_tree_node = selected_metadata_value_table_entry.getMetadataValueTreeNode();
     760            if (metadata_value_tree_node != null) {
     761            selected_metadata_value = metadata_value_tree_node.getFullValue();
     762            }
     763        }
     764
     765        // Update the metadata value tree
     766        metadata_value_tree.rebuild(selected_metadata_element, selected_metadata_value);
     767        }
     768    }
     769
     770
     771    /** A direct copy of javax.swing.plaf.basic.BasicTableUI$MouseInputHandler, except for one change in adjustFocusAndSelection(). The purpose of this change is to always keep the left-most cells of the table row selected visible. */
     772    private class TableMouseInputHandler implements MouseInputListener
     773    {
     774        // Component receiving mouse events during editing.
     775        // May not be editorComponent.
     776        private Component dispatchComponent;
     777        private boolean selectedOnPress;
     778
     779        //  The Table's mouse listener methods.
     780
     781        public void mouseClicked(MouseEvent e) {}
     782
     783        private void setDispatchComponent(MouseEvent e) {
     784        Component editorComponent = getEditorComponent();
     785        Point p = e.getPoint();
     786        Point p2 = SwingUtilities.convertPoint(metadata_value_table, p, editorComponent);
     787        dispatchComponent = SwingUtilities.getDeepestComponentAt(editorComponent,
     788                                     p2.x, p2.y);
     789        }
     790
     791        private boolean repostEvent(MouseEvent e) {
     792        // Check for isEditing() in case another event has
     793        // caused the editor to be removed. See bug #4306499.
     794        if (dispatchComponent == null || !isEditing()) {
     795            return false;
     796        }
     797        MouseEvent e2 = SwingUtilities.convertMouseEvent(metadata_value_table, e, dispatchComponent);
     798        dispatchComponent.dispatchEvent(e2);
     799        return true;
     800        }
     801
     802        private void setValueIsAdjusting(boolean flag) {
     803        getSelectionModel().setValueIsAdjusting(flag);
     804        getColumnModel().getSelectionModel().setValueIsAdjusting(flag);
     805        }
     806
     807        private boolean shouldIgnore(MouseEvent e) {
     808        return e.isConsumed() || (!(SwingUtilities.isLeftMouseButton(e) && isEnabled()));
     809        }
     810
     811        public void mousePressed(MouseEvent e) {
     812        if (e.isConsumed()) {
     813            selectedOnPress = false;
     814            return;
     815        }
     816        selectedOnPress = true;
     817        adjustFocusAndSelection(e);
     818        }
     819
     820        void adjustFocusAndSelection(MouseEvent e) {
     821        if (shouldIgnore(e)) {
     822            return;
     823        }
     824
     825        Point p = e.getPoint();
     826        int row = rowAtPoint(p);
     827        int column = columnAtPoint(p);
     828        // The autoscroller can generate drag events outside the Table's range.
     829        if ((column == -1) || (row == -1)) {
     830            return;
     831        }
     832
     833        if (editCellAt(row, column, e)) {
     834            setDispatchComponent(e);
     835            repostEvent(e);
     836        }
     837        else if (isRequestFocusEnabled()) {
     838            requestFocus();
     839        }
     840
     841        CellEditor editor = getCellEditor();
     842        if (editor == null || editor.shouldSelectCell(e)) {
     843            boolean adjusting = (e.getID() == MouseEvent.MOUSE_PRESSED) ? true : false;
     844            setValueIsAdjusting(adjusting);
     845
     846            // Special code for clicking the first column (folder-level metadata)
     847            if (column == 0) {
     848            selected_metadata_value_table_entry = metadata_value_table_model.getMetadataValueTableEntry(row);
     849
     850            // If this metadata is inherited, switch to the folder it came from
     851            if (selected_metadata_value_table_entry.isInheritedMetadata()) {
     852                File folder_metadata_inherited_from = selected_metadata_value_table_entry.getFolderMetadataInheritedFrom();
     853                if (folder_metadata_inherited_from != null) {
     854                collection_tree.setSelection(folder_metadata_inherited_from);
     855                }
     856            }
     857
     858            changeSelection(row, 0, e.isControlDown(), e.isShiftDown());
     859            }
     860            else {
     861            changeSelection(row, 1, e.isControlDown(), e.isShiftDown());
     862            }
     863        }
     864        }
     865
     866        public void mouseReleased(MouseEvent e) {
     867        if (selectedOnPress) {
     868            if (shouldIgnore(e)) {
     869            return;
     870            }
     871
     872            repostEvent(e);
     873            dispatchComponent = null;
     874            setValueIsAdjusting(false);
     875        } else {
     876            adjustFocusAndSelection(e);
     877        }
     878        }
     879
     880
     881        public void mouseEntered(MouseEvent e) {}
     882
     883        public void mouseExited(MouseEvent e) {}
     884
     885        //  The Table's mouse motion listener methods.
     886
     887        public void mouseMoved(MouseEvent e) {}
     888
     889        public void mouseDragged(MouseEvent e) {
     890        if (shouldIgnore(e)) {
     891            return;
     892        }
     893
     894        repostEvent(e);
     895
     896        CellEditor editor = getCellEditor();
     897        if (editor == null || editor.shouldSelectCell(e)) {
     898            Point p = e.getPoint();
     899            int row = rowAtPoint(p);
     900            int column = columnAtPoint(p);
     901            // The autoscroller can generate drag events outside the Table's range.
     902            if ((column == -1) || (row == -1)) {
     903            return;
     904            }
     905            changeSelection(row, column, false, true);
     906        }
     907        }
     908    }
     909    }
     910
     911
     912    /**
     913     * This class is a little bit complex, a little bit subtle, and a little bit odd.
     914     * The strange interaction model is due to the fact that it is very tightly
     915     * coupled to the EnrichPane.
     916     *
     917     * The interaction is complex because there are three separate controls that the
     918     * user may interact with, each of which can affect the other two. The three
     919     * controls are:
     920     *   - The "assigned metadata" table, at the top right of the meta edit pane.
     921     *   - The "metadata value" text field, where users can type in new values.
     922     *   - The "metadata value tree", which shows other values that have been
     923     *     assigned to the selected metadata element.
     924     *
     925     * The interactions are:
     926     *   - The "assigned metadata" table
     927     *     Users may select one (and only one) row in this table. Selecting a row
     928     *     chooses one metadata element. The text field will be set to the current
     929     *     value of the metadata element. This value will also be selected in the
     930     *     metadata value tree.
     931     *
     932     *   - The "metadata value" text field
     933     *     If the value the user has typed in this is a prefix of an entry in the
     934     *     value tree, this value will be selected in the value tree. In this case,
     935     *     pressing "Tab" will complete the value (ie. make the value in the text
     936     *     field the same as the value in the tree). This is to allow users to
     937     *     quickly and easily assign existing metadata values to new documents.
     938     *
     939     *   - The "metadata value tree"
     940     *     Selecting a value in the tree will set the text field to this value.
     941     */
     942    private class MetadataValueTree
     943    extends JPanel
     944    implements TreeSelectionListener
    817945    {
    818         // Component receiving mouse events during editing.
    819         // May not be editorComponent.
    820         private Component dispatchComponent;
    821     private boolean selectedOnPress;
    822 
    823     //  The Table's mouse listener methods.
    824 
    825         public void mouseClicked(MouseEvent e) {}
    826 
    827         private void setDispatchComponent(MouseEvent e) {
    828             Component editorComponent = table.getEditorComponent();
    829             Point p = e.getPoint();
    830             Point p2 = SwingUtilities.convertPoint(table, p, editorComponent);
    831             dispatchComponent = SwingUtilities.getDeepestComponentAt(editorComponent,
    832                                      p2.x, p2.y);
    833         }
    834 
    835         private boolean repostEvent(MouseEvent e) {
    836         // Check for isEditing() in case another event has
    837         // caused the editor to be removed. See bug #4306499.
    838             if (dispatchComponent == null || !table.isEditing()) {
    839                 return false;
    840             }
    841             MouseEvent e2 = SwingUtilities.convertMouseEvent(table, e, dispatchComponent);
    842             dispatchComponent.dispatchEvent(e2);
    843             return true;
    844         }
    845 
    846         private void setValueIsAdjusting(boolean flag) {
    847             table.getSelectionModel().setValueIsAdjusting(flag);
    848             table.getColumnModel().getSelectionModel().setValueIsAdjusting(flag);
    849         }
    850 
    851     private boolean shouldIgnore(MouseEvent e) {
    852         return e.isConsumed() || (!(SwingUtilities.isLeftMouseButton(e) && table.isEnabled()));
    853     }
    854 
    855         public void mousePressed(MouseEvent e) {
    856         if (e.isConsumed()) {
    857         selectedOnPress = false;
    858         return;
    859         }
    860         selectedOnPress = true;
    861         adjustFocusAndSelection(e);
    862     }
    863 
    864     void adjustFocusAndSelection(MouseEvent e) {
    865         if (shouldIgnore(e)) {
    866             return;
    867         }
    868 
    869             Point p = e.getPoint();
    870             int row = table.rowAtPoint(p);
    871             int column = table.columnAtPoint(p);
    872         // The autoscroller can generate drag events outside the Table's range.
    873             if ((column == -1) || (row == -1)) {
    874                 return;
    875             }
    876 
    877             if (table.editCellAt(row, column, e)) {
    878                 setDispatchComponent(e);
    879                 repostEvent(e);
    880             }
    881         else if (table.isRequestFocusEnabled()) {
    882                 table.requestFocus();
    883         }
    884 
    885             CellEditor editor = table.getCellEditor();
    886             if (editor == null || editor.shouldSelectCell(e)) {
    887         boolean adjusting = (e.getID() == MouseEvent.MOUSE_PRESSED) ? true : false;
    888                 setValueIsAdjusting(adjusting);
    889 
    890         // Special code for clicking the first column (folder-level metadata)
    891         if (column == 0) {
    892             selected_metadata = model.getMetadataAtRow(row);
    893 
    894             // If this metadata is inherited, switch to the folder it came from
    895             if (!selected_metadata.isFileLevel()) {
    896             File folder_inherited_from = selected_metadata.getFile();
    897             if (folder_inherited_from != null) {
    898                 collection_tree.setSelection(folder_inherited_from);
     946    private boolean ignore_tree_selection_event = false;
     947    private boolean manual_text_edit_event = false;
     948    private CardLayout card_layout;
     949    private String card_showing = null;
     950    /** The metadata element that is currently selected. */
     951    private MetadataElement selected_metadata_element = null;
     952    private JTextArea extracted_message;
     953    private JTextField value;
     954    private JTree tree;
     955
     956    static final private String NONE = "None";
     957    static final private String TREE = "Tree";
     958
     959
     960    public MetadataValueTree(int width, int height)
     961    {
     962        super();
     963
     964        setFont(Configuration.getFont("general.font", false));
     965        setPreferredSize(new Dimension(width, height));
     966
     967        JPanel metadata_pane = new JPanel();
     968
     969        JPanel value_pane = new JPanel();
     970        JLabel value_label = new JLabel();
     971        Dictionary.registerText(value_label, "MetaEdit.Value");
     972
     973        JPanel value_field_pane = new JPanel();
     974        value = new JTextField();
     975        value.setBackground(Configuration.getColor("coloring.editable_background", false));
     976        value.setForeground(Configuration.getColor("coloring.editable_foreground", false));
     977        value.setPreferredSize(new Dimension(413, 24));
     978        value.getDocument().addDocumentListener(new DocumentListenerImpl());
     979        value.addKeyListener(new MetadataFieldListener());
     980        value.setFocusTraversalKeysEnabled(false);
     981        Dictionary.setTooltip(value, "MetaEdit.Value_Field_Tooltip");
     982
     983        JPanel button_pane = new JPanel();
     984
     985        JPanel tree_pane = new JPanel();
     986        JLabel tree_label = new JLabel();
     987        Dictionary.registerText(tree_label, "MetaEdit.Tree");
     988
     989        tree = new JTree();
     990        tree.addTreeSelectionListener(this);
     991        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
     992        tree.setRootVisible(false);
     993        tree.putClientProperty("JTree.lineStyle", "Angled");
     994
     995        JPanel extracted_pane = new JPanel();
     996        JPanel extracted_header_pane = new JPanel();
     997        extracted_message = new JTextArea("");
     998        extracted_message.setEditable(false);
     999        extracted_message.setLineWrap(true);
     1000        extracted_message.setOpaque(false);
     1001        extracted_message.setWrapStyleWord(true);
     1002
     1003        card_layout = new CardLayout();
     1004
     1005        // Layout
     1006        value_field_pane.setBorder(BorderFactory.createEmptyBorder(0,5,0,5));
     1007        value_field_pane.setLayout(new BorderLayout(0, 0));
     1008        value_field_pane.add(value, BorderLayout.CENTER);
     1009
     1010        button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
     1011        button_pane.setLayout(new GridLayout());
     1012        button_pane.add(add);
     1013        button_pane.add(update);
     1014        button_pane.add(remove);
     1015
     1016        value_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     1017        value_pane.setLayout(new BorderLayout());
     1018        value_pane.add(value_label, BorderLayout.WEST);
     1019        value_pane.add(value_field_pane, BorderLayout.CENTER);
     1020        value_pane.add(expand, BorderLayout.EAST);
     1021        value_pane.add(button_pane, BorderLayout.SOUTH);
     1022
     1023        tree_pane.setLayout(new BorderLayout());
     1024        tree_pane.add(tree_label, BorderLayout.NORTH);
     1025        tree_pane.add(new JScrollPane(tree), BorderLayout.CENTER);
     1026
     1027        metadata_pane.setLayout(new BorderLayout());
     1028        metadata_pane.add(value_pane, BorderLayout.NORTH);
     1029        metadata_pane.add(tree_pane, BorderLayout.CENTER);
     1030
     1031        extracted_header_pane.setLayout(new BorderLayout());
     1032        extracted_header_pane.add(expand_for_extracted, BorderLayout.EAST);
     1033
     1034        extracted_pane.setBorder(BorderFactory.createEmptyBorder(0,10,25,0));
     1035        extracted_pane.setLayout(new BorderLayout());
     1036        extracted_pane.add(extracted_header_pane, BorderLayout.NORTH);
     1037        extracted_pane.add(extracted_message, BorderLayout.CENTER);
     1038
     1039        this.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     1040        this.setLayout(card_layout);
     1041        this.add(metadata_pane, TREE);
     1042        this.add(extracted_pane, NONE);
     1043        card_showing = TREE;
     1044    }
     1045
     1046
     1047    /** Returns a TreePath for the node most closely matching the metadata value. */
     1048    private TreePath getClosestPath(String val)
     1049    {
     1050        // Start at the root of the tree
     1051        MetadataValueTreeNode tree_node = (MetadataValueTreeNode) tree.getModel().getRoot();
     1052
     1053        // Separate hierarchical values
     1054        PatternTokenizer tokenizer = new PatternTokenizer(val, MetadataValueTreeNode.METADATA_VALUE_TREE_NODE_HIERARCHY_TOKEN);
     1055        while (tokenizer.hasMoreTokens()) {
     1056        String token = tokenizer.nextToken();
     1057
     1058        // All components except the last must match exactly
     1059        if (tokenizer.hasMoreTokens()) {
     1060            for (int i = 0; i < tree_node.getChildCount(); i++) {
     1061            MetadataValueTreeNode child_node = (MetadataValueTreeNode) tree_node.getChildAt(i);
     1062            if (child_node.getValue().equals(token)) {
     1063                // The matching node has been found, so move onto the next token
     1064                tree_node = child_node;
     1065                break;
    8991066            }
    9001067            }
    901 
    902             table.changeSelection(row, 0, e.isControlDown(), e.isShiftDown());
    903         }
     1068        }
     1069
     1070        // The last component may match partially
    9041071        else {
    905             table.changeSelection(row, 1, e.isControlDown(), e.isShiftDown());
    906         }
    907         }
    908         }
    909 
    910         public void mouseReleased(MouseEvent e) {
    911         if (selectedOnPress) {
    912         if (shouldIgnore(e)) {
     1072            for (int i = 0; i < tree_node.getChildCount(); i++) {
     1073            MetadataValueTreeNode child_node = (MetadataValueTreeNode) tree_node.getChildAt(i);
     1074            if (child_node.getValue().startsWith(token)) {
     1075                // The closest node has been found, so return its path
     1076                return new TreePath(child_node.getPath());
     1077            }
     1078            }
     1079
     1080            // Not even a partial match
     1081            return null;
     1082        }
     1083        }
     1084
     1085        // If nothing else, return the path of the root node
     1086        return new TreePath(tree_node.getPath());
     1087    }
     1088
     1089
     1090    public String getSelectedValue()
     1091    {
     1092        return value.getText().replaceAll("\\\\", MetadataValueTreeNode.METADATA_VALUE_TREE_NODE_HIERARCHY_TOKEN);
     1093    }
     1094
     1095
     1096    public void rebuild(MetadataElement metadata_element, String metadata_value)
     1097    {
     1098        // System.err.println("In MetadataValueTree.rebuild()...");
     1099
     1100        // Clear selection
     1101        if (metadata_element == null) {
     1102        if (metadata_edit_event == false) {
     1103            System.err.println("Clearing selection...");
     1104            selected_metadata_element = null;
     1105            validateDisplay();
     1106        }
     1107        return;
     1108        }
     1109
     1110        // Reload the value tree model if the selected metadata element has changed
     1111        if (selected_metadata_element != metadata_element) {
     1112        selected_metadata_element = metadata_element;
     1113        tree.setModel(selected_metadata_element.getMetadataValueTreeModel());
     1114        }
     1115
     1116        validateDisplay();
     1117
     1118        setSelectedValue(metadata_value);
     1119    }
     1120
     1121
     1122    /** This function is copied from JTree::setPathToVisible(), and modified so tree rows
     1123        are always shown flushed left. Note: doesn't do accessibleContext stuff. */
     1124    private void scrollTreePathToVisible(TreePath path)
     1125    {
     1126        if (path != null) {
     1127        tree.makeVisible(path);
     1128
     1129        Rectangle bounds = tree.getPathBounds(path);
     1130        if (bounds != null) {
     1131            bounds.width += bounds.x;
     1132            bounds.x = 0;
     1133            tree.scrollRectToVisible(bounds);
     1134        }
     1135        }
     1136    }
     1137
     1138
     1139    /** Sets the value in the text field. */
     1140    private void setSelectedValue(String metadata_value)
     1141    {
     1142        // Setting the text of the field causes the DocumentListener to be notified, and
     1143        //   updating the tree is handled there (DocumentListenerImpl::validate())
     1144        if (!card_showing.equals(NONE)) {
     1145        manual_text_edit_event = metadata_value.equals("");  // Set to false unless val == ""
     1146        value.setText(metadata_value);
     1147        manual_text_edit_event = true;
     1148        }
     1149    }
     1150
     1151
     1152    private void validateDisplay()
     1153    {
     1154        // If no metadata is selected in the metadata value table, display "no metadata element selected" card
     1155        if (file_nodes == null || selected_metadata_element == null) {
     1156        metadata_value_tree_card_layout.show(control_pane, TREE_CARD_NO_METADATA_ELEMENT_SELECTED);
     1157        }
     1158
     1159        // Otherwise, display the card with the metadata value tree
     1160        else {
     1161        metadata_value_tree_card_layout.show(control_pane, TREE_CARD);
     1162
     1163        // Special case the extracted metadata set
     1164        if (selected_metadata_element.getNamespace().equals(Utility.EXTRACTED_METADATA_NAMESPACE)) {
     1165            // Display the panel showing the "you cannot edit this metadata" message
     1166            String[] args = new String[1];
     1167            args[0] = selected_metadata_element.getFullName();
     1168            Dictionary.registerText(extracted_message, "MetaEdit.AutoMessage", args);
     1169            card_layout.show(this, NONE);
     1170            card_showing = NONE;
     1171        }
     1172        else {
     1173            // Display the panel for viewing and assigning metadata
     1174            card_layout.show(this, TREE);
     1175            card_showing = TREE;
     1176        }
     1177
     1178        // Validate the buttons above the value tree
     1179        MetadataValueTableEntry metadata_value_table_entry = metadata_value_table.getSelectedMetadataValueTableEntry();
     1180        if (metadata_value_table_entry.getValue().equals("")) {
     1181            // Can only append if something has been entered
     1182            add.setEnabled((getSelectedValue().length() > 0));
     1183
     1184            // Nothing to replace or remove
     1185            update.setEnabled(false);
     1186            remove.setEnabled(false);
    9131187            return;
    9141188        }
    9151189
    916         repostEvent(e);
    917         dispatchComponent = null;
    918         setValueIsAdjusting(false);
    919         } else {
    920         adjustFocusAndSelection(e);
    921         }
    922         }
    923 
    924 
    925         public void mouseEntered(MouseEvent e) {}
    926 
    927         public void mouseExited(MouseEvent e) {}
    928 
    929     //  The Table's mouse motion listener methods.
    930 
    931         public void mouseMoved(MouseEvent e) {}
    932 
    933         public void mouseDragged(MouseEvent e) {
    934         if (shouldIgnore(e)) {
    935             return;
    936         }
    937 
    938             repostEvent(e);
    939 
    940             CellEditor editor = table.getCellEditor();
    941             if (editor == null || editor.shouldSelectCell(e)) {
    942                 Point p = e.getPoint();
    943                 int row = table.rowAtPoint(p);
    944                 int column = table.columnAtPoint(p);
    945             // The autoscroller can generate drag events outside the Table's range.
    946                 if ((column == -1) || (row == -1)) {
    947                     return;
    948                 }
    949             table.changeSelection(row, column, false, true);
    950             }
    951         }
    952     }
    953 
    954 
    955     /** A listener for right mouse button clicks over the collection tree. */
    956     private class RightButtonListener
    957     extends MouseAdapter {
    958     /** Called whenever a mouse click occurs (right or left) over a target component.
    959      * @param event A <strong>MouseEvent</strong> containing further information about the mouse click action.
    960      * @see org.greenstone.gatherer.gui.EnrichPane.RightButtonMenu
    961      */
    962     public void mouseClicked(MouseEvent event) {
    963         if (SwingUtilities.isRightMouseButton(event)) {
    964         new RightButtonMenu(event);
    965         }
    966     }
    967     }
    968 
    969 
    970     /** When a user right-clicks within the collection tree they are presented with a small popup menu of context based options. This class provides such functionality.
    971      */
    972     private class RightButtonMenu
    973     extends JPopupMenu
    974     implements ActionListener {
    975 
    976     /** The tree over which the right click action occurred. */
    977     private DragTree tree = null;
    978     /** The tree nodes selected when the right click action occurred. */
    979     private TreePath[] selection_paths = null;
    980     /** The file record over which the right click action occurred. */
    981     private FileNode node = null;
    982 
    983     private JMenuItem collapse_folder = null;
    984     private JMenuItem expand_folder = null;
    985     private JMenuItem metaaudit = null;
    986     private JMenuItem open_externally = null;
    987 
    988 
    989     private RightButtonMenu(MouseEvent event)
    990     {
    991         super();
    992         this.tree = collection_tree;
    993 
    994         // Get the paths currently selected in the tree
    995         selection_paths = tree.getSelectionPaths();
    996 
    997         // Create an appropriate context menu, based on what is selected
    998         buildContextMenu(selection_paths);
    999 
    1000         // Show the popup menu on screen
    1001         show(tree, event.getX(), event.getY());
    1002     }
    1003 
    1004 
    1005     private void buildContextMenu(TreePath[] selection_paths)
    1006     {
    1007         // If nothing is selected, no options are available
    1008         if (selection_paths == null) {
    1009         return;
    1010         }
    1011 
    1012         DebugStream.println("Number of files/folders selected: " + selection_paths.length);
    1013 
    1014         // Always have meta-audit option
    1015         String[] args = new String[1];
    1016         args[0] = collection_tree.getSelectionDetails();
    1017         metaaudit = new JMenuItem(Dictionary.get("Menu.Metadata_View", args), KeyEvent.VK_A);
    1018         metaaudit.addActionListener(this);
    1019         add(metaaudit);
    1020 
    1021         // Only meta-audit is available if multiple items are selected...
    1022         if (selection_paths.length > 1) {
    1023         return;
    1024         }
    1025 
    1026         TreePath path = selection_paths[0];
    1027         node = (FileNode) path.getLastPathComponent();
    1028 
    1029         // ---- Options for file nodes ----
    1030         if (node.isLeaf()) {
    1031         // Open the file in an external program
    1032         open_externally = new JMenuItem(Dictionary.get("Menu.Open_Externally"), KeyEvent.VK_O);
    1033         open_externally.addActionListener(this);
    1034         add(open_externally);
    1035 
    1036         return;
    1037         }
    1038 
    1039         // ---- Options for folder nodes ----
    1040         // Collapse or expand, depending on current status
    1041         if (tree.isExpanded(path)) {
    1042         collapse_folder = new JMenuItem(Dictionary.get("Menu.Collapse"), KeyEvent.VK_C);
    1043         collapse_folder.addActionListener(this);
    1044         add(collapse_folder);
    1045         }
    1046         else {
    1047         expand_folder = new JMenuItem(Dictionary.get("Menu.Expand"), KeyEvent.VK_O);
    1048         expand_folder.addActionListener(this);
    1049         add(expand_folder);
    1050         }
    1051     }
    1052 
    1053 
    1054     /** Called whenever one of the menu items is clicked, this method then causes the appropriate effect. */
    1055     public void actionPerformed(ActionEvent event)
    1056     {
    1057         Object source = event.getSource();
    1058 
    1059         // Collapse folder
    1060         if (source == collapse_folder) {
    1061         tree.collapsePath(selection_paths[0]);
    1062         }
    1063 
    1064         // Expand folder
    1065         else if (source == expand_folder) {
    1066         tree.expandPath(selection_paths[0]);
    1067         }
    1068 
    1069         // Meta-audit
    1070         else if (source == metaaudit) {
    1071         Gatherer.g_man.showMetaAuditBox();
    1072         }
    1073 
    1074         // Open in external program
    1075         else if (source == open_externally) {
    1076         Gatherer.self.spawnApplication(node.getFile());
     1190        // Check if the text in the value field is the same as the metadata value
     1191        if (getSelectedValue().equals(metadata_value_table_entry.getFullValue())) {
     1192            // Can't replace
     1193            update.setEnabled(false);
     1194
     1195            // Adding, however, is dependant on whether the selected metadata is common or uncommon. If the later then you can append so as to make it common.
     1196            add.setEnabled(!metadata_value_table.isSelectedMetadataValueTableEntryCommon());
     1197        }
     1198        else {
     1199            // Can append or replace, if something has been entered
     1200            add.setEnabled((getSelectedValue().length() > 0));
     1201            update.setEnabled((getSelectedValue().length() > 0));
     1202        }
     1203
     1204        // Can only remove if the metadata is file level
     1205        if (metadata_value_table_entry != null) {  // Shouldn't be necessary, but is
     1206            remove.setEnabled((metadata_value_table_entry.isInheritedMetadata() == false));
     1207        }
     1208        }
     1209    }
     1210
     1211
     1212    /** Handles TreeSelectionEvents. */
     1213    public void valueChanged(TreeSelectionEvent event)
     1214    {
     1215        if (tree.getSelectionCount() != 0 && !ignore_tree_selection_event) {
     1216        TreePath path = tree.getSelectionPath();
     1217        MetadataValueTreeNode node = (MetadataValueTreeNode) path.getLastPathComponent();
     1218        setSelectedValue(node.getFullValue());
     1219        }
     1220    }
     1221
     1222
     1223    private class MetadataFieldListener
     1224        implements KeyListener {
     1225
     1226        /** Gives notification of key events on the text field */
     1227        public void keyPressed(KeyEvent e) {
     1228        if (e.getKeyCode() == KeyEvent.VK_TAB) {
     1229            // Tab: Auto-complete
     1230            if (tree.getSelectionCount() != 0 && !getSelectedValue().equals("")) {
     1231            TreePath path = tree.getSelectionPath();
     1232            MetadataValueTreeNode node = (MetadataValueTreeNode) path.getLastPathComponent();
     1233            setSelectedValue(node.getFullValue());
     1234            }
     1235        }
     1236        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
     1237            // Enter: Append the metadata value, if we're allowed to
     1238            if (add.isEnabled()) {
     1239            add.doClick();
     1240            }
     1241        }
     1242        }
     1243
     1244        public void keyReleased(KeyEvent e) { }
     1245
     1246        public void keyTyped(KeyEvent e) { }
     1247    }
     1248
     1249
     1250    private class DocumentListenerImpl
     1251        implements DocumentListener
     1252    {
     1253        /** Gives notification that an attribute or set of attributes changed */
     1254        public void changedUpdate(DocumentEvent e) {
     1255        validate();
     1256        }
     1257
     1258        /** Gives notification that there was an insert into the document */
     1259        public void insertUpdate(DocumentEvent e) {
     1260        validate();
     1261        }
     1262
     1263        /** Gives notification that a portion of the document has been removed */
     1264        public void removeUpdate(DocumentEvent e) {
     1265        validate();
     1266        }
     1267
     1268
     1269        /** Ensures that the value text field and value tree are synchronized */
     1270        private void validate()
     1271        {
     1272        String value_text = getSelectedValue();
     1273
     1274        // Ignore the validate() with empty text that occurs when value.setText() is used
     1275        if (!value_text.equals("") || manual_text_edit_event == true) {
     1276            TreePath closest_path = getClosestPath(value_text);
     1277
     1278            // Select the new path in the tree
     1279            // The tree selection event this causes must be ignored, since it alters value
     1280            ignore_tree_selection_event = true;
     1281            tree.setSelectionPath(closest_path);
     1282            ignore_tree_selection_event = false;
     1283
     1284            // If a folder has been specified, make sure it is expanded
     1285            if (value_text.endsWith(MetadataValueTreeNode.METADATA_VALUE_TREE_NODE_HIERARCHY_TOKEN) && !tree.isExpanded(closest_path)) {
     1286            tree.expandPath(closest_path);
     1287            }
     1288
     1289            // Make sure the path is visible on the screen
     1290            scrollTreePathToVisible(closest_path);
     1291            // One call should be enough, but it isn't in some cases (for some reason)
     1292            scrollTreePathToVisible(closest_path);
     1293
     1294            // Update the status of the buttons
     1295            validateDisplay();
     1296        }
    10771297        }
    10781298    }
     
    11461366
    11471367
    1148     /**
    1149      * This class is a little bit complex, a little bit subtle, and a little bit odd.
    1150      * The strange interaction model is due to the fact that it is very tightly
    1151      * coupled to the EnrichPane.
    1152      *
    1153      * The interaction is complex because there are three separate controls that the
    1154      * user may interact with, each of which can affect the other two. The three
    1155      * controls are:
    1156      *   - The "assigned metadata" table, at the top right of the meta edit pane.
    1157      *   - The "metadata value" text field, where users can type in new values.
    1158      *   - The "metadata value tree", which shows other values that have been
    1159      *     assigned to the selected metadata element.
    1160      *
    1161      * The interactions are:
    1162      *   - The "assigned metadata" table
    1163      *     Users may select one (and only one) row in this table. Selecting a row
    1164      *     chooses one metadata element. The text field will be set to the current
    1165      *     value of the metadata element. This value will also be selected in the
    1166      *     metadata value tree.
    1167      *
    1168      *   - The "metadata value" text field
    1169      *     If the value the user has typed in this is a prefix of an entry in the
    1170      *     value tree, this value will be selected in the value tree. In this case,
    1171      *     pressing "Enter" will complete the value (ie. make the value in the text
    1172      *     field the same as the value in the tree). This is to allow users to
    1173      *     quickly and easily assign existing metadata values to new documents.
    1174      *
    1175      *   - The "metadata value tree"
    1176      *     Selecting a value in the tree will set the text field to this value.
     1368    /** A listener for right mouse button clicks over the collection tree. */
     1369    private class RightButtonListener
     1370    extends MouseAdapter {
     1371    /** Called whenever a mouse click occurs (right or left) over a target component.
     1372     * @param event A <strong>MouseEvent</strong> containing further information about the mouse click action.
     1373     * @see org.greenstone.gatherer.gui.EnrichPane.RightButtonMenu
     1374     */
     1375    public void mouseClicked(MouseEvent event) {
     1376        if (SwingUtilities.isRightMouseButton(event)) {
     1377        new RightButtonMenu(event);
     1378        }
     1379    }
     1380    }
     1381
     1382
     1383    /** When a user right-clicks within the collection tree they are presented with a small popup menu of context based options. This class provides such functionality.
    11771384     */
    1178     private class GValueTree
    1179     extends JPanel
    1180     implements TreeSelectionListener {
    1181     private boolean ignore_tree_selection_event = false;
    1182     private boolean manual_text_edit_event;
    1183     private CardLayout card_layout;
    1184     private String card_showing = null;
    1185     /** The metadata element that is currently selected. */
    1186     private ElementWrapper selected_metadata_element = null;
    1187     private GValueModel vm;
    1188     private JTextArea extracted_message;
    1189     private JTextField value;
    1190     private JTree tree;
    1191 
    1192     static final private String NONE = "None";
    1193     static final private String TREE = "Tree";
    1194 
    1195 
    1196     public GValueTree(int width, int height)
     1385    private class RightButtonMenu
     1386    extends JPopupMenu
     1387    implements ActionListener {
     1388
     1389    /** The tree over which the right click action occurred. */
     1390    private DragTree tree = null;
     1391    /** The tree nodes selected when the right click action occurred. */
     1392    private TreePath[] selection_paths = null;
     1393    /** The file record over which the right click action occurred. */
     1394    private FileNode node = null;
     1395
     1396    private JMenuItem collapse_folder = null;
     1397    private JMenuItem expand_folder = null;
     1398    private JMenuItem metaaudit = null;
     1399    private JMenuItem open_externally = null;
     1400
     1401
     1402    private RightButtonMenu(MouseEvent event)
    11971403    {
    11981404        super();
    1199 
    1200         setFont(Configuration.getFont("general.font", false));
    1201         setPreferredSize(new Dimension(width, height));
    1202 
    1203         JPanel metadata_pane = new JPanel();
    1204 
    1205         JPanel value_pane = new JPanel();
    1206         JLabel value_label = new JLabel();
    1207         Dictionary.registerText(value_label, "MetaEdit.Value");
    1208 
    1209         JPanel value_field_pane = new JPanel();
    1210         value = new JTextField();
    1211         value.setBackground(Configuration.getColor("coloring.editable_background", false));
    1212         value.setForeground(Configuration.getColor("coloring.editable_foreground", false));
    1213         value.setPreferredSize(new Dimension(413, 24));
    1214         value.getDocument().addDocumentListener(new DocumentListenerImpl());
    1215         value.addKeyListener(new MetadataFieldListener());
    1216         value.setFocusTraversalKeysEnabled(false);
    1217         Dictionary.setTooltip(value, "MetaEdit.Value_Field_Tooltip");
    1218 
    1219         JPanel button_pane = new JPanel();
    1220 
    1221         JPanel tree_pane = new JPanel();
    1222         JLabel tree_label = new JLabel();
    1223         Dictionary.registerText(tree_label, "MetaEdit.Tree");
    1224 
    1225         tree = new JTree(new GValueModel());
    1226         tree.addTreeSelectionListener(this);
    1227         tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    1228         tree.setRootVisible(false);
    1229         tree.putClientProperty("JTree.lineStyle", "Angled");
    1230 
    1231         JPanel extracted_pane = new JPanel();
    1232         JPanel extracted_header_pane = new JPanel();
    1233         extracted_message = new JTextArea("");
    1234         extracted_message.setEditable(false);
    1235         extracted_message.setLineWrap(true);
    1236         extracted_message.setOpaque(false);
    1237         extracted_message.setWrapStyleWord(true);
    1238 
    1239         card_layout = new CardLayout();
    1240 
    1241         // Layout
    1242         value_field_pane.setBorder(BorderFactory.createEmptyBorder(0,5,0,5));
    1243         value_field_pane.setLayout(new BorderLayout(0, 0));
    1244         value_field_pane.add(value, BorderLayout.CENTER);
    1245 
    1246         button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
    1247         button_pane.setLayout(new GridLayout());
    1248         button_pane.add(add);
    1249         button_pane.add(update);
    1250         button_pane.add(remove);
    1251 
    1252         value_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
    1253         value_pane.setLayout(new BorderLayout());
    1254         value_pane.add(value_label, BorderLayout.WEST);
    1255         value_pane.add(value_field_pane, BorderLayout.CENTER);
    1256         value_pane.add(expand, BorderLayout.EAST);
    1257         value_pane.add(button_pane, BorderLayout.SOUTH);
    1258 
    1259         tree_pane.setLayout(new BorderLayout());
    1260         tree_pane.add(tree_label, BorderLayout.NORTH);
    1261         tree_pane.add(new JScrollPane(tree), BorderLayout.CENTER);
    1262 
    1263         metadata_pane.setLayout(new BorderLayout());
    1264         metadata_pane.add(value_pane, BorderLayout.NORTH);
    1265         metadata_pane.add(tree_pane, BorderLayout.CENTER);
    1266 
    1267         extracted_header_pane.setLayout(new BorderLayout());
    1268         extracted_header_pane.add(expand_for_extracted, BorderLayout.EAST);
    1269 
    1270         extracted_pane.setBorder(BorderFactory.createEmptyBorder(0,10,25,0));
    1271         extracted_pane.setLayout(new BorderLayout());
    1272         extracted_pane.add(extracted_header_pane, BorderLayout.NORTH);
    1273         extracted_pane.add(extracted_message, BorderLayout.CENTER);
    1274 
    1275         this.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    1276         this.setLayout(card_layout);
    1277         this.add(metadata_pane, TREE);
    1278         this.add(extracted_pane, NONE);
    1279         card_showing = TREE;
    1280     }
    1281 
    1282 
    1283     public GValueModel getModel() {
    1284         return (GValueModel) tree.getModel();
    1285     }
    1286 
    1287 
    1288     public ElementWrapper getSelectedMetadataElement() {
    1289         return selected_metadata_element;
    1290     }
    1291 
    1292 
    1293     public String getSelectedValue() {
    1294         String raw_value = value.getText();
    1295         raw_value = Codec.transformUnicode(raw_value);
    1296         raw_value = Codec.transform(raw_value, Codec.ENCODE_PATH);
    1297         raw_value = Codec.transform(raw_value, Codec.ENCODE_SQUARE_BRACKETS);
    1298         return raw_value;
    1299     }
    1300 
    1301 
    1302     public void setSelectedMetadataElement(ElementWrapper element)
    1303     {
    1304         ///ystem.err.println("Setting selected metadata element to: " + element);
    1305         if (element == null) {
    1306         selected_metadata_element = null;
     1405        this.tree = collection_tree;
     1406
     1407        // Get the paths currently selected in the tree
     1408        selection_paths = tree.getSelectionPaths();
     1409
     1410        // Create an appropriate context menu, based on what is selected
     1411        buildContextMenu(selection_paths);
     1412
     1413        // Show the popup menu on screen
     1414        show(tree, event.getX(), event.getY());
     1415    }
     1416
     1417
     1418    private void buildContextMenu(TreePath[] selection_paths)
     1419    {
     1420        // If nothing is selected, no options are available
     1421        if (selection_paths == null) {
    13071422        return;
    13081423        }
    13091424
    1310         // Don't bother if the element selected is the same as the current one
    1311         if (selected_metadata_element != null && element.equals(selected_metadata_element)) {
     1425        DebugStream.println("Number of files/folders selected: " + selection_paths.length);
     1426
     1427        // Always have meta-audit option
     1428        metaaudit = new JMenuItem(Dictionary.get("Menu.Metadata_View", collection_tree.getSelectionDetails()), KeyEvent.VK_A);
     1429        metaaudit.addActionListener(this);
     1430        add(metaaudit);
     1431
     1432        // Only meta-audit is available if multiple items are selected...
     1433        if (selection_paths.length > 1) {
    13121434        return;
    13131435        }
    13141436
    1315         if (vm != null) {
    1316         // Close any expanded paths in the tree
    1317         GValueNode root_node = (GValueNode) vm.getRoot();
    1318         for (int i = 0; i < root_node.getChildCount(); i++) {
    1319             GValueNode child_node = (GValueNode) root_node.getChildAt(i);
    1320             TreePath child_path = new TreePath(child_node.getPath());
    1321             if (tree.isExpanded(child_path)) {
    1322             tree.collapsePath(child_path);
    1323             }
    1324         }
    1325         }
    1326 
    1327         // Load the model for the newly selected metadata element
    1328         selected_metadata_element = element;
    1329         if (Gatherer.c_man != null && Gatherer.c_man.getCollection() != null && Gatherer.c_man.getCollection().msm != null && tree != null) {
    1330         vm = Gatherer.c_man.getCollection().msm.getValueTree(element);
    1331         tree.setModel(vm);
    1332         }
    1333 
    1334         // Special case the extracted metadata set
    1335         if (selected_metadata_element.getNamespace().equals(Utility.EXTRACTED_METADATA_NAMESPACE)) {
    1336         // Display the panel showing the "you cannot edit this metadata" message
    1337         String[] args = new String[1];
    1338         args[0] = selected_metadata_element.toString();
    1339         Dictionary.registerText(extracted_message, "MetaEdit.AutoMessage", args);
    1340         card_layout.show(this, NONE);
    1341         card_showing = NONE;
     1437        TreePath path = selection_paths[0];
     1438        node = (FileNode) path.getLastPathComponent();
     1439
     1440        // ---- Options for file nodes ----
     1441        if (node.isLeaf()) {
     1442        // Open the file in an external program
     1443        open_externally = new JMenuItem(Dictionary.get("Menu.Open_Externally"), KeyEvent.VK_O);
     1444        open_externally.addActionListener(this);
     1445        add(open_externally);
     1446        return;
     1447        }
     1448
     1449        // ---- Options for folder nodes ----
     1450        // Collapse or expand, depending on current status
     1451        if (tree.isExpanded(path)) {
     1452        collapse_folder = new JMenuItem(Dictionary.get("Menu.Collapse"), KeyEvent.VK_C);
     1453        collapse_folder.addActionListener(this);
     1454        add(collapse_folder);
    13421455        }
    13431456        else {
    1344         // Display the panel for viewing and assigning metadata
    1345         card_layout.show(this, TREE);
    1346         card_showing = TREE;
    1347         }
    1348     }
    1349 
    1350 
    1351     /** Handles TreeSelectionEvents. */
    1352     public void valueChanged(TreeSelectionEvent event)
    1353     {
    1354         if (tree.getSelectionCount() != 0 && !ignore_tree_selection_event) {
    1355         TreePath path = tree.getSelectionPath();
    1356         GValueNode node = (GValueNode) path.getLastPathComponent();
    1357         setSelectedValue(node.getFullPath(true));
    1358         }
    1359     }
    1360 
    1361 
    1362     /** Sets the value in the text field. */
    1363     public void setSelectedValue(String val)
    1364     {
    1365         // Setting the text of the field causes the DocumentListener to be notified, and
    1366         //   updating the tree is handled there (DocumentListenerImpl::validate())
    1367         if (!card_showing.equals(NONE)) {
    1368         // Decode val
    1369         ///ystem.err.println("Before transforms: " + val);
    1370         //val = Codec.transform(val, Codec.DECODE_SQUARE_BRACKETS);
    1371         //val = Codec.transform(val, Codec.DECODE_PATH);
    1372         ///ystem.err.println("Setting selected value to: " + val);
    1373         manual_text_edit_event = val.equals("");  // Set to false unless val == ""
    1374         value.setText(val); ///odec.transform(val, /odec.GREENSTONE_TO_TEXT));
    1375         value.setCaretPosition(0);
    1376         manual_text_edit_event = true;
    1377         }
    1378     }
    1379 
    1380 
    1381     /** Returns a TreePath for the node most closely matching the metadata value. */
    1382     private TreePath getClosestPath(String val)
    1383     {
    1384         ///ystem.err.println("Select closest path to: " + val);
    1385         // Start at the root of the tree
    1386         GValueNode tree_node = (GValueNode) tree.getModel().getRoot();
    1387 
    1388         // Hierarchical values are separated using '|'
    1389         PatternTokenizer tokenizer = new PatternTokenizer(val, StaticStrings.PIPE_STR);
    1390         while (tokenizer.hasMoreTokens()) {
    1391         String token = tokenizer.nextToken();
    1392 
    1393         // All components except the last must match exactly
    1394         if (tokenizer.hasMoreTokens()) {
    1395             for (int i = 0; i < tree_node.getChildCount(); i++) {
    1396             GValueNode child_node = (GValueNode) tree_node.getChildAt(i);
    1397             if (child_node.toString(GValueNode.DOM).equals(token)) {
    1398                 // The matching node has been found, so move onto the next token
    1399                 tree_node = child_node;
    1400                 break;
    1401             }
    1402             }
    1403         }
    1404 
    1405         // The last component may match partially
    1406         else {
    1407             for (int i = 0; i < tree_node.getChildCount(); i++) {
    1408             GValueNode child_node = (GValueNode) tree_node.getChildAt(i);
    1409             if (child_node.toString(GValueNode.DOM).startsWith(token)) {
    1410                 // The closest node has been found, so return its path
    1411                 return new TreePath(child_node.getPath());
    1412             }
    1413             }
    1414 
    1415             // Not even a partial match
    1416             return null;
    1417         }
    1418         }
    1419 
    1420         // If nothing else, return the path of the root node
    1421         return new TreePath(tree_node.getPath());
    1422     }
    1423 
    1424 
    1425     /** This function is copied from JTree::setPathToVisible(), and modified so tree rows
    1426         are always shown flushed left. Note: doesn't do accessibleContext stuff. */
    1427     private void scrollTreePathToVisible(TreePath path)
    1428     {
    1429         if (path != null) {
    1430         tree.makeVisible(path);
    1431 
    1432         Rectangle bounds = tree.getPathBounds(path);
    1433         if (bounds != null) {
    1434             bounds.width += bounds.x;
    1435             bounds.x = 0;
    1436             tree.scrollRectToVisible(bounds);
    1437         }
    1438         }
    1439     }
    1440 
    1441 
    1442     private class MetadataFieldListener
    1443         implements KeyListener {
    1444 
    1445         /** Gives notification of key events on the text field */
    1446         public void keyPressed(KeyEvent e) {
    1447         if (e.getKeyCode() == KeyEvent.VK_TAB) {
    1448             // Tab: Auto-complete
    1449             if (tree.getSelectionCount() != 0 && !getSelectedValue().equals("")) {
    1450             TreePath path = tree.getSelectionPath();
    1451             GValueNode node = (GValueNode) path.getLastPathComponent();
    1452             String val = node.getFullPath(true);
    1453             ///ystem.err.println("Setting value to: " + val);
    1454             value.setText(val);
    1455             val = null;
    1456             }
    1457         }
    1458         if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    1459             // Enter: Append the metadata value, if we're allowed to
    1460             if (add.isEnabled()) {
    1461             add.doClick();
    1462             }
    1463         }
    1464         }
    1465 
    1466         public void keyReleased(KeyEvent e) { }
    1467 
    1468         public void keyTyped(KeyEvent e) { }
    1469     }
    1470 
    1471 
    1472     private class DocumentListenerImpl
    1473         implements DocumentListener {
    1474         /** Gives notification that an attribute or set of attributes changed */
    1475         public void changedUpdate(DocumentEvent e) {
    1476         validate();
    1477         }
    1478 
    1479         /** Gives notification that there was an insert into the document */
    1480         public void insertUpdate(DocumentEvent e) {
    1481         validate();
    1482         }
    1483 
    1484         /** Gives notification that a portion of the document has been removed */
    1485         public void removeUpdate(DocumentEvent e) {
    1486         validate();
    1487         }
    1488 
    1489 
    1490         /** Ensures that the value text field and value tree are synchronized */
    1491         private void validate()
    1492         {
    1493         String value_text = getSelectedValue(); ///odec.transform(getSelectedValue(), /odec.TEXT_TO_DOM);
    1494         ///ystem.err.println("\n(Validate) Value text: " + value_text);
    1495 
    1496         // Ignore the validate() with empty text that occurs when value.setText() is used
    1497         if (!value_text.equals("") || manual_text_edit_event == true) {
    1498             TreePath closest_path = getClosestPath(value_text);
    1499 
    1500             ///ystem.err.println("The closest path is: " + closest_path);
    1501 
    1502             // Select the new path in the tree
    1503             // The tree selection event this causes must be ignored, since it alters value
    1504             ignore_tree_selection_event = true;
    1505             tree.setSelectionPath(closest_path);
    1506             ignore_tree_selection_event = false;
    1507 
    1508             // If a folder has been specified, make sure it is expanded
    1509             if (value_text.endsWith("\\") && !tree.isExpanded(closest_path)) {
    1510             tree.expandPath(closest_path);
    1511             }
    1512 
    1513             // Make sure the path is visible on the screen
    1514             scrollTreePathToVisible(closest_path);
    1515             // One call should be enough, but it isn't in some cases (for some reason)
    1516             scrollTreePathToVisible(closest_path);
    1517 
    1518             // Update the status of the buttons
    1519             validateControls(); // Don't update the tools view itself
    1520         }
     1457        expand_folder = new JMenuItem(Dictionary.get("Menu.Expand"), KeyEvent.VK_O);
     1458        expand_folder.addActionListener(this);
     1459        add(expand_folder);
     1460        }
     1461    }
     1462
     1463
     1464    /** Called whenever one of the menu items is clicked, this method then causes the appropriate effect. */
     1465    public void actionPerformed(ActionEvent event)
     1466    {
     1467        Object source = event.getSource();
     1468
     1469        // Collapse folder
     1470        if (source == collapse_folder) {
     1471        tree.collapsePath(selection_paths[0]);
     1472        }
     1473
     1474        // Expand folder
     1475        else if (source == expand_folder) {
     1476        tree.expandPath(selection_paths[0]);
     1477        }
     1478
     1479        // Meta-audit
     1480        else if (source == metaaudit) {
     1481        Gatherer.g_man.showMetaAuditBox();
     1482        }
     1483
     1484        // Open in external program
     1485        else if (source == open_externally) {
     1486        Gatherer.self.spawnApplication(node.getFile());
    15211487        }
    15221488    }
  • trunk/gli/src/org/greenstone/gatherer/gui/GUIManager.java

    r8258 r8313  
    6363import org.greenstone.gatherer.gui.tree.WorkspaceTree;
    6464import org.greenstone.gatherer.help.HelpFrame;
    65 import org.greenstone.gatherer.mem.MetadataEditorManager;
     65import org.greenstone.gatherer.metadata.MetadataSet;
     66import org.greenstone.gatherer.metadata.MetadataSetManager;
    6667import org.greenstone.gatherer.shell.GShell;
    6768import org.greenstone.gatherer.util.StaticStrings;
     
    166167    else if(esrc == menu_bar.file_close) {
    167168        boolean cont = showSaveCollectionBox(true, false);
     169        // System.err.println("Here 1.");
    168170        if(cont) {
    169171        tab_pane.setSelectedComponent(gather_pane);
     
    252254    // Metadata Options.
    253255    // *****************
    254     else if (esrc == menu_bar.metadata_import) {
    255         JFileChooser chooser = new JFileChooser(new File(Utility.METADATA_DIR));
    256         MDSFileFilter filter = new MDSFileFilter();
    257         chooser.setFileFilter(filter);
    258         int returnVal = chooser.showDialog(Gatherer.g_man, Dictionary.get("MSMPrompt.File_Import"));
    259         if (returnVal == JFileChooser.APPROVE_OPTION) {
    260         Gatherer.c_man.getCollection().msm.importMDS(chooser.getSelectedFile(), true);
    261         }
    262     }
    263     else if(esrc == menu_bar.metadata_edit) {
    264         showEditMetadataBox();
    265     }
    266     else if(esrc == menu_bar.metadata_export) {
    267         Gatherer.c_man.getCollection().msm.exportMDS();
    268     }
    269     else if(esrc == menu_bar.metadata_view) {
    270         showMetaAuditBox();
    271     }
     256//  else if (esrc == menu_bar.metadata_view) {
     257//      showMetaAuditBox();
     258//  }
    272259
    273260    // *************
     
    658645    }
    659646
    660     /** When the edit metadata option is choosen from the menu, this method is called to ensure we only edit the metadata if there is metadata loaded.
    661      */
    662     private void showEditMetadataBox() {
    663     if(Gatherer.c_man.getCollection() != null) {
    664         Gatherer.c_man.getCollection().msm.editMDS(null, MetadataEditorManager.NORMAL);
    665     }
    666     }
    667647    /** When the load collection option is choosen this method is called to produce the modal file load prompt.
    668648     */
     
    814794    //case SaveCollectionBox.SAVE_YES:
    815795    Gatherer.c_man.setClosingThread(true);
     796    // System.err.println("Here 2.");
    816797    Gatherer.c_man.saveCollection(close_after, exit_after);
     798    // System.err.println("Here 3.");
    817799    // Wait until it is closed.
    818800    try {
     
    823805        }
    824806    }
    825     catch(Exception error) {
    826         DebugStream.println("Exception: " + error);
    827         DebugStream.printStackTrace(error);
     807    catch (Exception exception) {
     808        DebugStream.printStackTrace(exception);
    828809    }
    829810   
     
    859840    }
    860841    // "View assigned metadata" menu item is disabled by default
    861     menu_bar.metadata_view.setCanEnable(false);
     842    // menu_bar.metadata_view.setCanEnable(false);
    862843    menu_bar.setMetaAuditSuffix(null);
    863844
     
    867848        gather_pane.gainFocus();
    868849        // "View assigned metadata" menu item is enabled for the "Gather" pane
    869         menu_bar.metadata_view.setCanEnable(true);
     850        // menu_bar.metadata_view.setCanEnable(true);
    870851    }
    871852    else if(selected_index == tab_pane.indexOfComponent(enrich_pane)) {
    872853        enrich_pane.gainFocus();
    873854        // "View assigned metadata" menu item is enabled for the "Enrich" pane
    874         menu_bar.metadata_view.setCanEnable(true);
     855        // menu_bar.metadata_view.setCanEnable(true);
    875856    }
    876857    else if(selected_index == tab_pane.indexOfComponent(design_pane)) {
     
    953934
    954935
    955     private class MDSFileFilter
    956     extends FileFilter
    957     {
    958     /** Override this method to return <i>true</i> only if the file extension is .mds.
    959      * @param f A possible mds <strong>File</strong>.
    960      * @return <i>true</i> if we should show this file, <i>false</i> otherwise.
    961      */
    962     public boolean accept(File f)
    963     {
    964         String file_name = f.getName().toLowerCase();
    965         if (file_name.endsWith(".mds") || file_name.indexOf(".") == -1) {
    966         return true;
    967         }
    968         return false;
    969     }
    970 
    971     /** Retrieve the description for this filter.
    972      * @return The description as a <strong>String</strong>.
    973      */
    974     public String getDescription()
    975     {
    976         return Dictionary.get("MSMPrompt.File_Filter_Description");
    977     }
    978     }
    979 
    980 
    981936    /** Listens to actions upon the menu bar, and if it detects a click over the help menu brings the help window to the front if it has become hidden.
    982937     */
  • trunk/gli/src/org/greenstone/gatherer/gui/MenuBar.java

    r8238 r8313  
    5757    private JMenu file               = null;
    5858    private JMenu edit               = null;
    59     private JMenu metadata           = null;
    6059    public JMenu help                = null;
    6160    public JMenuItem file_associations;
     
    7170    public JMenuItem edit_cut;
    7271    public JMenuItem edit_paste;
    73     public JMenuItem metadata_import = null;
    74     public JMenuItem metadata_edit   = null;
    75     public JMenuItem metadata_export = null;
    7672    public JMenuItem help_about;
    7773    public JMenuItem help_browse;
     
    8480    public JMenuItem help_mirror ;
    8581    public JMenuItem help_preview;
    86     public MagicMenuItem metadata_view   = null;
    8782
    8883    public MenuBar(MenuListener menu_listener)
     
    178173    edit.add(edit_paste);
    179174
    180     // Metadata menu
    181     metadata = new JMenu();
    182     metadata.setEnabled(false);
    183     metadata.setMnemonic(KeyEvent.VK_M);
    184     Dictionary.registerText(metadata, "Menu.Metadata");
    185 
    186     metadata_import = new JMenuItem();
    187     metadata_import.addActionListener(Gatherer.g_man);
    188     metadata_import.setMnemonic(KeyEvent.VK_I);
    189     Dictionary.registerText(metadata_import, "Menu.Metadata_Import");
    190 
    191     metadata_edit = new JMenuItem();
    192     metadata_edit.addActionListener(Gatherer.g_man);
    193     metadata_edit.setMnemonic(KeyEvent.VK_E);
    194     Dictionary.registerText(metadata_edit, "Menu.Metadata_Edit");
    195 
    196     metadata_export = new JMenuItem();
    197     metadata_export.addActionListener(Gatherer.g_man);
    198     metadata_export.setMnemonic(KeyEvent.VK_X);
    199     Dictionary.registerText(metadata_export, "Menu.Metadata_Export");
    200 
    201     metadata_view = new MagicMenuItem(Dictionary.get("Menu.Metadata_View") + " " + Dictionary.get("FileActions.No_Selection"), KeyEvent.VK_A);
    202     metadata_view.addActionListener(Gatherer.g_man);   
    203 
    204     // Layout (metadata sets menu)
    205     metadata.add(metadata_import);
    206     metadata.add(metadata_edit);
    207     metadata.add(metadata_export);
    208     metadata.add(metadata_view);
    209 
    210175    // Help menu
    211176    help = new JMenu();
     
    287252    this.add(Box.createHorizontalStrut(15));
    288253    this.add(edit);
    289     this.add(Box.createHorizontalStrut(15));
    290     this.add(metadata);
    291254    this.add(Box.createHorizontalGlue());
    292255    this.add(help);
     
    296259    file_close.setEnabled(ready);
    297260    file_save.setEnabled(ready);
    298     metadata.setEnabled(ready);
    299261    }
    300262
     
    303265    file.setEnabled(false);
    304266    edit.setEnabled(false);
    305     metadata.setEnabled(false);
    306267    help.setEnabled(false);
    307268    }
    308269
    309270    public void setMetaAuditSuffix(String metaaudit_suffix) {
    310     ///ystem.err.println("**** Set suffix: " + metaaudit_suffix);
    311     if(metaaudit_suffix == null) {
    312         metadata_view.setText(Dictionary.get("Menu.Metadata_View") + " " + Dictionary.get("FileActions.No_Selection"));
    313         metadata_view.setEnabled(false);
    314     }
    315     else {
    316         ///ystem.err.println("Set metadata view suffix: " + metaaudit_suffix);
    317         metadata_view.setText(Dictionary.get("Menu.Metadata_View") + " " + metaaudit_suffix);
    318         metadata_view.setEnabled(true);
    319     }
     271// ///ystem.err.println("**** Set suffix: " + metaaudit_suffix);
     272// if(metaaudit_suffix == null) {
     273//      metadata_view.setText(Dictionary.get("Menu.Metadata_View") + " " + Dictionary.get("FileActions.No_Selection"));
     274//      metadata_view.setEnabled(false);
     275// }
     276// else {
     277//      ///ystem.err.println("Set metadata view suffix: " + metaaudit_suffix);
     278//      metadata_view.setText(Dictionary.get("Menu.Metadata_View") + " " + metaaudit_suffix);
     279//      metadata_view.setEnabled(true);
     280// }
    320281    }
    321282
     
    344305
    345306
    346     public class MagicMenuItem
    347     extends JMenuItem {
    348 
    349     private boolean can_enable;
    350     private boolean should_enable;
    351 
    352     public MagicMenuItem(String title, int key_event) {
    353         super(title, key_event);
    354         super.setEnabled(false);
    355         can_enable = false;
    356         should_enable = false;
    357     }
    358 
    359     public void setCanEnable(boolean can_enable) {
    360         this.can_enable = can_enable;
    361         if (can_enable) {
    362         super.setEnabled(should_enable);
    363         }
    364         else {
    365         super.setEnabled(false);
    366         }
    367     }
    368 
    369     public void setEnabled(boolean should_enable) {
    370         this.should_enable = should_enable;
    371         if (can_enable) {
    372         super.setEnabled(should_enable);
    373         }
    374     }
    375     }
     307//     public class MagicMenuItem
     308// extends JMenuItem {
     309
     310// private boolean can_enable;
     311// private boolean should_enable;
     312
     313// public MagicMenuItem(String title, int key_event) {
     314//      super(title, key_event);
     315//      super.setEnabled(false);
     316//      can_enable = false;
     317//      should_enable = false;
     318// }
     319
     320// public void setCanEnable(boolean can_enable) {
     321//      this.can_enable = can_enable;
     322//      if (can_enable) {
     323//      super.setEnabled(should_enable);
     324//      }
     325//      else {
     326//      super.setEnabled(false);
     327//      }
     328// }
     329
     330// public void setEnabled(boolean should_enable) {
     331//      this.should_enable = should_enable;
     332//      if (can_enable) {
     333//      super.setEnabled(should_enable);
     334//      }
     335// }
     336//     }
    376337}
  • trunk/gli/src/org/greenstone/gatherer/gui/NewCollectionMetadataPrompt.java

    r8243 r8313  
    3232import java.util.*;
    3333import javax.swing.*;
     34import javax.swing.border.*;
    3435import javax.swing.event.*;
    3536import org.greenstone.gatherer.Configuration;
    3637import org.greenstone.gatherer.Dictionary;
    3738import org.greenstone.gatherer.Gatherer;
    38 import org.greenstone.gatherer.checklist.CheckList;
    39 import org.greenstone.gatherer.checklist.Entry;
    40 import org.greenstone.gatherer.cdm.ElementWrapper;
    41 import org.greenstone.gatherer.msm.MetadataSet;
    42 import org.greenstone.gatherer.util.StaticStrings;
     39import org.greenstone.gatherer.metadata.MetadataElement;
     40import org.greenstone.gatherer.metadata.MetadataSet;
     41import org.greenstone.gatherer.metadata.MetadataSetManager;
     42import org.greenstone.gatherer.metadata.MetadataTools;
    4343import org.greenstone.gatherer.util.Utility;
    44 import org.w3c.dom.*;
     44
    4545
    4646public class NewCollectionMetadataPrompt
     
    4848
    4949    private boolean cancelled = true;
    50     private CheckList sets_list;
    5150    private JDialog self;
    5251    private JList elements_list;
     52    private MetadataSetList sets_list;
    5353    static private Dimension size = new Dimension(700, 380);
    5454
     
    6868    setModal(true);
    6969    setSize(size);
    70    
    71 
    72     // And the remaining metadata sets.
    73     ArrayList sets = new ArrayList();
    74     // Determine what collections are available.
    75     File metadata_directory = new File(Utility.METADATA_DIR);
    76     File[] possible_mdses = metadata_directory.listFiles();
    77     for(int i = 0; i < possible_mdses.length; i++) {
    78         String name = possible_mdses[i].getName();
    79         if(name.endsWith(StaticStrings.METADATA_SET_EXTENSION) && !name.equals(Utility.EXTRACTED_METADATA_NAMESPACE + StaticStrings.METADATA_SET_EXTENSION)) {
    80         sets.add(new MetadataSet(possible_mdses[i]));
    81         }
     70
     71    // Show the metadata sets (except extracted!) available in the GLI "metadata" folder
     72    ArrayList sets = MetadataSetManager.listMetadataSets(new File(Utility.METADATA_DIR));
     73    ArrayList metadata_set_list_entries = new ArrayList();
     74    for (int i = 0; i < sets.size(); i++) {
     75        MetadataSet metadata_set = (MetadataSet) sets.get(i);
     76
     77        // Don't show the extracted metadata set
     78        if (metadata_set.getNamespace().equals(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE)) {
     79        continue;
     80        }
     81
     82        metadata_set_list_entries.add(new MetadataSetListEntry(metadata_set));
    8283    }
    8384
     
    9798    sets_list_label.setOpaque(false);
    9899    Dictionary.setText(sets_list_label, "NewCollectionPrompt.Select_MDS");
    99     sets_list = new CheckList(sets, true);
     100    sets_list = new MetadataSetList();
     101    sets_list.setListData(new Vector(metadata_set_list_entries));
     102    sets_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    100103
    101104    JPanel elements_list_pane = new JPanel();
     
    103106    Dictionary.setText(elements_list_label, "NewCollectionPrompt.Metadata_Elements");
    104107    elements_list = new JList();
     108    elements_list.setCellRenderer(new MetadataElementListCellRenderer());
    105109    elements_list.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
    106110    elements_list.setForeground(Configuration.getColor("coloring.collection_tree_foreground", false));
    107111    elements_list.setSelectionBackground(Configuration.getColor("coloring.collection_tree_background", false));
    108112    elements_list.setSelectionForeground(Configuration.getColor("coloring.collection_tree_foreground", false));
     113
     114    // Select the Dublin Core metadata set by default, at Ian's request
     115    sets_list.selectDublinCoreMetadataSet();
    109116
    110117    JPanel button_pane = new JPanel();
     
    119126    ok_button.addActionListener(new OKButtonListener());
    120127    cancel_button.addActionListener(new CancelButtonListener());
    121     sets_list.addListSelectionListener(new MetadataListSelectionListener());
    122128
    123129    // Display
     
    157163
    158164    public ArrayList getSets() {
    159     return sets_list.getSelected();
     165    return sets_list.getSelectedMetadataSets();
    160166    }
    161167
     
    163169    return cancelled;
    164170    }
     171
    165172
    166173    private class CancelButtonListener
     
    172179    }
    173180
    174     public class MetadataListSelectionListener
    175     implements ListSelectionListener {
    176     public void valueChanged(ListSelectionEvent event) {
    177         if(!sets_list.isSelectionEmpty()) {
    178         // Retrieve the selected set.
    179         Entry entry = (Entry) sets_list.getSelectedValue();
    180         MetadataSet set = (MetadataSet) entry.getObject();
    181         entry = null;
    182         // Build a model from its elements.
    183         NodeList elements = set.getElements();
    184         set = null;
    185         Vector elements_model = new Vector();
    186         for(int i = 0; i < elements.getLength(); i++) {
    187             elements_model.add(new ElementWrapper(elements.item(i)));
    188         }
    189         elements = null;
    190         Collections.sort(elements_model);
    191         elements_list.setListData(elements_model);
    192         elements_model = null;
    193         }
    194         else {
    195         elements_list.setListData(new String[0]);
    196         }
    197     }
    198     }
    199 
    200     public class OKButtonListener
     181
     182    private class MetadataSetList
     183    extends JList
     184    {
     185    public MetadataSetList()
     186    {
     187        super();
     188        addListSelectionListener(new MetadataSetListSelectionListener());
     189        addMouseListener(new MetadataSetListSelectionListener());
     190        setCellRenderer(new MetadataSetListCellRenderer());
     191    }
     192
     193
     194    public ArrayList getSelectedMetadataSets()
     195    {
     196        ArrayList selected_metadata_sets = new ArrayList();
     197
     198        ListModel model = (ListModel) getModel();
     199        for (int i = 0; i < model.getSize(); i++) {
     200        MetadataSetListEntry metadata_set_list_entry = (MetadataSetListEntry) model.getElementAt(i);
     201        if (metadata_set_list_entry.isSelected()) {
     202            selected_metadata_sets.add(metadata_set_list_entry.getMetadataSet());
     203        }
     204        }
     205
     206        return selected_metadata_sets;
     207    }
     208
     209
     210    /** Hack special-case code, used to select the Dublin Core metadata set by default */
     211    public void selectDublinCoreMetadataSet()
     212    {
     213        ListModel model = (ListModel) getModel();
     214        for (int i = 0; i < model.getSize(); i++) {
     215        MetadataSetListEntry metadata_set_list_entry = (MetadataSetListEntry) model.getElementAt(i);
     216        if (metadata_set_list_entry.getMetadataSet().getNamespace().equals("dc")) {
     217            metadata_set_list_entry.setSelected(true);
     218            metadata_set_list_entry.grabFocus();
     219            setSelectedIndex(i);
     220        }
     221        }
     222    }
     223
     224
     225    private class MetadataSetListCellRenderer
     226        extends JLabel
     227        implements ListCellRenderer {
     228
     229        public Component getListCellRendererComponent(JList list, Object value, int index, boolean is_selected, boolean cell_has_focus)
     230        {
     231        JCheckBox checkbox = (JCheckBox) value;
     232        checkbox.setBackground(is_selected ? list.getSelectionBackground() : list.getBackground());
     233        checkbox.setForeground(is_selected ? list.getSelectionForeground() : list.getForeground());
     234        checkbox.setBorderPainted(true);
     235        checkbox.setEnabled(list.isEnabled());
     236        checkbox.setFont(list.getFont());
     237        checkbox.setFocusPainted(false);
     238        checkbox.setBorder((is_selected) ? UIManager.getBorder("List.focusCellHighlightBorder") : new EmptyBorder(1, 1, 1, 1));
     239        return checkbox;
     240        }
     241    }
     242
     243
     244    private class MetadataSetListSelectionListener
     245        extends MouseAdapter
     246        implements ListSelectionListener {
     247
     248        public void mousePressed(MouseEvent e)
     249        {
     250        JList list = (JList) e.getSource();
     251        int index = list.locationToIndex(e.getPoint());
     252        MetadataSetListEntry metadata_set_list_entry = (MetadataSetListEntry) list.getModel().getElementAt(index);
     253        metadata_set_list_entry.setSelected(!metadata_set_list_entry.isSelected());
     254        metadata_set_list_entry.grabFocus();
     255
     256        // Fire a selection changed event
     257        fireSelectionValueChanged(index, index, false);
     258        }
     259
     260        public void valueChanged(ListSelectionEvent event)
     261        {
     262        if (!sets_list.isSelectionEmpty()) {
     263            // Retrieve the selected set
     264            MetadataSetListEntry metadata_set_list_entry = (MetadataSetListEntry) sets_list.getSelectedValue();
     265            MetadataSet set = (MetadataSet) metadata_set_list_entry.getMetadataSet();
     266            elements_list.setListData(new Vector(set.getMetadataSetElements()));
     267        }
     268        else {
     269            elements_list.setListData(new String[0]);
     270        }
     271        }
     272    }
     273    }
     274
     275
     276    private class MetadataSetListEntry
     277    extends JCheckBox
     278    {
     279    private MetadataSet metadata_set = null;
     280
     281    public MetadataSetListEntry(MetadataSet metadata_set)
     282    {
     283        this.metadata_set = metadata_set;
     284    }
     285
     286    public MetadataSet getMetadataSet()
     287    {
     288        return metadata_set;
     289    }
     290
     291    public String getText()
     292    {
     293        if (metadata_set == null) {
     294        return null;
     295        }
     296
     297        String interface_language_code = Configuration.getLanguage();
     298        String metadata_set_name = MetadataTools.getMetadataSetAttribute(metadata_set, "Name", interface_language_code, "en");
     299        return metadata_set_name + " (" + metadata_set.getNamespace() + ")";
     300    }
     301    }
     302
     303
     304    private class OKButtonListener
    201305    implements ActionListener {
    202306    public void actionPerformed(ActionEvent event) {
    203307        // See if the user has selected no metadata sets, and if so confirm thats what they really want.
    204         ArrayList selected_sets = sets_list.getSelected();
     308        ArrayList selected_sets = sets_list.getSelectedMetadataSets();
    205309        cancelled = false;
    206310        if(selected_sets.size() == 0) {
  • trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java

    r8236 r8313  
    5252import org.greenstone.gatherer.collection.Collection;
    5353import org.greenstone.gatherer.collection.CollectionManager;
     54import org.greenstone.gatherer.metadata.MetadataSetManager;
    5455import org.greenstone.gatherer.util.AppendLineOnlyFileDocument;
    5556import org.greenstone.gatherer.util.AppendLineOnlyFileDocumentOwner;
     
    424425        }
    425426        if (argument.getType() == Argument.METADATUM) {
    426             Vector meta_list = Gatherer.c_man.getCollection().msm.getAssignedElements();
    427             for (int i = 0; i < meta_list.size(); i++) {
    428             combobox.addItem(meta_list.get(i));
     427            ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
     428            for (int i = 0; i < every_metadata_set_element.size(); i++) {
     429            combobox.addItem(every_metadata_set_element.get(i));
    429430            }
    430431        }
  • trunk/gli/src/org/greenstone/gatherer/gui/metaaudit/HeaderListener.java

    r8243 r8313  
    3737package org.greenstone.gatherer.gui.metaaudit;
    3838
    39 /**************************************************************************************
    40  * Title:        Gatherer
    41  * Description:  The Gatherer: a tool for gathering and enriching a digital collection.
    42  * Company:      The University of Waikato
    43  * Written:      03/09/02
    44  * Revised:     
    45  * @author John Thompson, 9826509
    46  * @version 2.3
    47  **************************************************************************************/
     39
    4840import de.qfs.lib.gui.TableModelSorter;
    4941import java.awt.event.MouseAdapter;
    5042import java.awt.event.MouseEvent;
    5143import java.util.ArrayList;
     44import org.greenstone.gatherer.metadata.MetadataAuditTableModel;
    5245
    5346public class HeaderListener
     
    6760    Filter filter_model = table.getFilter();
    6861    Autofilter filter = filter_model.getFilter(clicked_column);
    69     MetaAuditModel model = table.getOriginalModel();
     62    MetadataAuditTableModel model = table.getOriginalModel();
    7063    ArrayList default_values = model.getColumnValues(clicked_column);
    7164    String column_name = model.getColumnName(clicked_column);
  • trunk/gli/src/org/greenstone/gatherer/gui/metaaudit/MetaAuditTable.java

    r8243 r8313  
    4444import javax.swing.table.*;
    4545import org.greenstone.gatherer.file.FileNode;
     46import org.greenstone.gatherer.metadata.MetadataAuditTableModel;
     47
    4648
    4749/**
     
    6365    private MetaAuditFrame parent_frame;
    6466
    65     private MetaAuditModel model;
     67    private MetadataAuditTableModel metadata_audit_table_model;
    6668
    6769    private SortedTableHelper helper;
     
    8385    }
    8486
    85     public MetaAuditModel getOriginalModel() {
    86     return model;
    87     }
     87
     88   public MetadataAuditTableModel getOriginalModel()
     89   {
     90      return metadata_audit_table_model;
     91   }
     92
    8893
    8994    public TableModelSorter getSorter() {
     
    105110    wait(true);
    106111    initial_state = true;
    107     ///ystem.err.println("Build new Model - should only be called once per click!");
    108     model = new MetaAuditModel(records);
    109     setModel(model);
    110     filter = new Filter(model.getColumnCount());
     112    // System.err.println("Build new Model - should only be called once per click!");
     113    metadata_audit_table_model = new MetadataAuditTableModel();
     114    metadata_audit_table_model.rebuild(records);
     115    setModel(metadata_audit_table_model);
     116    filter = new Filter(metadata_audit_table_model.getColumnCount());
    111117    helper = new SortedTableHelper (this, filter, new DefaultTableModelSorter(), header_renderer, null);
    112118    helper.prepareTable();
  • trunk/gli/src/org/greenstone/gatherer/shell/GShell.java

    r8250 r8313  
    5353import org.greenstone.gatherer.cdm.CollectionMetaManager;
    5454import org.greenstone.gatherer.cdm.CollectionMeta;
    55 import org.greenstone.gatherer.msm.GreenstoneArchiveParser;
     55import org.greenstone.gatherer.metadata.DocXMLFileManager;
    5656import org.greenstone.gatherer.util.StaticStrings;
    5757import org.greenstone.gatherer.util.Utility;
     
    542542        }
    543543
    544         // extract any new metadata from the archive directory.
     544        // Refresh the DocXMLFileManager
    545545        fireMessage(type, typeAsString(type) + "> " + Dictionary.get("GShell.Parsing_Metadata_Start"), status, null);
    546         new GreenstoneArchiveParser(progress, this);
     546        DocXMLFileManager.clearDocXMLFiles();
     547        DocXMLFileManager.loadDocXMLFiles(new File(Gatherer.c_man.getCollectionArchive()));
    547548        fireMessage(type, typeAsString(type) + "> " + Dictionary.get("GShell.Parsing_Metadata_Complete"), status, null);
    548549        }
    549550
    550         else if(type == BUILD) {
     551//      else if(type == BUILD) {
    551552       
    552         // download the building directory (if gsdl server is remote)           
    553         if (Gatherer.isGsdlRemote) {
    554             if (progress!=null) {
    555             progress.messageOnProgressBar("Downloading index data from server");
    556             }
    557 
    558             Utility.delete(Gatherer.c_man.getCollectionBuild()); // remove current build dir
    559             GathererApplet.download_url_zip(col_name,"building");
    560             Utility.unzip(col_name);
    561 
    562             if (progress!=null) {
    563             progress.messageOnProgressBar("");
    564             }
    565 
    566         }
    567 
    568         }
     553//      // download the building directory (if gsdl server is remote)           
     554//      if (Gatherer.isGsdlRemote) {
     555//          if (progress!=null) {
     556//          progress.messageOnProgressBar("Downloading index data from server");
     557//          }
     558
     559//          Utility.delete(Gatherer.c_man.getCollectionBuild()); // remove current build dir
     560//          GathererApplet.download_url_zip(col_name,"building");
     561//          Utility.unzip(col_name);
     562
     563//          if (progress!=null) {
     564//          progress.messageOnProgressBar("");
     565//          }
     566
     567//      }
     568
     569//      }
    569570    }
    570571
Note: See TracChangeset for help on using the changeset viewer.