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

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

Removed some occurrences of "gsdl_path", and added some checks so it is only used when a local Greenstone exists.

  • Property svn:keywords set to Author Date Id Revision
File size: 41.5 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 static public String getTmpDirectoryPath()
688 {
689 return gsdl_path + "tmp" + File.separator;
690 }
691
692 static public String getWGetPath() {
693 return (wget_path != null ? wget_path : "");
694 }
695
696 static public String getWGetVersion() {
697 return (wget_version_str != null ? wget_version_str : StaticStrings.NO_WGET_STR);
698 }
699
700 /** Remove a previously defined special directory mapping.
701 * @param name The name of the mapping to remove as a <strong>String</strong>.
702 * @return The <strong>File</strong> of the mapping removed.
703 */
704 static public File removeDirectoryMapping(String name) {
705 File file = null;
706 try {
707 // Ensure the name isn't already in use.
708 boolean found = false;
709 NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT);
710 for(int i = 0; !found && i < mappings.getLength(); i++) {
711 Element mapping_element = (Element) mappings.item(i);
712 if(mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equalsIgnoreCase(name)) {
713 file = new File(XMLTools.getValue(mapping_element));
714 directory_mappings_element.removeChild(mapping_element);
715 found = true;
716 }
717 mapping_element = null;
718 }
719 mappings = null;
720 }
721 catch(Exception error) {
722 DebugStream.printStackTrace(error);
723 }
724 return file;
725 } /** removeDirectoryMapping(String name) */
726
727 /** Export the general configuration to file. */
728 static public void save() {
729 ///ystem.err.println("Hits " + cache_hit + " vs Misses " + cache_miss);
730 // We first try exporting to a user specific place
731 File user_config_xml = null;
732 String config_xml_name = CONFIG_XML;
733 if (gsdl3_path!=null) {
734 config_xml_name = GS3_CONFIG_XML;
735 }
736 try {
737 user_config_xml = new File(Gatherer.getGLIUserDirectoryPath() + config_xml_name);
738 ///ystem.err.println("Trying to save to: " + user_config_xml.getAbsolutePath());
739 ///ystem.err.println("Writing.");
740 user_config_xml.getParentFile().mkdirs();
741 XMLTools.writeXMLFile(new File(user_config_xml.getAbsolutePath()), general_config);
742 }
743 catch(Exception exception) {
744 user_config_xml = null;
745 }
746 }
747
748 /** Set the named property, from the specified configuration, using the given boolean value. */
749 static public void set(String property, boolean general, boolean value) {
750 if(property.startsWith("workflow")) {
751 DebugStream.println("Set property: " + property + ", general=" + general + ", value=" + value);
752 }
753 setString(property, general, (value ? "true" : "false"));
754 }
755
756 /** Add a subtree of argument information to the other arguments part of the general configuration. This overwrites any such existing subtree. */
757 static public void setArguments(Element arguments_element) {
758 try {
759 Element document_element = general_config.getDocumentElement();
760 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
761 // Retrieve the name of the information
762 Element arguments_name_element = (Element)XMLTools.getNodeFromNamed(arguments_element, NAME);
763 String filename = XMLTools.getValue(arguments_element);
764 // Find any argument information subtree starting with the same name
765 Element obsolete_arguments_element = getArguments(filename);
766 // Create a copy of the arguments_element within our tree (import).
767 Element our_arguments_element = (Element) general_config.importNode(arguments_element, true);
768 // Now we insert this new node into the tree. If a previous node exists we replace it instead.
769 if(obsolete_arguments_element == null) {
770 other_element.appendChild(our_arguments_element);
771 }
772 else {
773 other_element.replaceChild(our_arguments_element, obsolete_arguments_element);
774 }
775 our_arguments_element = null;
776 obsolete_arguments_element = null;
777 filename = null;
778 arguments_name_element = null;
779 other_element = null;
780 document_element = null;
781 }
782 catch (Exception error) {
783 DebugStream.println("Error in Configuration.setArguments(): " + error);
784 DebugStream.printStackTrace(error);
785 }
786 }
787
788 /** Sets the language for the other arguments subtree */
789 static public void setArgumentsLanguage(String lang) {
790 Element document_element = general_config.getDocumentElement();
791 Element other_element = (Element) XMLTools.getNodeFromNamed(document_element, OTHER);
792 other_element.setAttribute(LANGUAGE, lang);
793 }
794
795
796 /** Set the collection configuration. */
797 static public void setCollectionConfiguration(Document collection_config) {
798 // clear the cached values
799 self.clear();
800 collection_config = collection_config;
801 updateUI();
802 ///atherer.println("Collection configuration set.");
803 }
804
805 /** Set the named property, from the specified configuration, using the given Rectangle value. */
806 static public void setBounds(String property, boolean general, Rectangle value) {
807 StringBuffer text = new StringBuffer("");
808 text.append(value.x);
809 text.append(", ");
810 text.append(value.y);
811 text.append(", ");
812 text.append(value.width);
813 text.append(", ");
814 text.append(value.height);
815 setString(property, general, text.toString());
816 }
817
818 /** Set the named property, from the specified configuration, using the given Color value. */
819 static public void setColor(String property, boolean general, Color value) {
820 StringBuffer text = new StringBuffer("");
821 text.append(value.getRed());
822 text.append(", ");
823 text.append(value.getGreen());
824 text.append(", ");
825 text.append(value.getBlue());
826 setString(property, general, text.toString());
827 }
828
829 /** Establish the current users email.
830 * @param email the email as a String
831 */
832 static public void setEmail(String email) {
833 setString(GENERAL_EMAIL_SETTING, true, email);
834 }
835
836 /** Set the named property, from the specified configuration, using the given Font value. */
837 static public void setFont(String property, boolean general, Font value) {
838 StringBuffer text = new StringBuffer("");
839 text.append(value.getName());
840 text.append(", ");
841 switch(value.getStyle()) {
842 case Font.BOLD:
843 text.append("BOLD");
844 break;
845 case Font.ITALIC:
846 text.append("ITALIC");
847 break;
848 default:
849 text.append("PLAIN");
850 }
851 text.append(", ");
852 text.append(value.getSize());
853 setString(property, general, text.toString());
854 }
855
856 /** Set the named property, from the specified configuration, using the given integer value. */
857 static public void setInt(String property, boolean general, int value) {
858 setString(property, general, String.valueOf(value));
859 }
860
861 /** Set the named property, from the specified configuration, using the given Locale value. */
862 static public void setLocale(String property, boolean general, Locale value) {
863 StringBuffer text = new StringBuffer("");
864 text.append(value.getLanguage());
865 String country = value.getCountry();
866 if(country != null && country.length() > 0) {
867 text.append("_");
868 text.append(country);
869 }
870 country = null;
871 setString(property, general, text.toString());
872 }
873
874 /** 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.
875 * @param value the new value for mode
876 */
877 static public void setMode(int value) {
878 setInt("general.mode", GENERAL_SETTING, value);
879 }
880
881 static public void setPreviewCommand(String value) {
882 setString("general.preview_program", GENERAL_SETTING, value);
883 }
884
885 static public void setSiteAndServlet(String site, String servlet) {
886 site_name = site;
887 servlet_path = servlet;
888 setString("general.site_name", GENERAL_SETTING, site);
889 setString("general.servlet_path", GENERAL_SETTING, servlet);
890
891 }
892 /** Sets the value of the named property argument using the given string. */
893 static public void setString(String property, boolean general, String value) {
894 DebugStream.println("Set configuration property: " + property + " = " + value + (general ? "" : " [Collection]"));
895 try {
896 Document document = general_config;
897 if(!general && collection_config != null) {
898 document = collection_config;
899 }
900 if(document != null) {
901 Element argument_element = null;
902 // Try to retrieve from cache
903 SoftReference reference = (SoftReference) self.get(property + general);
904 if(reference != null) {
905 argument_element = (Element) reference.get();
906 }
907 if(argument_element == null) {
908 Element document_element = document.getDocumentElement();
909 Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG);
910 NodeList arguments = document_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
911 boolean found = false;
912 for(int i = 0; argument_element == null && i < arguments.getLength(); i++) {
913 Element possible_element = (Element) arguments.item(i);
914 if(possible_element.getAttribute(ARGUMENT_NAME).equalsIgnoreCase(property)) {
915 argument_element = possible_element;
916 }
917 }
918 // If argument element is still null, create it in the target document.
919 if(argument_element == null) {
920 argument_element = document.createElement(GATHERER_CONFIG_ARGUMENT);
921 argument_element.setAttribute(ARGUMENT_NAME, property);
922 gatherer_element.appendChild(argument_element);
923 }
924 // Update cache
925 self.put(property + general, new SoftReference(argument_element));
926
927 }
928 if(value == null) {
929 value = "";
930 }
931 // Now remove any current text node children.
932 NodeList children = argument_element.getChildNodes();
933 for(int i = 0; i < children.getLength(); i++) {
934 argument_element.removeChild(children.item(i));
935 }
936 // Add a new text node child with the new value
937 argument_element.appendChild(document.createTextNode(value));
938 }
939 }
940 catch (Exception error) {
941 }
942 }
943
944 static public void setWGetPath(String path) {
945 wget_path = path;
946 }
947
948 static public void setWGetVersion(String version) {
949 wget_version_str = version;
950 }
951
952 static private void updateUI() {
953 // Buttons
954 UIManager.put("Button.select", new ColorUIResource(getColor("coloring.button_selected_background", false)));
955 UIManager.put("Button.background", new ColorUIResource(getColor("coloring.button_background", false)));
956 UIManager.put("Button.foreground", new ColorUIResource(getColor("coloring.button_foreground", false)));
957
958 UIManager.put("ToggleButton.background", new ColorUIResource(getColor("coloring.button_background", false)));
959 UIManager.put("ToggleButton.foreground", new ColorUIResource(getColor("coloring.button_foreground", false)));
960 UIManager.put("ToggleButton.select", new ColorUIResource(getColor("coloring.button_selected_background", false)));
961
962 // All the things with a lovely Collection green background
963 UIManager.put("OptionPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
964 UIManager.put("Panel.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
965 UIManager.put("Label.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
966 UIManager.put("TabbedPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
967 UIManager.put("SplitPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
968 UIManager.put("CheckBox.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
969
970
971 // Editable coloring
972 UIManager.put("ComboBox.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); // Indicate clickable
973 UIManager.put("Tree.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
974 UIManager.put("Tree.textBackground", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
975 UIManager.put("ProgressBar.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
976 UIManager.put("TextArea.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
977 UIManager.put("TextField.background", new ColorUIResource(getColor("coloring.editable_background", false)));
978 UIManager.put("Table.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
979 UIManager.put("List.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
980 UIManager.put("RadioButton.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
981
982 // Selection color
983 UIManager.put("TabbedPane.selected", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
984 UIManager.put("Tree.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
985 UIManager.put("ComboBox.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
986 UIManager.put("ProgressBar.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
987 UIManager.put("TextArea.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
988 UIManager.put("TextField.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
989 UIManager.put("List.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
990
991 // Scroll bar stuff
992 UIManager.put("ScrollBar.background", new ColorUIResource(getColor("coloring.scrollbar_background", false)));
993 UIManager.put("ScrollBar.thumb", new ColorUIResource(getColor("coloring.scrollbar_foreground", false)));
994 }
995}
Note: See TracBrowser for help on using the repository browser.