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

Last change on this file since 6847 was 6655, checked in by jmt12, 20 years ago

Temporarily disabled old config error dialog as it isn't multilingual, and we have the UNESCO multilingual prototype release bearing down upon us.

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