KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > handlers > gen > ClassGenerator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.mdr.handlers.gen;
20
21 import org.netbeans.mdr.storagemodel.StorableClass;
22 import org.netbeans.mdr.storagemodel.StorableObject;
23 import org.netbeans.mdr.util.DebugException;
24 import org.netbeans.mdr.util.Logger;
25 import org.netbeans.mdr.util.MOFConstants;
26 import javax.jmi.model.*;
27 import java.io.DataOutputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.util.*;
30
31 /**
32  *
33  * @author Martin Matula, Dusan Balek
34  * @version
35  */

36 class ClassGenerator extends FeaturedGenerator {
37     private static final String JavaDoc M_CREATE_NAME = "Create"; //NOI18N
38
private static final String JavaDoc M_CREATE_DESC = "([Ljava/lang/Object;)"; //NOI18N
39
private static final String JavaDoc M_CREATE_TYPE = "Ljavax/jmi/reflect/RefObject;"; //NOI18N
40
private static final String JavaDoc M_STRUCT_NAME = "Struct"; //NOI18N
41
private static final String JavaDoc M_STRUCT_DESC = "(Ljava/lang/String;[Ljava/lang/Object;)"; //NOI18N
42
private static final String JavaDoc M_STRUCT_TYPE = "Ljavax/jmi/reflect/RefStruct;"; //NOI18N
43

44     private static final String JavaDoc M_CREATE_DISPATCH_NAME = "_createInstance"; //NOI18N
45

46     
47     ClassGenerator(String JavaDoc name, Class JavaDoc ifc, Class JavaDoc handler, StorableClass storable, Class JavaDoc custom) {
48         super(name, ifc, handler, storable, custom);
49         dispatchMethods.put("_createStruct", new HashMap()); //NOI18N
50
}
51     
52     protected String JavaDoc getConstructorDescriptor() {
53         return "(Lorg/netbeans/mdr/storagemodel/StorableClass;)V"; //NOI18N
54
}
55     
56     protected MethodInfo[] generateMethods() throws IOException JavaDoc {
57         try {
58             ArrayList methods = new ArrayList();
59             HashSet createdMethods = new HashSet();
60         methods.add(generateConstructor());
61             StorableObject meta = obj.getMetaObject();
62             for (Iterator it = ((List) meta.getReference(MOFConstants.SH_MODEL_NAMESPACE_CONTENTS)).iterator(); it.hasNext();) {
63                 StorableObject element = (StorableObject) it.next();
64                 String JavaDoc elementName = (String JavaDoc) element.getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
65                 String JavaDoc metaTypeName = (String JavaDoc) element.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
66                 if (metaTypeName.equals(MOFConstants.SH_MODEL_STRUCTURE_TYPE)) {
67                     ArrayList parameters = new ArrayList();
68                     for (Iterator itt = ((List) element.getReference(MOFConstants.SH_MODEL_NAMESPACE_CONTENTS)).iterator(); itt.hasNext();) {
69                         StorableObject field = (StorableObject) itt.next();
70                         String JavaDoc fieldTypeName = (String JavaDoc) field.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
71                         if (fieldTypeName.equals(MOFConstants.SH_MODEL_STRUCTURE_FIELD))
72                             parameters.add(getTypeName2(field));
73                     }
74                     methods.addAll(getCreateMethod("create" + firstUpper(TagSupport.getSubstName(element)), (String JavaDoc[])parameters.toArray(new String JavaDoc[parameters.size()]), TagSupport.getTypeFullName(element), M_STRUCT_NAME, M_STRUCT_DESC, M_STRUCT_TYPE, elementName)); //NOI18N
75
}
76             }
77             ArrayList allAttributes = new ArrayList();
78             for (Iterator it = new ContainsIterator(meta); it.hasNext();) {
79                 StorableObject element = (StorableObject) it.next();
80                 String JavaDoc elementName = (String JavaDoc) element.getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
81                 String JavaDoc metaTypeName = (String JavaDoc) element.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
82                 String JavaDoc substName = TagSupport.getSubstName(element, elementName, metaTypeName);
83                 if (metaTypeName.equals(MOFConstants.SH_MODEL_ATTRIBUTE)) {
84                     VisibilityKind visibility = (VisibilityKind) element.getAttribute(MOFConstants.SH_MODEL_GENERALIZABLE_ELEMENT_VISIBILITY);
85                     ScopeKind scope = (ScopeKind) element.getAttribute(MOFConstants.SH_MODEL_FEATURE_SCOPE);
86                     if (visibility.equals(VisibilityKindEnum.PUBLIC_VIS) && scope.equals(ScopeKindEnum.CLASSIFIER_LEVEL)) {
87                         String JavaDoc attrName = firstUpper(substName);
88                         String JavaDoc attrTypeName = TagSupport.getDataTypeName(getAttrType(element));
89                         MultiplicityType multiplicity = (MultiplicityType) element.getAttribute(MOFConstants.SH_MODEL_STRUCTURAL_FEATURE_MULTIPLICITY);
90                         if (multiplicity.getUpper() == 1) {
91                             String JavaDoc name;
92                             String JavaDoc setterName;
93                             if (attrTypeName.equals("java.lang.Boolean")) { //NOI18N
94
if (attrName.substring(0, 2).equals("Is")) name = firstLower(attrName); //NOI18N
95
else name = "is" + attrName; //NOI18N
96
setterName = "set" + name.substring(2); //NOI18N
97
} else {
98                                 name = "get" + attrName; //NOI18N
99
setterName = "set" + attrName; //NOI18N
100
}
101                             String JavaDoc getterType = attrTypeName;
102                             if (multiplicity.getLower() == 1)
103                                 getterType = getPrimitiveName(getterType);
104                             String JavaDoc sign = name + getMethodDescriptor(new String JavaDoc[0], getterType);
105                             if (!createdMethods.contains(sign)) {
106                                 methods.addAll(getFeatureMethod(name, new String JavaDoc[0], getterType, M_GET_NAME, M_GET_DESC, M_GET_TYPE, element, null, "_getAttribute")); //NOI18N
107
createdMethods.add(sign);
108                             }
109                             boolean changeable = ((Boolean JavaDoc) element.getAttribute(MOFConstants.SH_MODEL_STRUCTURAL_FEATURE_IS_CHANGEABLE)).booleanValue();
110                             if (changeable) {
111                                 sign = setterName + getMethodDescriptor(new String JavaDoc[] {getterType}, "void"); //NOI18N
112
if (!createdMethods.contains(sign)) {
113                                     methods.addAll(getFeatureMethod(setterName, new String JavaDoc[] {getterType}, "void", M_SET_NAME, M_SET_DESC, M_SET_TYPE, element, null, "_setAttribute")); //NOI18N
114
createdMethods.add(sign);
115                                 }
116                             }
117                         } else if (multiplicity.getUpper() != 0) {
118                             String JavaDoc sign = "get" + attrName + getMethodDescriptor(new String JavaDoc[0], (multiplicity.isOrdered() ? DT_ORDERED : DT_MULTIVALUED)); //NOI18N
119
if (!createdMethods.contains(sign)) {
120                                 methods.addAll(getFeatureMethod("get" + attrName, new String JavaDoc[0], (multiplicity.isOrdered() ? DT_ORDERED : DT_MULTIVALUED), M_GET_NAME, M_GET_DESC, M_GET_TYPE, element, null, "_getAttribute")); //NOI18N
121
createdMethods.add(sign);
122                             }
123                         }
124                     } else if (!((Boolean JavaDoc) element.getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_IS_DERIVED)).booleanValue())
125                         allAttributes.add(getAttrTypeName(element));
126                 } else if (metaTypeName.equals(MOFConstants.SH_MODEL_OPERATION)) {
127                     ScopeKind scope = (ScopeKind) element.getAttribute(MOFConstants.SH_MODEL_FEATURE_SCOPE);
128                     if (scope.equals(ScopeKindEnum.CLASSIFIER_LEVEL)) {
129                         Collection parameters = new ArrayList();
130                         String JavaDoc operType = "void"; //NOI18N
131
for (Iterator itt = ((List) element.getReference(MOFConstants.SH_MODEL_NAMESPACE_CONTENTS)).iterator(); itt.hasNext();) {
132                             StorableObject el = (StorableObject) itt.next();
133                             String JavaDoc mtName = (String JavaDoc) el.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
134                             if (mtName.equals(MOFConstants.SH_MODEL_PARAMETER)) {
135                                 DirectionKind direction = (DirectionKind) el.getAttribute(MOFConstants.SH_MODEL_PARAMETER_DIRECTION_KIND);
136                                 if (direction.equals(DirectionKindEnum.RETURN_DIR))
137                                     operType = getAttrTypeName(el);
138                                 else
139                                     parameters.add(getAttrTypeName(el) + (direction.equals(DirectionKindEnum.IN_DIR) ? "" : "[]")); //NOI18N
140
}
141                         }
142                         String JavaDoc[] prms = (String JavaDoc[])parameters.toArray(new String JavaDoc [parameters.size()]);
143                         String JavaDoc sign = substName + getMethodDescriptor(prms, operType);
144                         if (!createdMethods.contains(sign)) {
145                             MethodInfo mInfo = getOperationMethod(substName, prms, operType, elementName);
146                             if (mInfo != null) {
147                                 Collection exceptions = (Collection) element.getReference(MOFConstants.SH_MODEL_OPERATION_EXCEPTIONS);
148                                 short[] declaredExceptions = new short[exceptions.size()];
149                                 int i = 0;
150                                 for (Iterator itt = exceptions.iterator(); itt.hasNext(); i++)
151                                     declaredExceptions[i] = cp.getClass(dotToSlash(TagSupport.getTypeFullName((StorableObject)itt.next())));
152                                 mInfo.setDeclaredExceptions(declaredExceptions);
153                                 methods.add(mInfo);
154                             }
155                             createdMethods.add(sign);
156                         }
157                     }
158                 }
159             }
160             if (!((Boolean JavaDoc) meta.getAttribute(MOFConstants.SH_MODEL_GENERALIZABLE_ELEMENT_IS_ABSTRACT)).booleanValue()) {
161                 String JavaDoc createName = "create" + TagSupport.getSubstName(meta); //NOI18N
162
String JavaDoc createType = TagSupport.getTypeFullName(meta);
163                 methods.addAll(getDefaultCreateMethod(createName, new String JavaDoc[0], createType, M_CREATE_NAME, M_CREATE_DESC, M_CREATE_TYPE));
164                 String JavaDoc[] attribs = (String JavaDoc[])allAttributes.toArray(new String JavaDoc [allAttributes.size()]);
165                 if (allAttributes.size() > 0)
166                     methods.addAll(getCreateMethod(createName, attribs, createType, M_CREATE_NAME, M_CREATE_DESC, M_CREATE_TYPE, null));
167                 methods.add(getInstanceCreateDispatcher(createName, attribs, createType));
168             }
169             MethodInfo[] mtds = super.generateMethods();
170             methods.add(getDispatcherMethod("_createStruct", new String JavaDoc[] {"java.lang.String", "java.lang.Object[]"}, "javax.jmi.reflect.RefStruct", (HashMap) dispatchMethods.get("_createStruct"))); //NOI18N
171
for(int i = 0; i < mtds.length; i++)
172                 methods.add(mtds[i]);
173             return (MethodInfo[]) methods.toArray(new MethodInfo[methods.size()]);
174         }catch (Exception JavaDoc e) {
175             throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
176         }
177     }
178     
179     protected MethodInfo getInstanceCreateDispatcher(String JavaDoc name, String JavaDoc[] attrs, String JavaDoc type) throws IOException JavaDoc {
180         MethodInfo minfo = new MethodInfo(M_CREATE_DISPATCH_NAME, M_CREATE_DESC + M_CREATE_TYPE, ACC_PUBLIC | ACC_FINAL);
181         int localSlot0 = 1 + getWordsPerType("java.lang.Object[]"); //NOI18N
182
DataOutputStream JavaDoc out = new DataOutputStream JavaDoc(minfo.getCodeStream());
183         
184         out.writeByte(opc_aload_1);
185         out.writeByte(opc_ifnull);
186         out.writeShort(8);
187         
188         out.writeByte(opc_aload_1);
189         out.writeByte(opc_arraylength);
190         out.writeByte(opc_ifne);
191         out.writeShort(8);
192
193         out.writeByte(opc_aload_0);
194         out.writeByte(opc_invokevirtual);
195         out.writeShort(cp.getMethodRef(dotToSlash(className), name, getMethodDescriptor(new String JavaDoc[0], type)));
196         out.writeByte(opc_areturn);
197         
198         code_aload(1, out);
199         out.writeByte(opc_arraylength);
200         code_ipush(attrs.length, out);
201         out.writeByte(opc_if_icmpeq);
202         out.writeShort(12);
203         out.writeByte(opc_new);
204         out.writeShort(cp.getClass("javax/jmi/reflect/WrongSizeException")); //NOI18N
205
out.writeByte(opc_dup);
206         out.writeByte(opc_aconst_null);
207         out.writeByte(opc_invokespecial);
208         out.writeShort(cp.getMethodRef("javax/jmi/reflect/WrongSizeException", "<init>", "(Ljavax/jmi/reflect/RefObject;)V")); //NOI18N
209
out.writeByte(opc_athrow);
210
211         short tryStart = (short) out.size();
212         out.writeByte(opc_aload_0);
213         for (int i = 0; i < attrs.length; i++) {
214             out.writeByte(opc_aload_1);
215             code_ipush(i, out);
216             out.writeByte(opc_aaload);
217             codeUnwrapArgumentNull(attrs[i], out);
218         }
219         out.writeByte(opc_invokevirtual);
220         out.writeShort(cp.getMethodRef(dotToSlash(className), name, getMethodDescriptor(attrs, type)));
221         out.writeByte(opc_areturn);
222         short catchStart = (short) out.size();
223
224         code_astore(localSlot0, out);
225         out.writeByte(opc_new);
226         out.writeShort(cp.getClass("javax/jmi/reflect/TypeMismatchException")); //NOI18N
227
out.writeByte(opc_dup);
228         out.writeByte(opc_aconst_null);
229         out.writeByte(opc_dup);
230         out.writeByte(opc_dup);
231         code_aload(localSlot0, out);
232         out.writeByte(opc_invokevirtual);
233         out.writeShort(cp.getMethodRef("java/lang/Throwable", "getMessage", "()Ljava/lang/String;")); //NOI18N
234
out.writeByte(opc_invokespecial);
235         out.writeShort(cp.getMethodRef("javax/jmi/reflect/TypeMismatchException", "<init>", "(Ljava/lang/Class;Ljava/lang/Object;Ljavax/jmi/reflect/RefObject;Ljava/lang/String;)V")); //NOI18N
236
out.writeByte(opc_athrow);
237
238         minfo.getExceptionTable().add(new ExceptionTableEntry(tryStart, catchStart, catchStart, cp.getClass("java/lang/ClassCastException"))); //NOI18N
239

240         minfo.setMaxStack((short)(6 + attrs.length));
241         minfo.setMaxLocals((short) (localSlot0 + 2));
242         
243         return minfo;
244     }
245     
246     protected void codeUnwrapArgumentNull(String JavaDoc typeName, DataOutputStream JavaDoc out) throws IOException JavaDoc {
247         PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName);
248         if (prim != null) {
249             out.writeByte(opc_dup);
250             out.writeByte(opc_ifnull);
251             out.writeShort(12);
252             
253             out.writeByte(opc_checkcast);
254             out.writeShort(cp.getClass(prim.wrapperClassName));
255             
256             out.writeByte(opc_invokevirtual);
257             out.writeShort(cp.getMethodRef(
258             prim.wrapperClassName,
259             prim.unwrapMethodName, prim.unwrapMethodDesc));
260             out.writeByte(opc_goto);
261             out.writeShort(5);
262             out.writeByte(opc_pop);
263             if (typeName.equals("long")) { //NOI18N
264
out.writeByte(opc_lconst_0);
265             } else if (typeName.equals("double")) { //NOI18N
266
out.writeByte(opc_dconst_0);
267             } else if (typeName.equals("float")) { //NOI18N
268
out.writeByte(opc_fconst_0);
269             } else {
270                 out.writeByte(opc_iconst_0);
271             }
272         } else {
273             out.writeByte(opc_checkcast);
274             out.writeShort(cp.getClass(getParamType(typeName)));
275         }
276     }
277     
278     protected Collection getCreateMethod(String JavaDoc methodName, String JavaDoc[] parameterTypes, String JavaDoc returnType, String JavaDoc handlerName, String JavaDoc handlerDescriptor, String JavaDoc handlerType, String JavaDoc featureName) throws IOException JavaDoc {
279         
280         if (featureName != null) {
281             HashMap item = (HashMap) dispatchMethods.get("_createStruct"); //NOI18N
282
item.put(featureName, new MethodDescHolder(methodName, parameterTypes, returnType));
283         }
284
285         short delegateMethod = getHandlerIndex(handlerName, handlerDescriptor, handlerType);
286         short preMethod = getPreIndex(handlerName, handlerDescriptor);
287         short postMethod = getPostIndex(handlerName, handlerType);
288         String JavaDoc desc = getMethodDescriptor(parameterTypes, returnType);
289         boolean isCustom = customImplContainsMethod(customImpl, methodName, desc);
290         
291         int[] parameterSlot = new int[parameterTypes.length];
292         int nextSlot = 1;
293         for (int i = 0; i < parameterSlot.length; i++) {
294             parameterSlot[i] = nextSlot;
295             nextSlot += getWordsPerType(parameterTypes[i]);
296         }
297         int localSlot0 = nextSlot;
298         
299         short fail = (short) localSlot0;
300         short extraInfo = (short) (localSlot0 + 1);
301         short result = (short) (localSlot0 + 2);
302         short addr = (short) (localSlot0 + 3);
303         short exception = (short) (localSlot0 + 4);
304         
305         MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL);
306         DataOutputStream JavaDoc out = new DataOutputStream JavaDoc(minfo.getCodeStream());
307         MethodInfo cminfo = null;
308         DataOutputStream JavaDoc cout = null;
309         if (isCustom) {
310             cminfo = new MethodInfo(CUSTOM_PREFIX + methodName, desc, ACC_PUBLIC | ACC_FINAL);
311             cout = new DataOutputStream JavaDoc(cminfo.getCodeStream());
312         }
313         
314         // store "true" in the fail variable
315
out.writeByte(opc_iconst_1);
316         code_istore(fail, out);
317         // store "null" in the extraInfo variable
318
out.writeByte(opc_aconst_null);
319         out.writeByte(opc_dup);
320         code_astore(extraInfo, out);
321         // store "null" in result variable
322
code_astore(result, out);
323         
324         // I'll pass this instance as the first parameter
325
code_aload(0, out);
326         
327         if (featureName != null)
328             // feature name as the second parameter
329
code_ldc(cp.getString(featureName), out);
330         
331         // The rest of parameters we'll put into Object[] array
332
code_ipush(parameterTypes.length, out);
333         out.writeByte(opc_anewarray);
334         out.writeShort(cp.getClass("java/lang/Object")); //NOI18N
335

