source: trunk/gli/src/org/greenstone/gatherer/cdm/Classifier.java@ 11378

Last change on this file since 11378 was 11282, checked in by kjdon, 18 years ago

when setting up the fields of an exsiting argument, we need to copy the hiddenGLI setting from the base argument

  • Property svn:keywords set to Author Date Id Revision
File size: 16.5 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29/**************************************************************************************
30 * Written: 01/05/02
31 * Revised: 16/08/02 Optimized and Commented.
32 * 11/07/03 DOM support
33 **************************************************************************************/
34import java.io.*;
35import java.util.*;
36import org.greenstone.gatherer.util.StaticStrings;
37import org.greenstone.gatherer.util.Utility;
38import org.w3c.dom.*;
39
40/** This class is responsible for storing information from a parsed classinfo.pl call in such a way that it allows easy access to parsed details for the purposes of user design and specification of classifiers.
41 * @author John Thompson, Greenstone Digital Library, University of Waikato
42 * @version 2.3
43 */
44public class Classifier
45 extends ArrayList
46 implements ArgumentContainer, Comparable, DOMProxyListEntry, Serializable {
47
48 static final public String CLASSIFIER_PREFIX = "CL";
49
50 private boolean is_abstract = false;
51
52 /** A reference to the classifier that this one inherits from. */
53 private Classifier super_classifier = null;
54 /** The element this classifier is based upon. */
55 private Element element;
56 /** A description of this classifier. */
57 private String description = null;
58 /** The name of the classifier as it would appear in the collect.cfg file. */
59 private String name = null;
60 /** This string is filled out the first time this classifier is created, and remains unchanged there-after. It is used to match up with Format commands that may not yet have been instantiated (and thus only have offline references along the lines of 'CL1' to figure out what Classifier they want.) */
61 private String old_position_string = null;
62
63 /** Constructor used only in DOMProxyListModel initializations.
64 */
65 public Classifier() {
66 }
67
68 public Classifier(Element element, Classifier base_classifier) {
69 super();
70 this.element = element;
71 this.name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
72 ///atherer.println("Establishing Classifier: " + name);
73 // Parse in any argument options for this classifier, keeping a list of the ones found
74 HashMap known_arguments = new HashMap();
75 NodeList option_elements = element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
76 int option_elements_length = option_elements.getLength();
77 for(int i = 0; i < option_elements_length; i++) {
78 Element option_element = (Element) option_elements.item(i);
79 Argument argument = new Argument(option_element);
80 ///atherer.println("Rebuilding existing argument: " + argument.getName());
81 argument.setOwner(name);
82 add(argument);
83 known_arguments.put(argument.getName(), argument);
84 }
85 // If a base classifier was given
86 if(base_classifier != null) {
87 // Copy the details, and add a reference to whatever base_classifiers super classifier is.
88 description = base_classifier.getDescription();
89 // Now search through the 'dummy' arguments belonging to the base classifier. For each found, if it is already assigned, fill out further details such as type. If any are found that are not already assigned for this classifier, copy them and add them, but without a value.
90 ArrayList all_arguments = base_classifier.getArguments(true, true);
91 int argument_count = all_arguments.size();
92 for(int j = 0; j < argument_count; j++) {
93 Argument base_argument = (Argument) all_arguments.get(j);
94 String base_argument_name = base_argument.getName();
95 ///atherer.println("Library indicates this classifier should have an argument: " + base_argument_name);
96 Argument existing_argument = (Argument) known_arguments.get(base_argument_name);
97 // Found an existing argument. Complete its details
98 if(existing_argument != null) {
99 ///atherer.println("Found existing argument. Filling out details.");
100 existing_argument.setCustomArgument(false);
101 existing_argument.setDefaultValue(base_argument.getDefaultValue());
102 existing_argument.setDescription(base_argument.getDescription());
103 existing_argument.setOptions(base_argument.getOptions());
104 existing_argument.setRequired(base_argument.isRequired());
105 existing_argument.setType(base_argument.getType());
106 existing_argument.setHiddenGLI(base_argument.isHiddenGLI());
107 }
108 // No existing argument. Copy base_argument and add it, but do not set its assigned flag. That should be set the first time its changed by the user.
109 else {
110 ///atherer.println("No such argument. Adding new, unassigned, argument.");
111 // The trick thing is that we have to create a new element in the DOM as well.
112 Argument new_argument = base_argument.copy();
113 new_argument.setOwner(name);
114 Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
115 argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, base_argument_name);
116 argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
117 argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.FALSE_STR);
118 new_argument.setElement(argument_element);
119 // All done. Add it.
120 element.appendChild(argument_element);
121 add(new_argument);
122 }
123 }
124 }
125 old_position_string = getPositionString();
126 }
127
128 /** Constructor.
129 * @param name The name of this classifier as a <strong>String</strong>.
130 * @param description A description of this classifier as a <strong>String</strong>.
131 * @param super_classifier The super class of this classifier, as a <strong>Classifier</strong>.
132 */
133 public Classifier(String name, String description, Classifier super_classifier) {
134 super();
135 this.description = description;
136 this.name = name;
137 this.super_classifier = super_classifier;
138 }
139
140 /** Method to add an argument to this classifier. Only adds the argument if it isn't already present.
141 * @param argument The <strong>Argument</strong> to add.
142 */
143 public void addArgument(Argument argument) {
144 if(element == null && !contains(argument)) {
145 add(argument);
146 argument.setOwner(name);
147 }
148 }
149
150 /** Method to compare two classifiers for ordering.
151 * @param object The classifier we are comparing to, as an <strong>Object</strong>.
152 * @return An <i>int</i> specifying the classifier order, using values as set out in String.
153 * @see java.lang.String#compareTo
154 */
155 public int compareTo(Object object) {
156 if(object == null) {
157 return -1;
158 }
159 return toString().compareTo(object.toString());
160 }
161
162 /** The assigned classifier constructor.
163 * @param element the DOM Element this classifier is based upon
164 */
165 public DOMProxyListEntry create(Element element) {
166 String classifier_name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
167 // Determine the base classifier from the classifier name
168 Classifier base_classifier = CollectionDesignManager.classifier_manager.getBaseClassifier(classifier_name);
169 Classifier classifier = new Classifier(element, base_classifier);
170 base_classifier = null;
171 classifier_name = null;
172 return classifier;
173 }
174
175 /** Method to determine if two classifiers are equal.
176 * @param object The classifier to test against, as an <strong>Object</strong>.
177 * @return <i>true</i> if the classifier names match, <i>false</i> otherwise.
178 */
179 public boolean equals(Object object) {
180 return (compareTo(object) == 0);
181 }
182
183 /** Method to retrieve an argument by its name.
184 * @param name The name of the argument as a <strong>String</strong>.
185 * @return The <strong>Argument</strong> requested, or <i>null</i> if no such argument.
186 */
187 public Argument getArgument(String name) {
188 // The name given may still include the '-'
189 if(name.startsWith("-")) {
190 name = name.substring(1);
191 }
192 ArrayList arguments = getArguments(true, true);
193 for(int i = 0; i < arguments.size(); i++) {
194 Argument argument = (Argument)arguments.get(i);
195 if(argument.getName().equals(name)) {
196 return argument;
197 }
198 }
199 return null;
200 }
201
202 /** Retrieve all of the arguments available to this base classifier, including its super classifiers arguments. Some complexity is added by allowing the caller to choose whether they want normal arguments, custom arguments, or both.
203 * @return an ArrayList of all of the arguments, starting with those for this classifier and ending with the arguments for basplug or similiar root classifier
204 */
205 public ArrayList getArguments(boolean include_normal, boolean include_custom) {
206 ArrayList arguments = new ArrayList();
207 if(include_normal && include_custom) {
208 arguments.addAll(this);
209 }
210 else {
211 int size = size();
212 for(int i = 0; i < size; i++) {
213 Argument argument = (Argument) get(i);
214 if(argument.isCustomArgument()) {
215 if(include_custom && !arguments.contains(argument)) {
216 arguments.add(argument);
217 }
218 }
219 else {
220 if(include_normal && !arguments.contains(argument)) {
221 arguments.add(argument);
222 }
223 }
224 argument = null;
225 }
226 }
227 if(super_classifier != null) {
228 ArrayList remainder = super_classifier.getArguments(include_normal, include_custom);
229 remainder.removeAll(arguments);
230 arguments.addAll(remainder);
231 }
232 return arguments;
233 }
234
235 /** Method to retrieve a classifiers custom argument information. Custom arguments are defined to be those that have not got matching arguments in the base reference classifier from the library. Of course if there is no base classifier then all arguments are considered to be custom.
236 * @return the custom arguments as a String
237 */
238 public String getCustom() {
239 StringBuffer custom_text = new StringBuffer();
240 // Retrieve all of the arguments, and append any that are custom into one long string
241 ArrayList arguments = getArguments(false, true);
242 int arguments_size = arguments.size();
243 boolean first = true;
244 for(int i = 0; i < arguments_size; i++) {
245 Argument argument = (Argument) arguments.get(i);
246 if(argument.isAssigned()) {
247 if(!first) {
248 custom_text.append(" ");
249 }
250 custom_text.append(argument.toString());
251 first = false;
252 }
253 }
254 return custom_text.toString();
255 }
256
257 public String getDescription() {
258 return description;
259 }
260
261 public Element getElement() {
262 return element;
263 }
264
265 /** Method to retrieve a classifiers name.
266 * @return A <strong>String</strong> containing the classifiers name.
267 */
268 public String getName() {
269 if(name == null && element != null) {
270 name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
271 }
272 return name;
273 }
274
275 /* private String getOldPositionString() {
276 return old_position_string;
277 } */
278
279 /** Generate the string showing this classifiers position. */
280 public String getPositionString() {
281 String position_string = CLASSIFIER_PREFIX;
282 if(element != null) {
283 // Determine our place in the collect.cfg file
284 int position_int = CollectionDesignManager.classifier_manager.indexOf(this) + 1;
285 if(position_int != -1) {
286 position_string = position_string + position_int;
287 }
288 }
289 return position_string;
290 }
291
292 public boolean isAbstract() {
293 return is_abstract;
294 }
295
296 public boolean isAssigned() {
297 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR));
298 }
299
300 public void setAssigned(boolean assigned) {
301 if(element != null) {
302 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
303 }
304 }
305
306 /** Set the custom arguments. This turns out to be quite tricky. We must parse in the string, searching for arguments (for that we use a handy method in CollectionConfiguration). Next, for each argument, we check if we already know about it. If so we update its value, otherwise we create a new argument and assign it (must assign!).
307 * @param custom_str the custom arguments all splodged together in one String
308 */
309 public void setCustom(String custom_str) {
310 HashMap raw_arguments = CollectionConfiguration.parseArguments(new CommandTokenizer(custom_str));
311 ArrayList custom_arguments = getArguments(false, true);
312 int size = custom_arguments.size();
313 for(int i = 0; i < size; i++) {
314 Argument argument = (Argument) custom_arguments.get(i);
315 String original_argument_name = StaticStrings.MINUS_CHARACTER + argument.getName();
316 if(raw_arguments.containsKey(original_argument_name)) {
317 // Set as assigned
318 argument.setAssigned(true);
319 String argument_value = (String)raw_arguments.remove(original_argument_name);
320 if(argument_value != null) {
321 argument.setValue(argument_value);
322 argument_value = null;
323 }
324 }
325 // We've removed it from our custom statement, so unassign
326 else {
327 argument.setAssigned(false);
328 }
329 argument = null;
330 }
331 // Any left over, add to the classifier
332 Iterator argument_names = raw_arguments.keySet().iterator();
333 while(argument_names.hasNext()) {
334 String argument_name = (String) argument_names.next();
335 String argument_value = (String) raw_arguments.get(argument_name);
336 // The tricky thing is that we have to create a new element in the DOM as well.
337 Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
338 argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, argument_name.substring(1));
339 argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
340 argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.TRUE_STR);
341 Argument argument = new Argument(argument_element);
342 argument_name = null;
343 if(argument_value != null) {
344 argument.setValue(argument_value);
345 argument_value = null;
346 }
347 // All done. Add it.
348 element.appendChild(argument_element);
349 add(argument);
350 argument_element = null;
351 }
352 raw_arguments = null;
353 }
354
355 /** Method to set the value of desc.
356 * @param description The new value of desc as a <strong>String</strong>.
357 */
358 public void setDescription(String description) {
359 this.description = description;
360 }
361
362 public void setElement(Element element) {
363 this.element = element;
364 }
365
366 public void setIsAbstract(boolean is_abstract) {
367 this.is_abstract = is_abstract;
368 }
369
370 /** Method to set the value of name.
371 * @param name The new value of name as a <strong>String</strong>.
372 */
373 public void setName(String name) {
374 this.name = name;
375 }
376
377 /** Method to set the value of the super_classifier.
378 * @param super_classifier The new value of super_classifier as a <strong>Classifier</strong>, or <i>null</i> if this class has no inheritance.
379 */
380 public void setSuper(Classifier super_classifier) {
381 this.super_classifier = super_classifier;
382 }
383
384
385 /** Method to print out this classifier as it would appear to the user in the interface
386 * @return A <strong>String</strong> containing a single classifier command.
387 */
388 public String toString()
389 {
390 if (element == null) {
391 return name;
392 }
393
394 if (name == null) {
395 name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
396 }
397
398 StringBuffer text = new StringBuffer(StaticStrings.CLASSIFY_STR);
399 text.append(" ");
400 text.append(name);
401
402 ArrayList arguments = getArguments(true, true);
403 for (int i = 0; i < arguments.size(); i++) {
404 Argument argument = (Argument) arguments.get(i);
405 if (argument.isAssigned()) {
406 text.append(" ");
407 text.append(argument.toString());
408 }
409 }
410
411 return text.toString();
412 }
413}
Note: See TracBrowser for help on using the repository browser.