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

Last change on this file since 36102 was 36102, checked in by kjdon, 2 years ago

removed the defaults of localsite and library for site_name and servlet_path - these may not be accurate

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