/* * Copyright 2004-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.compass.core.util.config; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import org.compass.core.config.ConfigurationException; /** * This is the default <code>ConfigurationHelper</code> implementation. */ public class PlainConfigurationHelper extends AbstractConfigurationHelper implements ConfigurationHelper, Serializable { private static final long serialVersionUID = 3546076943545219376L; /** * An empty (length zero) array of configuration objects. */ protected static final ConfigurationHelper[] EMPTY_ARRAY = new ConfigurationHelper[0]; private final String name; private final String location; private final String namespace; private final String prefix; private HashMap<String, String> attributes; private ArrayList<ConfigurationHelper> children; private String value; private boolean readOnly; /** * Create a new <code>DefaultConfiguration</code> instance. */ public PlainConfigurationHelper(final String name) { this(name, null, "", ""); } /** * Create a new <code>DefaultConfiguration</code> instance. */ public PlainConfigurationHelper(final String name, final String location) { this(name, location, "", ""); } /** * Create a new <code>DefaultConfiguration</code> instance. */ public PlainConfigurationHelper(final String name, final String location, final String ns, final String prefix) { this.name = name; this.location = location; namespace = ns; this.prefix = prefix; // only used as a serialization hint. Cannot be null } /** * Returns the name of this configuration element. */ public String getName() { return name; } /** * Returns the namespace of this configuration element */ public String getNamespace() throws ConfigurationException { if (null != namespace) { return namespace; } else { throw new ConfigurationException("No namespace (not even default \"\") is associated with the " + "configuration element \"" + getName() + "\" at " + getLocation()); } } /** * Returns the prefix of the namespace */ protected String getPrefix() throws ConfigurationException { if (null != prefix) { return prefix; } else { throw new ConfigurationException("No prefix (not even default \"\") is associated with the " + "configuration element \"" + getName() + "\" at " + getLocation()); } } /** * Returns a description of location of element. */ public String getLocation() { return location; } /** * Returns the value of the configuration element as a <code>String</code>. */ public String getValue(final String defaultValue) { if (null != value) { return value; } else { return defaultValue; } } public String getAttributeOrValue(String paramName) { String retVal = getAttribute(paramName, null); if (retVal != null) { return retVal; } return getValue(); } /** * Returns the value of the configuration element as a <code>String</code>. */ public String getValue() throws ConfigurationException { if (null != value) { return value; } else { throw new ConfigurationException("No value is associated with the " + "configuration element \"" + getName() + "\" at " + getLocation()); } } /** * Return an array of all attribute names. */ public String[] getAttributeNames() { if (null == attributes) { return new String[0]; } else { return attributes.keySet().toArray(new String[attributes.keySet().size()]); } } /** * Return an array of <code>Configuration</code> elements containing all * node children. */ public ConfigurationHelper[] getChildren() { if (null == children) { return new ConfigurationHelper[0]; } else { return children.toArray(new ConfigurationHelper[children.size()]); } } /** * Returns the value of the attribute specified by its name as a * <code>String</code>. */ public String getAttribute(final String name) throws ConfigurationException { final String value = (null != attributes) ? attributes.get(name) : null; if (null != value) { return value; } else { throw new ConfigurationException("No attribute named \"" + name + "\" is " + "associated with the configuration element \"" + getName() + "\" at " + getLocation()); } } /** * Return the first <code>Configuration</code> object child of this * associated with the given name. */ public ConfigurationHelper getChild(final String name, final boolean createNew) { if (null != children) { final int size = children.size(); for (int i = 0; i < size; i++) { final ConfigurationHelper configuration = children.get(i); if (name.equals(configuration.getName())) { return configuration; } } } if (createNew) { return new PlainConfigurationHelper(name, "<generated>" + getLocation(), namespace, prefix); } else { return null; } } /** * Return an array of <code>Configuration</code> objects children of this * associated with the given name. <br> * The returned array may be empty but is never <code>null</code>. */ public ConfigurationHelper[] getChildren(final String name) { if (null == children) { return new ConfigurationHelper[0]; } else { final ArrayList<ConfigurationHelper> children = new ArrayList<ConfigurationHelper>(); final int size = this.children.size(); for (int i = 0; i < size; i++) { final ConfigurationHelper configuration = this.children.get(i); if (name.equals(configuration.getName())) { children.add(configuration); } } return children.toArray(new ConfigurationHelper[children.size()]); } } public ConfigurationHelper[] getChildren(String... names) { final ArrayList<ConfigurationHelper> children = new ArrayList<ConfigurationHelper>(); for (String name : names) { children.addAll(Arrays.asList(getChildren(name))); } return children.toArray(new ConfigurationHelper[children.size()]); } /** * Set the value of this <code>Configuration</code> object to the * specified string. */ public void setValue(final String value) { checkWriteable(); this.value = value; } /** * Set the value of this <code>Configuration</code> object to the * specified int. */ public void setValue(final int value) { setValue(String.valueOf(value)); } /** * Set the value of this <code>Configuration</code> object to the * specified long. */ public void setValue(final long value) { setValue(String.valueOf(value)); } /** * Set the value of this <code>Configuration</code> object to the * specified boolean. */ public void setValue(final boolean value) { setValue(String.valueOf(value)); } /** * Set the value of this <code>Configuration</code> object to the * specified float. */ public void setValue(final float value) { setValue(String.valueOf(value)); } /** * Set the value of the specified attribute to the specified string. */ public void setAttribute(final String name, final String value) { checkWriteable(); if (null != value) { if (null == attributes) { attributes = new HashMap<String, String>(); } attributes.put(name, value); } else { if (null != attributes) { attributes.remove(name); } } } /** * Set the value of the specified attribute to the specified int. */ public void setAttribute(final String name, final int value) { setAttribute(name, String.valueOf(value)); } /** * Set the value of the specified attribute to the specified long. */ public void setAttribute(final String name, final long value) { setAttribute(name, String.valueOf(value)); } /** * Set the value of the specified attribute to the specified boolean. */ public void setAttribute(final String name, final boolean value) { setAttribute(name, String.valueOf(value)); } /** * Set the value of the specified attribute to the specified float. */ public void setAttribute(final String name, final float value) { setAttribute(name, String.valueOf(value)); } /** * Add a child <code>Configuration</code> to this configuration element. */ public void addChild(final ConfigurationHelper configuration) { checkWriteable(); if (null == children) { children = new ArrayList<ConfigurationHelper>(); } children.add(configuration); } /** * Add all the attributes, children and value from specified configuration * element to current configuration element. */ public void addAll(final ConfigurationHelper other) { checkWriteable(); setValue(other.getValue(null)); addAllAttributes(other); addAllChildren(other); } /** * Add all attributes from specified configuration element to current * configuration element. */ public void addAllAttributes(final ConfigurationHelper other) { checkWriteable(); final String[] attributes = other.getAttributeNames(); for (final String name : attributes) { final String value = other.getAttribute(name, null); setAttribute(name, value); } } /** * Add all child <code>Configuration</code> objects from specified * configuration element to current configuration element. */ public void addAllChildren(final ConfigurationHelper other) { checkWriteable(); final ConfigurationHelper[] children = other.getChildren(); for (ConfigurationHelper aChildren : children) { addChild(aChildren); } } /** * Add all child <code>Configuration</code> objects from specified * configuration element to current configuration element. */ public void addAllChildrenBefore(final ConfigurationHelper other) { checkWriteable(); final ConfigurationHelper[] children = other.getChildren(); if (null == this.children) { this.children = new ArrayList<ConfigurationHelper>(); } for (int i = children.length - 1; i >= 0; i--) { this.children.add(0, children[i]); } } /** * Remove a child <code>Configuration</code> to this configuration * element. */ public void removeChild(final ConfigurationHelper configuration) { checkWriteable(); if (null == children) { return; } children.remove(configuration); } /** * Return count of children. */ public int getChildCount() { if (null == children) { return 0; } return children.size(); } /** * Make this configuration read-only. */ public void makeReadOnly() { readOnly = true; } /** * heck if this configuration is writeable. */ protected final void checkWriteable() throws IllegalStateException { if (readOnly) { throw new IllegalStateException("Configuration is read only and can not be modified"); } } /** * Returns true iff this DefaultConfiguration has been made read-only. */ protected final boolean isReadOnly() { return readOnly; } /** * Compare if this configuration is equal to another. */ public boolean equals(Object other) { if (other == null) return false; if (!(other instanceof ConfigurationHelper)) return false; return ConfigurationHelperUtil.equals(this, (ConfigurationHelper) other); } /** * Obtaine the hashcode for this configuration. */ public int hashCode() { int hash = prefix.hashCode(); if (name != null) hash ^= name.hashCode(); hash >>>= 7; if (location != null) hash ^= location.hashCode(); hash >>>= 7; if (namespace != null) hash ^= namespace.hashCode(); hash >>>= 7; if (attributes != null) hash ^= attributes.hashCode(); hash >>>= 7; if (children != null) hash ^= children.hashCode(); hash >>>= 7; if (value != null) hash ^= value.hashCode(); hash >>>= 7; hash ^= (readOnly) ? 1 : 3; return hash; } }