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

Last change on this file since 8248 was 8236, checked in by mdewsnip, 20 years ago

Replaced all Gatherer.print* with DebugStream.print*.

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