1 package attrib4j.bcel;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.ObjectOutputStream;
7 import java.lang.reflect.Constructor;
8 import java.net.URL;
9 import java.net.URLClassLoader;
10
11 import org.apache.bcel.classfile.ClassParser;
12 import org.apache.bcel.generic.ClassGen;
13 import org.apache.bcel.generic.ConstantPoolGen;
14
15 import attrib4j.AttributeException;
16 import attrib4j.Log;
17
18 /***
19 * Class responsible for annotating a class with attributes
20 */
21 public class BCELClassAnnotator extends AbstractBCELClassAnnotator {
22
23 public BCELClassAnnotator(InputStream classFile, String classFileName)
24 throws AttributeException {
25
26 try {
27 //TODO use the Repository.lookupClass instead?
28 Log.debug(
29 "BCELClassAnnotator",
30 "Loading class from filename = " + classFileName);
31 if (classFile == null) {
32 throw new AttributeException("Illegal Arguement. InputStream to load classfile as resource is null");
33 }
34 _javaClass = new ClassParser(classFile, classFileName).parse();
35 Log.debug(
36 "BCELClassAnnotator",
37 "Created BCEL JavaClass = " + _javaClass.getClassName());
38 _constantPool = _javaClass.getConstantPool();
39 _constantPoolGen = new ConstantPoolGen(_constantPool);
40
41 // Constant[] poolarray = _constantPool.getConstantPool();
42 // for (int i=0;i<poolarray.length;i++) {
43 // System.out.println("** poolarray element " + i + " = " + poolarray[i]);
44 _classGen = new ClassGen(_javaClass);
45 } catch (IOException e) {
46 throw new AttributeException(
47 "Could not create an instance of BCELClassAnnotator",
48 e);
49 }
50 }
51
52 /***
53 * Internal routine to create an attribute instance. Will search for
54 * a classname specified in the attribute text and if not found will
55 * search for the classname with word 'Attribute' added to the classname.
56 * Will then prepend the packages specified in the attributepackages
57 * option.
58 *
59 * @param attributeText The text associated with the javadoc tag.
60 * @return The appropriatly created and initialized attribute instance.
61 */
62 public Object createAttributeInstance(
63 String attributeText,
64 URLClassLoader classLoader,
65 String[] attributePackages) {
66
67 Log.debug("BCELClassAnnotator", "Attribute Text = " + attributeText);
68 String attrClassname = AbstractBCELClassAnnotator.parseAttributeClassName(attributeText);
69 String[] attrParameters = AbstractBCELClassAnnotator.parseAttributeParams(attributeText);
70 java.util.List l = java.util.Arrays.asList(attrParameters);
71 Log.debug("BCELClassAnnotator", "Parsed Parameters = " + l);
72 Object ca = null;
73 //CustomAttribute ca = null;
74 Class customAttributeClass = null;
75 URL[] urls = classLoader.getURLs();
76 StringBuffer sbUrl = new StringBuffer();
77 if (urls != null) {
78 for (int i = 0; i < urls.length; i++ ) {
79 sbUrl.append(urls[i]);
80 sbUrl.append(",");
81 }
82 Log.debug("BCELClassAnnotator","Classloader = " + sbUrl.toString());
83 } else {
84 Log.error("BCELClassAnnotator","Classloader urls are null.");
85 }
86 try {
87 Log.debug(
88 "BCELClassAnnotator",
89 "Trying to create class with classname=" + attrClassname);
90 customAttributeClass =
91 Class.forName(attrClassname, true, classLoader);
92 } catch (ClassNotFoundException ex) { //now try adding Attribute to the classname.
93 try {
94 Log.debug(
95 "BCELClassAnnotator",
96 "Trying to create class with classname="
97 + attrClassname
98 + "Attribute");
99 customAttributeClass =
100 Class.forName(
101 attrClassname + "Attribute",
102 true,
103 classLoader);
104 } catch (Exception ex2) {
105 //now try searching through packagenames where attributes were
106 //said to exist.
107 try {
108 if (attributePackages != null) {
109 customAttributeClass =
110 AbstractBCELClassAnnotator.createFromPackageSearch(
111 attrClassname,
112 classLoader,
113 attributePackages);
114 }
115 } catch (AttributeException ex3) {
116 //ex3.printStackTrace();
117 StringBuffer sb = new StringBuffer();
118 //TODO use list.
119 if (attributePackages != null) {
120 for (int i = 0; i< attributePackages.length; i++) {
121 sb.append(attributePackages[i]);
122 sb.append(", ");
123 }
124 }
125 Log.error("BCELClassAnnotator","*********************************");
126 Log.error("BCELClassAnnotator","Could not create attribute named " + attrClassname + " from package list = "
127 + sb.toString());
128 Log.error("BCELClassAnnotator","*********************************");
129 Log.error("BCELClassAnnotator",ex3.getStackTraceString());
130 return null;
131 }
132 }
133 }
134
135 if (customAttributeClass != null) {
136 Log.debug(
137 "BCELClassAnnotator",
138 "Creating attribute with classname = " + customAttributeClass);
139 try {
140 // check for constructor that matches parameter numbers
141 Constructor[] ctors =
142 customAttributeClass.getDeclaredConstructors();
143 if (ctors.length < 1) {
144 throw new RuntimeException(
145 customAttributeClass.getName()
146 + " must have at least one public constructor");
147 }
148
149 for (int i = 0; i < ctors.length; i++) {
150 Class[] ctorParamTypes = ctors[i].getParameterTypes();
151 if (ctorParamTypes.length == attrParameters.length) {
152 Object[] ctorArgs = new Object[ctorParamTypes.length];
153 for (int j = 0; j < ctorParamTypes.length; j++) {
154 ctorArgs[j] =
155 AbstractBCELClassAnnotator.guessParam(
156 ctorParamTypes[j],
157 attrParameters[j]);
158
159 }
160
161 try {
162 ca = ctors[i].newInstance(ctorArgs);
163 } catch (Exception x) {
164 continue;
165 }
166 break;
167 }
168 }
169
170 if (ca == null) {
171 String signature = "";
172 for (int i = 0; i < attrParameters.length; i++) {
173 signature += attrParameters[i];
174 if (i + 1 < attrParameters.length) {
175 signature += " ";
176 }
177 }
178 throw new RuntimeException(
179 "No ctor in attribute matched " + signature + "!");
180 }
181
182 return ca;
183 } catch (Exception ex) {
184 // Do something
185 ex.printStackTrace();
186 return null;
187 }
188 } else {
189 return null;
190 }
191 }
192
193 public byte[] createBytesFromAttribute(Object attribute) {
194 return serialize(attribute);
195 }
196
197 private byte[] serialize(Object obj) {
198 try {
199 ByteArrayOutputStream baos = new ByteArrayOutputStream();
200 ObjectOutputStream oos = new ObjectOutputStream(baos);
201 oos.writeObject(obj);
202 return baos.toByteArray();
203 } catch (IOException ioEx) {
204 return null;
205 }
206 }
207
208 }
This page was automatically generated by Maven