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

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

More modifications to mirroring including testing for a valid version of Wget (and complaining if its missing or it is old) and rearranging buttons on the GProgressBar

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