FileDocCategorySizeDatePackage
TopLinkMethodWeaver.javaAPI DocGlassfish v2 API14626Thu Jul 19 11:51:58 BST 2007oracle.toplink.essentials.internal.weaving

TopLinkMethodWeaver

public class TopLinkMethodWeaver extends CodeAdapter implements Constants
INTERNAL: Used by TopLink's weaving feature to adjust methods to make use of ValueHolders that have been inserted by TopLinkClassWeaver. For FIELD access, changes references to GETFIELD and PUTFIELD to call newly added convenience methods. For Property access, modifies the getters and setters to make use of new ValueHolders Also adds initialization of newly added ValueHolders to constructor.

Fields Summary
protected TopLinkClassWeaver
tcw
protected String
methodName
private String
methodDescriptor
private boolean
methodStarted
private boolean
constructorInitializationDone
Constructors Summary
public TopLinkMethodWeaver(TopLinkClassWeaver tcw, String methodName, String methodDescriptor, CodeVisitor cv)

	
	      
		  
		
		super(cv);
		this.tcw = tcw;
		this.methodName = methodName;
		this.methodDescriptor = methodDescriptor;
	
Methods Summary
public voidaddValueHolderReferencesIfRequired()
INTERNAL: Modifies getter and setter methods for attributes using property access In a getter method for 'attributeName', the following line is added at the beginning of the method if (!_toplink_attributeName_vh.isInstantiated()){ setFoo((EntityC)_toplink_attributeName_vh.getValue()); } In a setter method, for 'attributeName', the following line is added at the beginning of the method _toplink_attributeName_vh.setValue(argument); _toplink_attributeName_vh.setIsCoordinatedWithProperty(true); TODO: In the end, the call to setValue() should be modified to somehow make use of the result of the getter method. This behavior has not yet been implemented.

        if (methodStarted){
            return;
        }
        AttributeDetails attributeDetails = (AttributeDetails)tcw.classDetails.getGetterMethodToAttributeDetails().get(methodName);
        if (attributeDetails != null && !attributeDetails.isAttributeOnSuperClass()){
            
            cv.visitVarInsn(ALOAD, 0);
            cv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_toplink_" + attributeDetails.getAttributeName() + "_vh", TopLinkClassWeaver.VHI_SIGNATURE);
            cv.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "isInstantiated", "()Z");
            Label l0 = new Label();
            cv.visitJumpInsn(IFNE, l0);
            
            
            cv.visitVarInsn(ALOAD, 0);
            cv.visitVarInsn(ALOAD, 0);
            cv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_toplink_" + attributeDetails.getAttributeName() + "_vh", TopLinkClassWeaver.VHI_SIGNATURE);
            cv.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;");
            cv.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClass().replace('.",'/"));
            cv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), attributeDetails.getSetterMethodName(), "(L" + attributeDetails.getReferenceClass().replace('.",'/") + ";)V");

            cv.visitLabel(l0);
            //cv.visitVarInsn(ALOAD, 0);
          //  cv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "foo", "L" + attributeDetails.getReferenceClass().replace('.','/') + ";");

        
        } else {
            attributeDetails = (AttributeDetails)tcw.classDetails.getSetterMethodToAttributeDetails().get(methodName);
            if (attributeDetails != null){
                cv.visitVarInsn(ALOAD, 0);
                cv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_toplink_" + attributeDetails.getAttributeName() + "_vh", TopLinkClassWeaver.VHI_SIGNATURE);
                cv.visitVarInsn(ALOAD, 1);
                cv.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "setValue", "(Ljava/lang/Object;)V");
                
                cv.visitVarInsn(ALOAD, 0);
                cv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_toplink_" + attributeDetails.getAttributeName() + "_vh", TopLinkClassWeaver.VHI_SIGNATURE);
                cv.visitInsn(ICONST_1);
                cv.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "setIsCoordinatedWithProperty", "(Z)V");
            }
        }
    
public voidvisitAttribute(oracle.toplink.libraries.asm.Attribute attr)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitAttribute(attr);
    
public voidvisitFieldInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        weaveAttributesIfRequired(opcode, owner, name, desc);
    
public voidvisitIincInsn(int var, int increment)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitIincInsn(var, increment);
    
public voidvisitInsn(int opcode)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        super.visitInsn(opcode);
    
public voidvisitIntInsn(int opcode, int operand)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitIntInsn(opcode, operand);
    
public voidvisitJumpInsn(int opcode, oracle.toplink.libraries.asm.Label label)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitJumpInsn(opcode, label);
    
public voidvisitLabel(oracle.toplink.libraries.asm.Label label)

        cv.visitLabel(label);
    
public voidvisitLdcInsn(java.lang.Object cst)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitLdcInsn(cst);
    
public voidvisitLineNumber(int line, oracle.toplink.libraries.asm.Label start)

        cv.visitLineNumber(line, start);
    
public voidvisitLocalVariable(java.lang.String name, java.lang.String desc, oracle.toplink.libraries.asm.Label start, oracle.toplink.libraries.asm.Label end, int index)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitLocalVariable(name, desc, start, end, index);
    
public voidvisitLookupSwitchInsn(oracle.toplink.libraries.asm.Label dflt, int[] keys, oracle.toplink.libraries.asm.Label[] labels)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitLookupSwitchInsn(dflt, keys, labels);
    
