alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

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.mdr.persistence.StorageException;
import org.netbeans.mdr.storagemodel.StorableFeatured;
import org.netbeans.mdr.storagemodel.StorableObject;
import org.netbeans.mdr.util.DebugException;
import org.netbeans.mdr.util.Logger;
import org.netbeans.mdr.util.MOFConstants;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;

/**
 *
 * @author Martin Matula, Dusan Balek
 * @version 
 */
abstract class FeaturedGenerator extends HandlerGenerator {
    
    protected static final String M_GET_NAME = "Get"; //NOI18N
    protected static final String M_GET_DESC = "(Ljava/lang/String;)"; //NOI18N
    protected static final String M_GET_TYPE = "Ljava/lang/Object;"; //NOI18N
    protected static final String M_SET_NAME = "Set"; //NOI18N
    protected static final String M_SET_DESC = "(Ljava/lang/String;Ljava/lang/Object;)"; //NOI18N
    protected static final String M_SET_TYPE = "V"; //NOI18N

    FeaturedGenerator(String name, Class ifc, Class handler, StorableFeatured storable, Class custom) {
        super(name, ifc, handler, storable, custom);
        dispatchMethods.put("_invokeOperation", new HashMap()); //NOI18N
        dispatchMethods.put("_setAttribute", new HashMap()); //NOI18N
        dispatchMethods.put("_getAttribute", new HashMap()); //NOI18N
    }
    
    protected MethodInfo[] generateMethods() throws IOException {
        try {
            ArrayList methods = new ArrayList();
            methods.add(getDispatcherMethod("_invokeOperation", new String[] {"java.lang.String", "java.lang.Object[]"}, "java.lang.Object", (HashMap) dispatchMethods.get("_invokeOperation"))); //NOI18N
            methods.add(getDispatcherMethod("_setAttribute", new String[] {"java.lang.String", "java.lang.Object"}, "void", (HashMap) dispatchMethods.get("_setAttribute"))); //NOI18N
            methods.add(getDispatcherMethod("_getAttribute", new String[] {"java.lang.String"}, "java.lang.Object", (HashMap) dispatchMethods.get("_getAttribute"))); //NOI18N
            return (MethodInfo[]) methods.toArray(new MethodInfo[methods.size()]);
        } catch (Exception e) {
            throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
        }
    }
    
    protected Collection getFeatureMethod(String methodName, String[] parameterTypes, String returnType, String handlerName, String handlerDescriptor, String handlerType, StorableObject feature, StorableFeatured parent, String dispatcher) throws IOException, StorageException {
        String name = (String) feature.getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
        if (dispatcher != null) {
            HashMap item = (HashMap) dispatchMethods.get(dispatcher);
            item.put(name, new MethodDescHolder(methodName, parameterTypes, returnType));
        }
        if (((Boolean) feature.getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_IS_DERIVED)).booleanValue()) {
            ArrayList ret = new ArrayList();
            ret.add(getDerivedMethod(methodName, parameterTypes, returnType));
            return ret;
        }
        else if (parent == null)
            return getHandlerMethod(methodName, parameterTypes, returnType, handlerName, handlerDescriptor, handlerType, name);
        else
            return getAttributeMethod(methodName, parameterTypes, returnType, handlerName, handlerDescriptor, handlerType, name, parent.getClassProxy().getAttrIndex(name));
    }
    
    protected Collection getAttributeMethod(String methodName, String[] parameterTypes, String returnType, String handlerName, String handlerDescriptor, String handlerType, String featureName, int attrIndex) throws IOException {
        short delegateMethod = getHandlerIndex(handlerName, "(I" + handlerDescriptor.substring("(Ljava/lang/String;".length()), handlerType); //NOI18N
        short preMethod = getPreIndex(handlerName, handlerDescriptor);
        short postMethod = getPostIndex(handlerName, handlerType);
        String desc = getMethodDescriptor(parameterTypes, returnType);
        boolean isCustom = customImplContainsMethod(customImpl, methodName, desc);

        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, desc, ACC_PUBLIC | ACC_FINAL);
        DataOutputStream out = new DataOutputStream(minfo.getCodeStream());
        MethodInfo cminfo = null;
        DataOutputStream cout = null;
        if (isCustom) {
            cminfo = new MethodInfo(CUSTOM_PREFIX + methodName, desc, 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);
        
        // 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);
        
        // store the returned object in a local variable
        code_astore(extraInfo, out);
        
        // start of the try block
        short tryStart = (short) out.size();

        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, desc));

            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);

            code_ipush(attrIndex, 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);

            code_ipush(attrIndex, 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
        out.writeByte(opc_aload);
        out.writeByte(exception);
        
        // 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)10);
        minfo.setMaxLocals((short) (localSlot0 + 7));
        if (isCustom) {
            cminfo.setMaxStack((short)10);
            cminfo.setMaxLocals((short) (localSlot0 + 5));
        }
        
        ArrayList ret = new ArrayList();
        ret.add(minfo);
        if (isCustom)
            ret.add(cminfo);
        return ret;
    }
    
    protected MethodInfo getOperationMethod(String methodName, String[] parameterTypes, String returnType, String featureName) throws IOException {
        HashMap item = (HashMap) dispatchMethods.get("_invokeOperation"); //NOI18N
        MethodInfo result = getDerivedMethod(methodName, parameterTypes, returnType);
        item.put(featureName, new MethodDescHolder(methodName, parameterTypes, returnType));
        return result;
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.