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

Last change on this file since 9869 was 9869, checked in by mdewsnip, 19 years ago

Dealing with the user config.xml files is now much smarter. Instead of throwing away all the user preferences every time the version of GLI is updated, they are now intelligently merged into the updated (core) config.xml file.

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