1 package it.imolinfo.jbi4corba.webservice.generator.typedef;
2
3 import it.imolinfo.jbi4corba.Logger;
4 import it.imolinfo.jbi4corba.LoggerFactory;
5 import it.imolinfo.jbi4corba.exception.ClassGenerationException;
6 import it.imolinfo.jbi4corba.webservice.generator.Util;
7 import it.imolinfo.jbi4corba.webservice.generator.bcm.ByteCodeManipulationUtil;
8
9 import java.io.File;
10 import java.lang.reflect.Field;
11
12 import javax.xml.bind.annotation.XmlTransient;
13 import javax.xml.bind.annotation.XmlType;
14 import javax.xml.bind.annotation.XmlValue;
15
16 import org.apache.commons.lang.ArrayUtils;
17 import org.apache.cxf.helpers.ServiceUtils;
18 import org.objectweb.asm.AnnotationVisitor;
19 import org.objectweb.asm.ClassWriter;
20 import org.objectweb.asm.FieldVisitor;
21 import org.objectweb.asm.Label;
22 import org.objectweb.asm.MethodVisitor;
23 import org.objectweb.asm.Opcodes;
24 import org.objectweb.asm.Type;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 @SuppressWarnings("unchecked")
61 public class SimpleTypeDef extends TypeDef {
62
63
64
65
66 private static final Logger LOG = LoggerFactory
67 .getLogger(SimpleTypeDef.class);
68
69 protected SimpleTypeDef(String className, String helperClassName, Class aliasedClass, String id) {
70 super(className, helperClassName, aliasedClass, id);
71 }
72
73
74
75
76
77 public void createTypeDefClass(String classesDir) throws ClassGenerationException {
78
79 String namespace = ServiceUtils.makeNamespaceFromClassName(this.getClassName(), "http");
80
81
82 String classInternalName = this.getClassName().replace('.','/');
83 String classDescriptor = "L" + classInternalName + ";";
84 String aliasedClassDescriptor = Type.getDescriptor(aliasedClass);
85 String objectArrayClassDescriptor = Type.getDescriptor(java.lang.Object[].class);
86
87
88 Class helperClass = this.getHelperClass(classesDir);
89 String helperDescriptor = Type.getDescriptor(helperClass);
90
91
92 String javaLangClassDescriptor = Type.getDescriptor(Class.class);
93 String javaLangObjectInternalName = Type.getInternalName(java.lang.Object.class);
94 String xmlTypeDescriptor = Type.getDescriptor(XmlType.class);
95 String xmlValueDescriptor = Type.getDescriptor(XmlValue.class);
96 String xmlTransientDescriptor = Type.getDescriptor(XmlTransient.class);
97
98 ClassWriter cw = new ClassWriter(true);
99
100
101 cw.visit(Opcodes.V1_5, ACC_PUBLIC + ACC_SUPER, classInternalName ,null, javaLangObjectInternalName, null);
102
103
104 AnnotationVisitor av = cw.visitAnnotation(xmlTypeDescriptor, true);
105 av.visit("namespace", namespace);
106 av.visitEnd();
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 FieldVisitor fv = null;
125
126
127
128
129
130 fv = cw.visitField(ACC_PUBLIC, "value", aliasedClassDescriptor, null, null);
131
132
133
134 if (!aliasedClass.equals(java.lang.Object.class)) {
135 AnnotationVisitor av2 = fv.visitAnnotation(xmlValueDescriptor, true);
136 av2.visitEnd();
137 fv.visitEnd();
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 ByteCodeManipulationUtil bcmUtil = new ByteCodeManipulationUtil();
159
160 bcmUtil.createSetter(cw, classInternalName, "value", aliasedClassDescriptor);
161
162
163
164
165
166 MethodVisitor mvinit = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
167 mvinit.visitCode();
168 Label linit = new Label();
169 mvinit.visitLabel(linit);
170 mvinit.visitLineNumber(7, linit);
171 mvinit.visitVarInsn(ALOAD, 0);
172 mvinit.visitMethodInsn(INVOKESPECIAL, javaLangObjectInternalName, "<init>", "()V");
173 mvinit.visitInsn(RETURN);
174 Label linit1 = new Label();
175 mvinit.visitLabel(linit1);
176 mvinit.visitLocalVariable("this", classDescriptor, null, linit, linit1, 0);
177 mvinit.visitMaxs(1, 1);
178 mvinit.visitEnd();
179
180 cw.visitEnd();
181 byte[] bytecode = cw.toByteArray();
182
183 String relativeClassName = getClassRelativeFileName();
184
185 if (LOG.isDebugEnabled()) {
186 LOG.debug("Writing out TypeDef class:" + classesDir + File.separatorChar + relativeClassName);
187 }
188
189 Util.saveAsJavaClass(classesDir, relativeClassName, bytecode);
190 }
191
192 @Override
193 public Object getTypeDefObject(ClassLoader classLoader, Object obj) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchFieldException {
194 Class classDefinition = classLoader.loadClass(getClassName());
195 Object typeDefObject = classDefinition.newInstance();
196 Field value = typeDefObject.getClass().getField("value");
197 LOG.debug("Trying to set: " + obj + " of object: " + obj + " on object:" + typeDefObject);
198
199 if (obj.getClass().isArray()) {
200
201 if (LOG.isDebugEnabled()) {
202 LOG.debug("Input: " + ArrayUtils.toString(obj));
203 }
204 Class aliasedClassCorrectCL = Class.forName(this.getAliasedClassName(), false, classLoader);
205 Object ob = TypeDefUtil.fillArray(obj, null, aliasedClassCorrectCL.getComponentType());
206 if (LOG.isDebugEnabled()) {
207 LOG.debug("Returned: " + ArrayUtils.toString(ob));
208 }
209 value.set(typeDefObject,ob);
210
211
212
213
214
215
216
217
218
219
220 } else {
221 value.set(typeDefObject, obj);
222 }
223 return typeDefObject;
224 }
225
226 @Override
227 public Object getAliasedObject(Object obj) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
228 Field value = obj.getClass().getField("value");
229 Object objValue = value.get(obj);
230 return objValue;
231 }
232
233 @Override
234 public String toString() {
235 return "SimpleTypeDef: " + super.toString();
236 }
237
238
239 }