1 package attrib4j;
2
3 import java.lang.reflect.Field;
4 import java.lang.reflect.Method;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.HashMap;
8 import java.util.Map;
9
10 /***
11 * This class contains convenience methods to access and test custom
12 * attributes. Attributes derive from the class {@link Attribute}.
13 * The settings of the {@link AttributeFactory} will determine which
14 * implementation is used to search for metadata associated with
15 * program elements.
16 *
17 * @author Ted Neward
18 * @author <a href="mailto:mpollack@speakeasy.net">Mark Pollack</a>
19 * @version $Revision: 1.4 $ $Date: 2003/04/18 23:52:40 $
20 */
21 public class Attributes {
22
23 /***
24 * Hold a cache of AttributeExtractors so we don't have to load the
25 * class loaded repeatedly when accessing custom attributes.
26 *
27 * @return a Map of classname (name), AttributeExtractor (values)
28 */
29 private static Map _classMap = new HashMap();
30
31 /***
32 * Return the list (possibly empty) of custom attributes associated
33 * with the class "cls".
34 *
35 * @param cls The java.lang.Class object to find the attributes on.
36 * @return The possibly 0-length array of attributes
37 */
38 public static Attribute[] getAttributes(Class cls) {
39 AttributeExtractor ae = getAttrExtractor(cls);
40 return ae.getClassAttributes();
41 }
42
43 public static Attribute[] getAttributes(Class cls, Class filter) {
44 AttributeExtractor ae = getAttrExtractor(cls);
45 return ae.getClassAttributes(filter);
46 }
47
48 /***
49 * Return all the attributes associated with the given method.
50 * @param method The java.lang.reflect.Method describing the method.
51 * @return Attribute[] all attributes associated with the method.
52 * Returns a 0 length array in case no attributes were found.
53 */
54 public static Attribute[] getAttributes(Method method) {
55 return getAttributes(method, null);
56 }
57
58 /***
59 * Return all the attributes associated with the given method but
60 * filtered by the attribute class.
61 * @param method The java.lang.reflect.Method describing the method.
62 * @param filter Only attributes that are an instanceof this class
63 * will be returned.
64 * @return Attribute[] Attributes that are an instance of the filter
65 * class on this method will be returned. Returns a 0 length array
66 * in case no attributes found.
67 */
68 public static Attribute[] getAttributes(Method method, Class filter) {
69 Class clazz = method.getDeclaringClass();
70
71 ArrayList attribList = new ArrayList();
72 while (true) {
73 Attribute[] returnAttribs = searchForMethodAttribs(clazz, method, filter);
74 //Log.debug("****** returnAttrib.length = " + returnAttribs.length);
75 if (returnAttribs.length > 0) {
76 //TODO: Should only add to list if the attribute is not
77 //already in the list and the attribute is allowed to be
78 //specified mulitple times.
79 attribList.addAll(Arrays.asList(returnAttribs));
80 }
81 Class superClazz = clazz.getSuperclass();
82 if (superClazz == null) {
83
84 break;
85 //TODO is there a better way to test for belonging to the jdk?
86 //sealed jars?
87 } else if (superClazz.getName().startsWith("java.")) {
88 break;
89 } else {
90 clazz = superClazz;
91 }
92
93 }
94 while (true) {
95 //end of the superclass search.
96 //now look for interfaces.
97 Class[] interfaceClazzs = clazz.getInterfaces();
98 for (int i = 0; i < interfaceClazzs.length; i++) {
99 Attribute[] intAttribs =
100 searchForMethodAttribs(interfaceClazzs[i], method, filter);
101 if (intAttribs.length > 0) {
102 attribList.addAll(Arrays.asList(intAttribs));
103 }
104 }
105 Class superClazz = clazz.getSuperclass();
106 if (superClazz == null) {
107 break;
108 } else if (superClazz.getName().startsWith("java.")) {
109 break;
110 } else {
111 clazz = superClazz;
112 }
113
114 }
115
116 return (Attribute[]) attribList.toArray(
117 new Attribute[attribList.size()]);
118 }
119
120 /***
121 * @param clazz
122 * @param method
123 * @return Attribute[]
124 */
125 private static Attribute[] searchForMethodAttribs(
126 Class clazz,
127 Method method,
128 Class filter) {
129
130 //Log.debug("********* Searching recursively on class = " + clazz.getName());
131 AttributeExtractor ae = getAttrExtractor(clazz);
132 if (ae != null) {
133 String[] paramTypes = new String[method.getParameterTypes().length];
134
135 for (int i = 0; i < paramTypes.length; i++) {
136 paramTypes[i] = method.getParameterTypes()[i].getName();
137 }
138 return ae.getMethodAttributes(method.getName(), paramTypes, filter);
139 } else {
140 return new Attribute[0];
141 }
142 }
143
144 /***
145 * Return the list (possibly empty) of custom attributes associated
146 * with the field "fld".
147 *
148 * @param cls The java.lang.reflect.Field object to find the attributes on.
149 * @return The possibly 0-length array of attributes
150 */
151 public static Attribute[] getAttributes(Field fld) {
152 AttributeExtractor ae = getAttrExtractor(fld.getDeclaringClass());
153 return ae.getFieldAttributes(fld.getName());
154 }
155
156 /***
157 * Return the list (possibly empty) of custom attributes associated
158 * with the field "fld".
159 *
160 * @param cls The java.lang.reflect.Field object to find the attributes on.
161 * @return The possibly 0-length array of attributes
162 */
163 /*
164 public static Object[] getCustomFieldAttributes(Field fld) {
165 AttributeExtractor ae = getAttrExtractor(fld.getDeclaringClass());
166 return ae.getCustomFieldAttributes(fld.getName());
167 }
168 */
169
170 private static synchronized AttributeExtractor getAttrExtractor(Class cls) {
171 AttributeExtractor ae = null;
172 if ((ae = (AttributeExtractor) _classMap.get(cls)) == null) {
173 String fqn = cls.getName();
174 try {
175 ClassLoader loader = cls.getClassLoader();
176 if (loader != null) {
177 ae = AttributeFactory.getFactory().getAttributeExtractor();
178 ae.open(fqn, cls.getClassLoader());
179 _classMap.put(cls, ae);
180 } else {
181 Log.log(
182 "Cannot extract attribute from class = "
183 + cls.getName()
184 + " since it was loaded by the bootstrap classloader.",
185 Log.ERROR);
186 }
187 //TODO: clean this up.
188 } catch (AttributeException e) {
189 e.printStackTrace();
190 }
191 }
192 return ae;
193 }
194
195 } //Attributes
This page was automatically generated by Maven