|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.mdr.handlers.gen;
import org.netbeans.lib.jmi.util.ClassFileGenerator;
import org.netbeans.mdr.storagemodel.*;
import org.netbeans.mdr.util.DebugException;
import org.netbeans.mdr.util.Logger;
import org.netbeans.mdr.util.MOFConstants;
import javax.jmi.model.MultiplicityType;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* Abstract base class for handler generators.
* @author Martin Matula, Dusan Balek
* @version 0.1
*/
public abstract class HandlerGenerator extends ClassFileGenerator {
/* -------------------------------------------------------------------- */
/* -- Private static constants ---------------------------------------- */
/* -------------------------------------------------------------------- */
private static final String PRE_TYPE = "Ljava/lang/Object;"; //NOI18N
private static final String POST_DESCRIPTOR = "Ljava/lang/Object;Z)V"; //NOI18N
private static final String POST_VOID_DESCRIPTOR = "(Ljava/lang/Object;Z)V"; //NOI18N
/* -------------------------------------------------------------------- */
/* -- Protected static constants ---------------------------------------- */
/* -------------------------------------------------------------------- */
protected static final String DT_MULTIVALUED = "java.util.Collection"; //NOI18N
protected static final String DT_ORDERED = "java.util.List"; //NOI18N
protected static final String PRE_PREFIX = "_pre"; //NOI18N
protected static final String POST_PREFIX = "_post"; //NOI18N
protected static final String HANDLE_PREFIX = "_handle"; //NOI18N
protected static final String CUSTOM_PREFIX = "super_"; //NOI18N
/* -------------------------------------------------------------------- */
/* -- Static methods (public) ----------------------------------------- */
/* -------------------------------------------------------------------- */
/**
* Generate a handler class given a name, interface and storable object to
* be wrapped by a handler object.
*/
public static byte[] generateHandler(final String name, Class ifc, StorableBaseObject storable) {
HandlerGenerator gen;
try {
if (storable instanceof StorableAssociation) {
gen = new AssociationGenerator(name, ifc, ((StorableAssociation)storable).getAssociationSuperclass(), (StorableAssociation)storable, ((StorableAssociation)storable).getAssociationCustomImpl());
} else if (storable instanceof StorableClass) {
gen = new ClassGenerator(name, ifc, ((StorableClass) storable).getClassSuperclass(), (StorableClass)storable, ((StorableClass) storable).getClassCustomImpl());
} else if (storable instanceof StorablePackage) {
gen = new PackageGenerator(name, ifc, ((StorablePackage) storable).getPackageSuperclass(), (StorablePackage)storable, ((StorablePackage) storable).getPackageCustomImpl());
} else if (storable instanceof StorableObject) {
gen = new InstanceGenerator(name, ifc, ((StorableObject) storable).getClassProxy().getInstanceSuperclass(), (StorableObject)storable, ((StorableObject) storable).getClassProxy().getInstanceCustomImpl());
} else {
throw new InternalError("Unknow dispatcher type."); //NOI18N
}
} catch (Exception e) {
throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
gen.generateClassFile(bout);
return bout.toByteArray();
}
public static boolean customImplContainsMethod(Class customImpl, String name, String descriptor) {
if (customImpl == null)
return false;
synchronized (customImplInfos) {
HashSet methods = (HashSet)customImplInfos.get(customImpl);
if (methods == null) {
methods = new HashSet();
Method[] m = customImpl.getMethods();
for (int i = 0; i < m.length; i++) {
if (Modifier.isAbstract(m[i].getModifiers()))
continue;
ArrayList params = new ArrayList();
Class[] p = m[i].getParameterTypes();
for(int j = 0; j < p.length; j++)
params.add(p[j].getName());
methods.add(m[i].getName() + getMethodDescriptor((String [])params.toArray(new String[params.size()]), m[i].getReturnType().getName()));
}
customImplInfos.put(customImpl, methods);
}
return methods.contains(name + descriptor);
}
}
/* -------------------------------------------------------------------- */
/* -- Static attributes ----------------------------------------------- */
/* -------------------------------------------------------------------- */
private static Map customImplInfos = new LinkedHashMap(10, .5f, true) {
private static final int MAX_SIZE = 5;
protected boolean removeEldestEntry(Map.Entry entry) {
return size() > MAX_SIZE;
}
};
/* -------------------------------------------------------------------- */
/* -- Attributes ------------------------------------------------------ */
/* -------------------------------------------------------------------- */
protected final StorableBaseObject obj;
protected final Class customImpl;
protected final HashMap dispatchMethods = new HashMap();
/* -------------------------------------------------------------------- */
/* -- Constructor ----------------------------------------------------- */
/* -------------------------------------------------------------------- */
/**
* Construct a HandlerGenerator to generate a handler class with the
* specified name and for the given interfaces.
*/
protected HandlerGenerator(String className, Class ifc, Class handler, StorableBaseObject storable, Class custom) {
super(className, new String[] {ifc.getName()}, handler.getName(), ACC_PUBLIC | ACC_FINAL | ACC_SUPER);
obj = storable;
customImpl = custom;
}
protected FieldInfo[] generateFields() throws IOException {
return new FieldInfo[0];
}
/**
* Generate the constructor method for the proxy class.
*/
protected MethodInfo generateConstructor() throws IOException {
MethodInfo minfo = new MethodInfo(
"", getConstructorDescriptor(), //NOI18N
ACC_PUBLIC);
DataOutputStream out = new DataOutputStream(minfo.getCodeStream());
code_aload(0, out);
code_aload(1, out);
// just call super.(String);
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef(dotToSlash(superclassName), "", getConstructorDescriptor())); //NOI18N
out.writeByte(opc_return);
minfo.setMaxStack((short)2);
minfo.setMaxLocals((short)2);
return minfo;
}
protected abstract String getConstructorDescriptor();
protected short getHandlerIndex(String methodName, String methodDescriptor, String methodType) {
return cp.getMethodRef(dotToSlash(superclassName), HANDLE_PREFIX + methodName, methodDescriptor + methodType);
}
protected short getPreIndex(String methodName, String methodDescriptor) {
return cp.getMethodRef(dotToSlash(superclassName), PRE_PREFIX + methodName, methodDescriptor + PRE_TYPE);
}
protected short getPostIndex(String methodName, String methodType) {
return cp.getMethodRef(dotToSlash(superclassName), POST_PREFIX + methodName, (methodType.equals("V") ? POST_VOID_DESCRIPTOR : ("(" + methodType + POST_DESCRIPTOR))); //NOI18N
}
protected Collection getHandlerMethod(String methodName, String[] parameterTypes, String returnType, String handlerName, String handlerDescriptor, String handlerType, String featureName) throws IOException {
short delegateMethod = getHandlerIndex(handlerName, handlerDescriptor, handlerType);
short preMethod = getPreIndex(handlerName, handlerDescriptor);
short postMethod = getPostIndex(handlerName, handlerType);
String methodDescriptor = getMethodDescriptor(parameterTypes, returnType);
boolean isCustom = customImplContainsMethod(customImpl, methodName, methodDescriptor);
int[] parameterSlot = new int[parameterTypes.length];
int nextSlot = 1;
for (int i = 0; i < parameterSlot.length; i++) {
parameterSlot[i] = nextSlot;
nextSlot += getWordsPerType(parameterTypes[i]);
}
int localSlot0 = nextSlot;
short fail = (short) localSlot0;
short extraInfo = (short) (localSlot0 + 1);
short result = (short) (localSlot0 + 2);
short addr = (short) (localSlot0 + 3);
short exception = (short) (localSlot0 + 4);
short customResult = (short) (localSlot0 + 5);
MethodInfo minfo = new MethodInfo(methodName, methodDescriptor, ACC_PUBLIC | ACC_FINAL);
DataOutputStream out = new DataOutputStream(minfo.getCodeStream());
MethodInfo cminfo = null;
DataOutputStream cout = null;
if (isCustom) {
cminfo = new MethodInfo(CUSTOM_PREFIX + methodName, methodDescriptor, ACC_PUBLIC | ACC_FINAL);
cout = new DataOutputStream(cminfo.getCodeStream());
}
// store "true" in the fail variable
out.writeByte(opc_iconst_1);
code_istore(fail, out);
// store "null" in the extraInfo variable
out.writeByte(opc_aconst_null);
out.writeByte(opc_dup);
code_astore(extraInfo, out);
// store "null" in result variable
code_astore(result, out);
// I'll pass this instance as the first parameter
code_aload(0, out);
if (featureName != null)
// feature name as the second parameter
code_ldc(cp.getString(featureName), out);
// The rest of parameters follows
for (int i = 0; i < parameterTypes.length; i++) {
codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
}
// call the _pre method
out.writeByte(opc_invokespecial);
out.writeShort(preMethod);
// start of the try block
short tryStart = (short) out.size();
// store the returned object in a local variable
code_astore(extraInfo, out);
if (isCustom) {
// I'll pass this instance as the first parameter
code_aload(0, out);
// The rest of parameters follows
for (int i = 0; i < parameterTypes.length; i++) {
codeLoad(parameterSlot[i], parameterTypes[i], out);
}
// call the custom method
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef(dotToSlash(superclassName), methodName, methodDescriptor));
if (!returnType.equals("void")) { //NOI18N
if (PrimitiveTypeInfo.get(returnType) == null)
code_astore(result, out);
else {
codeStore(customResult, returnType, out);
codeWrapArgument(returnType, customResult, out);
code_astore(result, out);
}
}
// I'll pass this instance as the first parameter
code_aload(0, cout);
if (featureName != null)
// feature name as the second parameter
code_ldc(cp.getString(featureName), cout);
// The rest of parameters follows
for (int i = 0; i < parameterTypes.length; i++) {
codeWrapArgument(parameterTypes[i], parameterSlot[i], cout);
}
// call the delegate method
cout.writeByte(opc_invokespecial);
cout.writeShort(delegateMethod);
if (returnType.equals("void")) //NOI18N
cout.writeByte(opc_return);
else
codeUnwrapReturnValue(returnType, cout);
}
else {
// I'll pass this instance as the first parameter
code_aload(0, out);
if (featureName != null)
// feature name as the second parameter
code_ldc(cp.getString(featureName), out);
// The rest of parameters follows
for (int i = 0; i < parameterTypes.length; i++) {
codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
}
// call the delegate method
out.writeByte(opc_invokespecial);
out.writeShort(delegateMethod);
if (!returnType.equals("void")) { //NOI18N
code_astore(result, out);
}
}
// change value of fail to "false"
out.writeByte(opc_iconst_0);
code_istore(fail, out);
// call the finally block and return
out.writeByte(opc_jsr);
if (returnType.equals("void")) { //NOI18N
out.writeShort(3 + 1 + 2*getBytesForLoadOrStore(exception) + 4);
out.writeByte(opc_return);
} else {
if (isCustom) {
if (PrimitiveTypeInfo.get(returnType) != null) {
out.writeShort(3 + getBytesForLoadOrStore(customResult) + 1 + 2*getBytesForLoadOrStore(exception) + 4);
codeLoad(customResult, returnType, out);
if (returnType.equals("int") || returnType.equals("boolean") || returnType.equals("byte") || returnType.equals("char") || returnType.equals("short")) //NOI18N
out.writeByte(opc_ireturn);
else if (returnType.equals("long")) //NOI18N
out.writeByte(opc_lreturn);
else if (returnType.equals("float")) //NOI18N
out.writeByte(opc_freturn);
else if (returnType.equals("double")) //NOI18N
out.writeByte(opc_dreturn);
else
_assert(false);
} else {
out.writeShort(3 + getBytesForLoadOrStore(result) + 1 + 2*getBytesForLoadOrStore(exception) + 4);
code_aload(result, out);
out.writeByte(opc_areturn);
}
}
else {
out.writeShort(3 + getBytesForLoadOrStore(result) + getBytesForUnwrapReturn(returnType) + 2*getBytesForLoadOrStore(exception) + 4);
// load the returned value
code_aload(result, out);
// convert it to the result type
codeUnwrapReturnValue(returnType, out);
}
}
// start of catch block
short catchStart = (short) out.size();
// store exception
code_astore(exception, out);
// call finally
out.writeByte(opc_jsr);
out.writeShort(3 + getBytesForLoadOrStore(exception) + 1);
// load exception
code_aload(exception, out);
// rethrow exception
out.writeByte(opc_athrow);
// start of finally block
// store the return address
code_astore(addr, out);
// load parameters
code_aload(0, out);
if (!returnType.equals("void")) { //NOI18N
code_aload(result, out);
}
code_aload(extraInfo, out);
code_iload(fail, out);
// call the _post method
out.writeByte(opc_invokespecial);
out.writeShort(postMethod);
// return from finally
out.writeByte(opc_ret);
out.writeByte(addr);
minfo.getExceptionTable().add(new ExceptionTableEntry(tryStart, catchStart, catchStart, (short) 0));
minfo.setMaxStack((short)15);
minfo.setMaxLocals((short)(localSlot0 + 6));
if (isCustom) {
cminfo.setMaxStack((short)15);
cminfo.setMaxLocals((short)(localSlot0 + 5));
}
ArrayList ret = new ArrayList();
ret.add(minfo);
if (isCustom)
ret.add(cminfo);
return ret;
}
protected MethodInfo getDerivedMethod(String methodName, String[] parameterTypes, String returnType) throws IOException {
String desc = getMethodDescriptor(parameterTypes, returnType);
MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL);
int[] parameterSlot = new int[parameterTypes.length];
int nextSlot = 1;
for (int i = 0; i < parameterSlot.length; i++) {
parameterSlot[i] = nextSlot;
nextSlot += getWordsPerType(parameterTypes[i]);
}
int localSlot0 = nextSlot;
DataOutputStream out = new DataOutputStream(minfo.getCodeStream());
// I'll pass this instance as the first parameter
code_aload(0, out);
// Load the rest of parameters
for (int i = 0; i < parameterTypes.length; i++) {
codeLoad(parameterSlot[i], parameterTypes[i], out);
}
// call the delegate method
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef(dotToSlash(superclassName), methodName, desc));
if (returnType.equals("void")) //NOI18N
out.writeByte(opc_return);
else if (PrimitiveTypeInfo.get(returnType) != null) {
if (returnType.equals("int") || returnType.equals("boolean") || returnType.equals("byte") || returnType.equals("char") || returnType.equals("short")) //NOI18N
out.writeByte(opc_ireturn);
else if (returnType.equals("long")) //NOI18N
out.writeByte(opc_lreturn);
else if (returnType.equals("float")) //NOI18N
out.writeByte(opc_freturn);
else if (returnType.equals("double")) //NOI18N
out.writeByte(opc_dreturn);
else
_assert(false);
} else
out.writeByte(opc_areturn);
minfo.setMaxStack((short)10);
minfo.setMaxLocals((short)(localSlot0 + 2));
return minfo;
}
protected void codeStore(int index, String type, DataOutputStream out) throws IOException {
if (type.equals("int") || type.equals("boolean") || type.equals("byte") || type.equals("char") || type.equals("short")) //NOI18N
code_istore(index, out);
else if (type.equals("long")) //NOI18N
code_lstore(index, out);
else if (type.equals("float")) //NOI18N
code_fstore(index, out);
else if (type.equals("double")) //NOI18N
code_dstore(index, out);
else
code_astore(index, out);
}
protected void codeLoad(int index, String type, DataOutputStream out) throws IOException {
if (type.equals("int") || type.equals("boolean") || type.equals("byte") || type.equals("char") || type.equals("short")) //NOI18N
code_iload(index, out);
else if (type.equals("long")) //NOI18N
code_lload(index, out);
else if (type.equals("float")) //NOI18N
code_fload(index, out);
else if (type.equals("double")) //NOI18N
code_dload(index, out);
else
code_aload(index, out);
}
protected int getBytesForLoadOrStore(int idx) {
if (idx <= 3)
return 1;
if (idx <= 0xFF)
return 2;
return 4;
}
protected void codeWrapArgument(String typeName, int slot, DataOutputStream out) throws IOException {
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName);
if (prim != null) {
out.writeByte(opc_new);
out.writeShort(cp.getClass(prim.wrapperClassName));
out.writeByte(opc_dup);
if (typeName.equals("int") || typeName.equals("boolean") || typeName.equals("byte") || typeName.equals("char") || typeName.equals("short")) { //NOI18N
code_iload(slot, out);
} else if (typeName.equals("long")) { //NOI18N
code_lload(slot, out);
} else if (typeName.equals("float")) { //NOI18N
code_fload(slot, out);
} else if (typeName.equals("double")) { //NOI18N
code_dload(slot, out);
} else {
_assert(false);
}
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef(prim.wrapperClassName, "", prim.wrapperConstructorDesc)); //NOI18N
} else {
code_aload(slot, out);
}
}
protected void codeUnwrapReturnValue(String typeName, DataOutputStream out) throws IOException {
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName);
if (prim != null) {
out.writeByte(opc_dup);
out.writeByte(opc_ifnull);
out.writeShort(10);
out.writeByte(opc_checkcast);
out.writeShort(cp.getClass(prim.wrapperClassName));
out.writeByte(opc_invokevirtual);
out.writeShort(cp.getMethodRef(prim.wrapperClassName, prim.unwrapMethodName, prim.unwrapMethodDesc));
if (typeName.equals("int") || typeName.equals("boolean") || typeName.equals("byte") || typeName.equals("char") || typeName.equals("short")) { //NOI18N
out.writeByte(opc_ireturn);
out.writeByte(opc_iconst_0);
out.writeByte(opc_ireturn);
} else if (typeName.equals("long")) { //NOI18N
out.writeByte(opc_lreturn);
out.writeByte(opc_lconst_0);
out.writeByte(opc_lreturn);
} else if (typeName.equals("float")) { //NOI18N
out.writeByte(opc_freturn);
out.writeByte(opc_fconst_0);
out.writeByte(opc_freturn);
} else if (typeName.equals("double")) { //NOI18N
out.writeByte(opc_dreturn);
out.writeByte(opc_dconst_0);
out.writeByte(opc_dreturn);
} else {
_assert(false);
}
} else {
out.writeByte(opc_checkcast);
out.writeShort(cp.getClass(dotToSlash(typeName)));
out.writeByte(opc_areturn);
}
}
protected int getBytesForUnwrapReturn(String typeName) {
if (PrimitiveTypeInfo.get(typeName) != null) {
return 13;
} else {
return 4;
}
}
protected StorableObject getAttrType(StorableObject attr) {
try {
StorableObject curType = (StorableObject) attr.getReference(MOFConstants.SH_MODEL_TYPED_ELEMENT_TYPE);
String typeName = (String) curType.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
if (typeName.equals(MOFConstants.SH_MODEL_ALIAS_TYPE))
curType = getAttrType(curType);
return curType;
} catch (Exception e) {
throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
}
}
// returns correct type name for attribute (depending on the multiplicity type)
protected String getAttrTypeName(StorableObject attr) {
try {
MultiplicityType mp = (MultiplicityType) attr.getAttribute(MOFConstants.SH_MODEL_STRUCTURAL_FEATURE_MULTIPLICITY);
if (mp.getUpper() > 1 || mp.getUpper() == -1) {
return (mp.isOrdered() ? DT_ORDERED : DT_MULTIVALUED);
} else if (mp.getLower() < 1) {
return TagSupport.getDataTypeName(getAttrType(attr));
} else {
return getTypeName2(attr);
}
} catch (Exception e) {
throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
}
}
protected String getTypeName2(StorableObject te) {
return getPrimitiveName(TagSupport.getDataTypeName(getAttrType(te)));
}
// converts object type name to primitive type name
protected String getPrimitiveName(String typeName) {
String name = (String) objectToPrimitive.get(typeName);
return name == null ? typeName : name;
}
// conversion table between object type names and primitive type names
protected static final HashMap objectToPrimitive = new HashMap(7);
static {
objectToPrimitive.put("java.lang.Short", "short"); //NOI18N
objectToPrimitive.put("java.lang.Integer", "int"); //NOI18N
objectToPrimitive.put("java.lang.Float", "float"); //NOI18N
objectToPrimitive.put("java.lang.Double", "double"); //NOI18N
objectToPrimitive.put("java.lang.Boolean", "boolean"); //NOI18N
objectToPrimitive.put("java.lang.Character", "char"); //NOI18N
objectToPrimitive.put("java.lang.Long", "long"); //NOI18N
}
protected MethodInfo getDispatcherMethod(String methodName, String[] parameterTypes, String returnType, HashMap features) throws IOException {
String desc = getMethodDescriptor(parameterTypes, returnType);
MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL);
int[] parameterSlot = new int[parameterTypes.length];
int nextSlot = 1;
for (int i = 0; i < parameterSlot.length; i++) {
parameterSlot[i] = nextSlot;
nextSlot += getWordsPerType(parameterTypes[i]);
}
int localSlot0 = nextSlot;
int maxStack = 0;
DataOutputStream out = new DataOutputStream(minfo.getCodeStream());
for (Iterator it = features.keySet().iterator(); it.hasNext();) {
String featureName = (String) it.next();
MethodDescHolder item = (MethodDescHolder) features.get(featureName);
// load name of feature
code_ldc(cp.getString(featureName), out);
//compare it with passed name
code_aload(1, out);
out.writeByte(opc_invokevirtual);
out.writeShort(cp.getMethodRef("java/lang/String", "equals", "(Ljava/lang/Object;)Z")); //NOI18N
// if it is not equal, continue processing
out.writeByte(opc_ifeq);
out.writeShort(7 + getBytesForArgUnwrap(methodName, item.getParameterTypes()) + getBytesForReturn(methodName, item.getReturnType()) + getBytesForPreReturn(item.getReturnType()));
// if it is equal, return result of a proper method
codePreReturn(item.getReturnType(), out);
out.writeByte(opc_aload_0);
codeUnwrapArguments(methodName, item.getParameterTypes(), out);
out.writeByte(opc_invokevirtual);
out.writeShort(cp.getMethodRef(dotToSlash(className), item.getName(), getMethodDescriptor(item.getParameterTypes(), item.getReturnType())));
codeReturn(methodName, item.getReturnType(), out);
if (item.getParameterTypes().length > maxStack)
maxStack = item.getParameterTypes().length;
}
short tryStop = (short) out.size();
// if the field was not found, throw an exception
out.writeByte(opc_new); // new
out.writeShort(cp.getClass("javax/jmi/reflect/InvalidNameException")); //NOI18N
out.writeByte(opc_dup); // dup
code_aload(1, out);
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef("javax/jmi/reflect/InvalidNameException", "", "(Ljava/lang/String;)V")); //NOI18N
out.writeByte(opc_athrow);
if (tryStop != 0) {
short catchStart = (short) out.size();
code_astore(localSlot0, out);
out.writeByte(opc_new);
out.writeShort(cp.getClass("javax/jmi/reflect/TypeMismatchException")); //NOI18N
out.writeByte(opc_dup);
out.writeByte(opc_aconst_null);
out.writeByte(opc_dup);
out.writeByte(opc_dup);
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef("javax/jmi/reflect/TypeMismatchException", "", "(Ljava/lang/Class;Ljava/lang/Object;Ljavax/jmi/reflect/RefObject;)V")); //NOI18N
out.writeByte(opc_athrow);
minfo.getExceptionTable().add(new ExceptionTableEntry((short)0, tryStop, catchStart, cp.getClass("java/lang/ClassCastException"))); //NOI18N
}
minfo.setMaxStack((short)(maxStack + 6));
minfo.setMaxLocals((short) (localSlot0 + 2));
return minfo;
}
protected void codeUnwrapArguments(String methodName, String[] paramTypeNames, DataOutputStream out) throws IOException {
if (methodName.equals("_invokeOperation") || methodName.equals("_createStruct")) { //NOI18N
code_aload(2, out);
out.writeByte(opc_arraylength);
code_ipush(paramTypeNames.length, out);
out.writeByte(opc_if_icmpeq);
out.writeShort(12);
out.writeByte(opc_new);
out.writeShort(cp.getClass("javax/jmi/reflect/WrongSizeException")); //NOI18N
out.writeByte(opc_dup);
out.writeByte(opc_aconst_null);
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef("javax/jmi/reflect/WrongSizeException", "", "(Ljavax/jmi/reflect/RefObject;)V")); //NOI18N
out.writeByte(opc_athrow);
for (int i = 0; i < paramTypeNames.length; i++) {
code_aload(2, out);
out.writeByte(opc_sipush);
out.writeShort(i & 0xFFFF);
out.writeByte(opc_aaload);
codeUnwrapArgument(paramTypeNames[i], out);
}
} else {
for (int i = 0; i < paramTypeNames.length; i++) {
out.writeByte(opc_aload);
out.writeByte(i + 2);
codeUnwrapArgument(paramTypeNames[i], out);
}
}
}
protected void codeUnwrapArgument(String typeName, DataOutputStream out) throws IOException {
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName);
if (prim != null) {
out.writeByte(opc_checkcast);
out.writeShort(cp.getClass(prim.wrapperClassName));
out.writeByte(opc_invokevirtual);
out.writeShort(cp.getMethodRef(
prim.wrapperClassName,
prim.unwrapMethodName, prim.unwrapMethodDesc));
} else {
out.writeByte(opc_checkcast);
out.writeShort(cp.getClass(getParamType(typeName)));
}
}
protected static String getParamType(String typeName) {
if (typeName.endsWith("[]")) //NOI18N
return "[" + getFieldType(typeName.substring(0, typeName.length()-2).trim()); //NOI18N
else
return dotToSlash(typeName);
}
protected int getBytesForArgUnwrap(String methodName, String[] parameterTypeNames) {
int result = 0;
if (methodName.equals("_invokeOperation") || methodName.equals("_createStruct")) { //NOI18N
result += 14 + getBytesForIPush(parameterTypeNames.length);
for (int i = 0; i < parameterTypeNames.length; i++) {
result += 5;
result += getBytesForOneArgUnwrap(parameterTypeNames[i]);
}
} else {
for (int i = 0; i < parameterTypeNames.length; i++) {
result += 2;
result += getBytesForOneArgUnwrap(parameterTypeNames[i]);
}
}
return result;
}
protected int getBytesForOneArgUnwrap(String typeName) {
if (PrimitiveTypeInfo.get(typeName) != null)
return 6;
else
return 3;
}
protected int getBytesForIPush(int value) {
if (value >= -1 && value <= 5)
return 1;
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
return 2;
return 3;
}
protected int getBytesForReturn(String methodName, String typeName) {
if (typeName.equals("void")) //NOI18N
return (methodName.equals("_invokeOperation") ? 2 : 1); //NOI18N
else if (PrimitiveTypeInfo.get(typeName) != null)
return 4;
else
return 1;
}
protected int getBytesForPreReturn(String typeName) {
if ((!typeName.equals("void")) && (PrimitiveTypeInfo.get(typeName) != null)) //NOI18N
return 4;
else
return 0;
}
protected void codePreReturn(String typeName, DataOutputStream out) throws IOException {
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName);
if ((!typeName.equals("void")) && (prim != null)) { //NOI18N
out.writeByte(opc_new);
out.writeShort(cp.getClass(prim.wrapperClassName));
out.writeByte(opc_dup);
}
}
protected void codeReturn(String methodName, String typeName, DataOutputStream out) throws IOException {
if (typeName.equals("void")) { //NOI18N
if (methodName.equals("_invokeOperation")) { //NOI18N
out.writeByte(opc_aconst_null);
out.writeByte(opc_areturn);
} else {
out.writeByte(opc_return);
}
} else {
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(typeName);
if (prim != null) {
out.writeByte(opc_invokespecial);
out.writeShort(cp.getMethodRef(prim.wrapperClassName, "", prim.wrapperConstructorDesc)); //NOI18N
}
out.writeByte(opc_areturn);
}
}
protected class MethodDescHolder {
private String name;
private String[] params;
private String ret;
public MethodDescHolder(String methodName, String []parameterTypes, String returnType) {
name = methodName;
params = parameterTypes;
ret = returnType;
}
public String getName() {
return name;
}
public String[] getParameterTypes() {
return params;
}
public String getReturnType() {
return ret;
}
}
}
|