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

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

Changed the configuration version for the Greenstone 2.52 release.

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