use of org.eclipse.persistence.internal.libraries.asm.Type in project eclipselink by eclipse-ee4j.
the class MetadataDynamicClassWriter method addMethods.
/**
* Add get methods for all virtual attributes
*/
@Override
protected void addMethods(ClassWriter cw, String parentClassType) {
for (MappingAccessor accessor : getDescriptor().getMappingAccessors()) {
String propertyName = propertyName(accessor.getAttributeName());
Type returnType = getAsmType(accessor);
// Add getter
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, GET + propertyName, "()" + returnType.getDescriptor(), null, new String[] { DYNAMIC_EXCEPTION });
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(accessor.getAttributeName());
mv.visitMethodInsn(INVOKESPECIAL, parentClassType, "get", "(" + LJAVA_LANG_STRING + ")" + LJAVA_LANG_OBJECT, false);
mv.visitTypeInsn(CHECKCAST, returnType.getInternalName());
mv.visitInsn(ARETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
// Add setter
mv = cw.visitMethod(ACC_PUBLIC, SET + propertyName, "(" + returnType.getDescriptor() + ")V", null, new String[] { DYNAMIC_EXCEPTION });
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn("id");
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, parentClassType, SET, "(" + LJAVA_LANG_STRING + LJAVA_LANG_OBJECT + ")" + LDYNAMIC_ENTITY, false);
mv.visitInsn(POP);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
}
use of org.eclipse.persistence.internal.libraries.asm.Type in project eclipselink by eclipse-ee4j.
the class AnnotationsProcessor method generateWrapperForMapClass.
private Class<?> generateWrapperForMapClass(JavaClass mapClass, JavaClass keyClass, JavaClass valueClass, TypeMappingInfo typeMappingInfo) {
String packageName = JAXB_DEV;
NamespaceResolver combinedNamespaceResolver = new NamespaceResolver();
if (!helper.isBuiltInJavaType(keyClass)) {
String keyPackageName = keyClass.getPackageName();
packageName = packageName + DOT_CHR + keyPackageName;
NamespaceInfo keyNamespaceInfo = getPackageInfoForPackage(keyClass).getNamespaceInfo();
if (keyNamespaceInfo != null) {
java.util.Vector<Namespace> namespaces = keyNamespaceInfo.getNamespaceResolver().getNamespaces();
for (Namespace n : namespaces) {
combinedNamespaceResolver.put(n.getPrefix(), n.getNamespaceURI());
}
}
}
if (!helper.isBuiltInJavaType(valueClass)) {
String valuePackageName = valueClass.getPackageName();
packageName = packageName + DOT_CHR + valuePackageName;
NamespaceInfo valueNamespaceInfo = getPackageInfoForPackage(valueClass).getNamespaceInfo();
if (valueNamespaceInfo != null) {
java.util.Vector<Namespace> namespaces = valueNamespaceInfo.getNamespaceResolver().getNamespaces();
for (Namespace n : namespaces) {
combinedNamespaceResolver.put(n.getPrefix(), n.getNamespaceURI());
}
}
}
String namespace = this.defaultTargetNamespace;
if (namespace == null) {
namespace = EMPTY_STRING;
}
PackageInfo packageInfo = packageToPackageInfoMappings.get(mapClass.getPackageName());
if (packageInfo == null) {
packageInfo = getPackageToPackageInfoMappings().get(packageName);
} else {
if (packageInfo.getNamespace() != null) {
namespace = packageInfo.getNamespace();
}
getPackageToPackageInfoMappings().put(packageName, packageInfo);
}
if (packageInfo == null) {
packageInfo = new PackageInfo();
packageInfo.setNamespaceInfo(new NamespaceInfo());
packageInfo.setNamespace(namespace);
packageInfo.setNamespaceResolver(combinedNamespaceResolver);
getPackageToPackageInfoMappings().put(packageName, packageInfo);
}
int beginIndex = keyClass.getName().lastIndexOf(DOT_CHR) + 1;
String keyName = keyClass.getName().substring(beginIndex);
int dollarIndex = keyName.indexOf(DOLLAR_SIGN_CHR);
if (dollarIndex > -1) {
keyName = keyName.substring(dollarIndex + 1);
}
beginIndex = valueClass.getName().lastIndexOf(DOT_CHR) + 1;
String valueName = valueClass.getName().substring(beginIndex);
dollarIndex = valueName.indexOf(DOLLAR_SIGN_CHR);
if (dollarIndex > -1) {
valueName = valueName.substring(dollarIndex + 1);
}
String collectionClassShortName = mapClass.getRawName().substring(mapClass.getRawName().lastIndexOf(DOT_CHR) + 1);
String suggestedClassName = keyName + valueName + collectionClassShortName;
String qualifiedClassName = packageName + DOT_CHR + suggestedClassName;
qualifiedClassName = getNextAvailableClassName(qualifiedClassName);
String qualifiedInternalClassName = qualifiedClassName.replace(DOT_CHR, SLASH_CHR);
String internalKeyName = keyClass.getQualifiedName().replace(DOT_CHR, SLASH_CHR);
String internalValueName = valueClass.getQualifiedName().replace(DOT_CHR, SLASH_CHR);
Type mapType = Type.getType(L + mapClass.getRawName().replace(DOT_CHR, SLASH_CHR) + SEMI_COLON);
EclipseLinkASMClassWriter cw = new EclipseLinkASMClassWriter();
String sig = "Lorg/eclipse/persistence/internal/jaxb/many/MapValue<L" + mapType.getInternalName() + "<L" + internalKeyName + ";L" + internalValueName + ";>;>;";
cw.visit(Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, qualifiedInternalClassName, sig, "org/eclipse/persistence/internal/jaxb/many/MapValue", null);
// Write Field: @... public Map entry
String fieldSig = L + mapType.getInternalName() + "<L" + internalKeyName + ";L" + internalValueName + ";>;";
FieldVisitor fv = cw.visitField(Opcodes.ACC_PUBLIC, "entry", L + mapType.getInternalName() + SEMI_COLON, fieldSig, null);
fv.visitAnnotation(Type.getDescriptor(XmlElement.class), true);
if (typeMappingInfo != null) {
Annotation[] annotations = typeMappingInfo.getAnnotations();
if (annotations != null) {
for (Annotation nextAnnotation : annotations) {
if (nextAnnotation != null && !(nextAnnotation instanceof XmlElement) && !(nextAnnotation instanceof XmlJavaTypeAdapter)) {
String annotationClassName = nextAnnotation.annotationType().getName();
AnnotationVisitor av = fv.visitAnnotation(L + annotationClassName.replace(DOT_CHR, SLASH_CHR) + SEMI_COLON, true);
for (Method next : nextAnnotation.annotationType().getDeclaredMethods()) {
try {
Object nextValue = next.invoke(nextAnnotation);
if (nextValue instanceof Class) {
Type nextType = Type.getType(L + ((Class) nextValue).getName().replace(DOT_CHR, SLASH_CHR) + SEMI_COLON);
nextValue = nextType;
}
av.visit(next.getName(), nextValue);
} catch (InvocationTargetException ignored) {
// ignore the invocation target exception here.
} catch (IllegalAccessException ignored) {
// ignore the illegal access exception here.
}
}
av.visitEnd();
}
}
}
}
fv.visitEnd();
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "org/eclipse/persistence/internal/jaxb/many/MapValue", "<init>", "()V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
// Write: @XmlTransient public void setItem(???)
String methodSig = "(L" + mapType.getInternalName() + "<L" + internalKeyName + ";L" + internalValueName + ";>;)V";
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setItem", "(L" + mapType.getInternalName() + ";)V", methodSig, null);
// TODO: Verify that we really want to put @XmlTranient on setItem
// method
mv.visitAnnotation("Ljakarta/xml/bind/annotation/XmlTransient;", true);
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitFieldInsn(Opcodes.PUTFIELD, qualifiedInternalClassName, "entry", L + mapType.getInternalName() + SEMI_COLON);
mv.visitInsn(Opcodes.RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
// Replacement?:LocalVariableTypeTableAttribute cvAttr = new
// LocalVariableTypeTableAttribute();
// mv.visitAttribute(cvAttr);
mv.visitMaxs(2, 2);
mv.visitEnd();
// Write @XmlTransient public ??? getItem()
methodSig = "()L" + mapType.getInternalName() + "<L" + internalKeyName + ";L" + internalValueName + ";>;";
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getItem", "()L" + mapType.getInternalName() + SEMI_COLON, methodSig, null);
mv.visitAnnotation("Ljakarta/xml/bind/annotation/XmlTransient;", true);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, qualifiedInternalClassName, "entry", L + mapType.getInternalName() + SEMI_COLON);
mv.visitInsn(Opcodes.ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "getItem", "()Ljava/lang/Object;", null, null);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, qualifiedInternalClassName, "getItem", "()L" + mapType.getInternalName() + SEMI_COLON, false);
mv.visitInsn(Opcodes.ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "setItem", "(Ljava/lang/Object;)V", null, null);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitTypeInsn(Opcodes.CHECKCAST, mapType.getInternalName());
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, qualifiedInternalClassName, "setItem", "(L" + mapType.getInternalName() + ";)V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
// Write @XmlType(namespace)
AnnotationVisitor av = cw.visitAnnotation("Ljakarta/xml/bind/annotation/XmlType;", true);
av.visit("namespace", namespace);
cw.visitEnd();
byte[] classBytes = cw.toByteArray();
return generateClassFromBytes(qualifiedClassName, classBytes);
}
use of org.eclipse.persistence.internal.libraries.asm.Type in project eclipselink by eclipse-ee4j.
the class AnnotationsProcessor method getNestedCollectionType.
private java.lang.reflect.Type getNestedCollectionType(TypeMappingInfo mappingInfo) {
java.lang.reflect.Type result = null;
if (mappingInfo != null && mappingInfo.getType() != null) {
// called for a collection, type must be parametrized ...
ParameterizedType pType = (ParameterizedType) mappingInfo.getType();
java.lang.reflect.Type[] actualTypeArguments = pType.getActualTypeArguments();
result = actualTypeArguments != null && actualTypeArguments.length > 0 ? actualTypeArguments[0] : null;
}
if (result == null) {
getLogger().logWarning("cant_get_nested_collection_type", new Object[] {});
}
return result;
}
use of org.eclipse.persistence.internal.libraries.asm.Type in project eclipselink by eclipse-ee4j.
the class MetadataDynamicClassWriter method getAsmType.
/**
* Get the {@link Type} for the accessor. If the accessor's type is
* primitive return the the non-primitive type.
*/
private Type getAsmType(MappingAccessor accessor) {
String attributeType = accessor.getFullyQualifiedClassName(accessor.getAttributeType());
Class<?> primClass = accessor.getPrimitiveClassForName(attributeType);
if (primClass != null) {
Type asmType = Type.getType(primClass);
switch(asmType.getSort()) {
case Type.BOOLEAN:
return Type.getType(ClassConstants.BOOLEAN);
case Type.BYTE:
return Type.getType(ClassConstants.BYTE);
case Type.CHAR:
return Type.getType(ClassConstants.CHAR);
case Type.DOUBLE:
return Type.getType(ClassConstants.DOUBLE);
case Type.FLOAT:
return Type.getType(ClassConstants.FLOAT);
case Type.INT:
return Type.getType(ClassConstants.INTEGER);
case Type.LONG:
return Type.getType(ClassConstants.LONG);
case Type.SHORT:
return Type.getType(ClassConstants.SHORT);
}
}
return Type.getType("L" + attributeType.replace(".", "/") + ";");
}
use of org.eclipse.persistence.internal.libraries.asm.Type in project eclipselink by eclipse-ee4j.
the class MethodWeaver method weaveBeginningOfMethodIfRequired.
/**
* Makes modifications to the beginning of a method.
*
* 1. Modifies getter method for attributes using property access
*
* In a getter method for 'attributeName', the following lines are added at the beginning of the method
*
* _persistence_checkFetched("attributeName");
* _persistence_initialize_attributeName_vh();
* if (!_persistence_attributeName_vh.isInstantiated()) {
* PropertyChangeListener temp_persistence_listener = _persistence_listener;
* _persistence_listener = null;
* setAttributeName((AttributeType)_persistence_attributeName_vh.getValue());
* _persistence_listener = temp_persistence_listener;
* }
*
* 2. Modifies setter methods to store old value of attribute
* If weaving for fetch groups:
*
* // if weaving for change tracking:
* if(_persistence_listener != null)
* // for Objects
* AttributeType oldAttribute = getAttribute()
* // for primitives
* AttributeWrapperType oldAttribute = new AttributeWrapperType(getAttribute());
* e.g. Double oldAttribute = Double.valueOf(getAttribute());
* else
* _persistence_checkFetchedForSet("attributeName");
* _persistence_propertyChange("attributeName", oldAttribute, argument);
*
* otherwise (not weaving for fetch groups):
*
* // for Objects
* AttributeType oldAttribute = getAttribute()
* // for primitives
* AttributeWrapperType oldAttribute = new AttributeWrapperType(getAttribute());
* e.g. Double oldAttribute = Double.valueOf(getAttribute());
* _persistence_propertyChange("attributeName", oldAttribute, argument);
*
* // if not weaving for change tracking, but for fetch groups only:
* _persistence_checkFetchedForSet("attributeName");
*
* 3. Modifies getter Method for attributes using virtual access
*
* add: _persistence_checkFetched(name);
*
* 4. Modifies setter Method for attributes using virtual access
*
* add code of the following form:
*
* Object obj = null;
* if(_persistence_listener != null){
* obj = get(name);
* } else {
* _persistence_checkFetchedForSet(name);
* }
* _persistence_propertyChange(name, obj, value);
*
* _persistence_checkFetchedForSet(name) call will be excluded if weaving of fetch groups is not enabled
*
* _persistence_propertyChange(name, obj, value); will be excluded if weaving of change tracking is not enabled
*/
public void weaveBeginningOfMethodIfRequired() {
if (this.methodStarted) {
return;
}
// Must set immediately, as weaving can trigger this method.
this.methodStarted = true;
boolean isVirtual = false;
AttributeDetails attributeDetails = tcw.classDetails.getGetterMethodToAttributeDetails().get(methodName);
boolean isGetMethod = (attributeDetails != null) && (this.methodDescriptor.startsWith("()") || (attributeDetails.isVirtualProperty() && this.methodDescriptor.startsWith("(" + ClassWeaver.STRING_SIGNATURE + ")")));
String attributeName = null;
String referenceClassName = null;
String setterMethodName = null;
Type referenceClassType = null;
String getterMethodName = null;
int valueHoldingLocation = 1;
int valueStorageLocation = 2;
if (attributeDetails == null) {
VirtualAttributeMethodInfo info = tcw.classDetails.getInfoForVirtualGetMethod(methodName);
if ((info != null) && this.methodDescriptor.equals(ClassWeaver.VIRTUAL_GETTER_SIGNATURE)) {
isGetMethod = true;
isVirtual = true;
referenceClassName = "java.lang.Object";
setterMethodName = info.getSetMethodName();
referenceClassType = Type.getType(ClassWeaver.OBJECT_SIGNATURE);
getterMethodName = methodName;
}
} else {
attributeName = attributeDetails.getAttributeName();
referenceClassName = attributeDetails.getReferenceClassName();
setterMethodName = attributeDetails.getSetterMethodName();
referenceClassType = attributeDetails.getReferenceClassType();
getterMethodName = attributeDetails.getGetterMethodName();
isVirtual = attributeDetails.isVirtualProperty();
}
if (isVirtual) {
valueHoldingLocation = 2;
valueStorageLocation = 3;
}
if (isVirtual || (isGetMethod && !attributeDetails.hasField())) {
if (tcw.classDetails.shouldWeaveFetchGroups()) {
mv.visitVarInsn(ALOAD, 0);
if (isVirtual) {
mv.visitVarInsn(ALOAD, 1);
} else {
mv.visitLdcInsn(attributeName);
}
// _persistence_checkFetched("attributeName");
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_checkFetched", "(Ljava/lang/String;)V", false);
}
if (!isVirtual && attributeDetails.weaveValueHolders()) {
// _persistence_initialize_attributeName_vh();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_initialize_" + attributeName + ClassWeaver.PERSISTENCE_FIELDNAME_POSTFIX, "()V", false);
// if (!_persistence_attributeName_vh.isInstantiated()) {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), ClassWeaver.PERSISTENCE_FIELDNAME_PREFIX + attributeName + ClassWeaver.PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
mv.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "isInstantiated", "()Z", true);
Label l0 = new Label();
mv.visitJumpInsn(IFNE, l0);
// Need to disable change tracking when the set method is called to avoid thinking the attribute changed.
if (tcw.classDetails.shouldWeaveChangeTracking()) {
// PropertyChangeListener temp_persistence_listener = _persistence_listener;
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_persistence_listener", ClassWeaver.PCL_SIGNATURE);
mv.visitVarInsn(ASTORE, 4);
// _persistence_listener = null;
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(ACONST_NULL);
mv.visitFieldInsn(PUTFIELD, tcw.classDetails.getClassName(), "_persistence_listener", ClassWeaver.PCL_SIGNATURE);
}
// setAttributeName((AttributeType)_persistence_attributeName_vh.getValue());
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), ClassWeaver.PERSISTENCE_FIELDNAME_PREFIX + attributeName + ClassWeaver.PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
mv.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, referenceClassName.replace('.', '/'));
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), setterMethodName, "(" + referenceClassType.getDescriptor() + ")V", false);
if (tcw.classDetails.shouldWeaveChangeTracking()) {
// _persistence_listener = temp_persistence_listener;
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 4);
mv.visitFieldInsn(PUTFIELD, tcw.classDetails.getClassName(), "_persistence_listener", ClassWeaver.PCL_SIGNATURE);
}
// }
mv.visitLabel(l0);
}
} else {
attributeDetails = tcw.classDetails.getSetterMethodToAttributeDetails().get(methodName);
boolean isSetMethod = (attributeDetails != null) && this.methodDescriptor.equals(attributeDetails.getSetterMethodSignature());
if (attributeDetails == null) {
VirtualAttributeMethodInfo info = tcw.classDetails.getInfoForVirtualSetMethod(methodName);
if (info != null && this.methodDescriptor.equals(ClassWeaver.VIRTUAL_GETTER_SIGNATURE)) {
isGetMethod = true;
isVirtual = true;
referenceClassName = "java.lang.Object";
setterMethodName = methodName;
referenceClassType = Type.getType(ClassWeaver.OBJECT_SIGNATURE);
getterMethodName = info.getGetMethodName();
}
} else {
attributeName = attributeDetails.getAttributeName();
referenceClassName = attributeDetails.getReferenceClassName();
setterMethodName = attributeDetails.getSetterMethodName();
referenceClassType = attributeDetails.getReferenceClassType();
getterMethodName = attributeDetails.getGetterMethodName();
isVirtual = attributeDetails.isVirtualProperty();
}
if (isVirtual) {
valueHoldingLocation = 2;
valueStorageLocation = 3;
}
if (isVirtual || (isSetMethod && !attributeDetails.hasField())) {
if (tcw.classDetails.shouldWeaveChangeTracking()) {
if (tcw.classDetails.shouldWeaveFetchGroups()) {
// if this is a primitive, get the wrapper class
String wrapper = ClassWeaver.wrapperFor(referenceClassType.getSort());
mv.visitInsn(ACONST_NULL);
if (wrapper != null) {
mv.visitVarInsn(ASTORE, valueStorageLocation + 1);
} else {
mv.visitVarInsn(ASTORE, valueStorageLocation);
}
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_persistence_listener", "Ljava/beans/PropertyChangeListener;");
Label l0 = new Label();
mv.visitJumpInsn(IFNULL, l0);
// 1st part of invoking constructor for primitives to wrap them
if (wrapper != null) {
mv.visitTypeInsn(NEW, wrapper);
mv.visitInsn(DUP);
}
// Call the getter
// getAttribute()
mv.visitVarInsn(ALOAD, 0);
String getterArgument = "";
String getterReturn = referenceClassType.getDescriptor();
if (isVirtual) {
getterArgument = ClassWeaver.STRING_SIGNATURE;
getterReturn = ClassWeaver.OBJECT_SIGNATURE;
mv.visitVarInsn(ALOAD, 1);
}
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), getterMethodName, "(" + getterArgument + ")" + getterReturn, false);
if (wrapper != null) {
// 2nd part of using constructor.
mv.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + referenceClassType.getDescriptor() + ")V", false);
mv.visitVarInsn(ASTORE, valueStorageLocation + 1);
} else {
// store the result
mv.visitVarInsn(ASTORE, valueStorageLocation);
}
Label l1 = new Label();
mv.visitJumpInsn(GOTO, l1);
mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0);
if (isVirtual) {
mv.visitVarInsn(ALOAD, 1);
} else {
mv.visitLdcInsn(attributeName);
}
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_checkFetchedForSet", "(Ljava/lang/String;)V", false);
mv.visitLabel(l1);
mv.visitVarInsn(ALOAD, 0);
if (isVirtual) {
mv.visitVarInsn(ALOAD, 1);
} else {
mv.visitLdcInsn(attributeName);
}
if (wrapper != null) {
mv.visitVarInsn(ALOAD, valueStorageLocation + 1);
mv.visitTypeInsn(NEW, wrapper);
mv.visitInsn(DUP);
} else {
mv.visitVarInsn(ALOAD, valueStorageLocation);
}
// get an appropriate load opcode for the type
int opcode = referenceClassType.getOpcode(ILOAD);
mv.visitVarInsn(opcode, valueHoldingLocation);
if (wrapper != null) {
mv.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + referenceClassType.getDescriptor() + ")V", false);
}
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_propertyChange", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", false);
} else {
// tcw.classDetails.shouldWeaveFetchGroups()
/**
* The code below constructs the following code
*
* AttributeType oldAttribute = getAttribute() // for Objects
*
* AttributeWrapperType oldAttribute = new AttributeWrapperType(getAttribute()); // for primitives
*/
// if this is a primitive, get the wrapper class
String wrapper = ClassWeaver.wrapperFor(referenceClassType.getSort());
// 1st part of invoking constructor for primitives to wrap them
if (wrapper != null) {
mv.visitTypeInsn(NEW, wrapper);
mv.visitInsn(DUP);
}
// Call the getter
// getAttribute()
mv.visitVarInsn(ALOAD, 0);
String getterArgument = "";
String getterReturn = referenceClassType.getDescriptor();
if (isVirtual) {
getterArgument = ClassWeaver.STRING_SIGNATURE;
getterReturn = ClassWeaver.OBJECT_SIGNATURE;
mv.visitVarInsn(ALOAD, 1);
}
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), getterMethodName, "(" + getterArgument + ")" + getterReturn, false);
if (wrapper != null) {
// 2nd part of using constructor.
mv.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")V", false);
mv.visitVarInsn(ASTORE, valueStorageLocation + 1);
} else {
// store the result
mv.visitVarInsn(ASTORE, valueStorageLocation);
}
// makes use of the value stored in weaveBeginningOfMethodIfRequired to call property change method
// _persistence_propertyChange("attributeName", oldAttribute, argument);
mv.visitVarInsn(ALOAD, 0);
if (isVirtual) {
mv.visitVarInsn(ALOAD, 1);
} else {
mv.visitLdcInsn(attributeName);
}
if (wrapper != null) {
mv.visitVarInsn(ALOAD, valueStorageLocation + 1);
mv.visitTypeInsn(NEW, wrapper);
mv.visitInsn(DUP);
} else {
mv.visitVarInsn(ALOAD, valueStorageLocation);
}
int opcode = referenceClassType.getOpcode(ILOAD);
mv.visitVarInsn(opcode, valueHoldingLocation);
if (wrapper != null) {
mv.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + referenceClassType.getDescriptor() + ")V", false);
}
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_propertyChange", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", false);
}
} else {
// !tcw.classDetails.shouldWeaveChangeTracking()
if (tcw.classDetails.shouldWeaveFetchGroups()) {
mv.visitVarInsn(ALOAD, 0);
if (isVirtual) {
mv.visitVarInsn(ALOAD, 1);
} else {
mv.visitLdcInsn(attributeName);
}
// _persistence_checkFetchedForSet("variableName");
mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_checkFetchedForSet", "(Ljava/lang/String;)V", false);
}
}
}
}
}
Aggregations