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

Last change on this file was 37554, checked in by anupama, 13 months ago

One more fix to this file. Although GLI launched OK after previous fix, gems did not launch and because of a nullpointer exception also, and required a tweak too.

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