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
8 import java.io.File;
9 import java.io.PrintWriter;
10 import java.io.StringWriter;
11 import java.lang.reflect.Field;
12 import java.lang.reflect.InvocationTargetException;
13 import java.lang.reflect.Method;
14
15 import javax.xml.bind.annotation.XmlAccessType;
16 import javax.xml.bind.annotation.XmlAccessorType;
17 import javax.xml.bind.annotation.XmlTransient;
18
19 import org.objectweb.asm.AnnotationVisitor;
20 import org.objectweb.asm.ClassReader;
21 import org.objectweb.asm.ClassVisitor;
22 import org.objectweb.asm.ClassWriter;
23 import org.objectweb.asm.FieldVisitor;
24 import org.objectweb.asm.Label;
25 import org.objectweb.asm.MethodVisitor;
26 import org.objectweb.asm.Opcodes;
27 import org.objectweb.asm.Type;
28 import org.objectweb.asm.util.CheckClassAdapter;
29 import org.objectweb.asm.util.TraceClassVisitor;
30 import org.omg.CORBA.Any;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 @SuppressWarnings("unchecked")
51 public class ComplexTypeDef extends TypeDef {
52
53 private static final String CLASS_EXTENSION = ".class";
54
55
56
57
58 private static final Logger LOG = LoggerFactory
59 .getLogger(ComplexTypeDef.class);
60
61 protected ComplexTypeDef(String className, String helperClassName, Class aliasedClass, String id) {
62 super(className, helperClassName, aliasedClass, id);
63 }
64
65
66
67
68
69
70 private void changeFinalAliasedClass(String classesDir) throws ClassGenerationException {
71 String filePath = aliasedClass.getName().replace('.', File.separatorChar).concat(CLASS_EXTENSION);
72
73
74 String absFilePath = classesDir + File.separator + filePath;
75
76 ClassWriter cw = new ClassWriter(true);
77 ClassVisitor cc = new CheckClassAdapter(cw);
78 StringWriter sw = new StringWriter();
79 ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
80 RemoveFinalAdapter rfa = new RemoveFinalAdapter(tv);
81
82 ClassReader cr = Util.getAsmCLassReader(absFilePath);
83 cr.accept(rfa, true);
84 byte [] newBytecode = cw.toByteArray();
85
86 LOG.debug("Class to change: " + absFilePath);
87 Util.saveAsJavaClass(absFilePath, newBytecode);
88 }
89
90 public void createTypeDefClass(String classesDir) throws ClassGenerationException {
91
92
93 changeFinalAliasedClass(classesDir);
94
95
96 String classInternalName = this.getClassName().replace('.','/');
97 String aliasedclassInternalName = Type.getInternalName(aliasedClass);
98
99
100 Class helperClass = this.getHelperClass(classesDir);
101 String helperDescriptor = Type.getDescriptor(helperClass);
102
103
104 String javaLangClassDescriptor = Type.getDescriptor(Class.class);
105 String xmlAccessorTypeDescriptor = Type.getDescriptor(XmlAccessorType.class);
106 String xmlAccessTypeDescriptor = Type.getDescriptor(XmlAccessType.class);
107 String xmlTransientDescriptor = Type.getDescriptor(XmlTransient.class);
108
109 ClassWriter cw = new ClassWriter(true);
110
111
112 cw.visit(Opcodes.V1_5, ACC_PUBLIC + ACC_SUPER, classInternalName ,null, aliasedclassInternalName, null);
113
114
115 AnnotationVisitor av = cw.visitAnnotation(xmlAccessorTypeDescriptor, true);
116
117 av.visitEnum("value", xmlAccessTypeDescriptor, "FIELD");
118 av.visitEnd();
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 MethodVisitor mvinit = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
151 mvinit.visitCode();
152 Label linit = new Label();
153 mvinit.visitLabel(linit);
154 mvinit.visitLineNumber(7, linit);
155 mvinit.visitVarInsn(ALOAD, 0);
156 mvinit.visitMethodInsn(INVOKESPECIAL, aliasedclassInternalName, "<init>", "()V");
157 mvinit.visitInsn(RETURN);
158 mvinit.visitMaxs(1, 1);
159 mvinit.visitEnd();
160
161 cw.visitEnd();
162 byte[] bytecode = cw.toByteArray();
163
164 String relativeClassName = getClassRelativeFileName();
165
166 if (LOG.isDebugEnabled()) {
167 LOG.debug("Writing out TypeDef class:" + classesDir + File.separatorChar + relativeClassName);
168 }
169
170 Util.saveAsJavaClass(classesDir, relativeClassName, bytecode);
171 }
172
173 public String toString() {
174 return "ComplexTypeDef: " + super.toString();
175 }
176
177 public boolean isWrapped() {
178 return false;
179 }
180
181 @Override
182 public Object getTypeDefObject(ClassLoader classLoader, Object obj) throws ClassNotFoundException,
183 InstantiationException, IllegalAccessException, SecurityException,
184 NoSuchFieldException {
185
186 Class classDefinition = classLoader.loadClass(getClassName());
187 Object typeDefObject = classDefinition.newInstance();
188 Field[] fields = obj.getClass().getFields();
189 for (int i = 0; i < fields.length; i++) {
190 fields[i].setAccessible(true);
191
192
193 fields[i].set(typeDefObject, fields[i].get(obj));
194 }
195 return typeDefObject;
196 }
197
198 @Override
199 public Object getAliasedObject(Object obj) throws SecurityException {
200
201 return obj;
202 }
203
204
205 }