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

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

Added a "-use_remote_greenstone" argument, and added the "gliserver_url" argument to the configRemote.xml file.

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