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

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

I find it annoying when switching between gs2 and 3 that the gli config file (in .gli/config.xml) gets changed back and forth. In the same way we now have configRemote.xml for when we are running remotely, now locally, config.xml gets saved as config2.xml or config3.xml. they use the same config.xml template though. added final static strings for the filenames, and always use these, so only Configuration now contains the actual text strings. made Configuration.CONFIG_XML and Configuration.TEMPLATE_CONFIG_XML lowercase as they are not final Strings, they get changed by Gatherer.

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