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

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

Updated configuration version for the gsdl-2.51u UNESCO release.

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