|
Commons Attributes example source code file (Attributes.java)
The Commons Attributes Attributes.java source code/* * Copyright 2003-2004 The Apache Software Foundation * * 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.apache.commons.attributes; import java.lang.reflect.Field; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.WeakHashMap; /** * API for accessing attributes. * * <h3>General Notes on Errors * * All Methods in this class may throw <code>RepositoryError or subclasses thereof. * This Error is thrown if an attribute repository can not be loaded for some Exceptional * reason. * * <h4>Rationale for Errors instead of Exceptions * * The methods in this class throws <code>Errors instead of* * do: * * <pre>
* Class myClass = ...;
* boolean shouldDoThis = Attributes.hasAttributeType (myClass, MyAttribute.class);
* for (int i = 0; i < 10000; i++) {
* if (shouldDoThis) {
* doThis(myClass);
* } else {
* doThat(myClass);
* }
* }
* </code>
*
* if the loop should run at maximum speed.
*
* @since 2.1
*/
public class Attributes {
/**
* A cache of attribute repositories. The map used is a WeakHashMap keyed on the
* Class owning the attribute repository. This works because Class objects use
* the identity function to compare for equality - i.e. if the two classes
* have the same name, and are loaded from the same two ClassLoaders, then
* <code>class1 == class2 . Also, (class1.equals(class2)) == (class1 ==
* class2)</code>. This means that a once a Class reference has been garbage-collected,
* it can't be re-created. Thus we can treat the cache map as a normal map - the only
* entries that will ever disappear are those we can't look up anyway because we
* can't ever create the key for them!
*
* <p>Also, this will keep the cache from growing too big in environments where
* classes are loaded and unloaded all the time (i.e. application servers).
*/
private final static Map classRepositories = new WeakHashMap ();
/**
* List used to keep track of the initialization list in getCachedRepository.
* Since the method is synchronized static, we only need one list.
*/
private static List initList = new ArrayList ();
private synchronized static CachedRepository getCachedRepository (Class clazz) throws RepositoryError, CircularDependencyError {
if (initList.contains (clazz)) {
List dependencyList = new ArrayList ();
dependencyList.addAll (initList);
dependencyList.add (clazz);
throw new CircularDependencyError (clazz.getName (), dependencyList);
} else if (classRepositories.containsKey (clazz)) {
CachedRepository cr = (CachedRepository) classRepositories.get (clazz);
return cr;
} else {
// Indicate that we're loading it.
CachedRepository cached = null;
initList.add (clazz);
try {
Class attributeRepo = null;
AttributeRepositoryClass repo = EmptyAttributeRepositoryClass.INSTANCE;
try {
attributeRepo = Class.forName (clazz.getName () + "$__attributeRepository", true, clazz.getClassLoader ());
repo = (AttributeRepositoryClass) attributeRepo.newInstance ();
} catch (ClassNotFoundException cnfe) {
// OK, just means no repo available, so default to empty one.
repo = EmptyAttributeRepositoryClass.INSTANCE;
} catch (InstantiationException ie) {
throw new RepositoryError (ie);
} catch (IllegalAccessException iae) {
throw new RepositoryError (iae);
}
cached = new DefaultCachedRepository (clazz, repo);
classRepositories.put (clazz, cached);
if (repo != null) {
Util.validateRepository (clazz, repo);
}
} finally {
initList.remove (initList.size () - 1);
}
return cached;
}
}
/**
* Selects from a collection of attributes one attribute with a given class.
*
* @param attrs the collection of attribute instances to select from.
* @param attributeClass the type of attribute wanted. May be <code>null , but this will not match anything.
* @return the attribute instance, or <code>null of none could be found.
* @throws MultipleAttributesError if the collection contains more than one
* instance of the specified class.
*/
private static Object getAttribute (Collection attrs, Class attributeClass) throws MultipleAttributesError {
Object candidate = null;
Iterator iter = attrs.iterator ();
while (iter.hasNext ()) {
Object attr = iter.next ();
if (attr.getClass () == attributeClass) {
if (candidate == null) {
candidate = attr;
} else {
throw new MultipleAttributesError (attributeClass.getName ());
}
}
}
return candidate;
}
/**
* Get one attributes of a given type from a class.
*
* @param clazz the class. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
* @return the attribute instance, or <code>null of none could be found.
* @throws MultipleAttributesError if the collection contains more than one
* instance of the specified class.
*
* @since 2.1
*/
public static Object getAttribute (Class clazz, Class attributeClass) throws RepositoryError, MultipleAttributesError {
return getAttribute (getAttributes (clazz), attributeClass);
}
/**
* Get one attributes of a given type from a field.
*
* @param field the field. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
* @return the attribute instance, or <code>null of none could be found.
* @throws MultipleAttributesError if the collection contains more than one
* instance of the specified class.
*
* @since 2.1
*/
public static Object getAttribute (Field field, Class attributeClass) throws RepositoryError, MultipleAttributesError {
return getAttribute (getAttributes (field), attributeClass);
}
/**
* Get one attributes of a given type from a constructor.
*
* @param constructor the constructor. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
* @return the attribute instance, or <code>null of none could be found.
* @throws MultipleAttributesError if the collection contains more than one
* instance of the specified class.
*
* @since 2.1
*/
public static Object getAttribute (Constructor constructor, Class attributeClass) throws RepositoryError, MultipleAttributesError {
return getAttribute (getAttributes (constructor), attributeClass);
}
/**
* Get one attributes of a given type from a method.
*
* @param method the method. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
* @return the attribute instance, or <code>null of none could be found.
* @throws MultipleAttributesError if the collection contains more than one
* instance of the specified class.
*
* @since 2.1
*/
public static Object getAttribute (Method method, Class attributeClass) throws RepositoryError, MultipleAttributesError {
return getAttribute (getAttributes (method), attributeClass);
}
/**
* Get one attributes of a given type from a parameter.
*
* @param method the method. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
* @param parameter index of the parameter in the method's parameter list.
* @return the attribute instance, or <code>null of none could be found.
* @throws MultipleAttributesError if the collection contains more than one
* instance of the specified class.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the method accepts.
*
* @since 2.1
*/
public static Object getParameterAttribute (Method method, int parameter, Class attributeClass) throws RepositoryError, MultipleAttributesError {
return getAttribute (getParameterAttributes (method, parameter), attributeClass);
}
/**
* Get one attributes of a given type from a constructor's parameter.
*
* @param constructor the constructor. May not be <code>null.
* @param parameter index of the parameter in the method's parameter list.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
* @return the attribute instance, or <code>null of none could be found.
* @throws MultipleAttributesError if the collection contains more than one
* instance of the specified class.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the constructor accepts.
*
* @since 2.1
*/
public static Object getParameterAttribute (Constructor constructor, int parameter, Class attributeClass) throws RepositoryError, MultipleAttributesError {
return getAttribute (getParameterAttributes (constructor, parameter), attributeClass);
}
/**
* Get one attributes of a given type from a method's return value.
*
* @param method the method. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
* @return the attribute instance, or <code>null of none could be found.
* @throws MultipleAttributesError if the collection contains more than one
* instance of the specified class.
*
* @since 2.1
*/
public static Object getReturnAttribute (Method method, Class attributeClass) throws RepositoryError, MultipleAttributesError {
return getAttribute (getReturnAttributes (method), attributeClass);
}
/**
* Gets all attributes for a class.
*
* @param clazz the class. May not be <code>null.
*
* @since 2.1
*/
public static Collection getAttributes (Class clazz) throws RepositoryError {
if (clazz == null) {
throw new NullPointerException ("clazz");
}
return getCachedRepository (clazz).getAttributes ();
}
/**
* Gets all attributes for a method.
*
* @param method the method. May not be <code>null.
*
* @since 2.1
*/
public static Collection getAttributes (Method method) throws RepositoryError {
if (method == null) {
throw new NullPointerException ("method");
}
return getCachedRepository (method.getDeclaringClass()).getAttributes (method);
}
/**
* Gets all attributes for a parameter of a method.
*
* @param method the method. May not be <code>null.
* @param parameter the index of the parameter in the method's parameter list.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the method accepts.
*
* @since 2.1
*/
public static Collection getParameterAttributes (Method method, int parameter) throws RepositoryError {
if (method == null) {
throw new NullPointerException ("method");
}
return getCachedRepository (method.getDeclaringClass()).getParameterAttributes (method, parameter);
}
/**
* Gets all attributes for a parameter of a constructor.
*
* @param constructor the constructor. May not be <code>null.
* @param parameter the index of the parameter in the constructor's parameter list.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the constructor accepts.
*
* @since 2.1
*/
public static Collection getParameterAttributes (Constructor constructor, int parameter) throws RepositoryError {
if (constructor == null) {
throw new NullPointerException ("constructor");
}
return getCachedRepository (constructor.getDeclaringClass()).getParameterAttributes (constructor, parameter);
}
/**
* Gets all attributes for the return value of a method.
*
* @param method the method. May not be <code>null.
*
* @since 2.1
*/
public static Collection getReturnAttributes (Method method) throws RepositoryError {
if (method == null) {
throw new NullPointerException ("method");
}
return getCachedRepository (method.getDeclaringClass()).getReturnAttributes (method);
}
/**
* Gets all attributes for a field.
*
* @param field the field. May not be <code>null.
*
* @since 2.1
*/
public static Collection getAttributes (Field field) throws RepositoryError {
if (field == null) {
throw new NullPointerException ("field");
}
return getCachedRepository (field.getDeclaringClass()).getAttributes (field);
}
/**
* Gets all attributes for a constructor.
*
* @param constructor the constructor. May not be <code>null.
*
* @since 2.1
*/
public static Collection getAttributes (Constructor constructor) throws RepositoryError {
if (constructor == null) {
throw new NullPointerException ("constructor");
}
return getCachedRepository (constructor.getDeclaringClass()).getAttributes (constructor);
}
/**
* Selects from a collection of attributes only those with a given class.
*
* @since 2.1
*/
private static Collection getAttributes (Collection attrs, Class attributeClass) {
HashSet result = new HashSet ();
Iterator iter = attrs.iterator ();
while (iter.hasNext ()) {
Object attr = iter.next ();
if (attr.getClass () == attributeClass) {
result.add (attr);
}
}
return Collections.unmodifiableCollection (result);
}
/**
* Get all attributes of a given type from a class. For all objects o in the returned
* collection, <code>o.getClass() == attributeClass.
*
* @param clazz the class. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static Collection getAttributes (Class clazz, Class attributeClass) throws RepositoryError {
return getAttributes (getAttributes (clazz), attributeClass);
}
/**
* Get all attributes of a given type from a field. For all objects o in the returned
* collection, <code>o.getClass() == attributeClass.
*
* @param field the field. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static Collection getAttributes (Field field, Class attributeClass) throws RepositoryError {
return getAttributes (getAttributes (field), attributeClass);
}
/**
* Get all attributes of a given type from a constructor. For all objects o in the returned
* collection, <code>o.getClass() == attributeClass.
*
* @param constructor the constructor. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static Collection getAttributes (Constructor constructor, Class attributeClass) throws RepositoryError {
return getAttributes (getAttributes (constructor), attributeClass);
}
/**
* Get all attributes of a given type from a method. For all objects o in the returned
* collection, <code>o.getClass() == attributeClass.
*
* @param method the method. May not be <code>null.
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static Collection getAttributes (Method method, Class attributeClass) throws RepositoryError {
return getAttributes (getAttributes (method), attributeClass);
}
/**
* Get all attributes of a given type from a method's parameter. For all objects o in the returned
* collection, <code>o.getClass() == attributeClass.
*
* @param method the method. May not be <code>null.
* @param parameter index of the parameter in the method's parameter list
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the method accepts.
*
* @since 2.1
*/
public static Collection getParameterAttributes (Method method, int parameter, Class attributeClass) throws RepositoryError {
return getAttributes (getParameterAttributes (method, parameter), attributeClass);
}
/**
* Get all attributes of a given type from a method's parameter. For all objects o in the returned
* collection, <code>o.getClass() == attributeClass.
*
* @param constructor the constructor. May not be <code>null.
* @param parameter index of the parameter in the constructor's parameter list
* @param attributeClass the type of attribute. May be <code>null, but this will not match anything.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the constructor accepts.
*
* @since 2.1
*/
public static Collection getParameterAttributes (Constructor constructor, int parameter, Class attributeClass) throws RepositoryError {
return getAttributes (getParameterAttributes (constructor, parameter), attributeClass);
}
/**
* Get all attributes of a given type from a method's return value. For all objects o in the returned
* collection, <code>o.getClass() == attributeClass.
*
* @param method the method
* @param attributeClass the type of attribute wanted. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static Collection getReturnAttributes (Method method, Class attributeClass) throws RepositoryError {
return getAttributes (getReturnAttributes (method), attributeClass);
}
/**
* Convenience function to test whether a collection of attributes contain
* an attribute of a given class.
*
* @since 2.1
*/
private static boolean hasAttributeType (Collection attrs, Class attributeClass) {
Iterator iter = attrs.iterator ();
while (iter.hasNext ()) {
Object attr = iter.next ();
if (attr.getClass () == attributeClass) {
return true;
}
}
return false;
}
/**
* Tests if a class has an attribute of a given type. That is, is there any attribute
* <code>attr such that attr.getClass() == attributeClass ?
*
* @param clazz the class. May not be <code>null.
* @param attributeClass the type of attribute. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static boolean hasAttributeType (Class clazz, Class attributeClass) throws RepositoryError {
return hasAttributeType (getAttributes (clazz), attributeClass);
}
/**
* Tests if a field has an attribute of a given type. That is, is there any attribute
* <code>attr such that attr.getClass() == attributeClass ?
*
* @param field the field. May not be <code>null.
* @param attributeClass the type of attribute. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static boolean hasAttributeType (Field field, Class attributeClass) throws RepositoryError {
return hasAttributeType (getAttributes (field), attributeClass);
}
/**
* Tests if a constructor has an attribute of a given type. That is, is there any attribute
* <code>attr such that attr.getClass() == attributeClass ?
*
* @param constructor the constructor. May not be <code>null.
* @param attributeClass the type of attribute. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static boolean hasAttributeType (Constructor constructor, Class attributeClass) throws RepositoryError {
return hasAttributeType (getAttributes (constructor), attributeClass);
}
/**
* Tests if a method has an attribute of a given type. That is, is there any attribute
* <code>attr such that attr.getClass() == attributeClass ?
*
* @param method the method. May not be <code>null.
* @param attributeClass the type of attribute. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static boolean hasAttributeType (Method method, Class attributeClass) throws RepositoryError {
return hasAttributeType (getAttributes (method), attributeClass);
}
/**
* Tests if a method's parameter has an attribute of a given type. That is, is there any attribute
* <code>attr such that attr.getClass() == attributeClass ?
*
* @param method the method. May not be <code>null.
* @param parameter the index of the parameter in the method's parameter list.
* @param attributeClass the type of attribute. May be <code>null, but this will not match anything.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the method accepts.
*
* @since 2.1
*/
public static boolean hasParameterAttributeType (Method method, int parameter, Class attributeClass) throws RepositoryError {
return hasAttributeType (getParameterAttributes (method, parameter), attributeClass);
}
/**
* Tests if a constructor's parameter has an attribute of a given type. That is, is there any attribute
* <code>attr such that attr.getClass() == attributeClass ?
*
* @param constructor the constructor. May not be <code>null.
* @param parameter the index of the parameter in the constructor's parameter list.
* @param attributeClass the type of attribute. May be <code>null, but this will not match anything.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the constructor accepts.
*
* @since 2.1
*/
public static boolean hasParameterAttributeType (Constructor constructor, int parameter, Class attributeClass) throws RepositoryError {
return hasAttributeType (getParameterAttributes (constructor, parameter), attributeClass);
}
/**
* Tests if a method's return value has an attribute of a given type. That is, is there any attribute
* <code>attr such that attr.getClass() == attributeClass ?
*
* @param method the method. May not be <code>null.
* @param attributeClass the type of attribute. May be <code>null, but this will not match anything.
*
* @since 2.1
*/
public static boolean hasReturnAttributeType (Method method, Class attributeClass) throws RepositoryError {
return hasAttributeType (getReturnAttributes (method), attributeClass);
}
/**
* Convenience function to test whether a collection of attributes contain
* an attribute.
*
* @since 2.1
*/
private static boolean hasAttribute (Collection attrs, Object attribute) throws RepositoryError {
return attrs.contains (attribute);
}
/**
* Tests if a class has an attribute. That is, is there any attribute
* <code>attr such that attr.equals(attribute) ?
*
* @param clazz the class. May not be <code>null.
* @param attribute the attribute to compare to.
*
* @since 2.1
*/
public static boolean hasAttribute (Class clazz, Object attribute) throws RepositoryError {
return hasAttribute (getAttributes (clazz), attribute);
}
/**
* Tests if a field has an attribute. That is, is there any attribute
* <code>attr such that attr.equals(attribute) ?
*
* @param field the field. May not be <code>null.
* @param attribute the attribute to compare to.
*
* @since 2.1
*/
public static boolean hasAttribute (Field field, Object attribute) throws RepositoryError {
return hasAttribute (getAttributes (field), attribute);
}
/**
* Tests if a constructor has an attribute. That is, is there any attribute
* <code>attr such that attr.equals(attribute) ?
*
* @param constructor the constructor. May not be <code>null.
* @param attribute the attribute to compare to.
*
* @since 2.1
*/
public static boolean hasAttribute (Constructor constructor, Object attribute) throws RepositoryError {
return hasAttribute (getAttributes (constructor), attribute);
}
/**
* Tests if a method has an attribute. That is, is there any attribute
* <code>attr such that attr.equals(attribute) ?
*
* @param method the method. May not be <code>null.
* @param attribute the attribute to compare to.
*
* @since 2.1
*/
public static boolean hasAttribute (Method method, Object attribute) throws RepositoryError {
return hasAttribute (getAttributes (method), attribute);
}
/**
* Tests if a method's parameter has an attribute. That is, is there any attribute
* <code>attr such that attr.equals(attribute) ?
*
* @param method the method. May not be <code>null.
* @param parameter the index of the parameter in the method's parameter list.
* @param attribute the attribute to compare to.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the method accepts.
*
* @since 2.1
*/
public static boolean hasParameterAttribute (Method method, int parameter, Object attribute) throws RepositoryError {
return hasAttribute (getParameterAttributes (method, parameter), attribute);
}
/**
* Tests if a constructor's parameter has an attribute. That is, is there any attribute
* <code>attr such that attr.equals(attribute) ?
*
* @param constructor the constructor. May not be <code>null.
* @param parameter the index of the parameter in the constructor's parameter list.
* @param attribute the attribute to compare to.
* @throws ParameterIndexOutOfBoundsException if the parameter index is < 0 or greater than the number
* of parameters the constructor accepts.
*
* @since 2.1
*/
public static boolean hasParameterAttribute (Constructor constructor, int parameter, Object attribute) throws RepositoryError {
return hasAttribute (getParameterAttributes (constructor, parameter), attribute);
}
/**
* Tests if a method's return value has an attribute. That is, is there any attribute
* <code>attr such that attr.equals(attribute) ?
*
* @param method the method. May not be <code>null.
* @param attribute the attribute to compare to.
*
* @since 2.1
*/
public static boolean hasReturnAttribute (Method method, Object attribute) throws RepositoryError {
return hasAttribute (getReturnAttributes (method), attribute);
}
/**
* Set attributes for a given class. The class must not have attributes set for it already
* (i.e. you can't redefine the attributes of a class at runtime). This because it
* really messes up the concept of inheritable attributes, and because the attribute set
* associated with a class is immutable, like the set of methods and fields.
*
* @param repo The repository. The repository will be sealed before any attributes are
* set. This to guarantee that the repository remains constant
* during setting.
* @throws IllegalStateException if the class whose attributes are defined already have
* attributes defined for it (even if it has no attributes).
* @since 2.1
*/
public static synchronized void setAttributes (RuntimeAttributeRepository repo) throws IllegalStateException {
if (repo == null) {
throw new NullPointerException ("repo");
}
repo.seal ();
Class clazz = repo.getDefinedClass ();
if (classRepositories.get (clazz) != null) {
throw new IllegalStateException (clazz.getName ());
}
Util.validateRepository (clazz, repo);
DefaultCachedRepository cached = new DefaultCachedRepository (clazz, repo);
classRepositories.put (clazz, cached);
}
}
Other Commons Attributes examples (source code examples)Here is a short list of links related to this Commons Attributes Attributes.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.