source: trunk/gli/src/org/greenstone/gatherer/Configuration.java@ 8204

Last change on this file since 8204 was 8015, checked in by mdewsnip, 20 years ago

Moved clear() and setValue() functions from MSMUtils into XMLTools. Moved NS_SEP string from MSMUtils into StaticStrings.

  • Property svn:keywords set to Author Date Id Revision
File size: 40.3 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 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer;
38
39import java.awt.*;
40import java.io.*;
41import java.lang.ref.*;
42import java.net.*;
43import java.util.*;
44import javax.swing.*;
45import javax.swing.plaf.*;
46import org.greenstone.gatherer.util.StaticStrings;
47import org.greenstone.gatherer.util.Utility;
48import org.greenstone.gatherer.util.XMLTools;
49import org.w3c.dom.*;
50
51/** This class stores the various configurable settings inside the Gatherer, both during a session, and between sessions in the form of XML. However not all data members are retained during xml serialization. To further improve efficiency, the property-name -> DOM Element pairs are stored in a SoftReferenced Hashtable.
52 * @author John Thompson, Greenstone Digital Library, University of Waikato
53 * @version 2.3
54 */
55public class Configuration
56 extends Hashtable {
57
58 static final public boolean COLLECTION_SPECIFIC = true;
59 static final public boolean GENERAL_SETTING = true;
60
61 static final public int ASSISTANT_MODE = 1;
62 static final public int LIBRARIAN_MODE = 2;
63 static final public int SYSTEMS_MODE = 3;
64 static final public int EXPERT_MODE = 4;
65
66 /** The string identifying an argument's name attribute. */
67 static final private String ARGUMENT_NAME = "name";
68 /** The name of the general Gatherer configuration file. */
69 static public String CONFIG_XML = "config.xml";
70 /** The name of the general Gatherer configuration file for running with GS3. */
71 static public String GS3_CONFIG_XML = "config3.xml";
72
73 static final private String CURRENT_CONFIGURATION_VERSION = "2.51u";
74 /** The name of the root element of the subtree containing gatherer configuration options. This is required as the document itself may contain several other subtrees of settings (such as in the case of a '.col' file). */
75 static final private String GATHERER_CONFIG = "GathererConfig";
76 /** The string identifying an argument element. */
77 static final private String GATHERER_CONFIG_ARGUMENT = "Argument";
78
79 static final private String GENERAL_EMAIL_SETTING = "general.email";
80 /** the lang attribute of the other element */
81 static final private String LANGUAGE = "lang";
82 /** The name of a Name Element. */
83 static final private String NAME = "Name";
84 /** The name of the other arguments element. */
85 static final private String OTHER = "Other";
86 /** The name of an information Element within the Other subtree. */
87 static final private String OTHER_INFO = "Info";
88 /** The name of the general Gatherer configuration template. */
89 static public String TEMPLATE_CONFIG_XML = "xml/config.xml";
90 /** The first of three patterns used during tokenization, this pattern handles a comma separated list. */
91 static final private String TOKENIZER_PATTERN1 = " ,\n\t";
92 /** The second of three patterns used during tokenization, this pattern handles an underscore separated list. */
93 static final private String TOKENIZER_PATTERN2 = "_\n\t";
94 /** The last of three patterns used during tokenization, this pattern handles an comma separated list containing spaces. */
95 static final private String TOKENIZER_PATTERN3 = ",\n\t";
96
97 public File exec_file;
98 /** The path (or url) to the webserver which is serving the Greenstone collection. */
99 public String exec_path = null;
100 /** The path to the Greenstone Suite installation directory. */
101 public String gsdl_path = "";
102 /** If we are using GLI in Greenstone 3, the path to gsdl3 directory */
103 public String gsdl3_path = "";
104 /** The path to the PERL executable, up to and including Perl.exe. */
105 public String perl_path = "";
106 /** The password for the proxy server indicated above. */
107 public String proxy_pass = null;
108 /** The username for the proxy server indicated above. */
109 public String proxy_user = null;
110 /** The screen size of the desktop the Gatherer will be displayed on. */
111 public Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();
112 /** The site name if we are using GS3 */
113 public String site_name = "";
114 /** The servlet path if we are using GS3 */
115 private String servlet_path = "";
116 /** If true, overrides the mirroring enabled setting in the config.xml file. */
117 private boolean mirroring_enabled = false;
118 /** Collection level configuration (which in some cases overrides general configuration. */
119 private Document collection_config;
120 /** The general configuration settings. */
121 private Document general_config;
122
123 /** The element, from glis config file, that contains the various directory mappings. */
124 private Element directory_mappings_element;
125
126 private int cache_hit = 0;
127 private int cache_miss = 0;
128
129 private String wget_path = null;
130 private String wget_version_str = StaticStrings.NO_WGET_STR;
131
132 public URL exec_address = null;
133
134 /** Constructor.
135 * @param gsdl_path The path to the Greenstone directory as a <strong>String</strong>.
136 * @param exec_path A <strong>String</strong> containing the path or url to the webserver serving the greenstone collections.
137 * @param perl_path The path to the PERL executable, as a <strong>String</strong>.
138 * @param mirroring_enabled If true will override the config.xml fiel setting for mirroring.
139 * @param site_name The name of the Greenstone 3 site currently in use.
140 */
141 public Configuration(String gsdl_path, String gsdl3_path, String exec_path, String perl_path, boolean mirroring_enabled, String site_name) {
142 super();
143 this.gsdl_path = gsdl_path;
144 this.gsdl3_path = gsdl3_path;
145 this.exec_path = exec_path;
146 this.mirroring_enabled = mirroring_enabled;
147 this.site_name = site_name;
148
149 // The exec_path may contain an url address, in which case we blindly use that and leave it up to the user to worry about settings and resetting.
150 Gatherer.println("EXEC_PATH = " + exec_path);
151 if(exec_path != null && exec_path.length() > 0) {
152 try {
153 exec_address = new URL(exec_path);
154 }
155 catch (MalformedURLException error) {
156 Gatherer.println("Not an address.");
157 Gatherer.printStackTrace(error);
158 }
159 }
160 // If the above failed, then its up to us to try and figure out what to do.
161 if(exec_address == null) {
162 // Try building a file from the given exec_path
163 try {
164 File local_file = new File(exec_path);
165 if(local_file.exists()) {
166 // All good. I hope.
167 exec_file = local_file;
168 }
169 else {
170 Gatherer.println("No local library at given file path.");
171 }
172 }
173 // All sorts of errors might be thrown by a bogus file path.
174 catch (Exception error) {
175 Gatherer.println("Libary url does not indicate the server.exe file.");
176 ///atherer.printStackTrace(error);
177 }
178 // We can generate the path to where the local library should be and use that if it is there.
179 if(exec_file == null) {
180 File server_exe = new File(gsdl_path + Utility.SERVER_EXE);
181 if(server_exe.exists()) {
182 exec_file = server_exe;
183 }
184 else {
185 Gatherer.println("No local library.");
186 }
187 }
188 // If we get to here with no exec_address nor an exec_file its just plain not going to work.
189 }
190 else {
191 Gatherer.println("exec_address != null -> " + exec_address);
192 }
193
194 ///ystem.err.println("Perl path.");
195 this.perl_path = perl_path;
196 // Ensure the perl path includes exe under windoze
197 if (!Gatherer.isGsdlRemote) {
198 if(Utility.isWindows() && !perl_path.toLowerCase().endsWith(".exe")) {
199 if(!perl_path.endsWith(File.separator)) {
200 perl_path = perl_path + File.separator;
201 }
202 perl_path = perl_path + "perl.exe";
203 }
204 }
205
206 // Try to reload the configuration. The first place we look is the user specific location
207 String config_xml_name = CONFIG_XML;
208 if (gsdl3_path != null) {
209 config_xml_name = GS3_CONFIG_XML;
210 }
211 File config_xml = new File(Utility.getGLIUserFolder(), config_xml_name);
212 if(config_xml != null && config_xml.exists()) {
213 general_config = Utility.parse(config_xml.getAbsolutePath(), false);
214 }
215
216 // We then try within the gli directory itself
217 if(general_config == null) {
218 config_xml = new File(config_xml_name);
219 if(config_xml.exists()) {
220 general_config = Utility.parse(config_xml_name, true);
221 }
222 }
223
224 // Check the version of the config we have loaded, and if it isn't recent enough, backup the old version, and then create a new config.
225 if(general_config != null) {
226 Element configuration_element = general_config.getDocumentElement();
227 String configuration_version = configuration_element.getAttribute(StaticStrings.VERSION_ATTRIBUTE);
228 if(!configuration_version.equals(CURRENT_CONFIGURATION_VERSION)) {
229 /** @todo - reenable this once we can change the dictionary. */
230 //JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Configuration.Obsolete_Config"), Dictionary.get("Configuration.Obsolete_Config_Title"), JOptionPane.ERROR_MESSAGE);
231 general_config = null;
232 configuration_element = null;
233 File backup = new File(config_xml.getAbsolutePath() + ".bak");
234 config_xml.renameTo(backup);
235 backup = null;
236 }
237 else {
238 configuration_element = null;
239 }
240 configuration_version = null;
241 }
242
243 // And if that fails retrieve the default configuration file from our xml library, which I'll personally guarantee to work.
244 if(general_config == null) {
245 general_config = Utility.parse(TEMPLATE_CONFIG_XML, true);
246 Gatherer.println("Loaded default Gatherer configuration template.");
247 }
248 else {
249 Gatherer.println("Loaded current Gatherer configuration.");
250 }
251
252 // Determine the Directory Mappings element
253 directory_mappings_element = (Element) XMLTools.getNodeFromNamed(general_config.getDocumentElement(), StaticStrings.DIRECTORY_MAPPINGS_ELEMENT);
254
255 // Re-establish the color settings.
256 updateUI();
257
258 // If we have no exec_address, see if one was specified in the config file
259 if (exec_address == null) {
260 String exec_address_string = getString("general.exec_address", true);
261 if (!exec_address_string.equals("")) {
262 try {
263 exec_address = new URL(exec_address_string);
264 }
265 catch (MalformedURLException error) {
266 ///ystem.err.println("Error: Bad address: " + exec_address_string);
267 }
268 }
269 }
270
271 if (Gatherer.GS3) {
272 if (this.site_name == null || this.site_name.equals("")) {
273 this.site_name = getString("general.site_name", true);
274 this.servlet_path = getString("general.servlet_path", true);
275 if (this.site_name.equals("")) {
276 this.site_name = "localsite"; // can we assume these??
277 this.servlet_path = "/library";
278 setString("general.site_name", true, this.site_name);
279 setString("general.servlet_path", true, this.servlet_path);
280 }
281
282 } else {
283 // we set the current one in the config
284 setString("general.site_name", true, this.site_name);
285 if (this.servlet_path != null && !this.servlet_path.equals("")) {
286 setString("general.servlet_path", true, this.servlet_path);
287 }
288 }
289 }
290 Gatherer.println("EXEC_FILE = " + exec_file);
291 Gatherer.println("EXEC_ADDRESS = " + exec_address);
292 }
293
294 /** Add a special directory mapping. */
295 public boolean addDirectoryMapping(String name, File file) {
296 boolean result = false;
297 try {
298 // Ensure the name isn't already in use.
299 boolean found = false;
300 NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT);
301 for(int i = 0; !found && i < mappings.getLength(); i++) {
302 Element mapping_element = (Element) mappings.item(i);
303 if(mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equalsIgnoreCase(name)) {
304 found = true;
305 }
306 mapping_element = null;
307 }
308 // Otherwise add the mapping.
309 if(!found) {
310 Element mapping_element = general_config.createElement(StaticStrings.MAPPING_ELEMENT);
311 mapping_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
312 mapping_element.setAttribute(StaticStrings.FILE_ATTRIBUTE, file.toString());
313 directory_mappings_element.appendChild(mapping_element);
314 result = true;
315 mapping_element = null;
316 }
317 mappings = null;
318 }
319 catch (Exception exception) {
320 Gatherer.printStackTrace(exception);
321 }
322 return result;
323 } /** addDirectoryMapping(String name, String file) **/
324
325 /** The default get action retrieves the named property from the desired configuration, and returns a true or false. */
326 public boolean get(String property, boolean general) {
327 if(general && mirroring_enabled && property.equals(StaticStrings.WORKFLOW_MIRROR)) {
328 return mirroring_enabled;
329 }
330 String raw = getString(property, general);
331 return (raw != null && raw.equalsIgnoreCase("true"));
332 }
333
334 /** Retrieve all of the configuration preferences which match a certain string. They are returned as a hash map of property names to String objects. */
335 public HashMap getAll(String property_pattern, boolean general) {
336 HashMap properties = new HashMap();
337 try {
338 // Locate the appropriate element
339 Element document_element = null;
340 if(general) {
341 document_element = general_config.getDocumentElement();
342 }
343 else if(collection_config != null) {
344 document_element = collection_config.getDocumentElement();
345 }
346 if(document_element != null) {
347 // Retrieve the Gatherer element
348 Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG);
349 NodeList arguments = gatherer_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
350 for(int i = 0; i < arguments.getLength(); i++) {
351 Element argument_element = (Element) arguments.item(i);
352 if(argument_element.getAttribute(ARGUMENT_NAME).matches(property_pattern)) {
353 String result = XMLTools.getValue(argument_element);
354 // Store a mapping in the cache. Sometimes we will overwrite an existing value (say for collection and general level workflow options) but the processing overhead of detecting these clashes far exceeds any savings.
355 put(argument_element.getAttribute(ARGUMENT_NAME) + general, new SoftReference(argument_element));
356 // Add mapping to the properties we're going to return
357 properties.put(argument_element.getAttribute(ARGUMENT_NAME), result);
358 }
359 }
360 }
361 }
362 catch(Exception error) {
363 }
364 return properties;
365 }
366
367 /** Retrieve the information subtree containing the arguments for the desired external program. If the program has marked superclasses append their arguments as well. */
368 public Element getArguments(String filename) {
369 Element argument_element = null;
370 try {
371 // Retrieve the other information subtree.
372 Element document_element = general_config.getDocumentElement();
373 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
374 NodeList argument_elements = other_element.getElementsByTagName(OTHER_INFO);
375 for(int i = 0; argument_element == null && i < argument_elements.getLength(); i++) {
376 Element possible_element = (Element) argument_elements.item(i);
377 Element possible_name_element = (Element) XMLTools.getNodeFromNamed(possible_element, NAME);
378 String possible_name = XMLTools.getValue(possible_name_element);
379 ///ystem.err.println("Does " + possible_name + " equal " + filename);
380 if(possible_name.equalsIgnoreCase(filename)) {
381 argument_element = possible_element;
382 }
383 possible_name = null;
384 possible_name_element = null;
385 possible_element = null;
386 }
387 argument_elements = null;
388 other_element = null;
389 document_element = null;
390 }
391 catch(Exception error) {
392 }
393 return argument_element;
394 }
395
396 /** Gets the language for the other arguments subtree
397 @return empty string if no language specified */
398 public String getArgumentsLanguage() {
399 Element document_element = general_config.getDocumentElement();
400 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
401 String lang = other_element.getAttribute(LANGUAGE);
402 if (lang == null) {
403 lang = "en";
404 }
405 return lang;
406 }
407
408 /** Retrieve the value of the named property as a Rectangle. */
409 public Rectangle getBounds(String property, boolean general) {
410 Rectangle result = null;
411 try {
412 String raw = getString(property, general);
413 // Rectangle is (x, y, width, height)
414 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1);
415 int x = Integer.parseInt(tokenizer.nextToken());
416 int y = Integer.parseInt(tokenizer.nextToken());
417 int width = Integer.parseInt(tokenizer.nextToken());
418 int height = Integer.parseInt(tokenizer.nextToken());
419 result = new Rectangle(x, y, width, height);
420 }
421 catch(Exception error) {
422 Gatherer.printStackTrace(error);
423 }
424 return result;
425 }
426
427 /** Retrieve the value of the named property as a Color. */
428 public Color getColor(String property, boolean general) {
429 Color result = Color.white; // Default
430 try {
431 String raw = getString(property, general);
432 // Color is a RGB triplet list, comma separated (also remove whitespace)
433 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1);
434 int red = Integer.parseInt(tokenizer.nextToken());
435 int green = Integer.parseInt(tokenizer.nextToken());
436 int blue = Integer.parseInt(tokenizer.nextToken());
437 result = new Color(red, green, blue);
438 }
439 catch(Exception error) {
440 Gatherer.printStackTrace(error);
441 }
442 return result;
443 }
444
445 /** Retrieve the value of the named property as a Dimension. */
446 /* private Dimension getDimension(String property, boolean general) {
447 Dimension result = new Dimension(100, 100); // Default
448 try {
449 String raw = getString(property, general);
450 // Dimension is a width by height pair, comma separated (also remove whitespace)
451 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1);
452 int width = Integer.parseInt(tokenizer.nextToken());
453 int height = Integer.parseInt(tokenizer.nextToken());
454 result = new Dimension(width, height);
455 }
456 catch(Exception error) {
457 Gatherer.printStackTrace(error);
458 }
459 return result;
460 } */
461
462 /** Retrieve the special directory mappings associated with this collection.
463 * @return A <strong>HashMap</strong> containing mappings from names to directories.
464 */
465 public HashMap getDirectoryMappings() {
466 HashMap special_directories = new HashMap();
467 try {
468 // Ensure the name isn't already in use.
469 boolean found = false;
470 NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT);
471 for(int i = 0; !found && i < mappings.getLength(); i++) {
472 Element mapping_element = (Element) mappings.item(i);
473 String name = mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
474 File file = new File(mapping_element.getAttribute(StaticStrings.FILE_ATTRIBUTE));
475 special_directories.put(name, file);
476 file = null;
477 name = null;
478 mapping_element = null;
479 }
480 mappings = null;
481 }
482 catch(Exception exception) {
483 Gatherer.printStackTrace(exception);
484 }
485 return special_directories;
486 } /** getDirectoryMappings() */
487
488 /** Retrieve the current users email. These are always stored in the general settings.
489 * @return the email address, if it is set, as a String
490 */
491 public String getEmail() {
492 String email = getString(GENERAL_EMAIL_SETTING, true);
493 return (email.length() > 0 ? email : null);
494 }
495
496 public Element getFileAssociations() {
497 NodeList file_association_elements = general_config.getDocumentElement().getElementsByTagName(StaticStrings.ASSOCIATIONS_ELEMENT);
498 return (Element) file_association_elements.item(0);
499 }
500
501 /** Retrieve the value of the named property as a FontUIResource. */
502 public FontUIResource getFont(String property, boolean general) {
503 FontUIResource result = new FontUIResource("Times New Roman", Font.PLAIN, 10);
504 try {
505 String raw = getString(property, general);
506 // Font is a face, style, size triplet.
507 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN3);
508 String face = tokenizer.nextToken().trim();
509 ///ystem.err.println("Face: " + face);
510 int style = Font.PLAIN;
511 String temp = tokenizer.nextToken().toUpperCase().trim();
512 ///ystem.err.println("Style: " + temp);
513 if(temp.equals("BOLD")) {
514 style = Font.BOLD;
515 }
516 else if(temp.equals("ITALIC")) {
517 style = Font.ITALIC;
518 }
519 int size = Integer.parseInt(tokenizer.nextToken().trim());
520 ///ystem.err.println("Size: " + size);
521 result = new FontUIResource(face, style, size);
522 }
523 catch(Exception error) {
524 Gatherer.printStackTrace(error);
525 }
526 return result;
527 }
528
529 /** Retrieve the value of the named property as an integer. */
530 public int getInt(String property, boolean general) {
531 int result = 0;
532 try {
533 String raw = getString(property, general);
534 result = Integer.parseInt(raw);
535 }
536 catch(Exception error) {
537 Gatherer.printStackTrace(error);
538 }
539 return result;
540 }
541
542 /** Retrieves the current interface language two letter code. */
543 public String getLanguage() {
544 Locale locale = getLocale("general.locale", GENERAL_SETTING);
545 String code = "en"; // Default
546 if(locale != null) {
547 code = locale.getLanguage();
548 }
549 return code;
550 }
551
552 /** Retrieve the value of the named property as a Locale. */
553 public Locale getLocale(String property, boolean general) {
554 Locale result = Locale.getDefault();
555 try {
556 String raw = getString(property, general);
557 // Locale is a underscore separated code.
558 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN2);
559 String language = tokenizer.nextToken();
560 if(tokenizer.hasMoreTokens()) {
561 String country = tokenizer.nextToken();
562 result = new Locale(language, country);
563 }
564 else {
565 result = new Locale(language);
566 }
567 }
568 catch(Exception error) {
569 Gatherer.printStackTrace(error);
570 }
571 return result;
572 }
573
574 /** Because modes will soon be an integral part of GLI, they get their own easy to remember methods such as this one to get the mode.
575 * @return an int representing the mode
576 */
577 public int getMode() {
578 return getInt("general.mode", GENERAL_SETTING);
579 }
580
581 /** Return the current mode as a string for use in title bar etc
582 * @return the mode as a String
583 */
584 public String getModeAsString() {
585 String result;
586 switch(getInt("general.mode", GENERAL_SETTING)) {
587 case ASSISTANT_MODE:
588 result = Dictionary.get("Preferences.Mode.Assistant");
589 break;
590 case SYSTEMS_MODE:
591 result = Dictionary.get("Preferences.Mode.Systems");
592 break;
593 case EXPERT_MODE:
594 result = Dictionary.get("Preferences.Mode.Expert");
595 break;
596 default:
597 result = Dictionary.get("Preferences.Mode.Librarian");
598 }
599 return result;
600 }
601
602 public String getPreviewCommand() {
603 return getString("general.preview_program", GENERAL_SETTING);
604 }
605
606 public String getServletPath() {
607 if (servlet_path == null) {
608 servlet_path = Gatherer.servlet_config.getServletPath(site_name);
609 }
610 return servlet_path;
611 }
612 /** Retrieve the value of the named property, and noting whether we consult the general or collection specific configuration. */
613 public String getString(String property, boolean general) {
614 // Its up to this method to find the appropriate node and retrieve the data itself.
615 String result = "";
616 try {
617 // First of all we look in the cache to see if we have a match.
618 SoftReference reference = (SoftReference) get(property + general);
619 if(reference != null) {
620 Element argument_element = (Element) reference.get();
621 if(argument_element != null) {
622 cache_hit++;
623 result = XMLTools.getValue(argument_element);
624 }
625 }
626 // We may have missed in the cache, or the reference may have been consumed.
627 if(result.length() == 0) {
628 cache_miss++;
629 // Locate the appropriate element
630 Element document_element = null;
631 if(general) {
632 document_element = general_config.getDocumentElement();
633 }
634 else if(collection_config != null) {
635 document_element = collection_config.getDocumentElement();
636 }
637 if(document_element != null) {
638 // Retrieve the Gatherer element
639 Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG);
640 NodeList arguments = gatherer_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
641 for(int i = 0; result.length() == 0 && i < arguments.getLength(); i++) {
642 Element argument_element = (Element) arguments.item(i);
643 if(argument_element.getAttribute(ARGUMENT_NAME).equalsIgnoreCase(property)) {
644 result = XMLTools.getValue(argument_element);
645 // Store a mapping in the cache. Sometimes we will overwrite an existing value (say for collection and general level workflow options) but the processing overhead of detecting these clashes far exceeds any savings.
646 put(property + general, new SoftReference(argument_element));
647 }
648 }
649 }
650 }
651 }
652 catch (Exception error) {
653 Gatherer.printStackTrace(error);
654 }
655 // If we still have no result, and the search was made in the collection configuration, retrieve the general one instead.
656 if(result.length() == 0 && !general) {
657 result = getString(property, true);
658 }
659 return result;
660 }
661
662 /** Retrieve the path to the PERL scripts within the Greenstone directory.
663 * @return A <strong>String</strong> containing the path.
664 */
665 public String getScriptPath() {
666 return gsdl_path + "bin" + File.separator + "script" + File.separator;
667 }
668
669 public String getGS3ScriptPath() {
670 return gsdl3_path + "bin" + File.separator + "script" + File.separator;
671 }
672
673
674 public String getWGetPath() {
675 return (wget_path != null ? wget_path : "");
676 }
677
678 public String getWGetVersion() {
679 return (wget_version_str != null ? wget_version_str : StaticStrings.NO_WGET_STR);
680 }
681
682 /** Remove a previously defined special directory mapping.
683 * @param name The name of the mapping to remove as a <strong>String</strong>.
684 * @return The <strong>File</strong> of the mapping removed.
685 */
686 public File removeDirectoryMapping(String name) {
687 File file = null;
688 try {
689 // Ensure the name isn't already in use.
690 boolean found = false;
691 NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT);
692 for(int i = 0; !found && i < mappings.getLength(); i++) {
693 Element mapping_element = (Element) mappings.item(i);
694 if(mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equalsIgnoreCase(name)) {
695 file = new File(XMLTools.getValue(mapping_element));
696 directory_mappings_element.removeChild(mapping_element);
697 found = true;
698 }
699 mapping_element = null;
700 }
701 mappings = null;
702 }
703 catch(Exception error) {
704 Gatherer.printStackTrace(error);
705 }
706 return file;
707 } /** removeDirectoryMapping(String name) */
708
709 /** Export the general configuration to file. */
710 public void save() {
711 ///ystem.err.println("Hits " + cache_hit + " vs Misses " + cache_miss);
712 // We first try exporting to a user specific place
713 File user_config_xml = null;
714 String config_xml_name = CONFIG_XML;
715 if (gsdl3_path!=null) {
716 config_xml_name = GS3_CONFIG_XML;
717 }
718 try {
719 user_config_xml = new File(Utility.getGLIUserFolder(), config_xml_name);
720 ///ystem.err.println("Trying to save to: " + user_config_xml.getAbsolutePath());
721 ///ystem.err.println("Writing.");
722 user_config_xml.getParentFile().mkdirs();
723 Utility.export(general_config, user_config_xml.getAbsolutePath());
724 }
725 catch(Exception exception) {
726 user_config_xml = null;
727 }
728 // Always do this if the above fails.
729 if(user_config_xml == null || !user_config_xml.exists()) {
730 // But failing that we produce a general copy
731 Utility.export(general_config, Utility.BASE_DIR + config_xml_name);
732 }
733 }
734
735 /** Set the named property, from the specified configuration, using the given boolean value. */
736 public void set(String property, boolean general, boolean value) {
737 if(property.startsWith("workflow")) {
738 Gatherer.println("Set property: " + property + ", general=" + general + ", value=" + value);
739 }
740 setString(property, general, (value ? "true" : "false"));
741 }
742
743 /** Add a subtree of argument information to the other arguments part of the general configuration. This overwrites any such existing subtree. */
744 public void setArguments(Element arguments_element) {
745 try {
746 Element document_element = general_config.getDocumentElement();
747 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
748 // Retrieve the name of the information
749 Element arguments_name_element = (Element)XMLTools.getNodeFromNamed(arguments_element, NAME);
750 String filename = XMLTools.getValue(arguments_element);
751 // Find any argument information subtree starting with the same name
752 Element obsolete_arguments_element = getArguments(filename);
753 // Create a copy of the arguments_element within our tree (import).
754 Element our_arguments_element = (Element) general_config.importNode(arguments_element, true);
755 // Now we insert this new node into the tree. If a previous node exists we replace it instead.
756 if(obsolete_arguments_element == null) {
757 other_element.appendChild(our_arguments_element);
758 }
759 else {
760 other_element.replaceChild(our_arguments_element, obsolete_arguments_element);
761 }
762 our_arguments_element = null;
763 obsolete_arguments_element = null;
764 filename = null;
765 arguments_name_element = null;
766 other_element = null;
767 document_element = null;
768 }
769 catch (Exception error) {
770 Gatherer.println("Error in Configuration.setArguments(): " + error);
771 Gatherer.printStackTrace(error);
772 }
773 }
774
775 /** Sets the language for the other arguments subtree */
776 public void setArgumentsLanguage(String lang) {
777 Element document_element = general_config.getDocumentElement();
778 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
779 other_element.setAttribute(LANGUAGE, lang);
780 }
781
782
783 /** Set the collection configuration. */
784 public void setCollectionConfiguration(Document collection_config) {
785 // clear the cached values
786 clear();
787 this.collection_config = collection_config;
788 updateUI();
789 ///atherer.println("Collection configuration set.");
790 }
791
792 /** Set the named property, from the specified configuration, using the given Rectangle value. */
793 public void setBounds(String property, boolean general, Rectangle value) {
794 StringBuffer text = new StringBuffer("");
795 text.append(value.x);
796 text.append(", ");
797 text.append(value.y);
798 text.append(", ");
799 text.append(value.width);
800 text.append(", ");
801 text.append(value.height);
802 setString(property, general, text.toString());
803 }
804
805 /** Set the named property, from the specified configuration, using the given Color value. */
806 public void setColor(String property, boolean general, Color value) {
807 StringBuffer text = new StringBuffer("");
808 text.append(value.getRed());
809 text.append(", ");
810 text.append(value.getGreen());
811 text.append(", ");
812 text.append(value.getBlue());
813 setString(property, general, text.toString());
814 }
815
816 /** Set the named property, from the specified configuration, using the given Dimension value. */
817 /* private void setDimension(String property, boolean general, Dimension value) {
818 StringBuffer text = new StringBuffer("");
819 text.append(value.width);
820 text.append(", ");
821 text.append(value.height);
822 setString(property, general, text.toString());
823 } */
824
825 /** Establish the current users email.
826 * @param email the email as a String
827 */
828 public void setEmail(String email) {
829 setString(GENERAL_EMAIL_SETTING, true, email);
830 }
831
832 /** Set the named property, from the specified configuration, using the given Font value. */
833 public void setFont(String property, boolean general, Font value) {
834 StringBuffer text = new StringBuffer("");
835 text.append(value.getName());
836 text.append(", ");
837 switch(value.getStyle()) {
838 case Font.BOLD:
839 text.append("BOLD");
840 break;
841 case Font.ITALIC:
842 text.append("ITALIC");
843 break;
844 default:
845 text.append("PLAIN");
846 }
847 text.append(", ");
848 text.append(value.getSize());
849 setString(property, general, text.toString());
850 }
851
852 /** Set the named property, from the specified configuration, using the given integer value. */
853 public void setInt(String property, boolean general, int value) {
854 setString(property, general, String.valueOf(value));
855 }
856
857 /** Set the named property, from the specified configuration, using the given Locale value. */
858 public void setLocale(String property, boolean general, Locale value) {
859 StringBuffer text = new StringBuffer("");
860 text.append(value.getLanguage());
861 String country = value.getCountry();
862 if(country != null && country.length() > 0) {
863 text.append("_");
864 text.append(country);
865 }
866 country = null;
867 setString(property, general, text.toString());
868 }
869
870 /** Because modes will soon be an integral part of GLI, they get their own easy to remember methods such as this one to set the mode.
871 * @param value the new value for mode
872 */
873 public void setMode(int value) {
874 setInt("general.mode", GENERAL_SETTING, value);
875 }
876
877 public void setPreviewCommand(String value) {
878 setString("general.preview_program", GENERAL_SETTING, value);
879 }
880
881 public void setSiteAndServlet(String site, String servlet) {
882 this.site_name = site;
883 this.servlet_path = servlet;
884 setString("general.site_name", GENERAL_SETTING, site);
885 setString("general.servlet_path", GENERAL_SETTING, servlet);
886
887 }
888 /** Sets the value of the named property argument using the given string. */
889 public void setString(String property, boolean general, String value) {
890 Gatherer.println("Set configuration property: " + property + " = " + value + (general ? "" : " [Collection]"));
891 try {
892 Document document = general_config;
893 if(!general && collection_config != null) {
894 document = collection_config;
895 }
896 if(document != null) {
897 Element argument_element = null;
898 // Try to retrieve from cache
899 SoftReference reference = (SoftReference) get(property + general);
900 if(reference != null) {
901 argument_element = (Element) reference.get();
902 }
903 if(argument_element == null) {
904 Element document_element = document.getDocumentElement();
905 Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG);
906 NodeList arguments = document_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
907 boolean found = false;
908 for(int i = 0; argument_element == null && i < arguments.getLength(); i++) {
909 Element possible_element = (Element) arguments.item(i);
910 if(possible_element.getAttribute(ARGUMENT_NAME).equalsIgnoreCase(property)) {
911 argument_element = possible_element;
912 }
913 }
914 // If argument element is still null, create it in the target document.
915 if(argument_element == null) {
916 argument_element = document.createElement(GATHERER_CONFIG_ARGUMENT);
917 argument_element.setAttribute(ARGUMENT_NAME, property);
918 gatherer_element.appendChild(argument_element);
919 }
920 // Update cache
921 put(property + general, new SoftReference(argument_element));
922
923 }
924 if(value == null) {
925 value = "";
926 }
927 // Now remove any current text node children.
928 NodeList children = argument_element.getChildNodes();
929 for(int i = 0; i < children.getLength(); i++) {
930 argument_element.removeChild(children.item(i));
931 }
932 // Add a new text node child with the new value
933 argument_element.appendChild(document.createTextNode(value));
934 }
935 }
936 catch (Exception error) {
937 }
938 }
939
940 public void setWGetPath(String path) {
941 wget_path = path;
942 }
943
944 public void setWGetVersion(String version) {
945 wget_version_str = version;
946 }
947
948 private void updateUI() {
949 // Buttons
950 UIManager.put("Button.select", new ColorUIResource(getColor("coloring.button_selected_background", false)));
951 UIManager.put("Button.background", new ColorUIResource(getColor("coloring.button_background", false)));
952 UIManager.put("Button.foreground", new ColorUIResource(getColor("coloring.button_foreground", false)));
953
954 UIManager.put("ToggleButton.background", new ColorUIResource(getColor("coloring.button_background", false)));
955 UIManager.put("ToggleButton.foreground", new ColorUIResource(getColor("coloring.button_foreground", false)));
956 UIManager.put("ToggleButton.select", new ColorUIResource(getColor("coloring.button_selected_background", false)));
957
958 // All the things with a lovely Collection green background
959 UIManager.put("OptionPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
960 UIManager.put("Panel.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
961 UIManager.put("Label.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
962 UIManager.put("TabbedPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
963 UIManager.put("SplitPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
964 UIManager.put("CheckBox.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
965
966
967 // Editable coloring
968 UIManager.put("ComboBox.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); // Indicate clickable
969 UIManager.put("Tree.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
970 UIManager.put("Tree.textBackground", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
971 UIManager.put("ProgressBar.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
972 UIManager.put("TextArea.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
973 UIManager.put("TextField.background", new ColorUIResource(getColor("coloring.editable_background", false)));
974 UIManager.put("Table.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
975 UIManager.put("List.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
976 UIManager.put("RadioButton.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
977
978 // Selection color
979 UIManager.put("TabbedPane.selected", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
980 UIManager.put("Tree.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
981 UIManager.put("ComboBox.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
982 UIManager.put("ProgressBar.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
983 UIManager.put("TextArea.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
984 UIManager.put("TextField.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
985 UIManager.put("List.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
986
987 // Scroll bar stuff
988 UIManager.put("ScrollBar.background", new ColorUIResource(getColor("coloring.scrollbar_background", false)));
989 UIManager.put("ScrollBar.thumb", new ColorUIResource(getColor("coloring.scrollbar_foreground", false)));
990 if (Gatherer.g_man != null) {
991 JPanel pane = (JPanel) Gatherer.g_man.getContentPane();
992 pane.updateUI();
993 // Also update all of the tabs according to workflow.
994 Gatherer.g_man.workflowUpdate("Mirror", get("workflow.mirror", false));
995 Gatherer.g_man.workflowUpdate("Gather", get("workflow.gather", false));
996 Gatherer.g_man.workflowUpdate("Enrich", get("workflow.enrich", false));
997 Gatherer.g_man.workflowUpdate("Design", get("workflow.design", false));
998 Gatherer.g_man.workflowUpdate("Export", get("workflow.export", false));
999 Gatherer.g_man.workflowUpdate("Create", get("workflow.create", false));
1000 }
1001 }
1002}
Note: See TracBrowser for help on using the repository browser.