public voidvisitMaxs(int maxStack, int maxLocals)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitMaxs(0, 0);
    
public voidvisitMethodInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        super.visitMethodInsn(opcode, owner, name, desc);     
        weaveConstructorIfRequired(opcode, owner, name, desc);
    
public voidvisitMultiANewArrayInsn(java.lang.String desc, int dims)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitMultiANewArrayInsn(desc, dims);
    
public voidvisitTableSwitchInsn(int min, int max, oracle.toplink.libraries.asm.Label dflt, oracle.toplink.libraries.asm.Label[] labels)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitTableSwitchInsn(min, max, dflt, labels);
    
public voidvisitTryCatchBlock(oracle.toplink.libraries.asm.Label start, oracle.toplink.libraries.asm.Label end, oracle.toplink.libraries.asm.Label handler, java.lang.String type)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitTryCatchBlock(start, end, handler, type);
    
public voidvisitTypeInsn(int opcode, java.lang.String desc)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitTypeInsn(opcode, desc);
    
public voidvisitVarInsn(int opcode, int var)

        addValueHolderReferencesIfRequired();
        methodStarted = true;
        cv.visitVarInsn(opcode, var);
    
public voidweaveAttributesIfRequired(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)
INTERNAL: Change GETFIELD and PUTFIELD for fields that use attribute access to make use of new convenience methods A GETFIELD for an attribute named 'variableName' will be replaced by a call to: _toplink_getvariableName() A PUTFIELD for an attribute named 'variableName' will be replaced by a call to: toplink_setvariableName(variableName)

		AttributeDetails attributeDetails = (AttributeDetails)tcw.classDetails.getAttributeDetailsFromClassOrSuperClass(name);	
        if (attributeDetails == null || !attributeDetails.isMappedWithAttributeAccess()){
            super.visitFieldInsn(opcode, owner, name, desc);
            return;
        }
		if (opcode == GETFIELD) {
			if (attributeDetails != null) {
                cv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_toplink_get" + name, "()L" + attributeDetails.getReferenceClass().replace('.",'/") + ";");
			} else {
				super.visitFieldInsn(opcode, owner, name, desc);
			}
	    }  else if (opcode == PUTFIELD) {
			if (attributeDetails != null) {
                cv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_toplink_set" + name, "(L" + attributeDetails.getReferenceClass().replace('.",'/") + ";)V");
			} else {
				super.visitFieldInsn(opcode, owner, name, desc);
			}
        }  else {
			super.visitFieldInsn(opcode, owner, name, desc);
	    }    
    
public voidweaveConstructorIfRequired(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)
INTERNAL: Add initialization of new ValueHolders to constuctors. If a ValueHolder called 'variableName' has been added, the following line will be added to the constructor. _toplink_variableName_vh = new ValueHolder(); _toplink_foo_vh.setIsNewlyWeavedValueHolder(true);

        if (!constructorInitializationDone && ("<init>".equals(methodName)||"<cinit>".equals(methodName))) {
                // look for the superclass initializer and insert the valueholder
            // initialization after it
            if (opcode == INVOKESPECIAL && name.startsWith("<init>")) {                  
                ClassDetails details = tcw.classDetails;
                Iterator attributes = details.getAttributesMap().keySet().iterator();
                while (attributes.hasNext()){
                    String key = (String)attributes.next();
                        
                    AttributeDetails attribute = (AttributeDetails)details.getAttributesMap().get(key);
                    if (attribute.weaveValueHolders() && !attribute.isCollectionMapping() && !attribute.isAttributeOnSuperClass()){
                        super.visitVarInsn(ALOAD, 0);
                        super.visitTypeInsn(NEW, TopLinkClassWeaver.VH_SHORT_SIGNATURE);
                        super.visitInsn(DUP);
                        super.visitMethodInsn(INVOKESPECIAL, TopLinkClassWeaver.VH_SHORT_SIGNATURE, "<init>", "()V");
                        super.visitFieldInsn(PUTFIELD, details.className, "_toplink_" + attribute.attributeName + "_vh", TopLinkClassWeaver.VHI_SIGNATURE);                    
                        
                        super.visitVarInsn(ALOAD, 0);
                        super.visitFieldInsn(GETFIELD, details.className, "_toplink_" + attribute.attributeName + "_vh", TopLinkClassWeaver.VHI_SIGNATURE);
                        super.visitInsn(ICONST_1);
                        super.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "setIsNewlyWeavedValueHolder", "(Z)V");
                    }
                }
            }
            constructorInitializationDone = true;
        }
    
protected oracle.toplink.essentials.internal.weaving.AttributeDetailsweaveValueHolders(oracle.toplink.essentials.internal.weaving.ClassDetails startingDetails, java.lang.String fieldName)

		
		if (startingDetails == null) {
			return null;
		} else {
			AttributeDetails attributeDetails =	(AttributeDetails)startingDetails.getAttributesMap().get(fieldName);
			if (attributeDetails != null && attributeDetails.weaveValueHolders()) {
				return attributeDetails;
			} else {
				return weaveValueHolders(startingDetails.getSuperClassDetails(),
					fieldName);
			}
		}