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

Last change on this file since 10345 was 10345, checked in by mdewsnip, 19 years ago

Removed some more crap out of the Utility class.

  • Property svn:keywords set to Author Date Id Revision
File size: 41.4 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.XMLTools;
48import org.w3c.dom.*;
49
50/** 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.
51 * @author John Thompson, Greenstone Digital Library, University of Waikato
52 * @version 2.3
53 */
54public class Configuration
55 extends Hashtable {
56
57 static final public boolean COLLECTION_SPECIFIC = true;
58 static final public boolean GENERAL_SETTING = true;
59
60 static final public int ASSISTANT_MODE = 1;
61 static final public int LIBRARIAN_MODE = 2;
62 static final public int SYSTEMS_MODE = 3;
63 static final public int EXPERT_MODE = 4;
64
65 /** The string identifying an argument's name attribute. */
66 static final private String ARGUMENT_NAME = "name";
67 /** The name of the general Gatherer configuration file. */
68 static public String CONFIG_XML = "config.xml";
69 /** The name of the general Gatherer configuration file for running with GS3. */
70 static public String GS3_CONFIG_XML = "config3.xml";
71
72 /** 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). */
73 static final private String GATHERER_CONFIG = "GathererConfig";
74 /** The string identifying an argument element. */
75 static final private String GATHERER_CONFIG_ARGUMENT = "Argument";
76
77 static final private String GENERAL_EMAIL_SETTING = "general.email";
78 /** the lang attribute of the other element */
79 static final private String LANGUAGE = "lang";
80 /** The name of a Name Element. */
81 static final private String NAME = "Name";
82 /** The name of the other arguments element. */
83 static final private String OTHER = "Other";
84 /** The name of an information Element within the Other subtree. */
85 static final private String OTHER_INFO = "Info";
86 /** The name of the general Gatherer configuration template. */
87 static public String TEMPLATE_CONFIG_XML = "xml/config.xml";
88 /** The first of three patterns used during tokenization, this pattern handles a comma separated list. */
89 static final private String TOKENIZER_PATTERN1 = " ,\n\t";
90 /** The second of three patterns used during tokenization, this pattern handles an underscore separated list. */
91 static final private String TOKENIZER_PATTERN2 = "_\n\t";
92 /** The last of three patterns used during tokenization, this pattern handles an comma separated list containing spaces. */
93 static final private String TOKENIZER_PATTERN3 = ",\n\t";
94
95 static public Configuration self = null;
96
97 static public boolean just_updated_config_xml_file = false;
98 /** The path to the Greenstone Suite installation directory. */
99 static public String gsdl_path = "";
100 /** If we are using GLI in Greenstone 3, the path to gsdl3 home (== web dir) */
101 static public String gsdl3_path = "";
102 /** If we are using GLI in Greenstone 3, the path to gsdl3 src directory (== gsdl3 dir)*/
103 static public String gsdl3_src_path = "";
104 /** The path to the PERL executable, up to and including Perl.exe. */
105 static public String perl_path = "";
106 /** The password for the proxy server indicated above. */
107 static public String proxy_pass = null;
108 /** The username for the proxy server indicated above. */
109 static public String proxy_user = null;
110 /** The screen size of the desktop the Gatherer will be displayed on. */
111 static public Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();
112 /** The site name if we are using GS3 */
113 static public String site_name = "";
114 /** The servlet path if we are using GS3 */
115 static public String servlet_path = "";
116 /** Collection level configuration (which in some cases overrides general configuration. */
117 static private Document collection_config;
118 /** The general configuration settings. */
119 static private Document general_config;
120
121 /** The element, from glis config file, that contains the various directory mappings. */
122 static private Element directory_mappings_element;
123
124 static private int cache_hit = 0;
125 static private int cache_miss = 0;
126
127 static private String wget_path = null;
128 static private String wget_version_str = StaticStrings.NO_WGET_STR;
129
130 static public URL library_url = null;
131
132
133 /** Constructor.
134 * @param gsdl_path The path to the Greenstone directory as a <strong>String</strong>.
135 * @param gsdl3_path The path to the Greenstone 3 home (web) directory as a <strong>String</strong>.
136 * @param gsdl3_src_path The path to the Greenstone 3 src directory as a <strong>String</strong>.
137 * @param site_name The name of the Greenstone 3 site currently in use.
138 */
139 public Configuration(String gsdl_path, String gsdl3_path, String gsdl3_src_path, String site_name)
140 {
141 super();
142 self = this;
143
144 this.gsdl_path = gsdl_path;
145 this.gsdl3_path = gsdl3_path;
146 this.gsdl3_src_path = gsdl3_src_path;
147 this.site_name = site_name;
148
149 // Try to load the configuration file from the user specific location
150 String config_xml_file_name = CONFIG_XML;
151 if (gsdl3_path != null) {
152 config_xml_file_name = GS3_CONFIG_XML;
153 }
154
155 // If the existing user config.xml file isn't recent enough, backup the old version and update it
156 File config_xml_file = new File(Gatherer.getGLIUserDirectoryPath() + config_xml_file_name);
157 if (config_xml_file != null && config_xml_file.exists()) {
158 just_updated_config_xml_file = updateUserConfigXMLFileIfNecessary(config_xml_file);
159 general_config = XMLTools.parseXMLFile(config_xml_file);
160 }
161
162 // Create a new config from the default configuration file from our xml library
163 if (general_config == null) {
164 general_config = XMLTools.parseXMLFile(TEMPLATE_CONFIG_XML, true);
165 just_updated_config_xml_file = true;
166 }
167
168 // Determine the Directory Mappings element
169 directory_mappings_element = (Element) XMLTools.getNodeFromNamed(general_config.getDocumentElement(), StaticStrings.DIRECTORY_MAPPINGS_ELEMENT);
170
171 // Re-establish the color settings.
172 updateUI();
173
174 // Read the Greenstone library URL from the config file
175 String library_url_string = getString("general.library_url", true);
176 if (!library_url_string.equals("")) {
177 try {
178 library_url = new URL(library_url_string);
179 }
180 catch (MalformedURLException exception) {
181 DebugStream.printStackTrace(exception);
182 }
183 }
184
185 if (gsdl3_path != null) {
186 if (this.site_name == null || this.site_name.equals("")) {
187 this.site_name = getString("general.site_name", true);
188 this.servlet_path = getString("general.servlet_path", true);
189 if (this.site_name.equals("")) {
190 this.site_name = "localsite"; // can we assume these??
191 this.servlet_path = "/library";
192 setString("general.site_name", true, this.site_name);
193 setString("general.servlet_path", true, this.servlet_path);
194 }
195
196 } else {
197 // we set the current one in the config
198 setString("general.site_name", true, this.site_name);
199 if (this.servlet_path != null && !this.servlet_path.equals("")) {
200 setString("general.servlet_path", true, this.servlet_path);
201 }
202 }
203 }
204 }
205
206
207 static private boolean updateUserConfigXMLFileIfNecessary(File config_xml_file)
208 {
209 // Check if the configuration file actually needs updating by looking at the version numbers
210 Document new_document = XMLTools.parseXMLFile(TEMPLATE_CONFIG_XML, true);
211 Document old_document = XMLTools.parseXMLFile(config_xml_file);
212
213 String new_version = new_document.getDocumentElement().getAttribute(StaticStrings.VERSION_ATTRIBUTE);
214 String old_version = old_document.getDocumentElement().getAttribute(StaticStrings.VERSION_ATTRIBUTE);
215 if (new_version.compareTo(old_version) <= 0) {
216 // Don't need to update file
217 return false;
218 }
219
220 System.err.println("Updating user config.xml from version " + old_version + " to version " + new_version + "...");
221
222 // Build up the new user config.xml file from the template config.xml with the user's preferences added
223 // Make a backup of the old config.xml file first
224 config_xml_file.renameTo(new File(config_xml_file.getAbsolutePath() + ".old"));
225
226 // Check all of the Argument elements in the new config.xml file
227 NodeList new_argument_elements_nodelist = new_document.getElementsByTagName("Argument");
228 NodeList old_argument_elements_nodelist = old_document.getElementsByTagName("Argument");
229 for (int i = 0; i < new_argument_elements_nodelist.getLength(); i++) {
230 Element new_argument_element = (Element) new_argument_elements_nodelist.item(i);
231 String new_argument_element_name = new_argument_element.getAttribute("name");
232 String new_argument_element_value = XMLTools.getElementTextValue(new_argument_element);
233
234 // Did this Argument have a non-default value set?
235 for (int j = old_argument_elements_nodelist.getLength() - 1; j >= 0; j--) {
236 Element old_argument_element = (Element) old_argument_elements_nodelist.item(j);
237 String old_argument_element_name = old_argument_element.getAttribute("name");
238
239 // Argument found
240 if (old_argument_element_name.equals(new_argument_element_name)) {
241 String old_argument_element_value = XMLTools.getElementTextValue(old_argument_element);
242 if (!old_argument_element_value.equals(new_argument_element_value)) {
243 XMLTools.setElementTextValue(new_argument_element, old_argument_element_value);
244 }
245
246 // We don't care about this option any more
247 old_argument_element.getParentNode().removeChild(old_argument_element);
248 break;
249 }
250 }
251 }
252
253 // Are there any old Argument elements left over? Keep these around for old time's sake
254 old_argument_elements_nodelist = old_document.getElementsByTagName("Argument");
255 if (old_argument_elements_nodelist.getLength() > 0) {
256 NodeList new_gathererconfig_elements_nodelist = new_document.getElementsByTagName("GathererConfig");
257 if (new_gathererconfig_elements_nodelist.getLength() > 0) {
258 Element new_gathererconfig_element = (Element) new_gathererconfig_elements_nodelist.item(0);
259 new_gathererconfig_element.appendChild(new_document.createComment(" Legacy options "));
260
261 // Add the legacy Arguments to the GathererConfig element
262 for (int i = 0; i < old_argument_elements_nodelist.getLength(); i++) {
263 Element old_argument_element = (Element) old_argument_elements_nodelist.item(i);
264 new_gathererconfig_element.appendChild(new_document.importNode(old_argument_element, true));
265 }
266 }
267 }
268
269 // Keep all the Mapping elements
270 NodeList new_directorymappings_elements_nodelist = new_document.getElementsByTagName("DirectoryMappings");
271 if (new_directorymappings_elements_nodelist.getLength() > 0) {
272 Element new_directorymappings_element = (Element) new_directorymappings_elements_nodelist.item(0);
273
274 NodeList old_mapping_elements_nodelist = old_document.getElementsByTagName("Mapping");
275 for (int i = 0; i < old_mapping_elements_nodelist.getLength(); i++) {
276 Element old_mapping_element = (Element) old_mapping_elements_nodelist.item(i);
277 new_directorymappings_element.appendChild(new_document.importNode(old_mapping_element, true));
278 }
279 }
280
281 // Check all of the Associations elements in the new config.xml file
282 NodeList new_entry_elements_nodelist = new_document.getElementsByTagName("Entry");
283 NodeList old_entry_elements_nodelist = old_document.getElementsByTagName("Entry");
284 for (int i = 0; i < new_entry_elements_nodelist.getLength(); i++) {
285 Element new_entry_element = (Element) new_entry_elements_nodelist.item(i);
286 String new_entry_element_name = new_entry_element.getAttribute("extension");
287 String new_entry_element_value = XMLTools.getElementTextValue(new_entry_element);
288
289 // Did this Entry have a non-default value set?
290 for (int j = old_entry_elements_nodelist.getLength() - 1; j >= 0; j--) {
291 Element old_entry_element = (Element) old_entry_elements_nodelist.item(j);
292 String old_entry_element_name = old_entry_element.getAttribute("extension");
293
294 // Entry found
295 if (old_entry_element_name.equals(new_entry_element_name)) {
296 String old_entry_element_value = XMLTools.getElementTextValue(old_entry_element);
297 if (!old_entry_element_value.equals(new_entry_element_value)) {
298 XMLTools.setElementTextValue(new_entry_element, old_entry_element_value);
299 }
300
301 // We don't care about this option any more
302 old_entry_element.getParentNode().removeChild(old_entry_element);
303 break;
304 }
305 }
306 }
307
308 // Are there any old Entry elements left over? We want to keep these
309 old_entry_elements_nodelist = old_document.getElementsByTagName("Entry");
310 if (old_entry_elements_nodelist.getLength() > 0) {
311 NodeList new_associations_elements_nodelist = new_document.getElementsByTagName("Associations");
312 if (new_associations_elements_nodelist.getLength() > 0) {
313 Element new_associations_element = (Element) new_associations_elements_nodelist.item(0);
314
315 // Add the legacy Entries to the Associations element
316 for (int i = 0; i < old_entry_elements_nodelist.getLength(); i++) {
317 Element old_entry_element = (Element) old_entry_elements_nodelist.item(i);
318 new_associations_element.appendChild(new_document.importNode(old_entry_element, true));
319 }
320 }
321 }
322
323 // Write out the updated config.xml file
324 XMLTools.writeXMLFile(config_xml_file, new_document);
325 return true;
326 }
327
328
329 /** Add a special directory mapping. */
330 static public boolean addDirectoryMapping(String name, File file) {
331 boolean result = false;
332 try {
333 // Ensure the name isn't already in use.
334 boolean found = false;
335 NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT);
336 for(int i = 0; !found && i < mappings.getLength(); i++) {
337 Element mapping_element = (Element) mappings.item(i);
338 if(mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equalsIgnoreCase(name)) {
339 found = true;
340 }
341 mapping_element = null;
342 }
343 // Otherwise add the mapping.
344 if(!found) {
345 Element mapping_element = general_config.createElement(StaticStrings.MAPPING_ELEMENT);
346 mapping_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
347 mapping_element.setAttribute(StaticStrings.FILE_ATTRIBUTE, file.toString());
348 directory_mappings_element.appendChild(mapping_element);
349 result = true;
350 mapping_element = null;
351 }
352 mappings = null;
353 }
354 catch (Exception exception) {
355 DebugStream.printStackTrace(exception);
356 }
357 return result;
358 } /** addDirectoryMapping(String name, String file) **/
359
360 /** The default get action retrieves the named property from the desired configuration, and returns a true or false. */
361 static public boolean get(String property, boolean general) {
362 String raw = getString(property, general);
363 return (raw != null && raw.equalsIgnoreCase("true"));
364 }
365
366 /** Retrieve all of the configuration preferences which match a certain string. They are returned as a hash map of property names to String objects. */
367 static public HashMap getAll(String property_pattern, boolean general) {
368 HashMap properties = new HashMap();
369 try {
370 // Locate the appropriate element
371 Element document_element = null;
372 if(general) {
373 document_element = general_config.getDocumentElement();
374 }
375 else if(collection_config != null) {
376 document_element = collection_config.getDocumentElement();
377 }
378 if(document_element != null) {
379 // Retrieve the Gatherer element
380 Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG);
381 NodeList arguments = gatherer_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
382 for(int i = 0; i < arguments.getLength(); i++) {
383 Element argument_element = (Element) arguments.item(i);
384 if(argument_element.getAttribute(ARGUMENT_NAME).matches(property_pattern)) {
385 String result = XMLTools.getValue(argument_element);
386 // 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.
387 self.put(argument_element.getAttribute(ARGUMENT_NAME) + general, new SoftReference(argument_element));
388 // Add mapping to the properties we're going to return
389 properties.put(argument_element.getAttribute(ARGUMENT_NAME), result);
390 }
391 }
392 }
393 }
394 catch(Exception error) {
395 }
396 return properties;
397 }
398
399 /** Retrieve the information subtree containing the arguments for the desired external program. If the program has marked superclasses append their arguments as well. */
400 static public Element getArguments(String filename) {
401 Element argument_element = null;
402 try {
403 // Retrieve the other information subtree.
404 Element document_element = general_config.getDocumentElement();
405 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
406 NodeList argument_elements = other_element.getElementsByTagName(OTHER_INFO);
407 for(int i = 0; argument_element == null && i < argument_elements.getLength(); i++) {
408 Element possible_element = (Element) argument_elements.item(i);
409 Element possible_name_element = (Element) XMLTools.getNodeFromNamed(possible_element, NAME);
410 String possible_name = XMLTools.getValue(possible_name_element);
411 ///ystem.err.println("Does " + possible_name + " equal " + filename);
412 if(possible_name.equalsIgnoreCase(filename)) {
413 argument_element = possible_element;
414 }
415 possible_name = null;
416 possible_name_element = null;
417 possible_element = null;
418 }
419 argument_elements = null;
420 other_element = null;
421 document_element = null;
422 }
423 catch(Exception error) {
424 }
425 return argument_element;
426 }
427
428 /** Gets the language for the other arguments subtree
429 @return empty string if no language specified */
430 static public String getArgumentsLanguage() {
431 Element document_element = general_config.getDocumentElement();
432 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
433 String lang = other_element.getAttribute(LANGUAGE);
434 if (lang == null) {
435 lang = "en";
436 }
437 return lang;
438 }
439
440 /** Retrieve the value of the named property as a Rectangle. */
441 static public Rectangle getBounds(String property, boolean general) {
442 Rectangle result = null;
443 try {
444 String raw = getString(property, general);
445 // Rectangle is (x, y, width, height)
446 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1);
447 int x = Integer.parseInt(tokenizer.nextToken());
448 int y = Integer.parseInt(tokenizer.nextToken());
449 int width = Integer.parseInt(tokenizer.nextToken());
450 int height = Integer.parseInt(tokenizer.nextToken());
451 result = new Rectangle(x, y, width, height);
452 }
453 catch(Exception error) {
454 DebugStream.printStackTrace(error);
455 }
456 return result;
457 }
458
459 /** Retrieve the value of the named property as a Color. */
460 static public Color getColor(String property, boolean general) {
461 Color result = Color.white; // Default
462 try {
463 String raw = getString(property, general);
464 // Color is a RGB triplet list, comma separated (also remove whitespace)
465 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1);
466 int red = Integer.parseInt(tokenizer.nextToken());
467 int green = Integer.parseInt(tokenizer.nextToken());
468 int blue = Integer.parseInt(tokenizer.nextToken());
469 result = new Color(red, green, blue);
470 }
471 catch(Exception error) {
472 error.printStackTrace();
473 }
474 return result;
475 }
476
477
478 /** Retrieve the special directory mappings associated with this collection.
479 * @return A <strong>HashMap</strong> containing mappings from names to directories.
480 */
481 static public HashMap getDirectoryMappings() {
482 HashMap special_directories = new HashMap();
483 try {
484 // Ensure the name isn't already in use.
485 boolean found = false;
486 NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT);
487 for(int i = 0; !found && i < mappings.getLength(); i++) {
488 Element mapping_element = (Element) mappings.item(i);
489 String name = mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
490 File file = new File(mapping_element.getAttribute(StaticStrings.FILE_ATTRIBUTE));
491 special_directories.put(name, file);
492 file = null;
493 name = null;
494 mapping_element = null;
495 }
496 mappings = null;
497 }
498 catch(Exception exception) {
499 DebugStream.printStackTrace(exception);
500 }
501 return special_directories;
502 } /** getDirectoryMappings() */
503
504 /** Retrieve the current users email. These are always stored in the general settings.
505 * @return the email address, if it is set, as a String
506 */
507 static public String getEmail() {
508 String email = getString(GENERAL_EMAIL_SETTING, true);
509 return (email.length() > 0 ? email : null);
510 }
511
512 static public Element getFileAssociations() {
513 NodeList file_association_elements = general_config.getDocumentElement().getElementsByTagName(StaticStrings.ASSOCIATIONS_ELEMENT);
514 return (Element) file_association_elements.item(0);
515 }
516
517 /** Retrieve the value of the named property as a FontUIResource. */
518 static public FontUIResource getFont(String property, boolean general) {
519 FontUIResource result = new FontUIResource("Times New Roman", Font.PLAIN, 10);
520 try {
521 String raw = getString(property, general);
522 // Font is a face, style, size triplet.
523 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN3);
524 String face = tokenizer.nextToken().trim();
525 ///ystem.err.println("Face: " + face);
526 int style = Font.PLAIN;
527 String temp = tokenizer.nextToken().toUpperCase().trim();
528 ///ystem.err.println("Style: " + temp);
529 if(temp.equals("BOLD")) {
530 style = Font.BOLD;
531 }
532 else if(temp.equals("ITALIC")) {
533 style = Font.ITALIC;
534 }
535 int size = Integer.parseInt(tokenizer.nextToken().trim());
536 ///ystem.err.println("Size: " + size);
537 result = new FontUIResource(face, style, size);
538 }
539 catch(Exception error) {
540 DebugStream.printStackTrace(error);
541 }
542 return result;
543 }
544
545 /** Retrieve the value of the named property as an integer. */
546 static public int getInt(String property, boolean general) {
547 int result = 0;
548 try {
549 String raw = getString(property, general);
550 result = Integer.parseInt(raw);
551 }
552 catch(Exception error) {
553 DebugStream.printStackTrace(error);
554 }
555 return result;
556 }
557
558 /** Retrieves the current interface language two letter code. */
559 static public String getLanguage() {
560 Locale locale = getLocale("general.locale", GENERAL_SETTING);
561 String code = "en"; // Default
562 if(locale != null) {
563 code = locale.getLanguage();
564 }
565 return code;
566 }
567
568 /** Retrieve the value of the named property as a Locale. */
569 static public Locale getLocale(String property, boolean general) {
570 Locale result = Locale.getDefault();
571 try {
572 String raw = getString(property, general);
573 // Locale is a underscore separated code.
574 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN2);
575 String language = tokenizer.nextToken();
576 if(tokenizer.hasMoreTokens()) {
577 String country = tokenizer.nextToken();
578 result = new Locale(language, country);
579 }
580 else {
581 result = new Locale(language);
582 }
583 }
584 catch(Exception error) {
585 DebugStream.printStackTrace(error);
586 }
587 return result;
588 }
589
590 /** 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.
591 * @return an int representing the mode
592 */
593 static public int getMode() {
594 return getInt("general.mode", GENERAL_SETTING);
595 }
596
597 /** Return the current mode as a string for use in title bar etc
598 * @return the mode as a String
599 */
600 static public String getModeAsString() {
601 String result;
602 switch(getInt("general.mode", GENERAL_SETTING)) {
603 case ASSISTANT_MODE:
604 result = Dictionary.get("Preferences.Mode.Assistant");
605 break;
606 case SYSTEMS_MODE:
607 result = Dictionary.get("Preferences.Mode.Systems");
608 break;
609 case EXPERT_MODE:
610 result = Dictionary.get("Preferences.Mode.Expert");
611 break;
612 default:
613 result = Dictionary.get("Preferences.Mode.Librarian");
614 }
615 return result;
616 }
617
618 static public String getPreviewCommand() {
619 return getString("general.preview_program", GENERAL_SETTING);
620 }
621
622 static public String getServletPath() {
623 return servlet_path;
624 }
625
626 /** Retrieve the value of the named property, and noting whether we consult the general or collection specific configuration. */
627 static public String getString(String property, boolean general) {
628 // Its up to this method to find the appropriate node and retrieve the data itself.
629 String result = "";
630 try {
631 // First of all we look in the cache to see if we have a match.
632 SoftReference reference = (SoftReference) self.get(property + general);
633 if(reference != null) {
634 Element argument_element = (Element) reference.get();
635 if(argument_element != null) {
636 cache_hit++;
637 result = XMLTools.getValue(argument_element);
638 }
639 }
640 // We may have missed in the cache, or the reference may have been consumed.
641 if(result.length() == 0) {
642 cache_miss++;
643 // Locate the appropriate element
644 Element document_element = null;
645 if(general) {
646 document_element = general_config.getDocumentElement();
647 }
648 else if(collection_config != null) {
649 document_element = collection_config.getDocumentElement();
650 }
651 if(document_element != null) {
652 // Retrieve the Gatherer element
653 Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG);
654 NodeList arguments = gatherer_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
655 for(int i = 0; result.length() == 0 && i < arguments.getLength(); i++) {
656 Element argument_element = (Element) arguments.item(i);
657 if(argument_element.getAttribute(ARGUMENT_NAME).equalsIgnoreCase(property)) {
658 result = XMLTools.getValue(argument_element);
659 // 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.
660 self.put(property + general, new SoftReference(argument_element));
661 }
662 }
663 }
664 }
665 }
666 catch (Exception error) {
667 error.printStackTrace();
668 }
669 // If we still have no result, and the search was made in the collection configuration, retrieve the general one instead.
670 if(result.length() == 0 && !general) {
671 result = getString(property, true);
672 }
673 return result;
674 }
675
676 /** Retrieve the path to the PERL scripts within the Greenstone directory.
677 * @return A <strong>String</strong> containing the path.
678 */
679 static public String getScriptPath() {
680 return gsdl_path + "bin" + File.separator + "script" + File.separator;
681 }
682
683 static public String getGS3ScriptPath() {
684 return gsdl3_src_path + "bin" + File.separator + "script" + File.separator;
685 }
686
687
688 static public String getWGetPath() {
689 return (wget_path != null ? wget_path : "");
690 }
691
692 static public String getWGetVersion() {
693 return (wget_version_str != null ? wget_version_str : StaticStrings.NO_WGET_STR);
694 }
695
696 /** Remove a previously defined special directory mapping.
697 * @param name The name of the mapping to remove as a <strong>String</strong>.
698 * @return The <strong>File</strong> of the mapping removed.
699 */
700 static public File removeDirectoryMapping(String name) {
701 File file = null;
702 try {
703 // Ensure the name isn't already in use.
704 boolean found = false;
705 NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT);
706 for(int i = 0; !found && i < mappings.getLength(); i++) {
707 Element mapping_element = (Element) mappings.item(i);
708 if(mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equalsIgnoreCase(name)) {
709 file = new File(XMLTools.getValue(mapping_element));
710 directory_mappings_element.removeChild(mapping_element);
711 found = true;
712 }
713 mapping_element = null;
714 }
715 mappings = null;
716 }
717 catch(Exception error) {
718 DebugStream.printStackTrace(error);
719 }
720 return file;
721 } /** removeDirectoryMapping(String name) */
722
723 /** Export the general configuration to file. */
724 static public void save() {
725 ///ystem.err.println("Hits " + cache_hit + " vs Misses " + cache_miss);
726 // We first try exporting to a user specific place
727 File user_config_xml = null;
728 String config_xml_name = CONFIG_XML;
729 if (gsdl3_path!=null) {
730 config_xml_name = GS3_CONFIG_XML;
731 }
732 try {
733 user_config_xml = new File(Gatherer.getGLIUserDirectoryPath() + config_xml_name);
734 ///ystem.err.println("Trying to save to: " + user_config_xml.getAbsolutePath());
735 ///ystem.err.println("Writing.");
736 user_config_xml.getParentFile().mkdirs();
737 XMLTools.writeXMLFile(new File(user_config_xml.getAbsolutePath()), general_config);
738 }
739 catch(Exception exception) {
740 user_config_xml = null;
741 }
742 }
743
744 /** Set the named property, from the specified configuration, using the given boolean value. */
745 static public void set(String property, boolean general, boolean value) {
746 if(property.startsWith("workflow")) {
747 DebugStream.println("Set property: " + property + ", general=" + general + ", value=" + value);
748 }
749 setString(property, general, (value ? "true" : "false"));
750 }
751
752 /** Add a subtree of argument information to the other arguments part of the general configuration. This overwrites any such existing subtree. */
753 static public void setArguments(Element arguments_element) {
754 try {
755 Element document_element = general_config.getDocumentElement();
756 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
757 // Retrieve the name of the information
758 Element arguments_name_element = (Element)XMLTools.getNodeFromNamed(arguments_element, NAME);
759 String filename = XMLTools.getValue(arguments_element);
760 // Find any argument information subtree starting with the same name
761 Element obsolete_arguments_element = getArguments(filename);
762 // Create a copy of the arguments_element within our tree (import).
763 Element our_arguments_element = (Element) general_config.importNode(arguments_element, true);
764 // Now we insert this new node into the tree. If a previous node exists we replace it instead.
765 if(obsolete_arguments_element == null) {
766 other_element.appendChild(our_arguments_element);
767 }
768 else {
769 other_element.replaceChild(our_arguments_element, obsolete_arguments_element);
770 }
771 our_arguments_element = null;
772 obsolete_arguments_element = null;
773 filename = null;
774 arguments_name_element = null;
775 other_element = null;
776 document_element = null;
777 }
778 catch (Exception error) {
779 DebugStream.println("Error in Configuration.setArguments(): " + error);
780 DebugStream.printStackTrace(error);
781 }
782 }
783
784 /** Sets the language for the other arguments subtree */
785 static public void setArgumentsLanguage(String lang) {
786 Element document_element = general_config.getDocumentElement();
787 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
788 other_element.setAttribute(LANGUAGE, lang);
789 }
790
791
792 /** Set the collection configuration. */
793 static public void setCollectionConfiguration(Document collection_config) {
794 // clear the cached values
795 self.clear();
796 collection_config = collection_config;
797 updateUI();
798 ///atherer.println("Collection configuration set.");
799 }
800
801 /** Set the named property, from the specified configuration, using the given Rectangle value. */
802 static public void setBounds(String property, boolean general, Rectangle value) {
803 StringBuffer text = new StringBuffer("");
804 text.append(value.x);
805 text.append(", ");
806 text.append(value.y);
807 text.append(", ");
808 text.append(value.width);
809 text.append(", ");
810 text.append(value.height);
811 setString(property, general, text.toString());
812 }
813
814 /** Set the named property, from the specified configuration, using the given Color value. */
815 static public void setColor(String property, boolean general, Color value) {
816 StringBuffer text = new StringBuffer("");
817 text.append(value.getRed());
818 text.append(", ");
819 text.append(value.getGreen());
820 text.append(", ");
821 text.append(value.getBlue());
822 setString(property, general, text.toString());
823 }
824
825 /** Establish the current users email.
826 * @param email the email as a String
827 */
828 static 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 static 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 static 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 static 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 static public void setMode(int value) {
874 setInt("general.mode", GENERAL_SETTING, value);
875 }
876
877 static public void setPreviewCommand(String value) {
878 setString("general.preview_program", GENERAL_SETTING, value);
879 }
880
881 static public void setSiteAndServlet(String site, String servlet) {
882 site_name = site;
883 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 static public void setString(String property, boolean general, String value) {
890 DebugStream.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) self.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 self.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 static public void setWGetPath(String path) {
941 wget_path = path;
942 }
943
944 static public void setWGetVersion(String version) {
945 wget_version_str = version;
946 }
947
948 static 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 }
991}
Note: See TracBrowser for help on using the repository browser.