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

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

Have finalised the code for user specific settings under windows. I've tested on WinXP and Win98 with multiple users, and Win98 with a single user. Under single user the user.home is C:\Windows. Apparently its pretty common to just create an Application Data folder and put settings there, with or without multiple users. I'm not sure if thats true for WinXP, but I can't really tes that.

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