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

Last change on this file since 14567 was 14302, checked in by qq6, 17 years ago

Added configuration of the remote gs3

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