336         for (int i = 0; i < parameterTypes.length; i++) {
337             out.writeByte(opc_dup);
338             code_ipush(i, out);
339             codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
340             out.writeByte(opc_aastore);
341         }
342         
343         // start of the try block
344
short tryStart = (short) out.size();
345
346         // call the _pre method
347
out.writeByte(opc_invokespecial);
348         out.writeShort(preMethod);
349         
350         // store the returned object in a local variable
351
code_astore(extraInfo, out);
352         
353         if (isCustom) {
354             // I'll pass this instance as the first parameter
355
code_aload(0, out);
356
357             // The rest of parameters follows
358
for (int i = 0; i < parameterTypes.length; i++) {
359                 codeLoad(parameterSlot[i], parameterTypes[i], out);
360             }
361
362             // call the custom method
363
out.writeByte(opc_invokespecial);
364             out.writeShort(cp.getMethodRef(dotToSlash(superclassName), methodName, desc));
365
366             code_astore(result, out);
367
368             // I'll pass this instance as the first parameter
369
code_aload(0, cout);
370
371             if (featureName != null)
372                 // feature name as the second parameter
373
code_ldc(cp.getString(featureName), cout);
374
375             // The rest of parameters we'll put into Object[] array
376
code_ipush(parameterTypes.length, cout);
377             cout.writeByte(opc_anewarray);
378             cout.writeShort(cp.getClass("java/lang/Object")); //NOI18N
379

380             for (int i = 0; i < parameterTypes.length; i++) {
381                 cout.writeByte(opc_dup);
382                 code_ipush(i, cout);
383                 codeWrapArgument(parameterTypes[i], parameterSlot[i], cout);
384                 cout.writeByte(opc_aastore);
385             }
386
387             // call the delegate method
388
cout.writeByte(opc_invokespecial);
389             cout.writeShort(delegateMethod);
390
391             // convert returned object to the result type and return
392
cout.writeByte(opc_checkcast);
393             cout.writeShort(cp.getClass(dotToSlash(returnType)));
394             cout.writeByte(opc_areturn);
395         }
396         else {
397             // I'll pass this instance as the first parameter
398
code_aload(0, out);
399
400             if (featureName != null)
401                 // feature name as the second parameter
402
code_ldc(cp.getString(featureName), out);
403
404             // The rest of parameters we'll put into Object[] array
405
code_ipush(parameterTypes.length, out);
406             out.writeByte(opc_anewarray);
407             out.writeShort(cp.getClass("java/lang/Object")); //NOI18N
408

409             for (int i = 0; i < parameterTypes.length; i++) {
410                 out.writeByte(opc_dup);
411                 code_ipush(i, out);
412                 codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
413                 out.writeByte(opc_aastore);
414             }
415
416             // call the delegate method
417
out.writeByte(opc_invokespecial);
418             out.writeShort(delegateMethod);
419
420             // convert the returned value to the result type and store
421
out.writeByte(opc_checkcast);
422             out.writeShort(cp.getClass(dotToSlash(returnType)));
423             code_astore(result, out);
424         }
425
426         // change value of fail to "false"
427
out.writeByte(opc_iconst_0);
428         code_istore(fail, out);
429         
430         // call the finally block and return
431
out.writeByte(opc_jsr);
432         out.writeShort(3 + getBytesForLoadOrStore(result) + 1 + 2*getBytesForLoadOrStore(exception) + 4);
433
434         // load the returned value
435
code_aload(result, out);
436         // return
437
out.writeByte(opc_areturn);
438         
439         // start of catch block
440
short catchStart = (short) out.size();
441         
442         // store exception
443
code_astore(exception, out);
444         
445         // call finally
446
out.writeByte(opc_jsr);
447         out.writeShort(3 + getBytesForLoadOrStore(exception) + 1);
448         
449         // load exception
450
code_aload(exception, out);
451         
452         // rethrow exception
453
out.writeByte(opc_athrow);
454         
455         // start of finally block
456
// store the return address
457
code_astore(addr, out);
458         
459         // load parameters
460
code_aload(0, out);
461         code_aload(result, out);
462         code_aload(extraInfo, out);
463         code_iload(fail, out);
464         
465         // call the _post method
466
out.writeByte(opc_invokespecial);
467         out.writeShort(postMethod);
468         
469         // return from finally
470
out.writeByte(opc_ret);
471         out.writeByte(addr);
472         
473         minfo.getExceptionTable().add(new ExceptionTableEntry(tryStart, catchStart, catchStart, (short) 0));
474         
475         minfo.setMaxStack((short)15);
476         minfo.setMaxLocals((short) (localSlot0 + 5));
477         if (isCustom) {
478             cminfo.setMaxStack((short)15);
479             cminfo.setMaxLocals((short) (localSlot0 + 5));
480         }
481         
482         ArrayList ret = new ArrayList();
483         ret.add(minfo);
484         if (isCustom)
485             ret.add(cminfo);
486         return ret;
487     }
488     
489     protected Collection getDefaultCreateMethod(String JavaDoc methodName, String JavaDoc[] parameterTypes, String JavaDoc returnType, String JavaDoc handlerName, String JavaDoc handlerDescriptor, String JavaDoc handlerType) throws IOException JavaDoc {
490         short delegateMethod = getHandlerIndex(handlerName, handlerDescriptor, handlerType);
491         short preMethod = getPreIndex(handlerName, handlerDescriptor);
492         short postMethod = getPostIndex(handlerName, handlerType);
493         String JavaDoc desc = getMethodDescriptor(parameterTypes, returnType);
494         boolean isCustom = customImplContainsMethod(customImpl, methodName, desc);
495         
496         int localSlot0 = 1;
497
498         short fail = (short) localSlot0;
499         short extraInfo = (short) (localSlot0 + 1);
500         short result = (short) (localSlot0 + 2);
501         short addr = (short) (localSlot0 + 3);
502         short exception = (short) (localSlot0 + 4);
503         
504         MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL);
505         DataOutputStream JavaDoc out = new DataOutputStream JavaDoc(minfo.getCodeStream());
506         MethodInfo cminfo = null;
507         DataOutputStream JavaDoc cout = null;
508         if (isCustom) {
509             cminfo = new MethodInfo(CUSTOM_PREFIX + methodName, desc, ACC_PUBLIC | ACC_FINAL);
510             cout = new DataOutputStream JavaDoc(cminfo.getCodeStream());
511         }
512         
513         // store "true" in the fail variable
514
out.writeByte(opc_iconst_1);
515         code_istore(fail, out);
516         // store "null" in the extraInfo variable
517
out.writeByte(opc_aconst_null);
518         out.writeByte(opc_dup);
519         code_astore(extraInfo, out);
520         // store "null" in result variable
521
code_astore(result, out);
522
523         // I'll pass this instance as the first parameter
524
code_aload(0, out);
525         out.writeByte(opc_aconst_null);
526         
527         // call the _pre method
528
out.writeByte(opc_invokespecial);
529         out.writeShort(preMethod);
530         
531         // store the returned object in a local variable
532
code_astore(extraInfo, out);
533         
534         // start of the try block
535
short tryStart = (short) out.size();
536
537         if (isCustom) {
538             // I'll pass this instance as the first parameter
539
code_aload(0, out);
540
541             // call the custom method
542
out.writeByte(opc_invokespecial);
543             out.writeShort(cp.getMethodRef(dotToSlash(superclassName), methodName, desc));
544
545             code_astore(result, out);
546
547             // I'll pass this instance as the first parameter
548
code_aload(0, cout);
549
550             // null as the second parameter
551
cout.writeByte(opc_aconst_null);
552
553             // call the delegate method
554
cout.writeByte(opc_invokespecial);
555             cout.writeShort(delegateMethod);
556
557             // convert returned object to the result type and return
558
cout.writeByte(opc_checkcast);
559             cout.writeShort(cp.getClass(dotToSlash(returnType)));
560             cout.writeByte(opc_areturn);
561         }
562         else {
563             // I'll pass this instance as the first parameter
564
code_aload(0, out);
565
566             // null as the second parameter
567
out.writeByte(opc_aconst_null);
568
569             // call the delegate method
570
out.writeByte(opc_invokespecial);
571             out.writeShort(delegateMethod);
572
573             code_astore(result, out);
574         }
575         
576         // change value of fail to "false"
577
out.writeByte(opc_iconst_0);
578         code_istore(fail, out);
579         
580         // call the finally block and return
581
out.writeByte(opc_jsr);
582         
583         if (isCustom) {
584             out.writeShort(3 + getBytesForLoadOrStore(result) + 1 + 2*getBytesForLoadOrStore(exception) + 4);
585
586             // load the returned value
587
code_aload(result, out);
588
589             // return
590
out.writeByte(opc_areturn);
591         }
592         else {
593             out.writeShort(3 + getBytesForLoadOrStore(result) + 4 + 2*getBytesForLoadOrStore(exception) + 4);
594
595             // load the returned value
596
code_aload(result, out);
597
598             // convert it to the result type and return
599
out.writeByte(opc_checkcast);
600             out.writeShort(cp.getClass(dotToSlash(returnType)));
601             out.writeByte(opc_areturn);
602         }
603         // start of catch block
604
short catchStart = (short) out.size();
605         
606         // store exception
607
code_astore(exception, out);
608         
609         // call finally
610
out.writeByte(opc_jsr);
611         out.writeShort(3 + getBytesForLoadOrStore(exception) + 1);
612         
613         // load exception
614
code_aload(exception, out);
615         
616         // rethrow exception
617
out.writeByte(opc_athrow);
618         
619         // start of finally block
620
// store the return address
621
code_astore(addr, out);
622         
623         // load parameters
624
code_aload(0, out);
625         code_aload(result, out);
626         code_aload(extraInfo, out);
627         code_iload(fail, out);
628         
629         // call the _post method
630
out.writeByte(opc_invokespecial);
631         out.writeShort(postMethod);
632         
633         // return from finally
634
out.writeByte(opc_ret);
635         out.writeByte(addr);
636         
637         minfo.getExceptionTable().add(new ExceptionTableEntry(tryStart, catchStart, catchStart, (short) 0));
638         
639         minfo.setMaxStack((short)10);
640         minfo.setMaxLocals((short) (localSlot0 + 5));
641         if (isCustom) {
642             cminfo.setMaxStack((short)10);
643             cminfo.setMaxLocals((short) (localSlot0 + 5));
644         }
645         
646         ArrayList ret = new ArrayList();
647         ret.add(minfo);
648         if (isCustom)
649             ret.add(cminfo);
650         return ret;
651     }
652 }
653
Popular Tags