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

Last change on this file since 13584 was 13026, checked in by mdewsnip, 18 years ago

Removed all the old WGet stuff.

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