org.apache.commons.attributes.DefaultCachedRepository Maven / Gradle / Ivy
/*
* 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.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.HashMap;
class DefaultCachedRepository implements CachedRepository {
private final static Collection EMPTY_COLLECTION = new ArrayList (0);
private final Collection classAttributes;
private final Map fields = new HashMap ();
private final Map methods = new HashMap ();
private final Map constructors = new HashMap ();
private static class MethodAttributeBundle {
private Collection attributes = EMPTY_COLLECTION;
private List parameterAttributes = new ArrayList ();
private Collection returnAttributes = EMPTY_COLLECTION;
public MethodAttributeBundle () {
}
public Collection getAttributes () {
return attributes;
}
public Collection getReturnAttributes () {
return returnAttributes;
}
public Collection getParameterAttributes (int index) {
return (Collection) parameterAttributes.get (index);
}
public void setAttributes (Collection attributes) {
this.attributes = Collections.unmodifiableCollection (attributes);
}
public void setReturnAttributes (Collection returnAttributes) {
this.returnAttributes = Collections.unmodifiableCollection (returnAttributes);
}
public void addParameterAttributes (Collection parameterAttributes) {
this.parameterAttributes.add (Collections.unmodifiableCollection (parameterAttributes));
}
}
public DefaultCachedRepository (Class clazz, AttributeRepositoryClass repo) {
// ---- Fix up class attributes
Set tempClassAttributes = new HashSet ();
tempClassAttributes.addAll (repo.getClassAttributes ());
tempClassAttributes.addAll (getInheritableClassAttributes (clazz.getSuperclass ()));
Class[] ifs = clazz.getInterfaces ();
for (int i = 0; i < ifs.length; i++) {
tempClassAttributes.addAll (getInheritableClassAttributes (ifs[i]));
}
this.classAttributes = Collections.unmodifiableCollection (tempClassAttributes);
// ---- Fix up method attributes
Method[] methods = clazz.getDeclaredMethods ();
for (int i = 0; i < methods.length; i++) {
MethodAttributeBundle bundle = new MethodAttributeBundle ();
Method m = methods[i];
String key = Util.getSignature (m);
List attributeBundle = null;
if (repo.getMethodAttributes ().containsKey (key)) {
attributeBundle = (List) repo.getMethodAttributes ().get (key);
}
Set attributes = new HashSet ();
if (attributeBundle != null) {
attributes.addAll ((Collection) attributeBundle.get (0));
}
attributes.addAll (getInheritableMethodAttributes (clazz.getSuperclass (), m.getName (), m.getParameterTypes ()));
for (int j = 0; j < ifs.length; j++) {
attributes.addAll (getInheritableMethodAttributes (ifs[j], m.getName (), m.getParameterTypes ()));
}
if (attributes.size () > 0) {
bundle.setAttributes (attributes);
}
// ---- Return value attributes
attributes = new HashSet ();
if (attributeBundle != null) {
attributes.addAll ((Collection) attributeBundle.get (1));
}
attributes.addAll (getInheritableReturnAttributes (clazz.getSuperclass (), m.getName (), m.getParameterTypes ()));
for (int j = 0; j < ifs.length; j++) {
attributes.addAll (getInheritableReturnAttributes (ifs[j], m.getName (), m.getParameterTypes ()));
}
if (attributes.size () > 0) {
bundle.setReturnAttributes (attributes);
}
// ---- Parameter attributes
int numParameters = m.getParameterTypes().length;
for (int k = 0; k < numParameters; k++) {
attributes = new HashSet ();
if (attributeBundle != null) {
attributes.addAll ((Collection) attributeBundle.get (k + 2));
}
attributes.addAll (getInheritableMethodParameterAttributes (clazz.getSuperclass (), m.getName (), m.getParameterTypes (), k));
for (int j = 0; j < ifs.length; j++) {
attributes.addAll (getInheritableMethodParameterAttributes (ifs[j], m.getName (), m.getParameterTypes (), k));
}
bundle.addParameterAttributes (attributes);
}
this.methods.put (m, bundle);
}
// --- Just copy constructor attributes (they aren't inherited)
Constructor[] constructors = clazz.getDeclaredConstructors ();
for (int i = 0; i < constructors.length; i++) {
Constructor ctor = constructors[i];
String key = Util.getSignature (ctor);
if (repo.getConstructorAttributes ().containsKey (key)) {
List attributeBundle = null;
attributeBundle = (List) repo.getConstructorAttributes ().get (key);
MethodAttributeBundle bundle = new MethodAttributeBundle ();
bundle.setAttributes ((Collection) attributeBundle.get (0));
// ---- Parameter attributes
int numParameters = ctor.getParameterTypes().length;
for (int k = 0; k < numParameters; k++) {
bundle.addParameterAttributes ((Collection) attributeBundle.get (k + 1));
}
this.constructors.put (ctor, bundle);
}
}
// --- Just copy field attributes (they aren't inherited)
Field[] fields = clazz.getDeclaredFields ();
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
String key = f.getName ();
if (repo.getFieldAttributes ().containsKey (key)) {
this.fields.put (f, Collections.unmodifiableCollection ((Collection) repo.getFieldAttributes ().get (key)));
}
}
}
private static Collection getInheritableAttributes (Collection attrs) {
HashSet result = new HashSet ();
Iterator iter = attrs.iterator ();
while (iter.hasNext ()) {
Object attr = iter.next ();
if (Attributes.hasAttributeType (attr.getClass (), Inheritable.class)) {
result.add (attr);
}
}
return result;
}
private static Collection getInheritableClassAttributes (Class c) {
if (c == null) {
return new ArrayList (0);
}
HashSet result = new HashSet ();
result.addAll (getInheritableAttributes (Attributes.getAttributes (c)));
// Traverse the class hierarchy
result.addAll (getInheritableClassAttributes (c.getSuperclass ()));
// Traverse the interface hierarchy
Class[] ifs = c.getInterfaces ();
for (int i = 0; i < ifs.length; i++) {
result.addAll (getInheritableClassAttributes (ifs[i]));
}
return result;
}
private static Collection getInheritableMethodAttributes (Class c, String methodName, Class[] methodParams) {
if (c == null) {
return new ArrayList (0);
}
HashSet result = new HashSet ();
try {
// Get equivalent method in c
Method m = c.getDeclaredMethod (methodName, methodParams);
if ((m.getModifiers () & Modifier.PRIVATE) == 0) {
result.addAll (getInheritableAttributes (Attributes.getAttributes (m)));
}
} catch (NoSuchMethodException nsme) {
}
// Traverse the class hierarchy
result.addAll (getInheritableMethodAttributes (c.getSuperclass (), methodName, methodParams));
// Traverse the interface hierarchy
Class[] ifs = c.getInterfaces ();
for (int i = 0; i < ifs.length; i++) {
result.addAll (getInheritableMethodAttributes (ifs[i], methodName, methodParams));
}
return result;
}
private static Collection getInheritableMethodParameterAttributes (Class c, String methodName, Class[] methodParams, int parameter) {
if (c == null) {
return new ArrayList (0);
}
HashSet result = new HashSet ();
try {
// Get equivalent method in c
Method m = c.getDeclaredMethod (methodName, methodParams);
if ((m.getModifiers () & Modifier.PRIVATE) == 0) {
result.addAll (getInheritableAttributes (Attributes.getParameterAttributes (m, parameter)));
}
} catch (NoSuchMethodException nsme) {
}
// Traverse the class hierarchy
result.addAll (getInheritableMethodParameterAttributes (c.getSuperclass (), methodName, methodParams, parameter));
// Traverse the interface hierarchy
Class[] ifs = c.getInterfaces ();
for (int i = 0; i < ifs.length; i++) {
result.addAll (getInheritableMethodParameterAttributes (ifs[i], methodName, methodParams, parameter));
}
return result;
}
private static Collection getInheritableReturnAttributes (Class c, String methodName, Class[] methodParams) {
if (c == null) {
return new ArrayList (0);
}
HashSet result = new HashSet ();
try {
// Get equivalent method in c
Method m = c.getDeclaredMethod (methodName, methodParams);
if ((m.getModifiers () & Modifier.PRIVATE) == 0) {
result.addAll (getInheritableAttributes (Attributes.getReturnAttributes (m)));
}
} catch (NoSuchMethodException nsme) {
}
// Traverse the class hierarchy
result.addAll (getInheritableReturnAttributes (c.getSuperclass (), methodName, methodParams));
// Traverse the interface hierarchy
Class[] ifs = c.getInterfaces ();
for (int i = 0; i < ifs.length; i++) {
result.addAll (getInheritableReturnAttributes (ifs[i], methodName, methodParams));
}
return result;
}
public Collection getAttributes () {
return classAttributes;
}
public Collection getAttributes (Field f) {
if (fields.containsKey (f)) {
return (Collection) fields.get (f);
} else {
return EMPTY_COLLECTION;
}
}
public Collection getAttributes (Method m) {
if (methods.containsKey (m)) {
return ((MethodAttributeBundle) methods.get (m)).getAttributes ();
} else {
return EMPTY_COLLECTION;
}
}
public Collection getParameterAttributes (Constructor c, int parameter) {
if (constructors.containsKey (c)) {
return ((MethodAttributeBundle) constructors.get (c)).getParameterAttributes (parameter);
} else {
return EMPTY_COLLECTION;
}
}
public Collection getParameterAttributes (Method m, int parameter) {
if (methods.containsKey (m)) {
return ((MethodAttributeBundle) methods.get (m)).getParameterAttributes (parameter);
} else {
return EMPTY_COLLECTION;
}
}
public Collection getReturnAttributes (Method m) {
if (methods.containsKey (m)) {
return ((MethodAttributeBundle) methods.get (m)).getReturnAttributes ();
} else {
return EMPTY_COLLECTION;
}
}
public Collection getAttributes (Constructor c) {
if (constructors.containsKey (c)) {
return ((MethodAttributeBundle) constructors.get (c)).getAttributes ();
} else {
return EMPTY_COLLECTION;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy