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

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

Fixed the parsing of Fonts with spaces in their names

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