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

Last change on this file since 11791 was 11182, checked in by kjdon, 18 years ago

if we have changed versions of greenstone, we don't want to caryr over the open_collection argument.

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