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

Last change on this file since 28995 was 28995, checked in by ak19, 10 years ago

First commit for GLI part of GS2 to GS3 Format Conversion. Contains all the changes needed for the FormatConversionDialog to work, and some cosmetic changes to cdm.Format4gs3Manager.java. Still need to implement undo and redo and think about what needs to happen and how for Remote GS3.

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