org.rhq.enterprise.communications.command.param.ParametersImpl Maven / Gradle / Ivy
/*
* RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* 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 version 2 of the License.
*
* 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.rhq.enterprise.communications.command.param;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeMap;
import mazz.i18n.Logger;
import org.rhq.enterprise.communications.i18n.CommI18NFactory;
import org.rhq.enterprise.communications.i18n.CommI18NResourceKeys;
/**
* A class holding specific information about a set of parameters. It follows the Java Collection interface contract and
* thus can be used anywhere a Collection can be used.
*
* This collection follows both list and map connotations. It behaves like a list in that items that come out of it
* are in the same order as when they were added to it. It behaves like a map in that duplicate elements are not allowed
* and looking up elements have constant time performance that is analogous to java.util.HashMap
.
*
*
This class is not thread-safe.
*
* @author Charles Crouch
* @author John Mazzitelli
*/
public class ParametersImpl implements Parameters {
/**
* Logger
*/
private static final Logger LOG = CommI18NFactory.getLogger(ParametersImpl.class);
/**
* The serialVersionUID. Be careful if you want to change this - parameters in a serialized form may be persisted.
*/
private static final long serialVersionUID = 1L;
/**
* A map containing all the Parameter objects; keyed on {@link ParameterNameIndex}.
*/
private Map m_parameters;
/**
* The index of the last parameter that was added to the collection.
*/
private int m_lastIndex;
/**
* Constructor for {@link ParametersImpl} that initializes the object with no parameters.
*/
public ParametersImpl() {
m_parameters = new HashMap();
m_lastIndex = -1;
}
/**
* Copy-constructor for {@link ParametersImpl}.
*
* @param original the original to copy
*/
public ParametersImpl(Parameters original) {
this();
if (original != null) {
// don't just do a m_parameters.putAll - we want to create a duplicate of the Parameter object
for (Iterator iter = original.iterator(); iter.hasNext();) {
Parameter parameter = (Parameter) iter.next();
add(new Parameter(parameter));
}
}
return;
}
/**
* @see Parameters#getParameter(String)
*/
public Parameter getParameter(String parameterName) {
if (parameterName == null) {
return null;
}
return m_parameters.get(new ParameterNameIndex(parameterName, -1));
}
/**
* @see Parameters#getParameterDefinition(String)
*/
public ParameterDefinition getParameterDefinition(String parameterName) throws InvalidParameterDefinitionException {
Parameter parameter = getParameter(parameterName);
if (parameter == null) {
throw new InvalidParameterDefinitionException(LOG.getMsgString(CommI18NResourceKeys.NO_PARAMETER,
parameterName));
}
return parameter.getDefinition();
}
/**
* @see Parameters#getParameterValue(String)
*/
public Object getParameterValue(String parameterName) throws InvalidParameterDefinitionException {
Parameter parameter = getParameter(parameterName);
if (parameter == null) {
throw new InvalidParameterDefinitionException(LOG.getMsgString(CommI18NResourceKeys.NO_PARAMETER,
parameterName));
}
return parameter.getValue();
}
/**
* @see Parameters#setParameterValue(String, Object)
*/
public void setParameterValue(String parameterName, Object parameterValue)
throws InvalidParameterDefinitionException {
Parameter parameter = getParameter(parameterName);
if (parameter == null) {
throw new InvalidParameterDefinitionException(LOG.getMsgString(CommI18NResourceKeys.NO_PARAMETER,
parameterName));
}
parameter.setValue(parameterValue);
return;
}
/**
* The returned object is not a copy - changes made to that collection affect this object's internal collection.
* That means that if you add or remove parameters from the returned object, those parameters are also added or
* removed from this object.
*
* @see Parameters#getPublicParameters()
*/
public Parameters getPublicParameters() {
return new Proxy(false);
}
/**
* The returned object is not a copy - changes made to that collection affect this object's internal collection.
* That means that if you add or remove parameters from the returned object, those parameters are also added or
* removed from this object.
*
* @see Parameters#getInternalParameters()
*/
public Parameters getInternalParameters() {
return new Proxy(true);
}
/**
* @see Parameters#applyResourceBundleToParameterRenderingInformation(ResourceBundle)
*/
public void applyResourceBundleToParameterRenderingInformation(ResourceBundle resourceBundle) {
for (Iterator iter = iterator(); iter.hasNext();) {
Parameter param = (Parameter) iter.next();
ParameterDefinition definition = param.getDefinition();
ParameterRenderingInformation renderingInfo = definition.getRenderingInfo();
renderingInfo.applyResourceBundle(resourceBundle);
}
}
/**
* The returned object is not a copy - changes made to that collection affect this object's internal collection.
* That means that if you add or remove parameters from the returned object, those parameters are also added or
* removed from this object.
*
* @see java.util.Collection#size()
*/
public int size() {
return m_parameters.size();
}
/**
* @see java.util.Collection#clear()
*/
public void clear() {
m_parameters.clear();
m_lastIndex = -1;
}
/**
* @see java.util.Collection#isEmpty()
*/
public boolean isEmpty() {
return m_parameters.isEmpty();
}
/**
* @see Parameters#add(Parameter)
*/
public boolean add(Parameter parameter) throws NullPointerException {
if (parameter == null) {
throw new NullPointerException("parameter=null"); // NPE to follow Collection contract
}
m_lastIndex++;
m_parameters.put(new ParameterNameIndex(parameter.getDefinition().getName(), m_lastIndex), parameter);
return true;
}
/**
* This is here to satisfy the {@link Collection} interface contract. Same as if calling {@link #contains(String)}
* where the argument is the parameter name or {@link #contains(Parameter)}.
*
* @see java.util.Collection#contains(Object)
*/
public boolean contains(Object o) throws ClassCastException, NullPointerException {
if (o == null) {
throw new NullPointerException("o=null");
}
if (o instanceof String) {
return contains((String) o);
} else if (o instanceof Parameter) {
return contains((Parameter) o);
}
throw new ClassCastException(LOG.getMsgString(CommI18NResourceKeys.MUST_BE_STRING_OR_PARAM));
}
/**
* @see Parameters#contains(String)
*/
public boolean contains(String parameterName) throws NullPointerException {
if (parameterName == null) {
throw new NullPointerException("parameterName=null");
}
return m_parameters.containsKey(new ParameterNameIndex(parameterName, -1));
}
/**
* @see Parameters#contains(Parameter)
*/
public boolean contains(Parameter parameter) throws NullPointerException {
if (parameter == null) {
throw new NullPointerException("parameter=null");
}
return contains(parameter.getDefinition().getName());
}
/**
* This is here to satisfy the {@link Collection} interface contract. Same as if calling {@link #remove(String)}
* where the argument is the parameter name or {@link #remove(Parameter)}.
*
* @see java.util.Collection#remove(Object)
*/
public boolean remove(Object o) throws ClassCastException, NullPointerException {
if (o == null) {
throw new NullPointerException("object=null");
}
if (o instanceof String) {
return remove((String) o);
} else if (o instanceof Parameter) {
return remove((Parameter) o);
}
throw new ClassCastException(LOG.getMsgString(CommI18NResourceKeys.MUST_BE_STRING_OR_PARAM));
}
/**
* Removes the parameter stored in this collection whose name matches parameterName
.
*
* @param parameterName the name of the parameter to remove from this collection
*
* @return true
if the object was removed; false
if there was no object in this collection
* with the given parameter name
*
* @throws NullPointerException if parameterName
is null
, as per Collection interface
* contract
*/
public boolean remove(String parameterName) throws NullPointerException {
if (parameterName == null) {
throw new NullPointerException("parameterName=null");
}
// note that we don't need to mess with the lastIndex - the sorting won't get screwed up
return (m_parameters.remove(new ParameterNameIndex(parameterName, -1)) != null);
}
/**
* Removes the parameter whose name is the same as the name in the given parameter
. The full definition
* and value of the given parameter
is ignored when determining a match - only the parameter name is
* used in the comparision.
*
* @param parameter the parameter whose name is used to determine what to remove
*
* @return true
if the object was removed
*
* @throws NullPointerException if parameter
is null
, as per Collection interface contract
*/
public boolean remove(Parameter parameter) throws NullPointerException {
if (parameter == null) {
throw new NullPointerException("parameter=null");
}
return remove(parameter.getDefinition().getName());
}
/**
* Adds the elements found in the c
collection. If one or more elements in c
is not a
* {@link Parameter}, an exception will be thrown.
*
* @see java.util.Collection#addAll(java.util.Collection)
*/
public boolean addAll(Collection extends Parameter> c) throws ClassCastException, NullPointerException {
if (c == null) {
throw new NullPointerException("c=null");
}
boolean changed = false;
if (!c.isEmpty()) {
for (Parameter parameter : c) {
changed |= add(parameter);
}
}
return changed;
}
/**
* Checks to see if all the elements found in the c
collection are in this collection. If one or more
* elements in c
is not a {@link Parameter} or String
, an exception will be thrown.
*
* @see java.util.Collection#containsAll(Collection)
*/
public boolean containsAll(Collection> c) throws ClassCastException, NullPointerException {
if (c == null) {
throw new NullPointerException("c=null");
}
boolean hasAll = true;
if (!c.isEmpty()) {
for (Object parameter : c) {
hasAll &= contains(parameter);
}
}
return hasAll;
}
/**
* Removes the elements found in the c
collection. If one or more elements in c
is not a
* {@link Parameter}, an exception will be thrown.
*
* @see java.util.Collection#removeAll(Collection)
*/
public boolean removeAll(Collection> c) throws ClassCastException, NullPointerException {
if (c == null) {
throw new NullPointerException("c=null");
}
boolean changed = false;
if (!c.isEmpty()) {
for (Object parameter : c) {
changed |= remove(parameter);
}
}
return changed;
}
/**
* Retains only those elements found in the c
collection. If one or more elements in c
is
* not a {@link Parameter}, an exception will be thrown. The implementation will remove all elements in this
* collection and then add all the elements in c
. Because of this, true
is always returned
* - even if the elements end up being the same in the end.
*
* @see java.util.Collection#retainAll(Collection)
*/
public boolean retainAll(Collection> c) throws ClassCastException, NullPointerException {
clear();
for (Object object : c) {
add((Parameter) object);
}
return true;
}
/**
* The iterator will contain objects of type {@link Parameter}.
*
* @see java.util.Collection#iterator()
*/
public Iterator iterator() {
return getSortedIterator();
}
/**
* The returned array may be cast to a {@link Parameter} array.
*
* @see java.util.Collection#toArray()
*/
public Object[] toArray() {
Parameter[] array = new Parameter[m_parameters.size()];
System.arraycopy(getSortedCollection().toArray(), 0, array, 0, array.length);
return array;
}
/**
* Returns an array of {@link Parameter} objects.
*
* @see java.util.Collection#toArray(T[])
*/
public T[] toArray(T[] a) {
return getSortedCollection().toArray(a);
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return m_parameters.toString();
}
/**
* @see java.lang.Object#equals(Object)
*/
public boolean equals(Object obj) {
if ((obj == null) || (!(obj instanceof ParametersImpl))) {
return false;
}
return this.m_parameters.equals(((ParametersImpl) obj).m_parameters);
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return m_parameters.hashCode();
}
/**
* This returns a collection that will be sorted - it will have this object's collection elements in order of their
* index numbers. That is, in the order they were added to the collection.
*
* @return Collection that has its elements sorted
*/
private Collection getSortedCollection() {
TreeMap map = new TreeMap(
new SortedParameterNameIndexComparator());
map.putAll(m_parameters);
return map.values();
}
/**
* This returns an iterator that will return the collection elements in order of their index numbers. That is, in
* the order they were added to the collection.
*
* @return Iterator that returns the elements in order of when they were added
*/
private Iterator getSortedIterator() {
return getSortedCollection().iterator();
}
/**
* A proxy to the parent parameters implementation that will only expose a subset of the full parameters collection.
* This is used to provide a view into the parameters collection that only exposes hidden parameters or only public
* parameters.
*
* A proxy has an associated view mode - hidden only or public only.
*
* @see Parameters#getInternalParameters()
* @see Parameters#getPublicParameters()
*/
class Proxy implements Parameters {
/**
* the UID to identify the serializable version of this class. Be careful if you want to change this -
* parameters in a serialized form may be persisted.
*/
private static final long serialVersionUID = 1L;
/**
* Defines this proxy's view mode - that is, shows a view of only hidden parameters or public parameters. If
* true
, the proxy only exposes hidden parameters; false
for public parameters
*/
private final boolean m_onlyHidden;
/**
* Constructor for {@link Proxy} that defines that proxy's view mode. The view mode defines which parameters
* this proxy should expose.
*
* @param onlyHidden if true
, exposes only hidden parameters; if false
, exposes only
* public, non-hidden parameters
*/
Proxy(boolean onlyHidden) {
m_onlyHidden = onlyHidden;
}
/**
* Only returns the parameter if it is of the proper view type, null
otherwise.
*
* @see Parameters#getParameter(String)
*/
public Parameter getParameter(String parameterName) {
Parameter retParam = ParametersImpl.this.getParameter(parameterName);
if ((retParam != null) && (retParam.getDefinition() != null)
&& (retParam.getDefinition().isHidden() != m_onlyHidden)) {
return null;
}
return retParam;
}
/**
* Only returns the parameter definition if the parameter is of the proper view type, an exception is thrown
* otherwise.
*
* @see Parameters#getParameterDefinition(String)
*/
public ParameterDefinition getParameterDefinition(String parameterName)
throws InvalidParameterDefinitionException {
Parameter param = getParameter(parameterName);
if (param == null) {
throw new InvalidParameterDefinitionException(LOG.getMsgString(CommI18NResourceKeys.NO_PARAMETER,
parameterName));
}
return param.getDefinition();
}
/**
* Only returns the parameter value if the parameter is of the proper view type, an exception is thrown
* otherwise.
*
* @see Parameters#getParameterValue(String)
*/
public Object getParameterValue(String parameterName) throws InvalidParameterDefinitionException {
Parameter param = getParameter(parameterName);
if (param == null) {
throw new InvalidParameterDefinitionException(LOG.getMsgString(CommI18NResourceKeys.NO_PARAMETER,
parameterName));
}
return param.getValue();
}
/**
* Only sets the parameter value if the parameter is of the proper view type, an exception is thrown otherwise.
*
* @see Parameters#setParameterValue(String, Object)
*/
public void setParameterValue(String parameterName, Object parameterValue)
throws InvalidParameterDefinitionException {
Parameter param = getParameter(parameterName);
if (param == null) {
throw new InvalidParameterDefinitionException(LOG.getMsgString(CommI18NResourceKeys.NO_PARAMETER,
parameterName));
}
param.setValue(parameterValue);
return;
}
/**
* If this collection is already exposing the public parameters, a reference to itself is returned. Otherwise,
* an empty parameters collection is returned to indicate there are no internal parameters in this collection.
*
* @see Parameters#getPublicParameters()
*/
public Parameters getPublicParameters() {
return (m_onlyHidden) ? ((Parameters) new ParametersImpl()) : ((Parameters) this);
}
/**
* If this collection is already exposing the internal, hidden parameters, a reference to itself is returned.
* Otherwise, an empty parameters collection is returned to indicate there are no internal parameters in this
* collection.
*
* @see Parameters#getInternalParameters()
*/
public Parameters getInternalParameters() {
return (!m_onlyHidden) ? ((Parameters) new ParametersImpl()) : ((Parameters) this);
}
/**
* @see Parameters#applyResourceBundleToParameterRenderingInformation(ResourceBundle)
*/
public void applyResourceBundleToParameterRenderingInformation(ResourceBundle resourceBundle) {
for (Iterator iter = this.iterator(); iter.hasNext();) {
Parameter param = (Parameter) iter.next();
ParameterDefinition definition = param.getDefinition();
ParameterRenderingInformation renderingInfo = definition.getRenderingInfo();
renderingInfo.applyResourceBundle(resourceBundle);
}
}
/**
* @see Parameters#contains(String)
*/
public boolean contains(String parameterName) throws NullPointerException {
return (getParameter(parameterName) != null);
}
/**
* @see Parameters#contains(Parameter)
*/
public boolean contains(Parameter parameter) throws NullPointerException {
return (getParameter(parameter.getDefinition().getName()) != null);
}
/**
* As allowed by the Collections API contract, this will throw an IllegalArgumentException
if the
* given parameter is not of the proper view type (that is, if this proxy's view mode is only exposing hidden
* parameters, you can only add hidden parameters to it; same with public, non-hidden parameters).
*
* @see Parameters#add(Parameter)
*/
public boolean add(Parameter parameter) throws NullPointerException, IllegalArgumentException {
if (parameter.getDefinition().isHidden() != m_onlyHidden) {
throw new IllegalArgumentException(LOG.getMsgString(CommI18NResourceKeys.PARAMETERS_IMPL_HIDDEN,
parameter.getName(), parameter.getDefinition().isHidden()));
}
return ParametersImpl.this.add(parameter);
}
/**
* @see Parameters#remove(String)
*/
public boolean remove(String parameterName) throws NullPointerException {
// make sure you do this contains check - don't want the caller to try to remove something from the parent parameters
// without ensuring the doomed parameter is of the proper view type (hidden only or public only).
if (contains(parameterName)) {
return ParametersImpl.this.remove(parameterName);
}
return false;
}
/**
* @see Parameters#remove(Parameter)
*/
public boolean remove(Parameter parameter) throws NullPointerException {
// make sure you do this contains check - don't want the caller to try to remove something from the parent parameters
// without ensuring the doomed parameter is of the proper view type (hidden only or public only).
if (contains(parameter)) {
return ParametersImpl.this.remove(parameter);
}
return false;
}
/**
* @see java.util.Collection#size()
*/
public int size() {
Parameter[] allParams = (Parameter[]) ParametersImpl.this.toArray();
int retSize = 0;
for (int i = 0; i < allParams.length; i++) {
if (allParams[i].getDefinition().isHidden() == m_onlyHidden) {
retSize++;
}
}
return retSize;
}
/**
* This clears this proxy's collection by removing all the parameters of the proper view type from the parent
* parameters collection. For example, if this proxy is exposing only hidden parameters, all hidden parameters
* will be removed from the parent parameters collection leaving all public parameters intact.
*
* @see java.util.Collection#clear()
*/
public void clear() {
Parameter[] allParams = (Parameter[]) ParametersImpl.this.toArray();
for (int i = 0; i < allParams.length; i++) {
if (allParams[i].getDefinition().isHidden() == m_onlyHidden) {
ParametersImpl.this.remove(allParams[i]);
}
}
return;
}
/**
* @see java.util.Collection#isEmpty()
*/
public boolean isEmpty() {
return (size() == 0);
}
/**
* @see java.util.Collection#toArray()
*/
public Object[] toArray() {
Parameter[] allArray = (Parameter[]) ParametersImpl.this.toArray();
Parameter[] retArray = new Parameter[size()];
if (retArray.length > 0) {
// doing it this way ensures the ordering of the parameters stays the same as in the parent parameters collection
int retIndex = 0;
for (int i = 0; i < allArray.length; i++) {
if (allArray[i].getDefinition().isHidden() == m_onlyHidden) {
retArray[retIndex++] = allArray[i]; // if array-out-of-bounds occurs, someone concurrently modified the parent map
}
}
}
return retArray;
}
/**
* @see java.util.Collection#contains(Object)
*/
public boolean contains(Object o) throws ClassCastException, NullPointerException {
if (o == null) {
throw new NullPointerException("o=null");
}
if (o instanceof String) {
return contains((String) o);
} else if (o instanceof Parameter) {
return contains((Parameter) o);
}
throw new ClassCastException(LOG.getMsgString(CommI18NResourceKeys.MUST_BE_STRING_OR_PARAM));
}
/**
* @see java.util.Collection#remove(Object)
*/
public boolean remove(Object o) throws ClassCastException, NullPointerException {
if (o == null) {
throw new NullPointerException("o=null");
}
if (o instanceof String) {
return remove((String) o);
} else if (o instanceof Parameter) {
return remove((Parameter) o);
}
throw new ClassCastException(LOG.getMsgString(CommI18NResourceKeys.MUST_BE_STRING_OR_PARAM));
}
/**
* As allowed by the Collections API contract, this will throw an IllegalArgumentException
if the
* given parameter's object is a parameter that is not of the proper view type (that is, if this proxy's view
* mode is only exposing hidden parameters, you can only add hidden parameters to it; same with public,
* non-hidden parameters).
*
* @see java.util.Collection#addAll(Collection)
*/
public boolean addAll(Collection extends Parameter> c) throws ClassCastException, NullPointerException,
IllegalArgumentException {
if (c == null) {
throw new NullPointerException("c=null");
}
boolean changed = false;
if (!c.isEmpty()) {
for (Parameter parameter : c) {
changed |= add(parameter);
}
}
return changed;
}
/**
* @see java.util.Collection#containsAll(Collection)
*/
public boolean containsAll(Collection c) throws ClassCastException, NullPointerException {
if (c == null) {
throw new NullPointerException("c=null");
}
boolean hasAll = true;
if (!c.isEmpty()) {
for (Iterator iter = c.iterator(); iter.hasNext() && hasAll;) {
Object element = iter.next();
hasAll &= contains(element);
}
}
return hasAll;
}
/**
* @see java.util.Collection#removeAll(Collection)
*/
public boolean removeAll(Collection c) {
if (c == null) {
throw new NullPointerException("c=null");
}
boolean changed = false;
if (!c.isEmpty()) {
for (Iterator iter = c.iterator(); iter.hasNext();) {
Object element = iter.next();
changed |= remove(element);
}
}
return changed;
}
/**
* @see java.util.Collection#retainAll(Collection)
*/
public boolean retainAll(Collection> c) {
clear();
for (Object object : c) {
add((Parameter) object);
}
return true;
}
/**
* @see java.util.Collection#iterator()
*/
public Iterator iterator() {
TreeMap map = new TreeMap(
new SortedParameterNameIndexComparator());
// only put those parameters with the proper view type will be put in our tree map
Set> entrySet = m_parameters.entrySet();
for (Map.Entry entry : entrySet) {
Parameter param = entry.getValue();
if (param.getDefinition().isHidden() == m_onlyHidden) {
map.put(entry.getKey(), param);
}
}
return map.values().iterator();
}
/**
* @see java.util.Collection#toArray(T[])
*/
@SuppressWarnings("unchecked")
public T[] toArray(T[] a) {
Object[] retArray;
Object[] proxyParameters = toArray(); // gets just those parameters exposed by the proxy
if (a.length >= proxyParameters.length) {
System.arraycopy(proxyParameters, 0, a, 0, proxyParameters.length);
if (a.length > proxyParameters.length) {
a[proxyParameters.length] = null; // as per Collections toArray(Object[]) contract - see its javadoc
}
retArray = a;
} else {
retArray = proxyParameters;
}
return (T[]) retArray; // this cast is OK, we know all its items conform to the type T (which is Parameter)
}
}
}