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

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

Commented out an exception for the Windows local library.

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