Ignore:
Timestamp:
2003-05-27T15:34:50+12:00 (21 years ago)
Author:
kjdon
Message:

re-tabbed the code for java

File:
1 edited

Legend:

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

    r4293 r4363  
    6161 */
    6262final public class CustomAZList
    63     implements CustomClassifier {
    64     /** When this the control dialog is disposed, should we go ahead a add this custom AZ list (by processing all file records and building a new hierarchy)? */
    65     private boolean process = false;
    66     /** A reference to the Gatherer for access to the Collection and MetadataSetManager. */
    67     private Gatherer gatherer = null;
    68     /** A mapping from a String pattern to a specific GValueNode within the hidden hierarchy. */
    69     private Hashtable mappings = null;
    70     /** The button used to cancel the dialog. */
    71     private JButton cancel = null;
    72     /** The button used to confirm and close the dialog. */
    73     private JButton ok = null;
    74     /** The dialog which contains the controls for configuring this custom classifier. */
    75     private JDialog controls = null;
    76     /** The checkbox used to indicate whether there is a name given for the classifier button (in the Greenstone collections menubar). */
    77     private JCheckBox buttonname_label = null;
    78     /** The checkbox used to indicate that the final classifier should be sorted in some way. */
    79     private JCheckBox sort_label = null;
    80     /** The control allowing you to choose the assigned metadata this classifier should be based on. */
    81     private JComboBox metadata = null;
    82     /** The metadata the final classifier should be sorted by. */
    83     private JComboBox sort = null;
    84     /** A field for entering the button name. */
    85     private JTextField buttonname = null;
    86     /** A field which provides a clear indication of the current ranges selected for your custom classifier. */
    87     private JTextField separators_preview = null;
    88     /** An array of togglebuttons showing what separations are available. */
    89     private JToggleButton separators[] = null;
    90     /** A private dictionary for this custom classifier. */
    91     private ResourceBundle dictionary = null;
    92     /** The name of the hidden metadata. We at least luck out in that we don't need a live reference to the metadata, because the user can never change it (or if they do its their own stinking fault). */
    93     private String hidden_mde_name = null;
    94     /** The name of this pseudo-classifier. */
    95     final static public String NAME = "CustomAZList";
    96     /** The size of a label. */
    97     final static private Dimension LABEL_SIZE = new Dimension(200,25);
    98     /** The size of the controls for this pseudo-classifier. */
    99     final static private Dimension SIZE = new Dimension(550,400);
    100     /** An array of values for the separators. */
    101     final static private String VALUES[] = {"Numbers", "A", "B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    102     /** The same array as above, except as integer values (note that "Numbers" becomes "#"). */
    103     static public int INT_VALUES[] = {'#','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
    104     /** A third array which is almost the same as the others (can anyone else say poor code reuse) but subsitutes "#" for "Numbers". */
    105     static public String STRING_VALUES[] = {"#","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    106     /** Default Constructor. Needed to load this class dynamically. */
    107     public CustomAZList() {}
    108     /** Constructor.
     63    implements CustomClassifier {
     64    /** When this the control dialog is disposed, should we go ahead a add this custom AZ list (by processing all file records and building a new hierarchy)? */
     65    private boolean process = false;
     66    /** A reference to the Gatherer for access to the Collection and MetadataSetManager. */
     67    private Gatherer gatherer = null;
     68    /** A mapping from a String pattern to a specific GValueNode within the hidden hierarchy. */
     69    private Hashtable mappings = null;
     70    /** The button used to cancel the dialog. */
     71    private JButton cancel = null;
     72    /** The button used to confirm and close the dialog. */
     73    private JButton ok = null;
     74    /** The dialog which contains the controls for configuring this custom classifier. */
     75    private JDialog controls = null;
     76    /** The checkbox used to indicate whether there is a name given for the classifier button (in the Greenstone collections menubar). */
     77    private JCheckBox buttonname_label = null;
     78    /** The checkbox used to indicate that the final classifier should be sorted in some way. */
     79    private JCheckBox sort_label = null;
     80    /** The control allowing you to choose the assigned metadata this classifier should be based on. */
     81    private JComboBox metadata = null;
     82    /** The metadata the final classifier should be sorted by. */
     83    private JComboBox sort = null;
     84    /** A field for entering the button name. */
     85    private JTextField buttonname = null;
     86    /** A field which provides a clear indication of the current ranges selected for your custom classifier. */
     87    private JTextField separators_preview = null;
     88    /** An array of togglebuttons showing what separations are available. */
     89    private JToggleButton separators[] = null;
     90    /** A private dictionary for this custom classifier. */
     91    private ResourceBundle dictionary = null;
     92    /** The name of the hidden metadata. We at least luck out in that we don't need a live reference to the metadata, because the user can never change it (or if they do its their own stinking fault). */
     93    private String hidden_mde_name = null;
     94    /** The name of this pseudo-classifier. */
     95    final static public String NAME = "CustomAZList";
     96    /** The size of a label. */
     97    final static private Dimension LABEL_SIZE = new Dimension(200,25);
     98    /** The size of the controls for this pseudo-classifier. */
     99    final static private Dimension SIZE = new Dimension(550,400);
     100    /** An array of values for the separators. */
     101    final static private String VALUES[] = {"Numbers", "A", "B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
     102    /** The same array as above, except as integer values (note that "Numbers" becomes "#"). */
     103    static public int INT_VALUES[] = {'#','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
     104    /** A third array which is almost the same as the others (can anyone else say poor code reuse) but subsitutes "#" for "Numbers". */
     105    static public String STRING_VALUES[] = {"#","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
     106    /** Default Constructor. Needed to load this class dynamically. */
     107    public CustomAZList() {}
     108    /** Constructor.
    109109      * @param gatherer A reference to the <strong>Gatherer</strong>.
    110110      */
    111     public CustomAZList(Gatherer gatherer) {
    112           this.gatherer = gatherer;
    113     }
    114     /** Used to compare this classifier to another classifier for the purposes of ordering.
     111    public CustomAZList(Gatherer gatherer) {
     112    this.gatherer = gatherer;
     113    }
     114    /** Used to compare this classifier to another classifier for the purposes of ordering.
    115115      * @param object The other classifier as an <strong>Object</strong>.
    116116      * @see org.greenstone.gatherer.cdm.Classifier
    117117      * @see org.greenstone.gatherer.cdm.CustomClassifier
    118118      */
    119     public int compareTo(Object object) {
    120           if(object instanceof Classifier) {
    121                 Classifier classifier = (Classifier) object;
    122                 return NAME.compareTo(classifier.getName());
    123           }
    124           else if(object instanceof CustomClassifier) {
    125                 CustomClassifier classifier = (CustomClassifier) object;
    126                 return NAME.compareTo(classifier.getName());
    127           }             
    128           return NAME.compareTo(object.toString());
    129     }
    130     /** Ensure that the dialog can be correctly garbage collected. */
    131     public void destroy() {
    132           controls = null;
    133     }
    134     /** Produce a new copy of this custom classifier. Remember that what the classifier manager does is create instances of all possible classifiers, then as they are assigned creates and assigns copies of the original reserve. This way we only have to parse arguments once.
     119    public int compareTo(Object object) {
     120    if(object instanceof Classifier) {
     121        Classifier classifier = (Classifier) object;
     122        return NAME.compareTo(classifier.getName());
     123    }
     124    else if(object instanceof CustomClassifier) {
     125        CustomClassifier classifier = (CustomClassifier) object;
     126        return NAME.compareTo(classifier.getName());
     127    }               
     128    return NAME.compareTo(object.toString());   
     129    }
     130    /** Ensure that the dialog can be correctly garbage collected. */
     131    public void destroy() {
     132    controls = null;
     133    }
     134    /** Produce a new copy of this custom classifier. Remember that what the classifier manager does is create instances of all possible classifiers, then as they are assigned creates and assigns copies of the original reserve. This way we only have to parse arguments once.
    135135      * @return A new <strong>CustomClassifier</strong> which is a copy of this one.
    136136      * @see org.greenstone.gatherer.Gatherer
    137137      */
    138     public CustomClassifier copy() {
    139           return new CustomAZList(gatherer);
    140     }
    141     /** Show the controls for configuring this pseudo-classifier.
     138    public CustomClassifier copy() {
     139    return new CustomAZList(gatherer);
     140    }
     141    /** Show the controls for configuring this pseudo-classifier.
    142142      * @param show <i>true</i> to actually display the configuration dialog on screen, <i>false</i> to do everything except show the control and process the data (useful for setting the control up and/or reloading custom classifiers from collect.cfg).
    143143      * @see org.greenstone.gatherer.Configuration
     
    152152      * @see org.greenstone.gatherer.msm.MetadataSetManager
    153153      */
    154     public boolean display(boolean show) {
    155           if(controls == null) {
    156                 Vector elements = gatherer.c_man.getCollection().msm.getAssignedElements();
     154    public boolean display(boolean show) {
     155    if(controls == null) {
     156        Vector elements = gatherer.c_man.getCollection().msm.getAssignedElements();
    157157                // Creation
    158                 controls = new JDialog();
    159                 controls.setModal(true);
    160                 controls.setSize(SIZE);
    161                 controls.setTitle(get("Title_JDialog"));
    162                 JPanel content_pane = (JPanel) controls.getContentPane();
    163                 JPanel upper_pane = new JPanel();
    164                 JPanel metadata_pane = new JPanel();
    165                 JLabel metadata_label = new JLabel(get("Metadata_JLabel"));
    166                 metadata_label.setPreferredSize(LABEL_SIZE);
    167                 metadata = new JComboBox(elements);
    168                 JPanel buttonname_pane = new JPanel();
    169                 buttonname_label = new JCheckBox(get("Buttonname_JCheckBox"));
    170                 buttonname_label.setPreferredSize(LABEL_SIZE);
    171                 buttonname = new JTextField();
    172                 buttonname.setBackground(Color.lightGray);
    173                 buttonname.setEnabled(false);
    174                 JPanel sort_pane = new JPanel();
    175                 sort_label = new JCheckBox(get("Sort_JLabel"));
    176                 sort = new JComboBox(elements);
    177                 JPanel separations_pane = new JPanel();
    178                 JLabel separations_label = new JLabel(get("Separations_JLabel"));
    179                 separations_label.setPreferredSize(LABEL_SIZE);
    180                 separators_preview = new JTextField();
    181                 separators_preview.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    182                 separators_preview.setEnabled(false); // View only.
    183                 separators_preview.setForeground(Color.black);
    184                 JPanel lower_pane = new JPanel();
    185                 JPanel button_pane = new JPanel();
    186                 ok = new JButton(get("OK_JButton"));
    187                 cancel = new JButton(get("Cancel_JButton"));
     158        controls = new JDialog();
     159        controls.setModal(true);
     160        controls.setSize(SIZE);
     161        controls.setTitle(get("Title_JDialog"));
     162        JPanel content_pane = (JPanel) controls.getContentPane();
     163        JPanel upper_pane = new JPanel();
     164        JPanel metadata_pane = new JPanel();
     165        JLabel metadata_label = new JLabel(get("Metadata_JLabel"));
     166        metadata_label.setPreferredSize(LABEL_SIZE);
     167        metadata = new JComboBox(elements);
     168        JPanel buttonname_pane = new JPanel();
     169        buttonname_label = new JCheckBox(get("Buttonname_JCheckBox"));
     170        buttonname_label.setPreferredSize(LABEL_SIZE);
     171        buttonname = new JTextField();
     172        buttonname.setBackground(Color.lightGray);
     173        buttonname.setEnabled(false);
     174        JPanel sort_pane = new JPanel();
     175        sort_label = new JCheckBox(get("Sort_JLabel"));
     176        sort = new JComboBox(elements);
     177        JPanel separations_pane = new JPanel();
     178        JLabel separations_label = new JLabel(get("Separations_JLabel"));
     179        separations_label.setPreferredSize(LABEL_SIZE);
     180        separators_preview = new JTextField();
     181        separators_preview.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     182        separators_preview.setEnabled(false); // View only.
     183        separators_preview.setForeground(Color.black);
     184        JPanel lower_pane = new JPanel();
     185        JPanel button_pane = new JPanel();
     186        ok = new JButton(get("OK_JButton"));
     187        cancel = new JButton(get("Cancel_JButton"));
    188188                // Connection
    189                 buttonname_label.addActionListener(new ButtonNameListener());
    190                 cancel.addActionListener(new CancelListener());
    191                 ok.addActionListener(new OKListener());
    192                 sort_label.addActionListener(new SortListener());
     189        buttonname_label.addActionListener(new ButtonNameListener());
     190        cancel.addActionListener(new CancelListener());
     191        ok.addActionListener(new OKListener());
     192        sort_label.addActionListener(new SortListener());
    193193                // The Toggle Button block. Done all at once so we don't end up with three for loops.
    194                 JPanel center_pane = new JPanel();
    195                 center_pane.setLayout(new GridLayout(3, 9));
    196                 separators = new JToggleButton[VALUES.length];
    197                 SeparatorListener sl = new SeparatorListener();
    198                 for(int i = 0; i < VALUES.length; i++) {
    199                      separators[i] = new JToggleButton(get(VALUES[i]));
    200                      separators[i].addActionListener(sl);
    201                      if(i != 0) {
    202                           center_pane.add(separators[i]);
    203                      }
    204                      else {
    205                           JLabel temp = new JLabel(get(VALUES[0]));
    206                           temp.setHorizontalAlignment(JLabel.CENTER);
    207                           center_pane.add(temp);
    208                      }
    209                 }
    210                 separators_preview.setText(getPreview(true));
     194        JPanel center_pane = new JPanel();
     195        center_pane.setLayout(new GridLayout(3, 9));
     196        separators = new JToggleButton[VALUES.length];
     197        SeparatorListener sl = new SeparatorListener();
     198        for(int i = 0; i < VALUES.length; i++) {
     199        separators[i] = new JToggleButton(get(VALUES[i]));
     200        separators[i].addActionListener(sl);
     201        if(i != 0) {
     202            center_pane.add(separators[i]);
     203        }
     204        else {
     205            JLabel temp = new JLabel(get(VALUES[0]));
     206            temp.setHorizontalAlignment(JLabel.CENTER);
     207            center_pane.add(temp);
     208        }
     209        }
     210        separators_preview.setText(getPreview(true));
    211211                // Layout
    212                 metadata_pane.setBorder(BorderFactory.createEmptyBorder(1,0,1,0));
    213                 metadata_pane.setLayout(new BorderLayout());
    214                 metadata_pane.add(metadata_label, BorderLayout.WEST);
    215                 metadata_pane.add(metadata, BorderLayout.CENTER);
     212        metadata_pane.setBorder(BorderFactory.createEmptyBorder(1,0,1,0));
     213        metadata_pane.setLayout(new BorderLayout());
     214        metadata_pane.add(metadata_label, BorderLayout.WEST);
     215        metadata_pane.add(metadata, BorderLayout.CENTER);
    216216               
    217                 buttonname_pane.setBorder(BorderFactory.createEmptyBorder(1,0,1,0));
    218                 buttonname_pane.setLayout(new BorderLayout());
    219                 buttonname_pane.add(buttonname_label, BorderLayout.WEST);
    220                 buttonname_pane.add(buttonname, BorderLayout.CENTER);
     217        buttonname_pane.setBorder(BorderFactory.createEmptyBorder(1,0,1,0));
     218        buttonname_pane.setLayout(new BorderLayout());
     219        buttonname_pane.add(buttonname_label, BorderLayout.WEST);
     220        buttonname_pane.add(buttonname, BorderLayout.CENTER);
    221221               
    222                 sort_pane.setBorder(BorderFactory.createEmptyBorder(1,0,1,0));
    223                 sort_pane.setLayout(new BorderLayout());
    224                 sort_pane.add(sort_label, BorderLayout.WEST);
    225                 sort_pane.add(sort, BorderLayout.CENTER);
     222        sort_pane.setBorder(BorderFactory.createEmptyBorder(1,0,1,0));
     223        sort_pane.setLayout(new BorderLayout());
     224        sort_pane.add(sort_label, BorderLayout.WEST);
     225        sort_pane.add(sort, BorderLayout.CENTER);
    226226
    227                 upper_pane.setBorder(BorderFactory.createEmptyBorder(0,0,4,0));
    228                 upper_pane.setLayout(new GridLayout(3, 1));
    229                 upper_pane.add(metadata_pane);
    230                 upper_pane.add(buttonname_pane);
    231                 upper_pane.add(separations_label);
     227        upper_pane.setBorder(BorderFactory.createEmptyBorder(0,0,4,0));
     228        upper_pane.setLayout(new GridLayout(3, 1));
     229        upper_pane.add(metadata_pane);
     230        upper_pane.add(buttonname_pane);
     231        upper_pane.add(separations_label);
    232232               
    233                 separations_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,0,5,0), BorderFactory.createRaisedBevelBorder()));
    234                 separations_pane.setLayout(new BorderLayout());
    235                 separations_pane.add(separators_preview, BorderLayout.CENTER);
     233        separations_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,0,5,0), BorderFactory.createRaisedBevelBorder()));
     234        separations_pane.setLayout(new BorderLayout());
     235        separations_pane.add(separators_preview, BorderLayout.CENTER);
    236236               
    237                 lower_pane.setLayout(new GridLayout(2,1));
    238                 lower_pane.add(separations_pane);
    239                 lower_pane.add(button_pane);
     237        lower_pane.setLayout(new GridLayout(2,1));
     238        lower_pane.add(separations_pane);
     239        lower_pane.add(button_pane);
    240240               
    241                 button_pane.setLayout(new GridLayout(1,2));
    242                 button_pane.add(ok);
    243                 button_pane.add(cancel);
     241        button_pane.setLayout(new GridLayout(1,2));
     242        button_pane.add(ok);
     243        button_pane.add(cancel);
    244244               
    245                 content_pane.setBorder(BorderFactory.createEmptyBorder(4,5,5,5));
    246                 content_pane.setLayout(new BorderLayout());
    247                 content_pane.add(upper_pane, BorderLayout.NORTH);
    248                 content_pane.add(center_pane, BorderLayout.CENTER);
    249                 content_pane.add(lower_pane, BorderLayout.SOUTH);
     245        content_pane.setBorder(BorderFactory.createEmptyBorder(4,5,5,5));
     246        content_pane.setLayout(new BorderLayout());
     247        content_pane.add(upper_pane, BorderLayout.NORTH);
     248        content_pane.add(center_pane, BorderLayout.CENTER);
     249        content_pane.add(lower_pane, BorderLayout.SOUTH);
    250250                // Display
    251                 Dimension screen_size = Gatherer.config.screen_size;
    252                 controls.setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
    253                 screen_size = null;
    254                 if(show) {
    255                      controls.show();
    256                      // Create the new metadata, hierarchy etc.
    257                      if(process) {
    258                           process((ElementWrapper)metadata.getSelectedItem(), getPreview(false));
    259                           return true;
    260                      }
    261                      return false;
    262                 }
    263                 else {
    264                      return true;
    265                 }
     251        Dimension screen_size = Gatherer.config.screen_size;
     252        controls.setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
     253        screen_size = null;
     254        if(show) {
     255        controls.show();
     256        // Create the new metadata, hierarchy etc.
     257        if(process) {
     258            process((ElementWrapper)metadata.getSelectedItem(), getPreview(false));
     259            return true;
     260        }
     261        return false;
     262        }
     263        else {
     264        return true;
     265        }
    266266                // We do everything -except- display the control.
    267           }
    268           else {
    269                 process = false;
    270                 controls.show();
    271                 if(process) {
    272                      process((ElementWrapper)metadata.getSelectedItem(), getPreview(false));
    273                      return true;
    274                 }
    275                 return false;
    276           }
    277     }
    278     /** Determine if this classifier and another given classifier are equal.
     267    }
     268    else {
     269        process = false;
     270        controls.show();
     271        if(process) {
     272        process((ElementWrapper)metadata.getSelectedItem(), getPreview(false));
     273        return true;
     274        }
     275        return false;
     276    }
     277    }
     278    /** Determine if this classifier and another given classifier are equal.
    279279      * @param object The classifier to check against for equality, as an <strong>Object</strong>.
    280280      * @see org.greenstone.gatherer.cdm.CustomClassifier
    281281      */
    282     public boolean equals(Object object) {
    283           if(object instanceof CustomClassifier) {
    284                 CustomClassifier classifier = (CustomClassifier) object;
    285                 if(getCommand().equalsIgnoreCase(classifier.getCommand())) {
    286                      return true;
    287                 }
    288                 return false;
    289           }
    290           else {
    291                 if(getCommand().equalsIgnoreCase(object.toString())) {
    292                      return true;
    293                 }
    294                 return false;
    295           }
    296     }
    297     /** Method to return this pseudo-classifier represented as a String.
     282    public boolean equals(Object object) {
     283    if(object instanceof CustomClassifier) {
     284        CustomClassifier classifier = (CustomClassifier) object;
     285        if(getCommand().equalsIgnoreCase(classifier.getCommand())) {
     286        return true;
     287        }
     288        return false;
     289    }
     290    else {
     291        if(getCommand().equalsIgnoreCase(object.toString())) {
     292        return true;
     293        }
     294        return false;
     295    }
     296    }
     297    /** Method to return this pseudo-classifier represented as a String.
    298298      * @return A <strong>String</strong>.
    299299      */
    300     public String getCommand() {
    301           StringBuffer text = new StringBuffer("classify ");
    302           text.append("Hierarchy");
    303           text.append(" -metadata ");
    304           text.append(hidden_mde_name); // @TODO
    305           if(buttonname_label.isSelected()) {
    306                 text.append(" -buttonname \"");
    307                 text.append(buttonname.getText());
    308                 text.append("\"");
    309           }
    310           text.append(" -hfile ");
    311           text.append(hidden_mde_name + ".txt");
    312           text.append(" -hlist_at_top");
    313           text.append("\n");
    314           return text.toString();
    315     }
    316     /** Retrieve the custom command, a command line that overrides and replaces some other 'actual' classifier.
     300    public String getCommand() {
     301    StringBuffer text = new StringBuffer("classify ");
     302    text.append("Hierarchy");
     303    text.append(" -metadata ");
     304    text.append(hidden_mde_name); // @TODO
     305    if(buttonname_label.isSelected()) {
     306        text.append(" -buttonname \"");
     307        text.append(buttonname.getText());
     308        text.append("\"");
     309    }
     310    text.append(" -hfile ");
     311    text.append(hidden_mde_name + ".txt");
     312    text.append(" -hlist_at_top");
     313    text.append("\n");
     314    return text.toString();
     315    }
     316    /** Retrieve the custom command, a command line that overrides and replaces some other 'actual' classifier.
    317317      * @param index The number of the classifer this one is replacing.
    318318      */
    319     public String getCustomCommand(int index) {
    320           StringBuffer text = new StringBuffer("customclassifier ");
    321           text.append(NAME);
    322           text.append(" -replaces CL");
    323           text.append(index);
    324           text.append(" -separations ");
    325           text.append(getPreview(false));
    326           return text.toString();
    327     }
    328     /** Get the name of this custom classifier.
     319    public String getCustomCommand(int index) {
     320    StringBuffer text = new StringBuffer("customclassifier ");
     321    text.append(NAME);
     322    text.append(" -replaces CL");
     323    text.append(index);
     324    text.append(" -separations ");
     325    text.append(getPreview(false));
     326    return text.toString();
     327    }
     328    /** Get the name of this custom classifier.
    329329      * @return The name as a <strong>String</strong>.
    330330      */
    331     public String getName() {
    332           return NAME;
    333     }
    334     /** Process a record by adding hidden metadata as necessary.
     331    public String getName() {
     332    return NAME;
     333    }
     334    /** Process a record by adding hidden metadata as necessary.
    335335      * @param record The <strong>FileNode</strong> to be edited.
    336336      * @see org.greenstone.gatherer.msm.ElementWrapper
    337337      */
    338     public void process(FileNode record) {
    339           ElementWrapper element = (ElementWrapper) metadata.getSelectedItem();
    340           if(element != null) {
    341                 addMetadata(0L, record, element);
    342           }
    343     }
    344     /** Recreate a CustomAZList given several parameters including the real classifier created during custom design.
     338    public void process(FileNode record) {
     339    ElementWrapper element = (ElementWrapper) metadata.getSelectedItem();
     340    if(element != null) {
     341        addMetadata(0L, record, element);
     342    }
     343    }
     344    /** Recreate a CustomAZList given several parameters including the real classifier created during custom design.
    345345      * @param classifier The real <strong>Classifier</strong>.
    346346      * @param separations A <strong>String</strong> representing the choosen separations.
     
    353353      * @see org.greenstone.gatherer.valuetree.GValueNode
    354354      */
    355     public void recreate(Classifier classifier, String separations) {
    356           // Rebuild controls
    357           display(false);
    358           // Calculate original element.
    359           hidden_mde_name = classifier.getArgument("metadata").getValue();
    360           ElementWrapper hidden_mde = gatherer.c_man.getCollection().msm.getElement(hidden_mde_name);
    361           String mde_name = (hidden_mde_name.substring(MetadataSetManager.HIDDEN.length() + 1)).replace('_','.');
    362           ElementWrapper mde = gatherer.c_man.getCollection().msm.getElement(mde_name);
    363           // Set metadata element combobox.
    364           metadata.setSelectedItem(mde);
    365           // Set button name.
    366           String bn = classifier.getArgument("buttonname").getValue();
    367           if(bn != null) {
    368                 buttonname_label.setSelected(true);
    369                 buttonname.setBackground(Color.white);
    370                 buttonname.setEnabled(true);
    371                 buttonname.setText(bn);
    372           }
    373           // Set sort element.
    374           String sort_mde_name = classifier.getArgument("sort").getValue();
    375           ElementWrapper sort_mde = gatherer.c_man.getCollection().msm.getElement(sort_mde_name);
    376           if(sort_mde != null) {
    377                 sort_label.setSelected(true);
    378                 sort.setBackground(Color.white);
    379                 sort.setEnabled(true);
    380                 sort.setSelectedItem(sort_mde);
    381           }
    382           // Recover value tree.
    383           GValueModel model = gatherer.c_man.getCollection().msm.getValueTree(hidden_mde);
    384           // For each token in the tokenizer, set toggle buttons and recover node.
    385           StringTokenizer tokenizer = new StringTokenizer(separations, ",");
    386           mappings = new Hashtable();
    387           while(tokenizer.hasMoreTokens()) {
    388                 String key = tokenizer.nextToken();
    389                 for(int j = 1; j < STRING_VALUES.length; j++) {
    390                      if(key.startsWith(STRING_VALUES[0])) {
    391                           j = STRING_VALUES.length;
    392                      }
    393                      else if(key.startsWith(STRING_VALUES[j])) {
    394                           separators[j].setSelected(true);
    395                           j = STRING_VALUES.length;
    396                      }
    397                 }
     355    public void recreate(Classifier classifier, String separations) {
     356    // Rebuild controls
     357    display(false);
     358    // Calculate original element.
     359    hidden_mde_name = classifier.getArgument("metadata").getValue();
     360    ElementWrapper hidden_mde = gatherer.c_man.getCollection().msm.getElement(hidden_mde_name);
     361    String mde_name = (hidden_mde_name.substring(MetadataSetManager.HIDDEN.length() + 1)).replace('_','.');
     362    ElementWrapper mde = gatherer.c_man.getCollection().msm.getElement(mde_name);
     363    // Set metadata element combobox.
     364    metadata.setSelectedItem(mde);
     365    // Set button name.
     366    String bn = classifier.getArgument("buttonname").getValue();
     367    if(bn != null) {
     368        buttonname_label.setSelected(true);
     369        buttonname.setBackground(Color.white);
     370        buttonname.setEnabled(true);
     371        buttonname.setText(bn);
     372    }
     373    // Set sort element.
     374    String sort_mde_name = classifier.getArgument("sort").getValue();
     375    ElementWrapper sort_mde = gatherer.c_man.getCollection().msm.getElement(sort_mde_name);
     376    if(sort_mde != null) {
     377        sort_label.setSelected(true);
     378        sort.setBackground(Color.white);
     379        sort.setEnabled(true);
     380        sort.setSelectedItem(sort_mde);
     381    }
     382    // Recover value tree.
     383    GValueModel model = gatherer.c_man.getCollection().msm.getValueTree(hidden_mde);
     384    // For each token in the tokenizer, set toggle buttons and recover node.
     385    StringTokenizer tokenizer = new StringTokenizer(separations, ",");
     386    mappings = new Hashtable();
     387    while(tokenizer.hasMoreTokens()) {
     388        String key = tokenizer.nextToken();
     389        for(int j = 1; j < STRING_VALUES.length; j++) {
     390        if(key.startsWith(STRING_VALUES[0])) {
     391            j = STRING_VALUES.length;
     392        }
     393        else if(key.startsWith(STRING_VALUES[j])) {
     394            separators[j].setSelected(true);
     395            j = STRING_VALUES.length;
     396        }
     397        }
    398398                // Rebuild mappings hashtable for this pattern. Add it if not present.
    399                 GValueNode node = model.addValue(key);
     399        GValueNode node = model.addValue(key);
    400400                // If the key is simple, ie "C", then add the mapping "C"->node
    401                 if(node == null) {
    402                      // Do nothing.
    403                 }
    404                 else if(key.indexOf("-") == -1) {
    405                      mappings.put(key, node);
    406                 }
     401        if(node == null) {
     402        // Do nothing.
     403        }
     404        else if(key.indexOf("-") == -1) {
     405        mappings.put(key, node);
     406        }
    407407                // If the key is more complex, say "D-L", then we add mappings for all string values so "D"->node, "E"->node, ... "L"->node. This is miles eaiser to do here, than when you are trying to match a records metadata ie matchin "D-L" to "Igloos are cool". Note that it is guarantee that the keys are all of the same length, ie "A-L", "MA-ML", "MMA-STF", "STFA-ZZZZ".
    408                 else {
    409                      String start = key.substring(0, key.indexOf("-"));
    410                      String end = key.substring(key.indexOf("-") + 1);
    411                      for(key = start; key != null && key.compareTo(end) <= 0; key = increment(key)) {
    412                           ///ystem.err.println("Adding " + key + " -> " + node);
    413                           mappings.put(key, node); 
    414                      }
    415                 }
    416           }
    417           separators_preview.setText(getPreview(true));
    418     }
    419     /** Sets the value of Gatherer, for those classes loaded dynamically.
     408        else {
     409        String start = key.substring(0, key.indexOf("-"));
     410        String end = key.substring(key.indexOf("-") + 1);
     411        for(key = start; key != null && key.compareTo(end) <= 0; key = increment(key)) {
     412            ///ystem.err.println("Adding " + key + " -> " + node);
     413            mappings.put(key, node);   
     414        }
     415        }
     416    }
     417    separators_preview.setText(getPreview(true));
     418    }
     419    /** Sets the value of Gatherer, for those classes loaded dynamically.
    420420      * @param gatherer A reference to the <strong>Gatherer</strong>.
    421421      */
    422     public void setGatherer(Gatherer gatherer) {
    423           this.gatherer = gatherer;
    424     }
     422    public void setGatherer(Gatherer gatherer) {
     423    this.gatherer = gatherer;
     424    }
    425425
    426     public void setManager(ClassifierManager manager) {
    427     }
     426    public void setManager(ClassifierManager manager) {
     427    }
    428428
    429     /** Translate this object into a string such as you would find in the collection configuration file.
     429    /** Translate this object into a string such as you would find in the collection configuration file.
    430430      * @return A <strong>String</strong> representation.
    431431      */
    432     public String toString() {
    433           StringBuffer text = new StringBuffer("classify ");
    434           text.append(NAME);
    435           text.append(" -metadata ");
    436           text.append(metadata.getSelectedItem().toString());
    437           if(buttonname_label.isSelected()) {
    438                 text.append(" -buttonname \"");
    439                 text.append(buttonname.getText());
    440                 text.append("\"");
    441           }
    442           text.append(" -separations ");
    443           text.append(getPreview(false));
    444           return text.toString();
    445     }
    446     /** Add a pertinant piece of metadata to the given record. */
    447     private void addMetadata(long id, FileNode record, ElementWrapper element) {
    448           // Add custom metadata based on target metadata. No recursion.
    449           ArrayList temp_value = Gatherer.c_man.getCollection().gdm.getMetadata(record.getFile(), element);
    450           boolean found = false; // Only want to add the custom classifier metadata once.
    451           for(int i = 0; !found && i < temp_value.size(); i++) {
    452                 String metadata_value = (String)temp_value.get(i);
    453                 for(Enumeration keys = mappings.keys(); metadata_value != null && keys.hasMoreElements(); ) {
    454                      String key = (String)keys.nextElement();
    455                      // Try to match the value and the pattern. Remember to check for any case, ie key is '#' and metadata_value starts with anything other than a character.
    456                      if(metadata_value.toUpperCase().startsWith(key) || (key.equals("#") && !Character.isLetter(metadata_value.charAt(0)))) {
    457                           GValueNode node = (GValueNode) mappings.get(key);
    458                           if(node != null) { // And it shouldn't.
    459                                 Metadata metadata = new Metadata(node);
    460                                 //record.addMetadata(id, metadata, MetaEditPromptBox.ACCUMULATE_ALL, false, 1);
    461                                 Gatherer.c_man.getCollection().msm.fireMetadataChanged(0, record, null, metadata);
    462                                 found = true;
    463                           }
    464                      }
    465                 }
    466           }
    467     }
    468     /** Create a separation preview String from the currently selected toggle buttons.
     432    public String toString() {
     433    StringBuffer text = new StringBuffer("classify ");
     434    text.append(NAME);
     435    text.append(" -metadata ");
     436    text.append(metadata.getSelectedItem().toString());
     437    if(buttonname_label.isSelected()) {
     438        text.append(" -buttonname \"");
     439        text.append(buttonname.getText());
     440        text.append("\"");
     441    }
     442    text.append(" -separations ");
     443    text.append(getPreview(false));
     444    return text.toString();
     445    }
     446    /** Add a pertinant piece of metadata to the given record. */
     447    private void addMetadata(long id, FileNode record, ElementWrapper element) {
     448    // Add custom metadata based on target metadata. No recursion.
     449    ArrayList temp_value = Gatherer.c_man.getCollection().gdm.getMetadata(record.getFile(), element);
     450    boolean found = false; // Only want to add the custom classifier metadata once.
     451    for(int i = 0; !found && i < temp_value.size(); i++) {
     452        String metadata_value = (String)temp_value.get(i);
     453        for(Enumeration keys = mappings.keys(); metadata_value != null && keys.hasMoreElements(); ) {
     454        String key = (String)keys.nextElement();
     455        // Try to match the value and the pattern. Remember to check for any case, ie key is '#' and metadata_value starts with anything other than a character.
     456        if(metadata_value.toUpperCase().startsWith(key) || (key.equals("#") && !Character.isLetter(metadata_value.charAt(0)))) {
     457            GValueNode node = (GValueNode) mappings.get(key);
     458            if(node != null) { // And it shouldn't.
     459            Metadata metadata = new Metadata(node);
     460            //record.addMetadata(id, metadata, MetaEditPromptBox.ACCUMULATE_ALL, false, 1);
     461            Gatherer.c_man.getCollection().msm.fireMetadataChanged(0, record, null, metadata);
     462            found = true;
     463            }
     464        }
     465        }
     466    }
     467    }
     468    /** Create a separation preview String from the currently selected toggle buttons.
    469469      * @param spaces <i>true</i> if the returned String should contain spaces for readability, <i>false</i> if we mean to process it and spaces would just make that more difficult.
    470470      * @return A <strong>String</strong> representing the current separation state, such as "#, A-L, M-Z".
    471471      */
    472     private String getPreview(boolean spaces) {
    473           String sep_sep = ",";
    474           if(spaces) {
    475                 sep_sep = ", ";
    476           }
    477           StringBuffer preview = new StringBuffer(get(VALUES[0]));
    478           for(int i = 1; i < separators.length - 1; i++) {
    479                 if(separators[i].isSelected()) {
    480                      // Special case, where we specifically avoid #-#, A...
    481                      if(i == 1) {
    482                           preview.append(sep_sep);
    483                           preview.append(get(VALUES[i]));
    484                      }
    485                      // Check previous value. We don't want ...A-L, M-M, N...
    486                      else if(separators[i - 1].isSelected()) {
    487                           preview.append(sep_sep);
    488                           preview.append(get(VALUES[i]));
    489                      }
    490                      // Otherwise ..-VALUE[i-1], VALUE[i]...
    491                      else {
    492                           preview.append("-");
    493                           preview.append(get(VALUES[i-1]));
    494                           preview.append(sep_sep);
    495                           preview.append(get(VALUES[i]));
    496                      }
    497                 }
    498           }
    499           // Special case of "...-Y,Z"
    500           if(separators[separators.length - 1].isSelected()) {
    501                 preview.append("-");
    502                 preview.append(get(VALUES[VALUES.length - 2]));
    503                 preview.append(sep_sep);
    504                 preview.append(get(VALUES[VALUES.length - 1]));
    505           }
    506           // Otherwise "...-Z"
    507           else {
    508                 preview.append("-");
    509                 preview.append(get(VALUES[VALUES.length - 1]));
    510           }             
    511           return preview.toString();
    512     }
    513     /** Load the custom argument dictionary if necessary, then retrieve the requested phrase.
     472    private String getPreview(boolean spaces) {
     473    String sep_sep = ",";
     474    if(spaces) {
     475        sep_sep = ", ";
     476    }
     477    StringBuffer preview = new StringBuffer(get(VALUES[0]));
     478    for(int i = 1; i < separators.length - 1; i++) {
     479        if(separators[i].isSelected()) {
     480        // Special case, where we specifically avoid #-#, A...
     481        if(i == 1) {
     482            preview.append(sep_sep);
     483            preview.append(get(VALUES[i]));
     484        }
     485        // Check previous value. We don't want ...A-L, M-M, N...
     486        else if(separators[i - 1].isSelected()) {
     487            preview.append(sep_sep);
     488            preview.append(get(VALUES[i]));
     489        }
     490        // Otherwise ..-VALUE[i-1], VALUE[i]...
     491        else {
     492            preview.append("-");
     493            preview.append(get(VALUES[i-1]));
     494            preview.append(sep_sep);
     495            preview.append(get(VALUES[i]));
     496        }
     497        }
     498    }
     499    // Special case of "...-Y,Z"
     500    if(separators[separators.length - 1].isSelected()) {
     501        preview.append("-");
     502        preview.append(get(VALUES[VALUES.length - 2]));
     503        preview.append(sep_sep);
     504        preview.append(get(VALUES[VALUES.length - 1]));
     505    }
     506    // Otherwise "...-Z"
     507    else {
     508        preview.append("-");
     509        preview.append(get(VALUES[VALUES.length - 1]));
     510    }               
     511    return preview.toString();
     512    }
     513    /** Load the custom argument dictionary if necessary, then retrieve the requested phrase.
    514514      * @param key A key <strong>String</strong> which maps to the phrase to retrieve.
    515515      * @return A phrase as a <strong>String</strong>.
     
    517517      * @see org.greenstone.gatherer.Gatherer
    518518      */
    519     private String get(String key) {
    520           if(dictionary == null) {
    521                 dictionary = ResourceBundle.getBundle("org.greenstone.gatherer.cdm.custom." + NAME, Gatherer.config.getLocale("general.locale", false));
    522           }
    523           return dictionary.getString(key);
    524     }
    525     /** Listens to the buttonname checkbox, and enable buttonname appropriately when action detected. */
    526     private class ButtonNameListener
    527           implements ActionListener {
    528           /** When an action is performed on a registered control, this method is called which either enables or disables the buttonname field depending on the buttonname checkbox.
    529             * @param event An <strong>ActionEvent</strong> containing information about the action performed.
     519    private String get(String key) {
     520    if(dictionary == null) {
     521        dictionary = ResourceBundle.getBundle("org.greenstone.gatherer.cdm.custom." + NAME, Gatherer.config.getLocale("general.locale", false));
     522    }
     523    return dictionary.getString(key);
     524    }
     525    /** Listens to the buttonname checkbox, and enable buttonname appropriately when action detected. */
     526    private class ButtonNameListener
     527    implements ActionListener {
     528    /** When an action is performed on a registered control, this method is called which either enables or disables the buttonname field depending on the buttonname checkbox.
     529     * @param event An <strong>ActionEvent</strong> containing information about the action performed.
    530530            */
    531           public void actionPerformed(ActionEvent event) {
    532                 if(buttonname_label.isSelected()) {
    533                      buttonname.setBackground(Color.white);
    534                      buttonname.setEnabled(true);
    535                 }
    536                 else {
    537                      buttonname.setBackground(Color.lightGray);
    538                      buttonname.setEnabled(false);
    539                 }                   
    540           }
    541     }
    542     /** Listens to the cancel button, and disposes appropriately when action detected. */
    543     private class CancelListener
    544           implements ActionListener {
    545           /** If the cancel button is pressed then we should dispose of the dialog without processing any records.
    546             * @param event An <strong>ActionEvent</strong> containing information about the action performed.
     531    public void actionPerformed(ActionEvent event) {
     532        if(buttonname_label.isSelected()) {
     533        buttonname.setBackground(Color.white);
     534        buttonname.setEnabled(true);
     535        }
     536        else {
     537        buttonname.setBackground(Color.lightGray);
     538        buttonname.setEnabled(false);
     539        }                   
     540    }
     541    }
     542    /** Listens to the cancel button, and disposes appropriately when action detected. */
     543    private class CancelListener
     544    implements ActionListener {
     545    /** If the cancel button is pressed then we should dispose of the dialog without processing any records.
     546     * @param event An <strong>ActionEvent</strong> containing information about the action performed.
    547547            */
    548           public void actionPerformed(ActionEvent event) {
    549                 process = false;
    550                 controls.dispose();
    551           }
    552     }
    553     /** Listens to the ok button, and sets process to true then disposes appropriately when action detected. */
    554     private class OKListener
    555           implements ActionListener {
    556           /** If the ok button is pressed then we should dispose of the dialog after processing all records.
    557             * @param event An <strong>ActionEvent</strong> containing information about the action performed.
     548    public void actionPerformed(ActionEvent event) {
     549        process = false;
     550        controls.dispose();
     551    }
     552    }
     553    /** Listens to the ok button, and sets process to true then disposes appropriately when action detected. */
     554    private class OKListener
     555    implements ActionListener {
     556    /** If the ok button is pressed then we should dispose of the dialog after processing all records.
     557     * @param event An <strong>ActionEvent</strong> containing information about the action performed.
    558558            */
    559           public void actionPerformed(ActionEvent event) {
    560                 process = true;
    561                 controls.dispose();
    562           }
    563     }
    564     /** Listens for the toggling of a separator value, and updates the separator preview field. */
    565     private class SeparatorListener
    566           implements ActionListener {
    567           /** When one of the separator buttons is toggled we update the separator preview field.
    568             * @param event An <strong>ActionEvent</strong> containing information about the action performed.
     559    public void actionPerformed(ActionEvent event) {
     560        process = true;
     561        controls.dispose();
     562    }
     563    }
     564    /** Listens for the toggling of a separator value, and updates the separator preview field. */
     565    private class SeparatorListener
     566    implements ActionListener {
     567    /** When one of the separator buttons is toggled we update the separator preview field.
     568     * @param event An <strong>ActionEvent</strong> containing information about the action performed.
    569569            */
    570           public void actionPerformed(ActionEvent event) {
    571                 separators_preview.setText(getPreview(true));
    572           }
    573     }
    574     /** Listens to the sort checkbox, and enables/disables sort appropriately when action detected. */
    575     private class SortListener
    576           implements ActionListener {
    577           /** If this checkbox is actioned, enabled or disable the sort control based on whether we are checked (selected) or not.
    578             * @param event An <strong>ActionEvent</strong> containing information about the action performed.
     570    public void actionPerformed(ActionEvent event) {
     571        separators_preview.setText(getPreview(true));
     572    }
     573    }
     574    /** Listens to the sort checkbox, and enables/disables sort appropriately when action detected. */
     575    private class SortListener
     576    implements ActionListener {
     577    /** If this checkbox is actioned, enabled or disable the sort control based on whether we are checked (selected) or not.
     578     * @param event An <strong>ActionEvent</strong> containing information about the action performed.
    579579            */
    580           public void actionPerformed(ActionEvent event) {
    581                 if(sort_label.isSelected()) {
    582                      sort.setBackground(Color.white);
    583                      sort.setEnabled(true);
    584                 }
    585                 else {
    586                      sort.setBackground(Color.lightGray);
    587                      sort.setEnabled(false);
    588                 }                   
    589           }
    590     }
    591     /** Display a progress bar while creating the required hidden system hierarchy.
     580    public void actionPerformed(ActionEvent event) {
     581        if(sort_label.isSelected()) {
     582        sort.setBackground(Color.white);
     583        sort.setEnabled(true);
     584        }
     585        else {
     586        sort.setBackground(Color.lightGray);
     587        sort.setEnabled(false);
     588        }                   
     589    }
     590    }
     591    /** Display a progress bar while creating the required hidden system hierarchy.
    592592      * @param element An <strong>ElementWrapper</strong> containing the metadata element we want to build a custom classifier on.
    593593      * @param state A <strong>String</strong> representing the currently selected separators, of the form "#,A-L,MA-Ml,MM-MZ,N-Z". */
    594     private void process(ElementWrapper element, String state) {
    595           // Create a new progress bar dialog, using these divisions:
    596           // 33% - Creation and removal of old metadata tree.
    597           // 33% - Creation of new metadata tree, 33 / <number of separations>.
    598           // 33% - Allocation of metadata to records, 33 / <number of files>.
    599           // Hopefully the previous dialog should have already vanished (its dispose() caused by the process click).
    600           ProgressDialog pd = new ProgressDialog("Custom Classifier Creation", "Preparing for operation.");
    601           // Step 1: Create the new dummy element and add it if necessary.
    602           pd.setText("Creating dummy metadata element.");
    603           MetadataSet hidden_mds = gatherer.c_man.getCollection().msm.getSet(MetadataSetManager.HIDDEN);
    604           Element hidden_e = hidden_mds.getElement(element.toString().replace('.','_'));
    605           boolean found = true;
    606           ElementWrapper hidden_mde = null;
    607           if(hidden_mde != null) {
    608                 hidden_mde = new ElementWrapper(hidden_e);
    609           }
    610           else {
    611                 hidden_mde = hidden_mds.addElement(element.toString().replace('.','_'));
    612                 found = false;
    613           }
    614           hidden_mde_name = hidden_mde.toString();
    615           pd.increase(1,2,20);
    616           // Step 2: Remove any existing value tree for this element. Wastefull I know but I don't want to lag for too long, and this is the quickest way.
    617           pd.setText("Removing any existing hierarchy.");
    618           if(found) {
    619                 hidden_mds.removeValueTree(hidden_mde);
    620           }
    621           pd.increase(1,2,20);
    622           // Step 3: Create a value tree for this element.
    623           pd.setText("Creating new hierary root.");
    624           GValueModel value_tree = gatherer.c_man.getCollection().msm.getValueTree(hidden_mde);
    625           pd.increase(5, 5, 5);
    626           // Step 4: Build the single level value hierarchy using state's value. Here a hashtable mapping string patterns to value nodes is built.
    627           pd.setText("Creating separations.");
    628           StringTokenizer tokenizer = new StringTokenizer(state, ",");
    629           int separator_count = tokenizer.countTokens();
    630           mappings = new Hashtable();
    631           for(int i = 0; i < separator_count; i++) {
    632                 String key = tokenizer.nextToken();
    633                 GValueNode node = value_tree.addValue(key);
     594    private void process(ElementWrapper element, String state) {
     595    // Create a new progress bar dialog, using these divisions:
     596    // 33% - Creation and removal of old metadata tree.
     597    // 33% - Creation of new metadata tree, 33 / <number of separations>.
     598    // 33% - Allocation of metadata to records, 33 / <number of files>.
     599    // Hopefully the previous dialog should have already vanished (its dispose() caused by the process click).
     600    ProgressDialog pd = new ProgressDialog("Custom Classifier Creation", "Preparing for operation.");
     601    // Step 1: Create the new dummy element and add it if necessary.
     602    pd.setText("Creating dummy metadata element.");
     603    MetadataSet hidden_mds = gatherer.c_man.getCollection().msm.getSet(MetadataSetManager.HIDDEN);
     604    Element hidden_e = hidden_mds.getElement(element.toString().replace('.','_'));
     605    boolean found = true;
     606    ElementWrapper hidden_mde = null;
     607    if(hidden_mde != null) {
     608        hidden_mde = new ElementWrapper(hidden_e);
     609    }
     610    else {
     611        hidden_mde = hidden_mds.addElement(element.toString().replace('.','_'));
     612        found = false;
     613    }
     614    hidden_mde_name = hidden_mde.toString();
     615    pd.increase(1,2,20);
     616    // Step 2: Remove any existing value tree for this element. Wastefull I know but I don't want to lag for too long, and this is the quickest way.
     617    pd.setText("Removing any existing hierarchy.");
     618    if(found) {
     619        hidden_mds.removeValueTree(hidden_mde);
     620    }
     621    pd.increase(1,2,20);
     622    // Step 3: Create a value tree for this element.
     623    pd.setText("Creating new hierary root.");
     624    GValueModel value_tree = gatherer.c_man.getCollection().msm.getValueTree(hidden_mde);
     625    pd.increase(5, 5, 5);
     626    // Step 4: Build the single level value hierarchy using state's value. Here a hashtable mapping string patterns to value nodes is built.
     627    pd.setText("Creating separations.");
     628    StringTokenizer tokenizer = new StringTokenizer(state, ",");
     629    int separator_count = tokenizer.countTokens();
     630    mappings = new Hashtable();
     631    for(int i = 0; i < separator_count; i++) {
     632        String key = tokenizer.nextToken();
     633        GValueNode node = value_tree.addValue(key);
    634634                // If the key is simple, ie "C", then add the mapping "C"->node
    635                 if(key.indexOf("-") == -1) {
    636                      mappings.put(key, node);
    637                 }
     635        if(key.indexOf("-") == -1) {
     636        mappings.put(key, node);
     637        }
    638638                // If the key is more complex, say "D-L", then we add mappings for all string values so "D"->node, "E"->node, ... "L"->node. This is miles eaiser to do here, than when you are trying to match a records metadata ie matchin "D-L" to "Igloos are cool". Note that it is guarantee that the keys are all of the same length, ie "A-L", "MA-ML", "MMA-STF", "STFA-ZZZZ".
    639                 else {
    640                      String start = key.substring(0, key.indexOf("-"));
    641                      String end = key.substring(key.indexOf("-") + 1);
    642                      for(key = start; key != null && key.compareTo(end) <= 0; key = increment(key)) {
    643                           mappings.put(key, node); 
    644                      }
    645                 }
     639        else {
     640        String start = key.substring(0, key.indexOf("-"));
     641        String end = key.substring(key.indexOf("-") + 1);
     642        for(key = start; key != null && key.compareTo(end) <= 0; key = increment(key)) {
     643            mappings.put(key, node);   
     644        }
     645        }
    646646                // Each iteration.
    647                 pd.increase(1, separator_count, 25);
    648           }
    649           // Step 5: Recurse the entire tree, adding the appropriate values where necessary (overwriting any existing value for this element).
    650           pd.setText("Allocating metadata to records.");
    651           int document_count = gatherer.c_man.getCollection().getDocumentCount();
    652           TreeModel record_tree = gatherer.c_man.getRecordSet();
    653           FileNode records[] = ArrayTools.add(null, (FileNode)record_tree.getRoot());
    654           while(records != null) {
    655                 if(records[0].isLeaf()) {
    656                      addMetadata(0L, records[0], element);
    657                      // Each iteration.
    658                      pd.increase(1, document_count, 50);
    659                 }
    660                 else {
    661                      // Add all children to records at once hopefully.
    662                      FileNode children[] = new FileNode[records[0].getChildCount()];
    663                      for(int i = 0; i < children.length; i++) {
    664                           children[i] = (FileNode) records[0].getChildAt(i);
    665                      }
    666                      records = ArrayTools.add(records, children);
    667                 }
    668                 records = ArrayTools.tail(records);
    669           }
    670           // Step 6: Done.
    671           pd.dispose();
    672     }
    673     /** A dialog window used to show the progress of processing the file records in terms of adding hidden metadata. */
    674     private class ProgressDialog
    675           extends JDialog {
    676           /** The current value represented by the progress bar (where value is double and the progress bar shows an int). */
    677           private double value = 0.0;
    678           /** The default size of this dialog. */
    679           private Dimension dialog_size = new Dimension(500,100);
    680           /** The label explaining what action is currently happening (1 of 5 steps). */
    681           private JLabel label = new JLabel();
    682           /** The progress bar itself. */
    683           private JProgressBar bar = new JProgressBar();
    684           /** Constructor.
    685             * @param t The title for this dialog as a <strong>String</strong>.
    686             * @param l The initial label for the progress bar also a <strong>String</strong>.
    687             */
    688           public ProgressDialog(String t, String l) {
    689                 super();
    690                 setModal(false);
    691                 setSize(dialog_size);
    692                 setTitle(t);
     647        pd.increase(1, separator_count, 25);
     648    }
     649    // Step 5: Recurse the entire tree, adding the appropriate values where necessary (overwriting any existing value for this element).
     650    pd.setText("Allocating metadata to records.");
     651    int document_count = gatherer.c_man.getCollection().getDocumentCount();
     652    TreeModel record_tree = gatherer.c_man.getRecordSet();
     653    FileNode records[] = ArrayTools.add(null, (FileNode)record_tree.getRoot());
     654    while(records != null) {
     655        if(records[0].isLeaf()) {
     656        addMetadata(0L, records[0], element);
     657        // Each iteration.
     658        pd.increase(1, document_count, 50);
     659        }
     660        else {
     661        // Add all children to records at once hopefully.
     662        FileNode children[] = new FileNode[records[0].getChildCount()];
     663        for(int i = 0; i < children.length; i++) {
     664            children[i] = (FileNode) records[0].getChildAt(i);
     665        }
     666        records = ArrayTools.add(records, children);
     667        }
     668        records = ArrayTools.tail(records);
     669    }
     670    // Step 6: Done.
     671    pd.dispose();
     672    }
     673    /** A dialog window used to show the progress of processing the file records in terms of adding hidden metadata. */
     674    private class ProgressDialog
     675    extends JDialog {
     676    /** The current value represented by the progress bar (where value is double and the progress bar shows an int). */
     677    private double value = 0.0;
     678    /** The default size of this dialog. */
     679    private Dimension dialog_size = new Dimension(500,100);
     680    /** The label explaining what action is currently happening (1 of 5 steps). */
     681    private JLabel label = new JLabel();
     682    /** The progress bar itself. */
     683    private JProgressBar bar = new JProgressBar();
     684    /** Constructor.
     685     * @param t The title for this dialog as a <strong>String</strong>.
     686     * @param l The initial label for the progress bar also a <strong>String</strong>.
     687     */
     688    public ProgressDialog(String t, String l) {
     689        super();
     690        setModal(false);
     691        setSize(dialog_size);
     692        setTitle(t);
    693693                // Create
    694                 JPanel content_pane = (JPanel) getContentPane();
    695                 label.setText(l);
    696                 bar.setMaximum(100);
    697                 bar.setMinimum(0);
    698                 bar.setValue(0);
     694        JPanel content_pane = (JPanel) getContentPane();
     695        label.setText(l);
     696        bar.setMaximum(100);
     697        bar.setMinimum(0);
     698        bar.setValue(0);
    699699                // Connect
    700700                // Layout
    701                 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    702                 content_pane.setLayout(new BorderLayout());
    703                 content_pane.add(label, BorderLayout.NORTH);
    704                 content_pane.add(bar, BorderLayout.CENTER);
     701        content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     702        content_pane.setLayout(new BorderLayout());
     703        content_pane.add(label, BorderLayout.NORTH);
     704        content_pane.add(bar, BorderLayout.CENTER);
    705705                // Display
    706                 Dimension screen_size = Gatherer.config.screen_size;
    707                 setLocation((screen_size.width - dialog_size.width) / 2, (screen_size.height - dialog_size.height) / 2);
    708                 screen_size = null;
    709                 show();
    710           }
    711           /** Increase the progress bar by a certain ammount.
     706        Dimension screen_size = Gatherer.config.screen_size;
     707        setLocation((screen_size.width - dialog_size.width) / 2, (screen_size.height - dialog_size.height) / 2);
     708        screen_size = null;
     709        show();
     710    }
     711    /** Increase the progress bar by a certain ammount.
    712712            * @param item An <i>int</i> indicating what item number this is.
    713713            * @param out_of An <i>int</i> detailing the number of items expected in total for this phase.
    714714            * @param total The maximum value of the progress bar as an <i>int</i>.
    715715            */
    716           public void increase(int item, int out_of, int total) {
    717                 value = value + (((double) item / (double) out_of) * (double)total);
    718                 int int_value = (int) value;
     716    public void increase(int item, int out_of, int total) {
     717        value = value + (((double) item / (double) out_of) * (double)total);
     718        int int_value = (int) value;
    719719                ///ystem.err.println("Value is " + value + " which rounds to " + int_value);
    720                 if(int_value != bar.getValue()) {
    721                      bar.setValue(int_value);
    722                 }
    723           }
    724           /** Set the message shown in the progress bar.
     720        if(int_value != bar.getValue()) {
     721        bar.setValue(int_value);
     722        }
     723    }
     724    /** Set the message shown in the progress bar.
    725725            * @param l The new progress bar label as a <strong>String</strong>.
    726726            */
    727           public void setText(String l) {
    728                 label.setText(l);
    729           }
    730     }
    731     /** The String equivelent of int++, this method increments the value of a String by one letter at a time.
     727    public void setText(String l) {
     728        label.setText(l);
     729    }
     730    }
     731    /** The String equivelent of int++, this method increments the value of a String by one letter at a time.
    732732      * @param str The <strong>String</strong> to be incremented.
    733733      * @return A <strong>String</strong> whose 'checksum' value (adding the INT_VALUE[] of the letters together) is one greater than the initial String, while still containing only those values in STRING_VALUE[].
    734734      */
    735     public String increment(String str) {
    736           ///ystem.err.print("Incrementing " + str + " -> ");
    737           char chars[] = str.toCharArray();
    738           boolean found = false;
    739           int pos = str.length() - 1;
    740           while(found == false && pos >= 0) {
    741                 if((int)chars[pos] + 1 <= INT_VALUES[26]) {
    742                      if((int)chars[pos] == INT_VALUES[0]) { // Anything else symbol
    743                           chars[pos] = (char) INT_VALUES[1];
    744                      }
    745                      else {
    746                           chars[pos] = (char)((int)chars[pos] + 1);
    747                      }
    748                      found = true;
    749                
    750                 else {
    751                      chars[pos] = (char)INT_VALUES[1];
    752                      pos--;
    753                 }
    754           }
    755           // If we haven't found it yet, return null.
    756           if(!found) {
    757                 return null;
    758           }
    759           ///ystem.err.println(String.valueOf(chars));
    760           return String.valueOf(chars);
    761     }
     735    public String increment(String str) {
     736    ///ystem.err.print("Incrementing " + str + " -> ");
     737    char chars[] = str.toCharArray();
     738    boolean found = false;
     739    int pos = str.length() - 1;
     740    while(found == false && pos >= 0) {
     741        if((int)chars[pos] + 1 <= INT_VALUES[26]) {
     742        if((int)chars[pos] == INT_VALUES[0]) { // Anything else symbol
     743            chars[pos] = (char) INT_VALUES[1];
     744        }
     745        else {
     746            chars[pos] = (char)((int)chars[pos] + 1);
     747        }
     748        found = true;
     749       
     750        else {
     751        chars[pos] = (char)INT_VALUES[1];
     752        pos--;
     753        }
     754    }
     755    // If we haven't found it yet, return null.
     756    if(!found) {
     757        return null;
     758    }
     759    ///ystem.err.println(String.valueOf(chars));
     760    return String.valueOf(chars);
     761    }
    762762}
    763763
Note: See TracChangeset for help on using the changeset viewer.