/* * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.flexdock.plaf; import java.util.HashMap; import org.flexdock.plaf.resources.ResourceHandler; import org.flexdock.plaf.resources.ResourceHandlerFactory; import org.flexdock.util.ResourceManager; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * @author Christopher Butler */ public final class Configurator implements XMLConstants { public static final String DEFAULT_PREFS_URI = "org/flexdock/plaf/flexdock-themes-default.xml"; public static final String PREFS_URI = "flexdock-themes.xml"; private Configurator() { //does nothing } public static Document loadUserPrefs() { return ResourceManager.getDocument(PREFS_URI); } public static Document loadDefaultPrefs() { return ResourceManager.getDocument(DEFAULT_PREFS_URI); } public static HashMap getNamedElementsByTagName(String tagName) { if(isNull(tagName)) { return null; } HashMap cache = new HashMap(256); // load defaults Document defaults = Configurator.loadDefaultPrefs(); loadNamedElementsByTagName(defaults, tagName, cache); // overwrite/add with user prefs Document user = Configurator.loadUserPrefs(); loadNamedElementsByTagName(user, tagName, cache); return cache; } private static void loadNamedElementsByTagName(Document document, String tagName, HashMap cache) { if(document==null) { return; } NodeList elements = document.getElementsByTagName(tagName); for(int i=0; i<elements.getLength(); i++) { Element elem = (Element)elements.item(i); String key = elem.getAttribute(NAME_KEY); boolean inherit = "true".equals(elem.getAttribute(INHERITS_KEY)); if(!isNull(key)) { if(inherit) { // mark as overridden, so we don't overwrite it in the cache Element oldValue = (Element)cache.get(key); if(oldValue!=null) { cache.put(OVERRIDDEN_KEY + key, oldValue); } } cache.put(key, elem); } } } public static PropertySet[] getProperties(String tagName) { HashMap map = getNamedElementsByTagName(tagName); if(map==null) { return new PropertySet[0]; } String[] names = (String[])map.keySet().toArray(new String[0]); return getProperties(names, map); } public static PropertySet getProperties(String name, String tagName) { HashMap map = getNamedElementsByTagName(tagName); if(map==null) { return null; } return getProperties(name, map); } public static PropertySet[] getProperties(String[] names, String tagName) { HashMap map = names==null? null: getNamedElementsByTagName(tagName); if(map==null) { return new PropertySet[0]; } return getProperties(names, map); } public static PropertySet[] getProperties(String[] names, HashMap cache) { PropertySet[] properties = new PropertySet[names.length]; for(int i=0; i<names.length; i++) { properties[i] = getProperties(names[i], cache); } return properties; } private static PropertySet getProperties(String elemName, HashMap cache) { Element elem = isNull(elemName)? null: (Element)cache.get(elemName); if(elem==null) { return null; } PropertySet set = new PropertySet(); set.setName(elemName); // load all the parent properties first, so we can add/overwrite our own later String parentName = elem.getAttribute(EXTENDS_KEY); PropertySet parent = isNull(parentName)? null: getProperties(parentName, cache); if(parent!=null) { set.setAll(parent); } // check to see if we're supposed to inherit from an overridden element if("true".equalsIgnoreCase(elem.getAttribute(INHERITS_KEY))) { PropertySet overridden = getProperties(OVERRIDDEN_KEY + elemName, cache); if(overridden!=null) { set.setAll(overridden); } } // get the default handler name String propertyHandlerName = getPropertyHandlerName(elem); NodeList list = elem.getElementsByTagName(PROPERTY_KEY); int len = list.getLength(); for(int i=0; i<len; i++) { elem = (Element)list.item(i); String key = elem.getAttribute(NAME_KEY); if(!isNull(key)) { String value = elem.getAttribute(VALUE_KEY); String handler = elem.getAttribute(HANDLER_KEY); Object resource = getResource(value, handler, propertyHandlerName); if(resource!=null) { set.setProperty(key, resource); } } } return set; } private static String getPropertyHandlerName(Element elem) { String handlerName = elem.getAttribute(PROP_HANDLER_KEY); if(isNull(handlerName)) { handlerName = ResourceHandlerFactory.getPropertyHandler(elem.getTagName()); } return isNull(handlerName)? null: handlerName; } public static Object getResource(String stringValue, String currentHandlerName, String defaultHandlerName) { String handlerName = isNull(currentHandlerName)? defaultHandlerName: currentHandlerName; if(isNull(handlerName)) { return nullify(stringValue); } ResourceHandler handler = ResourceHandlerFactory.getResourceHandler(handlerName); return handler==null? nullify(stringValue): handler.getResource(stringValue); } private static String nullify(String data) { return isNull(data)? null: data; } public static boolean isNull(String data) { return data == null || data.trim().length() == 0; } }