Search in sources :

Example 1 with Type

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();
    }
}
Also used : Type(org.eclipse.persistence.internal.libraries.asm.Type) MappingAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor) MethodVisitor(org.eclipse.persistence.internal.libraries.asm.MethodVisitor)

Example 2 with Type

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);
}
Also used : XmlJavaTypeAdapter(jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter) Label(org.eclipse.persistence.internal.libraries.asm.Label) EclipseLinkASMClassWriter(org.eclipse.persistence.internal.libraries.asm.EclipseLinkASMClassWriter) Method(java.lang.reflect.Method) JavaMethod(org.eclipse.persistence.jaxb.javamodel.JavaMethod) FieldVisitor(org.eclipse.persistence.internal.libraries.asm.FieldVisitor) Namespace(org.eclipse.persistence.internal.oxm.Namespace) JavaAnnotation(org.eclipse.persistence.jaxb.javamodel.JavaAnnotation) Annotation(java.lang.annotation.Annotation) InvocationTargetException(java.lang.reflect.InvocationTargetException) MethodVisitor(org.eclipse.persistence.internal.libraries.asm.MethodVisitor) Type(org.eclipse.persistence.internal.libraries.asm.Type) XmlType(jakarta.xml.bind.annotation.XmlType) XmlAccessorType(jakarta.xml.bind.annotation.XmlAccessorType) ParameterizedType(java.lang.reflect.ParameterizedType) XmlMimeType(jakarta.xml.bind.annotation.XmlMimeType) XmlAccessType(org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType) XmlSchemaType(jakarta.xml.bind.annotation.XmlSchemaType) AnnotationVisitor(org.eclipse.persistence.internal.libraries.asm.AnnotationVisitor) NamespaceResolver(org.eclipse.persistence.oxm.NamespaceResolver) XmlElement(jakarta.xml.bind.annotation.XmlElement) JavaClass(org.eclipse.persistence.jaxb.javamodel.JavaClass)

Example 3 with Type

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;
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) Type(org.eclipse.persistence.internal.libraries.asm.Type) XmlType(jakarta.xml.bind.annotation.XmlType) XmlAccessorType(jakarta.xml.bind.annotation.XmlAccessorType) ParameterizedType(java.lang.reflect.ParameterizedType) XmlMimeType(jakarta.xml.bind.annotation.XmlMimeType) XmlAccessType(org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType) XmlSchemaType(jakarta.xml.bind.annotation.XmlSchemaType)

Example 4 with Type

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(".", "/") + ";");
}
Also used : Type(org.eclipse.persistence.internal.libraries.asm.Type)

Example 5 with Type

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);
                }
            }
        }
    }
}
Also used : Type(org.eclipse.persistence.internal.libraries.asm.Type) VirtualAttributeMethodInfo(org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo) Label(org.eclipse.persistence.internal.libraries.asm.Label)

Aggregations

Type (org.eclipse.persistence.internal.libraries.asm.Type)5 XmlAccessorType (jakarta.xml.bind.annotation.XmlAccessorType)2 XmlMimeType (jakarta.xml.bind.annotation.XmlMimeType)2 XmlSchemaType (jakarta.xml.bind.annotation.XmlSchemaType)2 XmlType (jakarta.xml.bind.annotation.XmlType)2 ParameterizedType (java.lang.reflect.ParameterizedType)2 Label (org.eclipse.persistence.internal.libraries.asm.Label)2 MethodVisitor (org.eclipse.persistence.internal.libraries.asm.MethodVisitor)2 XmlAccessType (org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType)2 XmlElement (jakarta.xml.bind.annotation.XmlElement)1 XmlJavaTypeAdapter (jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter)1 Annotation (java.lang.annotation.Annotation)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 VirtualAttributeMethodInfo (org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo)1 MappingAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor)1 AnnotationVisitor (org.eclipse.persistence.internal.libraries.asm.AnnotationVisitor)1 EclipseLinkASMClassWriter (org.eclipse.persistence.internal.libraries.asm.EclipseLinkASMClassWriter)1 FieldVisitor (org.eclipse.persistence.internal.libraries.asm.FieldVisitor)1 Namespace (org.eclipse.persistence.internal.oxm.Namespace)1