TopLinkMethodWeaverpublic class TopLinkMethodWeaver extends CodeAdapter implements ConstantsINTERNAL:
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 void | addValueHolderReferencesIfRequired()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 void | visitAttribute(oracle.toplink.libraries.asm.Attribute attr)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitAttribute(attr);
| public void | visitFieldInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)
addValueHolderReferencesIfRequired();
methodStarted = true;
weaveAttributesIfRequired(opcode, owner, name, desc);
| public void | visitIincInsn(int var, int increment)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitIincInsn(var, increment);
| public void | visitInsn(int opcode)
addValueHolderReferencesIfRequired();
methodStarted = true;
super.visitInsn(opcode);
| public void | visitIntInsn(int opcode, int operand)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitIntInsn(opcode, operand);
| public void | visitJumpInsn(int opcode, oracle.toplink.libraries.asm.Label label)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitJumpInsn(opcode, label);
| public void | visitLabel(oracle.toplink.libraries.asm.Label label)
cv.visitLabel(label);
| public void | visitLdcInsn(java.lang.Object cst)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitLdcInsn(cst);
| public void | visitLineNumber(int line, oracle.toplink.libraries.asm.Label start)
cv.visitLineNumber(line, start);
| public void | visitLocalVariable(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 void | visitLookupSwitchInsn(oracle.toplink.libraries.asm.Label dflt, int[] keys, oracle.toplink.libraries.asm.Label[] labels)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitLookupSwitchInsn(dflt, keys, labels);
| public void | visitMaxs(int maxStack, int maxLocals)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitMaxs(0, 0);
| public void | visitMethodInsn(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 void | visitMultiANewArrayInsn(java.lang.String desc, int dims)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitMultiANewArrayInsn(desc, dims);
| public void | visitTableSwitchInsn(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 void | visitTryCatchBlock(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 void | visitTypeInsn(int opcode, java.lang.String desc)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitTypeInsn(opcode, desc);
| public void | visitVarInsn(int opcode, int var)
addValueHolderReferencesIfRequired();
methodStarted = true;
cv.visitVarInsn(opcode, var);
| public void | weaveAttributesIfRequired(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 void | weaveConstructorIfRequired(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.AttributeDetails | weaveValueHolders(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);
}
}
|
|