/** *######################################################################### * Configuration * A component of the Gatherer application, part of the Greenstone digital * library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * *

* * Author: John Thompson, Greenstone Digital Library, University of Waikato * *

* * Copyright (C) 1999 New Zealand Digital Library Project * *

* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * *

* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *

* * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ package org.greenstone.gatherer; import java.awt.*; import java.io.*; import java.lang.ref.*; import java.net.*; import java.util.*; import javax.swing.*; import javax.swing.plaf.*; import org.greenstone.gatherer.util.StaticStrings; import org.greenstone.gatherer.util.XMLTools; import org.w3c.dom.*; /** 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. * @author John Thompson, Greenstone Digital Library, University of Waikato * @version 2.3 */ public class Configuration extends Hashtable { static final public boolean COLLECTION_SPECIFIC = true; static final public boolean GENERAL_SETTING = true; static final public int ASSISTANT_MODE = 1; static final public int LIBRARIAN_MODE = 2; static final public int EXPERT_MODE = 3; /** The string identifying an argument's name attribute. */ static final private String ARGUMENT_NAME = "name"; /** The name of the general Gatherer configuration file. */ static public String CONFIG_XML = "config.xml"; static public String FEDORA_CONFIG_PREFIX = "fedora-"; /** 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). */ static final private String GATHERER_CONFIG = "GathererConfig"; /** The string identifying an argument element. */ static final private String GATHERER_CONFIG_ARGUMENT = "Argument"; static final private String GENERAL_EMAIL_SETTING = "general.email"; /** the lang attribute of the other element */ static final private String LANGUAGE = "lang"; /** The name of a Name Element. */ static final private String NAME = "Name"; /** The name of the other arguments element. */ static final private String OTHER = "Other"; /** The name of the general Gatherer configuration template. */ static public String TEMPLATE_CONFIG_XML = "xml/config.xml"; /** The first of three patterns used during tokenization, this pattern handles a comma separated list. */ static final private String TOKENIZER_PATTERN1 = " ,\n\t"; /** The second of three patterns used during tokenization, this pattern handles an underscore separated list. */ static final private String TOKENIZER_PATTERN2 = "_\n\t"; /** The last of three patterns used during tokenization, this pattern handles an comma separated list containing spaces. */ static final private String TOKENIZER_PATTERN3 = ",\n\t"; static public Configuration self = null; static public String gli_user_directory_path = null; static public boolean just_updated_config_xml_file = false; /** The path to the Greenstone Suite installation directory. */ static public String gsdl_path = ""; /** If we are using GLI in Greenstone 3, the path to gsdl3 home (== web dir) */ static public String gsdl3_path = ""; /** If we are using GLI in Greenstone 3, the path to gsdl3 src directory (== gsdl3 dir)*/ static public String gsdl3_src_path = ""; static public FedoraInfo fedora_info = null; /** The path to the PERL executable, up to and including Perl.exe. */ static public String perl_path = ""; /** The password for the proxy server indicated above. */ static public String proxy_pass = null; /** The username for the proxy server indicated above. */ static public String proxy_user = null; /** The screen size of the desktop the Gatherer will be displayed on. */ static public Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize(); /** The site name if we are using GS3 */ static public String site_name = ""; /** The servlet path if we are using GS3 */ static public String servlet_path = ""; /** Collection level configuration (which in some cases overrides general configuration. */ static private Document collection_config; /** The general configuration settings. */ static private Document general_config; /** The element, from glis config file, that contains the various directory mappings. */ static private Element directory_mappings_element; static private int cache_hit = 0; static private int cache_miss = 0; static public URL gliserver_url = null; static public URL library_url = null; /** Constructor. * @param gsdl_path The path to the Greenstone directory as a String. * @param gsdl3_path The path to the Greenstone 3 home (web) directory as a String. * @param gsdl3_src_path The path to the Greenstone 3 src directory as a String. * @param site_name The name of the Greenstone 3 site currently in use. * @param fedora_info A FedoraInfo object containing the user-provided details for creating * a connection to a Fedora repository. */ public Configuration(String gli_user_directory_path, String gsdl_path, String gsdl3_path, String gsdl3_src_path, String site_name, FedoraInfo fedora_info) { super(); self = this; // allows Configuration to statically refer to itself in the static methods this.gli_user_directory_path = gli_user_directory_path; this.gsdl_path = gsdl_path; this.gsdl3_path = gsdl3_path; this.gsdl3_src_path = gsdl3_src_path; this.site_name = site_name; this.fedora_info = fedora_info; // Try to load the configuration file from the user specific location String config_xml_file_name = CONFIG_XML; if (fedora_info != null && fedora_info.isActive()) { config_xml_file_name = FEDORA_CONFIG_PREFIX + config_xml_file_name; } // If the existing user config.xml file isn't recent enough, backup the old version and update it File config_xml_file = new File(gli_user_directory_path + config_xml_file_name); if (config_xml_file != null && config_xml_file.exists()) { just_updated_config_xml_file = updateUserConfigXMLFileIfNecessary(config_xml_file); general_config = XMLTools.parseXMLFile(config_xml_file); } // Create a new config from the default configuration file from our xml library if (general_config == null) { general_config = XMLTools.parseXMLFile(TEMPLATE_CONFIG_XML, true); just_updated_config_xml_file = true; } // Determine the Directory Mappings element directory_mappings_element = (Element) XMLTools.getNodeFromNamed(general_config.getDocumentElement(), StaticStrings.DIRECTORY_MAPPINGS_ELEMENT); // Re-establish the color settings. updateUI(); // Read the Greenstone library URL from the config file String library_url_string = getString("general.library_url"+gliPropertyNameSuffix(), true); if (!library_url_string.equals("")) { try { library_url = new URL(library_url_string); } catch (MalformedURLException exception) { DebugStream.printStackTrace(exception); } } // Read the Greenstone gliserver URL from the config file, if using a remote Greenstone if (Gatherer.isGsdlRemote) { String gliserver_url_string = getString("general.gliserver_url", true); if (!gliserver_url_string.equals("")) { try { gliserver_url = new URL(gliserver_url_string); } catch (MalformedURLException exception) { DebugStream.printStackTrace(exception); } } } if(gsdl3_path != null) { prepareForGS3(); } } /** @return the suffix for the the config file's library_url/open_collection propertyname. * For Fedora and remote GS2 cases, there is no suffix. * However, when dealing with a local Greenstone server, this returns suffix _gs2 or _gs3 * so it can be appended to the default library_url/open_collection propertynames. * Having 2 separate library URL properties and open_collection properties for the two * local versions of Greenstone allows GLI to save the library_url and last opened * collection for both GS2 and GS3, in case anyone runs them alternatively. (This is useful * when developing and testing across GS versions.) */ static public String gliPropertyNameSuffix() { if(Gatherer.isGsdlRemote) { return ""; // no special suffix } else if(Gatherer.GS3) { // local GS3, including FLI for GS3 return "_gs3"; } else { // local GS2, including FLI for GS2 return "_gs2"; } } // Called when (gsdl3_path != null) || (Gatherer.GS3 && Gatherer.isGsdlRemote) static public void prepareForGS3() { if (site_name == null || site_name.equals("")) { site_name = getString("general.site_name", true); servlet_path = getString("general.servlet_path", true); if (site_name.equals("")) { site_name = "localsite"; // can we assume these?? servlet_path = "/library"; setString("general.site_name", true, site_name); setString("general.servlet_path", true, servlet_path); } } else { // we set the current one in the config setString("general.site_name", true, site_name); if (servlet_path != null && !servlet_path.equals("")) { setString("general.servlet_path", true, servlet_path); } } } static private boolean updateUserConfigXMLFileIfNecessary(File config_xml_file) { // Check if the configuration file actually needs updating by looking at the version numbers Document new_document = XMLTools.parseXMLFile(TEMPLATE_CONFIG_XML, true); Document old_document = XMLTools.parseXMLFile(config_xml_file); if (new_document == null || old_document == null) { // Something has gone badly wrong, so we can't update the file return false; } String new_version = new_document.getDocumentElement().getAttribute(StaticStrings.VERSION_ATTRIBUTE); String old_version = old_document.getDocumentElement().getAttribute(StaticStrings.VERSION_ATTRIBUTE); if (new_version.equals(old_version)) { // Don't need to update file return false; } System.err.println("Converting user config.xml from version " + old_version + " to version " + new_version + "..."); // Build up the new user config.xml file from the template config.xml with the user's preferences added // Make a backup of the old config.xml file first config_xml_file.renameTo(new File(config_xml_file.getAbsolutePath() + ".old")); // Check all of the Argument elements in the new config.xml file NodeList new_argument_elements_nodelist = new_document.getElementsByTagName("Argument"); NodeList old_argument_elements_nodelist = old_document.getElementsByTagName("Argument"); for (int i = 0; i < new_argument_elements_nodelist.getLength(); i++) { Element new_argument_element = (Element) new_argument_elements_nodelist.item(i); String new_argument_element_name = new_argument_element.getAttribute("name"); String new_argument_element_value = XMLTools.getElementTextValue(new_argument_element); // Did this Argument have a non-default value set? for (int j = old_argument_elements_nodelist.getLength() - 1; j >= 0; j--) { Element old_argument_element = (Element) old_argument_elements_nodelist.item(j); String old_argument_element_name = old_argument_element.getAttribute("name"); // Argument found if (old_argument_element_name.equals(new_argument_element_name)) { // we don't want to carry over open_collection or library_url // as these may be invalid if (!new_argument_element_name.equals("general.open_collection"+Configuration.gliPropertyNameSuffix()) && !new_argument_element_name.equals("general.library_url"+Configuration.gliPropertyNameSuffix())) { String old_argument_element_value = XMLTools.getElementTextValue(old_argument_element); if (!old_argument_element_value.equals(new_argument_element_value)) { XMLTools.setElementTextValue(new_argument_element, old_argument_element_value); } } // We don't care about this option any more old_argument_element.getParentNode().removeChild(old_argument_element); break; } } } // Are there any old Argument elements left over? Keep these around for old time's sake old_argument_elements_nodelist = old_document.getElementsByTagName("Argument"); if (old_argument_elements_nodelist.getLength() > 0) { NodeList new_gathererconfig_elements_nodelist = new_document.getElementsByTagName("GathererConfig"); if (new_gathererconfig_elements_nodelist.getLength() > 0) { Element new_gathererconfig_element = (Element) new_gathererconfig_elements_nodelist.item(0); new_gathererconfig_element.appendChild(new_document.createComment(" Legacy options ")); // Add the legacy Arguments to the GathererConfig element for (int i = 0; i < old_argument_elements_nodelist.getLength(); i++) { Element old_argument_element = (Element) old_argument_elements_nodelist.item(i); new_gathererconfig_element.appendChild(new_document.importNode(old_argument_element, true)); } } } // Keep all the Mapping elements NodeList new_directorymappings_elements_nodelist = new_document.getElementsByTagName("DirectoryMappings"); if (new_directorymappings_elements_nodelist.getLength() > 0) { Element new_directorymappings_element = (Element) new_directorymappings_elements_nodelist.item(0); NodeList old_mapping_elements_nodelist = old_document.getElementsByTagName("Mapping"); for (int i = 0; i < old_mapping_elements_nodelist.getLength(); i++) { Element old_mapping_element = (Element) old_mapping_elements_nodelist.item(i); new_directorymappings_element.appendChild(new_document.importNode(old_mapping_element, true)); } } // Check all of the Associations elements in the new config.xml file NodeList new_entry_elements_nodelist = new_document.getElementsByTagName("Entry"); NodeList old_entry_elements_nodelist = old_document.getElementsByTagName("Entry"); for (int i = 0; i < new_entry_elements_nodelist.getLength(); i++) { Element new_entry_element = (Element) new_entry_elements_nodelist.item(i); String new_entry_element_name = new_entry_element.getAttribute("extension"); String new_entry_element_value = XMLTools.getElementTextValue(new_entry_element); // Did this Entry have a non-default value set? for (int j = old_entry_elements_nodelist.getLength() - 1; j >= 0; j--) { Element old_entry_element = (Element) old_entry_elements_nodelist.item(j); String old_entry_element_name = old_entry_element.getAttribute("extension"); // Entry found if (old_entry_element_name.equals(new_entry_element_name)) { String old_entry_element_value = XMLTools.getElementTextValue(old_entry_element); if (!old_entry_element_value.equals(new_entry_element_value)) { XMLTools.setElementTextValue(new_entry_element, old_entry_element_value); } // We don't care about this option any more old_entry_element.getParentNode().removeChild(old_entry_element); break; } } } // Are there any old Entry elements left over? We want to keep these old_entry_elements_nodelist = old_document.getElementsByTagName("Entry"); if (old_entry_elements_nodelist.getLength() > 0) { NodeList new_associations_elements_nodelist = new_document.getElementsByTagName("Associations"); if (new_associations_elements_nodelist.getLength() > 0) { Element new_associations_element = (Element) new_associations_elements_nodelist.item(0); // Add the legacy Entries to the Associations element for (int i = 0; i < old_entry_elements_nodelist.getLength(); i++) { Element old_entry_element = (Element) old_entry_elements_nodelist.item(i); new_associations_element.appendChild(new_document.importNode(old_entry_element, true)); } } } // Write out the updated config.xml file XMLTools.writeXMLFile(config_xml_file, new_document); return true; } /** Add a special directory mapping. */ static public boolean addDirectoryMapping(String name, File file) { boolean result = false; try { // Ensure the name isn't already in use. boolean found = false; NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT); for(int i = 0; !found && i < mappings.getLength(); i++) { Element mapping_element = (Element) mappings.item(i); if(mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equalsIgnoreCase(name)) { found = true; } mapping_element = null; } // Otherwise add the mapping. if(!found) { Element mapping_element = general_config.createElement(StaticStrings.MAPPING_ELEMENT); mapping_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name); mapping_element.setAttribute(StaticStrings.FILE_ATTRIBUTE, file.toString()); directory_mappings_element.appendChild(mapping_element); result = true; mapping_element = null; } mappings = null; } catch (Exception exception) { DebugStream.printStackTrace(exception); } return result; } /** addDirectoryMapping(String name, String file) **/ /** The default get action retrieves the named property from the desired configuration, and returns a true or false. */ static public boolean get(String property, boolean general) { String raw = getString(property, general); return (raw != null && raw.equalsIgnoreCase("true")); } /** Retrieve all of the configuration preferences which match a certain string. They are returned as a hash map of property names to String objects. */ static public HashMap getAll(String property_pattern, boolean general) { HashMap properties = new HashMap(); try { // Locate the appropriate element Element document_element = null; if(general) { document_element = general_config.getDocumentElement(); } else if(collection_config != null) { document_element = collection_config.getDocumentElement(); } if(document_element != null) { // Retrieve the Gatherer element Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG); NodeList arguments = gatherer_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT); for(int i = 0; i < arguments.getLength(); i++) { Element argument_element = (Element) arguments.item(i); if(argument_element.getAttribute(ARGUMENT_NAME).matches(property_pattern)) { String result = XMLTools.getValue(argument_element); // 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. self.put(argument_element.getAttribute(ARGUMENT_NAME) + general, new SoftReference(argument_element)); // Add mapping to the properties we're going to return properties.put(argument_element.getAttribute(ARGUMENT_NAME), result); } } } } catch (Exception exception) { DebugStream.printStackTrace(exception); } return properties; } /** Retrieve the value of the named property as a Rectangle. */ static public Rectangle getBounds(String property, boolean general) { Rectangle result = null; try { String raw = getString(property, general); // Rectangle is (x, y, width, height) StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1); int x = Integer.parseInt(tokenizer.nextToken()); int y = Integer.parseInt(tokenizer.nextToken()); int width = Integer.parseInt(tokenizer.nextToken()); int height = Integer.parseInt(tokenizer.nextToken()); result = new Rectangle(x, y, width, height); } catch (Exception exception) { DebugStream.printStackTrace(exception); } return result; } /** Retrieve the value of the named property as a Color. */ static public Color getColor(String property, boolean general) { Color result = Color.white; // Default try { String raw = getString(property, general); // Color is a RGB triplet list, comma separated (also remove whitespace) StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1); int red = Integer.parseInt(tokenizer.nextToken()); int green = Integer.parseInt(tokenizer.nextToken()); int blue = Integer.parseInt(tokenizer.nextToken()); result = new Color(red, green, blue); } catch (Exception exception) { DebugStream.printStackTrace(exception); } return result; } /** Retrieve the special directory mappings associated with this collection. * @return A HashMap containing mappings from names to directories. */ static public HashMap getDirectoryMappings() { HashMap special_directories = new HashMap(); try { // Ensure the name isn't already in use. boolean found = false; NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT); for(int i = 0; !found && i < mappings.getLength(); i++) { Element mapping_element = (Element) mappings.item(i); String name = mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE); File file = new File(mapping_element.getAttribute(StaticStrings.FILE_ATTRIBUTE)); if(file.exists()) { special_directories.put(name, file); } file = null; name = null; mapping_element = null; } mappings = null; } catch (Exception exception) { DebugStream.printStackTrace(exception); } return special_directories; } /** getDirectoryMappings() */ /** Retrieve the current users email. These are always stored in the general settings. * @return the email address, if it is set, as a String */ static public String getEmail() { String email = getString(GENERAL_EMAIL_SETTING, true); return (email.length() > 0 ? email : null); } static public Element getFileAssociations() { NodeList file_association_elements = general_config.getDocumentElement().getElementsByTagName(StaticStrings.ASSOCIATIONS_ELEMENT); return (Element) file_association_elements.item(0); } /** Retrieve the value of the named property as a FontUIResource. */ static public FontUIResource getFont(String property, boolean general) { FontUIResource result = new FontUIResource("Times New Roman", Font.PLAIN, 10); try { String raw = getString(property, general); // Font is a face, style, size triplet. StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN3); String face = tokenizer.nextToken().trim(); ///ystem.err.println("Face: " + face); int style = Font.PLAIN; String temp = tokenizer.nextToken().toUpperCase().trim(); ///ystem.err.println("Style: " + temp); if(temp.equals("BOLD")) { style = Font.BOLD; } else if(temp.equals("ITALIC")) { style = Font.ITALIC; } int size = Integer.parseInt(tokenizer.nextToken().trim()); ///ystem.err.println("Size: " + size); result = new FontUIResource(face, style, size); } catch (Exception exception) { DebugStream.printStackTrace(exception); } return result; } /** Retrieve the value of the named property as an integer. */ static public int getInt(String property, boolean general) { int result = 0; try { String raw = getString(property, general); result = Integer.parseInt(raw); } catch (Exception exception) { DebugStream.printStackTrace(exception); } return result; } /** Retrieves the current interface language two letter code. */ static public String getLanguage() { Locale locale = getLocale("general.locale", GENERAL_SETTING); String code = "en"; // Default if(locale != null) { code = locale.getLanguage(); } return code; } /** Retrieve the value of the named property as a Locale. */ static public Locale getLocale(String property, boolean general) { Locale result = Locale.getDefault(); try { String raw = getString(property, general); // Locale is a underscore separated code. StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN2); String language = tokenizer.nextToken(); if(tokenizer.hasMoreTokens()) { String country = tokenizer.nextToken(); result = new Locale(language, country); } else { result = new Locale(language); } } catch (Exception exception) { DebugStream.printStackTrace(exception); } return result; } /** 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. * @return an int representing the mode */ static public int getMode() { return getInt("general.mode", GENERAL_SETTING); } /** Return the current mode as a string for use in title bar etc * @return the mode as a String */ static public String getModeAsString() { String result; switch(getInt("general.mode", GENERAL_SETTING)) { case ASSISTANT_MODE: result = Dictionary.get("Preferences.Mode.Assistant"); break; case EXPERT_MODE: result = Dictionary.get("Preferences.Mode.Expert"); break; default: result = Dictionary.get("Preferences.Mode.Librarian"); } return result; } static public String getPreviewCommand() { return getString("general.preview_program", GENERAL_SETTING); } static public String getApplicationTitle() { String gli_title = getString("GLI.Title", GENERAL_SETTING); String title = (gli_title=="") ? Gatherer.PROGRAM_NAME : gli_title; return title; } static public String getServletPath() { return servlet_path; } /** Retrieve the value of the named property, and noting whether we consult the general or collection specific configuration. */ static public String getString(String property, boolean general) { // Its up to this method to find the appropriate node and retrieve the data itself. String result = ""; try { // First of all we look in the cache to see if we have a match. SoftReference reference = (SoftReference) self.get(property + general); if(reference != null) { Element argument_element = (Element) reference.get(); if(argument_element != null) { cache_hit++; result = XMLTools.getValue(argument_element); } } // We may have missed in the cache, or the reference may have been consumed. if(result.length() == 0) { cache_miss++; // Locate the appropriate element Element document_element = null; if(general) { document_element = general_config.getDocumentElement(); } else if(collection_config != null) { document_element = collection_config.getDocumentElement(); } if(document_element != null) { // Retrieve the Gatherer element Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG); NodeList arguments = gatherer_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT); for(int i = 0; result.length() == 0 && i < arguments.getLength(); i++) { Element argument_element = (Element) arguments.item(i); if(argument_element.getAttribute(ARGUMENT_NAME).equalsIgnoreCase(property)) { result = XMLTools.getValue(argument_element); // 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. self.put(property + general, new SoftReference(argument_element)); } } } } } catch (Exception exception) { DebugStream.printStackTrace(exception); } // If we still have no result, and the search was made in the collection configuration, retrieve the general one instead. if(result.length() == 0 && !general) { result = getString(property, true); } return result; } static public String getGS3ScriptPath() { return gsdl3_src_path + "bin" + File.separator + "script" + File.separator; } /** Remove a previously defined special directory mapping. * @param name The name of the mapping to remove as a String. * @return The File of the mapping removed. */ static public File removeDirectoryMapping(String name) { File file = null; try { // Ensure the name isn't already in use. boolean found = false; NodeList mappings = directory_mappings_element.getElementsByTagName(StaticStrings.MAPPING_ELEMENT); for(int i = 0; !found && i < mappings.getLength(); i++) { Element mapping_element = (Element) mappings.item(i); if(mapping_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equalsIgnoreCase(name)) { file = new File(XMLTools.getValue(mapping_element)); directory_mappings_element.removeChild(mapping_element); found = true; } mapping_element = null; } mappings = null; } catch (Exception exception) { DebugStream.printStackTrace(exception); } return file; } /** removeDirectoryMapping(String name) */ /** Export the general configuration to file. */ static public void save() { ///ystem.err.println("Hits " + cache_hit + " vs Misses " + cache_miss); // We first try exporting to a user specific place File user_config_xml = null; String config_xml_name = CONFIG_XML; if (fedora_info != null && fedora_info.isActive()) { config_xml_name = FEDORA_CONFIG_PREFIX + config_xml_name; } try { user_config_xml = new File(gli_user_directory_path + config_xml_name); ///ystem.err.println("Trying to save to: " + user_config_xml.getAbsolutePath()); ///ystem.err.println("Writing."); user_config_xml.getParentFile().mkdirs(); XMLTools.writeXMLFile(new File(user_config_xml.getAbsolutePath()), general_config); } catch (Exception exception) { DebugStream.printStackTrace(exception); user_config_xml = null; } } /** Set the named property, from the specified configuration, using the given boolean value. */ static public void set(String property, boolean general, boolean value) { if(property.startsWith("workflow")) { DebugStream.println("Set property: " + property + ", general=" + general + ", value=" + value); } setString(property, general, (value ? "true" : "false")); } /** Set the collection configuration. */ static public void setCollectionConfiguration(Document collection_config_arg) { // clear the cached values self.clear(); collection_config = collection_config_arg; updateUI(); ///atherer.println("Collection configuration set."); } /** Set the named property, from the specified configuration, using the given Rectangle value. */ static public void setBounds(String property, boolean general, Rectangle value) { StringBuffer text = new StringBuffer(""); text.append(value.x); text.append(", "); text.append(value.y); text.append(", "); text.append(value.width); text.append(", "); text.append(value.height); setString(property, general, text.toString()); } /** Set the named property, from the specified configuration, using the given Color value. */ static public void setColor(String property, boolean general, Color value) { StringBuffer text = new StringBuffer(""); text.append(value.getRed()); text.append(", "); text.append(value.getGreen()); text.append(", "); text.append(value.getBlue()); setString(property, general, text.toString()); } /** Establish the current users email. * @param email the email as a String */ static public void setEmail(String email) { setString(GENERAL_EMAIL_SETTING, true, email); } /** Set the named property, from the specified configuration, using the given Font value. */ static public void setFont(String property, boolean general, Font value) { StringBuffer text = new StringBuffer(""); text.append(value.getName()); text.append(", "); switch(value.getStyle()) { case Font.BOLD: text.append("BOLD"); break; case Font.ITALIC: text.append("ITALIC"); break; default: text.append("PLAIN"); } text.append(", "); text.append(value.getSize()); setString(property, general, text.toString()); } /** Set the named property, from the specified configuration, using the given integer value. */ static public void setInt(String property, boolean general, int value) { setString(property, general, String.valueOf(value)); } /** Set the named property, from the specified configuration, using the given Locale value. */ static public void setLocale(String property, boolean general, Locale value) { StringBuffer text = new StringBuffer(""); text.append(value.getLanguage()); String country = value.getCountry(); if(country != null && country.length() > 0) { text.append("_"); text.append(country); } country = null; setString(property, general, text.toString()); } /** 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. * @param value the new value for mode */ static public void setMode(int value) { setInt("general.mode", GENERAL_SETTING, value); } static public void setPreviewCommand(String value) { setString("general.preview_program", GENERAL_SETTING, value); } static public void setSiteAndServlet(String site, String servlet) { site_name = site; servlet_path = servlet; setString("general.site_name", GENERAL_SETTING, site); setString("general.servlet_path", GENERAL_SETTING, servlet); } /** Sets the value of the named property argument using the given string. */ static public void setString(String property, boolean general, String value) { DebugStream.println("Set configuration property: " + property + " = " + value + (general ? "" : " [Collection]")); try { Document document = general_config; if(!general && collection_config != null) { document = collection_config; } if(document != null) { Element argument_element = null; // Try to retrieve from cache SoftReference reference = (SoftReference) self.get(property + general); if(reference != null) { argument_element = (Element) reference.get(); } if(argument_element == null) { Element document_element = document.getDocumentElement(); Element gatherer_element = (Element) XMLTools.getNodeFromNamed(document_element, GATHERER_CONFIG); NodeList arguments = document_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT); boolean found = false; for(int i = 0; argument_element == null && i < arguments.getLength(); i++) { Element possible_element = (Element) arguments.item(i); if(possible_element.getAttribute(ARGUMENT_NAME).equalsIgnoreCase(property)) { argument_element = possible_element; } } // If argument element is still null, create it in the target document. if(argument_element == null) { argument_element = document.createElement(GATHERER_CONFIG_ARGUMENT); argument_element.setAttribute(ARGUMENT_NAME, property); gatherer_element.appendChild(argument_element); } // Update cache self.put(property + general, new SoftReference(argument_element)); } if(value == null) { value = ""; } // Now remove any current text node children. NodeList children = argument_element.getChildNodes(); for(int i = 0; i < children.getLength(); i++) { argument_element.removeChild(children.item(i)); } // Add a new text node child with the new value argument_element.appendChild(document.createTextNode(value)); } } catch (Exception exception) { DebugStream.printStackTrace(exception); } } static private void updateUI() { // Buttons UIManager.put("Button.select", new ColorUIResource(getColor("coloring.button_selected_background", false))); UIManager.put("Button.background", new ColorUIResource(getColor("coloring.button_background", false))); UIManager.put("Button.foreground", new ColorUIResource(getColor("coloring.button_foreground", false))); UIManager.put("ToggleButton.background", new ColorUIResource(getColor("coloring.button_background", false))); UIManager.put("ToggleButton.foreground", new ColorUIResource(getColor("coloring.button_foreground", false))); UIManager.put("ToggleButton.select", new ColorUIResource(getColor("coloring.button_selected_background", false))); // All the things with a lovely Collection green background UIManager.put("OptionPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false))); UIManager.put("Panel.background", new ColorUIResource(getColor("coloring.collection_heading_background", false))); UIManager.put("Label.background", new ColorUIResource(getColor("coloring.collection_heading_background", false))); UIManager.put("TabbedPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false))); UIManager.put("SplitPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false))); UIManager.put("CheckBox.background", new ColorUIResource(getColor("coloring.collection_heading_background", false))); // Editable coloring UIManager.put("ComboBox.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); // Indicate clickable UIManager.put("Tree.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); UIManager.put("Tree.textBackground", new ColorUIResource(getColor("coloring.collection_tree_background", false))); UIManager.put("ProgressBar.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); UIManager.put("TextArea.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); UIManager.put("TextField.background", new ColorUIResource(getColor("coloring.editable_background", false))); UIManager.put("Table.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); UIManager.put("List.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); UIManager.put("RadioButton.background", new ColorUIResource(getColor("coloring.collection_tree_background", false))); // Selection color UIManager.put("TabbedPane.selected", new ColorUIResource(getColor("coloring.collection_selection_background", false))); UIManager.put("Tree.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false))); UIManager.put("ComboBox.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false))); UIManager.put("ProgressBar.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false))); UIManager.put("TextArea.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false))); UIManager.put("TextField.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false))); UIManager.put("List.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false))); // Scroll bar stuff UIManager.put("ScrollBar.background", new ColorUIResource(getColor("coloring.scrollbar_background", false))); UIManager.put("ScrollBar.thumb", new ColorUIResource(getColor("coloring.scrollbar_foreground", false))); } }