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

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

Now looks at a plugin's block_exp as well as its process_exp to determine if it will "process" a file.

  • Property svn:keywords set to Author Date Id Revision
File size: 19.2 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
29import java.io.*;
30import java.util.*;
31import org.greenstone.gatherer.DebugStream;
32import org.greenstone.gatherer.util.StaticStrings;
33import org.w3c.dom.*;
34
35/** This class is responsible for storing information from a parsed pluginfo call in such a way that it allows easy access to parsed details for the purposes of user design and specification of plugins. */
36public class Plugin
37 extends ArrayList
38 implements ArgumentContainer, Comparable, DOMProxyListEntry, Serializable {
39 /** The DOM Element this assigned Plugin is modelled on. */
40 private Element element;
41 private boolean does_explode_metadata_databases = false; // Only for Base
42 private boolean is_abstract = false; // Only for Base
43 /** The parent Plugin this one inherits from, if any. */
44 private Plugin super_plugin; // Only for Base
45 private String description; // Only for Base
46 private String name; // Only for Base
47
48 /** Constructor used in DOMProxyListModel initializations, and Library Level. Used for Base plugins (those in the list of available plugins, not ones that are in the DOMProxyList)
49 */
50 public Plugin() {
51 }
52
53 /** Constructor used for the plugins that are in the DOMProxyList */
54 // Every time the list of plugins in the assigned plugins box changes, (eg plugin added or removed, not when plugin configured), the plugins seem to be regenerated, using the element from the old plugin. All known args get added to the element the first time this happens - we need to add them to the arguments list in the order they are found in the base plugins though, not this order.
55 public Plugin(Element element, Plugin base_plugin) {
56 super();
57 this.element = element;
58 this.name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
59 //DebugStream.println("Establishing Plugin: " + name);
60 // Parse in any argument options for this plugin, keeping a list of the ones found
61 HashMap known_arguments = new HashMap();
62 NodeList option_elements = element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
63 int option_elements_length = option_elements.getLength();
64 for(int i = 0; i < option_elements_length; i++) {
65 Element option_element = (Element) option_elements.item(i);
66 Argument argument = new Argument(option_element);
67 //DebugStream.println("Rebuilding existing argument: " + argument.getName());
68 known_arguments.put(argument.getName(), argument);
69 if (base_plugin == null) {
70 // otherwise they will all be added in the next step
71 argument.setOwner(name);
72 add(argument);
73 }
74 }
75 // If a base plugin was given
76 if(base_plugin != null) {
77 //DebugStream.println("Based on previous plugin.");
78 // Copy the details, and add a reference to whatever base_plugins super plugin is. ??
79 description = base_plugin.getDescription();
80 // Now search through the 'dummy' arguments belonging to the base plugin. 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 plugin, copy them and add them, but without a value.
81 ArrayList all_arguments = base_plugin.getArguments(true, true);
82 int argument_count = all_arguments.size();
83 for(int j = 0; j < argument_count; j++) {
84 Argument base_argument = (Argument) all_arguments.get(j);
85 String base_argument_name = base_argument.getName();
86 //DebugStream.println("Library indicates this plugin should have an argument: " + base_argument_name);
87 Argument existing_argument = (Argument) known_arguments.get(base_argument_name);
88 // Found an existing argument. Complete its details
89 if(existing_argument != null) {
90 //DebugStream.println("Found existing argument. Filling out details.");
91 existing_argument.setCustomArgument(false);
92 existing_argument.setDefaultValue(base_argument.getDefaultValue());
93 existing_argument.setDescription(base_argument.getDescription());
94 existing_argument.setOptions(base_argument.getOptions());
95 existing_argument.setRequired(base_argument.isRequired());
96 existing_argument.setType(base_argument.getType());
97 existing_argument.setMinimum(base_argument.getMinimum());
98 existing_argument.setMaximum(base_argument.getMaximum());
99 existing_argument.setOwner(base_argument.getOwner());
100 existing_argument.setHiddenGLI(base_argument.isHiddenGLI());
101 add(existing_argument);
102
103 }
104 // 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.
105 else {
106 //DebugStream.println("No such argument. Adding new, unassigned, argument.");
107 // The trick thing is that we have to create a new element in the DOM as well.
108 Argument new_argument = base_argument.copy();
109 Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
110 argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, base_argument_name);
111 argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
112 argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.FALSE_STR);
113 // All done. Add it.
114 // if we are not in the first collection opened, then this
115 /// will belong to a different document, so need to import
116 // it.
117 Node new_element = element.getOwnerDocument().importNode(argument_element, true);
118 new_argument.setElement((Element) new_element);
119 element.appendChild(new_element);
120 add(new_argument);
121 }
122 }
123 }
124 }
125
126 /** Method to add an argument to this base plugin. Only adds the argument if it isn't already present, and only if this is a base plugin (ie not based on DOM).
127 * @param argument the Argument to add
128 */
129 public void addArgument(Argument argument) {
130 if(element == null && !contains(argument)) {
131 add(argument);
132 argument.setOwner(name);
133 }
134 }
135
136 /** Method to compare two plugins for ordering.
137 * @param object The plugin we are comparing to, as an <strong>Object</strong>.
138 * @return An <i>int</i> specifying the plugin order, using values as set out in <strong>String</strong>.
139 * @see java.lang.String#compareTo
140 */
141 public int compareTo(Object object) {
142 if(object instanceof Plugin) {
143 return name.compareTo(((Plugin)object).getName());
144 }
145 return -1;
146 }
147
148 /** The assigned plugin constructor.
149 * @param element the DOM Element this plugin is based upon
150 */
151 public DOMProxyListEntry create(Element element) {
152 String plugin_name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
153 // Determine the base plugin from the plugin name
154 Plugin base_plugin = CollectionDesignManager.plugin_manager.getBasePlugin(plugin_name);
155 Plugin plugin = new Plugin(element, base_plugin);
156 base_plugin = null;
157 plugin_name = null;
158 return plugin;
159 }
160
161
162 /** Checks whether the plugin this instance is based on processes metadata databases that can be exploded. */
163 public boolean doesExplodeMetadataDatabases()
164 {
165 Plugin base_plugin = CollectionDesignManager.plugin_manager.getBasePlugin(getName());
166 if (base_plugin == null) {
167 return false;
168 }
169 return base_plugin.does_explode_metadata_databases;
170 }
171
172
173 /** Checks whether this plugin instance will process the specified file (given its block_exp). */
174 public boolean doesBlockFile(File file)
175 {
176 // Check the filename against the plugin's block_exp value
177 ArrayList arguments = getArguments(true, true);
178 for (int i = 0; i < arguments.size(); i++) {
179 Argument argument = (Argument) arguments.get(i);
180 if (argument.getName().equals("block_exp")) {
181 // Try the assigned value first, for when the user has manually set the value
182 String regular_expression = argument.getValue();
183 if (regular_expression == null || regular_expression.equals("")) {
184 // Not set, so use the default value
185 regular_expression = argument.getDefaultValue();
186 if (regular_expression.equals("")) {
187 continue;
188 }
189 }
190
191 // The $ at the end doesn't seem to work in Java, so need to add ".*" at the start
192 if (regular_expression.startsWith("(?i)")) {
193 // Don't mess up case-insensitive matching though
194 regular_expression = "(?i)" + ".*" + regular_expression.substring("(?i)".length());
195 }
196 else {
197 regular_expression = ".*" + regular_expression;
198 }
199
200 // If the filename matches the regular expression, this plugin will deal with the file in some way
201 if (file.getName().matches(regular_expression)) {
202 return true;
203 }
204 }
205 }
206
207 // This plugin will (probably) not deal with the specified file
208 return false;
209 }
210
211
212 /** Checks whether this plugin instance will process the specified file (given its process_exp). */
213 public boolean doesProcessFile(File file)
214 {
215 // Check the filename against the plugin's process_exp value
216 ArrayList arguments = getArguments(true, true);
217 for (int i = 0; i < arguments.size(); i++) {
218 Argument argument = (Argument) arguments.get(i);
219 if (argument.getName().equals("process_exp")) {
220 // Try the assigned value first, for when the user has manually set the value
221 String regular_expression = argument.getValue();
222 if (regular_expression == null || regular_expression.equals("")) {
223 // Not set, so use the default value
224 regular_expression = argument.getDefaultValue();
225 if (regular_expression.equals("")) {
226 continue;
227 }
228 }
229
230 // The $ at the end doesn't seem to work in Java, so need to add ".*" at the start
231 if (regular_expression.startsWith("(?i)")) {
232 // Don't mess up case-insensitive matching though
233 regular_expression = "(?i)" + ".*" + regular_expression.substring("(?i)".length());
234 }
235 else {
236 regular_expression = ".*" + regular_expression;
237 }
238
239 // If the filename matches the regular expression, this plugin will deal with the file in some way
240 if (file.getName().matches(regular_expression)) {
241 return true;
242 }
243 }
244 }
245
246 // This plugin will (probably) not deal with the specified file
247 return false;
248 }
249
250
251 /** Method to determine if two plugins are equal.
252 * @param object The plugin to test against, as an <strong>Object</strong>.
253 * @return <i>true</i> if the plugin names match, <i>false</i> otherwise.
254 */
255 public boolean equals(Object object) {
256 return (compareTo(object) == 0);
257 }
258
259 /** Method to retrieve an argument by its name.
260 * @param name The name of the argument as a <strong>String</strong>.
261 * @return The <strong>Argument</strong> requested, or <i>null</i> if no such argument.
262 */
263 public Argument getArgument(String name) {
264 // The name given may still include the '-'
265 if(name.startsWith("-")) {
266 name = name.substring(1);
267 }
268 ArrayList arguments = getArguments(true, true);
269 for(int i = 0; i < arguments.size(); i++) {
270 Argument argument = (Argument)arguments.get(i);
271 if(argument.getName().equals(name)) {
272 return argument;
273 }
274 }
275 return null;
276 }
277
278 /** Retrieve all of the arguments available to this base plugin, including its super plugins arguments. Some complexity is added by allowing the caller to choose whether they want normal arguments, custom arguments, or both.
279 * @return an ArrayList of all of the arguments, starting with those for this plugin and ending with the arguments for basplug or similiar root plugin
280 */
281 public ArrayList getArguments(boolean include_normal, boolean include_custom) {
282 ArrayList arguments = new ArrayList();
283 if(include_normal && include_custom) {
284 arguments.addAll(this);
285 }
286 else {
287 int size = size();
288 for(int i = 0; i < size; i++) {
289 Argument argument = (Argument) get(i);
290 if(argument.isCustomArgument()) {
291 if(include_custom && !arguments.contains(argument)) {
292 arguments.add(argument);
293 }
294 }
295 else {
296 if(include_normal && !arguments.contains(argument)) {
297 arguments.add(argument);
298 }
299 }
300 argument = null;
301 }
302 }
303 if(super_plugin != null) {
304 ArrayList remainder = super_plugin.getArguments(include_normal, include_custom);
305 remainder.removeAll(arguments);
306 arguments.addAll(remainder);
307 }
308 return arguments;
309 }
310
311 /** Method to retrieve a plugins custom argument information. Custom arguments are defined to be those that have not got matching arguments in the base reference plugin from the library. Of course if there is no base plugin then all arguments are considered to be custom.
312 * @return the custom arguments as a String
313 */
314 public String getCustom() {
315 StringBuffer custom_text = new StringBuffer();
316 // Retrieve all of the arguments, and append any that are custom into one long string
317 ArrayList arguments = getArguments(false, true);
318 int arguments_size = arguments.size();
319 boolean first = true;
320 for(int i = 0; i < arguments_size; i++) {
321 Argument argument = (Argument) arguments.get(i);
322 if(argument.isAssigned()) {
323 if(!first) {
324 custom_text.append(" ");
325 }
326 custom_text.append(argument.toString());
327 first = false;
328 }
329 }
330 return custom_text.toString();
331 }
332
333 public String getDescription() {
334 return description;
335 }
336
337 public Element getElement() {
338 return element;
339 }
340
341 /** Method to retrieve a plugins name.
342 * @return A <strong>String</strong> containing the plugins name.
343 */
344 public String getName() {
345 if(name == null && element != null) {
346 name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
347 }
348 return name;
349 }
350
351 public boolean isAbstract() {
352 return is_abstract;
353 }
354
355 public boolean isAssigned() {
356 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR));
357 }
358
359 public boolean isSeparator() {
360 return (element != null && element.getAttribute(StaticStrings.SEPARATOR_ATTRIBUTE).equals(StaticStrings.TRUE_STR));
361 }
362
363 public void setAssigned(boolean assigned) {
364 if(element != null) {
365 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
366 }
367 }
368
369 /** 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!).
370 * @param custom_str the custom arguments all splodged together in one String
371 */
372 public void setCustom(String custom_str) {
373 HashMap raw_arguments = CollectionConfiguration.parseArguments(new CommandTokenizer(custom_str));
374 ArrayList custom_arguments = getArguments(false, true);
375 int size = custom_arguments.size();
376 for(int i = 0; i < size; i++) {
377 Argument argument = (Argument) custom_arguments.get(i);
378 String original_argument_name = StaticStrings.MINUS_CHARACTER + argument.getName();
379 if(raw_arguments.containsKey(original_argument_name)) {
380 // Set as assigned
381 argument.setAssigned(true);
382 String argument_value = (String)raw_arguments.remove(original_argument_name);
383 if(argument_value != null) {
384 argument.setValue(argument_value);
385 argument_value = null;
386 }
387 }
388 // We've removed it from our custom statement, so unassign
389 else {
390 argument.setAssigned(false);
391 }
392 argument = null;
393 }
394 // Any left over, add to the plugin
395 Iterator argument_names = raw_arguments.keySet().iterator();
396 while(argument_names.hasNext()) {
397 String argument_name = (String) argument_names.next();
398 String argument_value = (String) raw_arguments.get(argument_name);
399 // The tricky thing is that we have to create a new element in the DOM as well.
400 Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
401 argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, argument_name.substring(1));
402 argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
403 argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.TRUE_STR);
404 Argument argument = new Argument(argument_element);
405 argument_name = null;
406 if(argument_value != null) {
407 argument.setValue(argument_value);
408 argument_value = null;
409 }
410 // All done. Add it.
411 element.appendChild(argument_element);
412 add(argument);
413 argument_element = null;
414 }
415 raw_arguments = null;
416 }
417
418 /** Method to set the value of desc.
419 * @param description The new value of desc as a <strong>String</strong>.
420 */
421 public void setDescription(String description) {
422 this.description = description;
423 }
424
425 public void setDoesExplodeMetadataDatabases(boolean does_explode_metadata_databases) {
426 this.does_explode_metadata_databases = does_explode_metadata_databases;
427 }
428
429 public void setElement(Element element) {
430 this.element = element;
431 }
432
433 public void setIsAbstract(boolean is_abstract) {
434 this.is_abstract = is_abstract;
435 }
436
437 /** Method to set the value of name.
438 * @param name The new value of name as a <strong>String</strong>.
439 */
440 public void setName(String name) {
441 this.name = name;
442 }
443
444 /** Method to set the value of the super_plugin.
445 * @param super_plugin The new value of super_plugin as a <strong>Plugin</strong>, or <i>null</i> if this class has no inheritance.
446 */
447 public void setSuper(Plugin super_plugin) {
448 this.super_plugin = super_plugin;
449 }
450
451 /** Method to print out this plugin as it would appear as a command within the collection configuration file.
452 * @return A <strong>String</strong> containing a single plugin command.
453 */
454 public String toString() {
455 if(element != null) {
456 if(name == null) {
457 name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
458 }
459 StringBuffer text = new StringBuffer(StaticStrings.PLUGIN_STR);
460 text.append(" ");
461 text.append(name);
462 text.append(" ");
463 ArrayList arguments = getArguments(true, true);
464 int arguments_size = arguments.size();
465 for(int i = 0; i < arguments_size; i++) {
466 Argument argument = (Argument)arguments.get(i);
467 if(argument.isAssigned()) {
468 text.append(argument.toString());
469 text.append(" ");
470 }
471 argument = null;
472 }
473 return text.substring(0, text.length() - 1);
474 }
475 // Basic Plugin
476 else {
477 return name;
478 }
479 }
480}
Note: See TracBrowser for help on using the repository browser.