- /*
- * 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;
- }
- }
- }