Search in sources :

Example 1 with MappingAccessor

use of org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor in project eclipselink by eclipse-ee4j.

the class ClassAccessor method addAccessors.

/**
 * INTERNAL:
 * Add the accessors from this class accessors java class to the descriptor
 * tied to this class accessor. This method is called for every class
 * accessor and is also called from parent class accessors to each of its
 * subclasses of a TABLE_PER_CLASS inheritance strategy.
 *
 * Add accessors is called in the preProcess stage and must not be called
 * until its owning class accessor has processed its access type.
 */
public void addAccessors() {
    if (m_attributes != null) {
        for (MappingAccessor accessor : m_attributes.getAccessors()) {
            // Load the accessible object from the class.
            MetadataAccessibleObject accessibleObject = null;
            // We must init all xml mapping accessors with a reference
            // of their owning class accessor. The mapping accessors
            // require metatata information from them to ensure they
            // process themselves correctly.
            accessor.initXMLMappingAccessor(this);
            // from a parent class)
            if (accessor.usesVirtualAccess()) {
                accessibleObject = getAccessibleVirtualMethod(accessor);
            } else if (accessor.usesPropertyAccess()) {
                accessibleObject = getAccessibleMethod(accessor);
            } else {
                accessibleObject = getAccessibleField(accessor);
            }
            // further process this accessor.
            if (accessibleObject != null) {
                // Initialize the accessor with its real accessible object
                // now, that is a field or method since it will currently
                // hold a reference to its owning class' accessible object.
                accessor.initXMLObject(accessibleObject, getEntityMappings());
                // It's now safe to init the correct access type for this
                // mapping accessor since we now have set the actual
                // accessible object for this mapping accessor. Note: the
                // initAccess call was originally in initXMLObject, but with
                // the current processing setup that isn't valid since
                // mapping accessors have their accessible object 'faked'
                // out for xml merging purposes during XMLAttributes
                // initXMLObject call. Doing the access initialization there
                // could cause one of two problems: Firstly, an incorrect
                // access type setting and secondly and more importantly, a
                // null pointer exception (bug 264596) since our descriptor
                // hasn't been set which we use to retrieve the default
                // access type.
                accessor.initAccess();
                // for a virtual class.
                if (accessor.usesVirtualAccess() && !accessor.hasAttributeType()) {
                    throw ValidationException.noAttributeTypeSpecification(accessor.getAttributeName(), getJavaClassName(), getLocation());
                }
                // Add the accessor to the descriptor's list
                addAccessor(accessor);
            }
        }
    }
    // look any further then what is defined in XML.
    if (!usesVirtualAccess()) {
        if (usesPropertyAccess()) {
            addAccessorMethods(false);
        } else {
            addAccessorFields(false);
        }
    }
}
Also used : MetadataAccessibleObject(org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAccessibleObject) MappingAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor)

Example 2 with MappingAccessor

use of org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor in project eclipselink by eclipse-ee4j.

the class MetadataDescriptor method getMappingAccessor.

/**
 * INTERNAL:
 * This method will first check for an accessor with name equal to field or
 * property name. If no accessor is found and the checkForMethodName flag is
 * set to true then we'll attempt to convert a potential method name to its
 * corresponding property name and looks for the accessor again. If still no
 * accessor is found and this descriptor represents an inheritance subclass,
 * then traverse up the chain to look for that accessor. Null is returned
 * otherwise.
 */
protected MappingAccessor getMappingAccessor(String fieldOrPropertyName, boolean checkForMethodName) {
    MappingAccessor accessor = m_mappingAccessors.get(fieldOrPropertyName);
    if (accessor == null) {
        // specifies a method name.
        if (checkForMethodName) {
            accessor = m_mappingAccessors.get(Helper.getAttributeNameFromMethodName(fieldOrPropertyName));
        }
        // accessor list, we don't want to deal with it.
        if (accessor == null && isInheritanceSubclass() && !usesTablePerClassInheritanceStrategy()) {
            accessor = getInheritanceParentDescriptor().getMappingAccessor(fieldOrPropertyName, checkForMethodName);
        }
    }
    if (accessor == null) {
        // Traverse any dot notation (nested embeddables) if specified.
        int idx = fieldOrPropertyName.indexOf('.');
        if (idx > -1) {
            String attributeName = fieldOrPropertyName.substring(0, idx);
            String subAttributeName = fieldOrPropertyName.substring(idx + 1);
            MappingAccessor embeddedAccessor = m_mappingAccessors.get(attributeName);
            if (embeddedAccessor != null) {
                accessor = embeddedAccessor.getReferenceDescriptor().getMappingAccessor(subAttributeName, checkForMethodName);
            }
        }
        // of tests that don't use the dot notation.
        if (accessor == null) {
            // descriptor), check our aggregate descriptors now.
            for (MetadataDescriptor embeddableDescriptor : m_embeddableDescriptors) {
                // If the attribute name employs the dot notation, rip off
                // the first  bit (up to the first dot and keep burying down
                // the embeddables)
                String subAttributeName = fieldOrPropertyName;
                if (subAttributeName.contains(".")) {
                    subAttributeName = subAttributeName.substring(fieldOrPropertyName.indexOf('.') + 1);
                }
                accessor = embeddableDescriptor.getMappingAccessor(fieldOrPropertyName, checkForMethodName);
                if (accessor != null) {
                    // Found one, stop looking ...
                    break;
                }
            }
        }
    }
    return accessor;
}
Also used : MappingAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor)

Example 3 with MappingAccessor

use of org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor in project eclipselink by eclipse-ee4j.

the class MetadataDescriptor method processMappingAccessors.

/**
 * INTERNAL:
 * Process this descriptors mapping accessors. Some accessors will not be
 * processed right away, instead stored on the project for processing in a
 * later  stage. This method can not and must not be called beyond
 * MetadataProject stage 2 processing.
 */
public void processMappingAccessors() {
    for (MappingAccessor accessor : m_mappingAccessors.values()) {
        if (!accessor.isProcessed()) {
            // key, process that embeddable accessor now.
            if (accessor.isMappedKeyMapAccessor()) {
                MappedKeyMapAccessor mapAccessor = (MappedKeyMapAccessor) accessor;
                EmbeddableAccessor mapKeyEmbeddableAccessor = getProject().getEmbeddableAccessor(mapAccessor.getMapKeyClass());
                if (mapKeyEmbeddableAccessor != null && !mapKeyEmbeddableAccessor.isProcessed()) {
                    mapKeyEmbeddableAccessor.process();
                }
            }
            // Care must be taken in the order of checking here.
            if (accessor.isDirectEmbeddableCollection() || accessor.isEmbedded()) {
                EmbeddableAccessor embeddableAccessor = getProject().getEmbeddableAccessor(accessor.getReferenceClass());
                // not an Embeddable.
                if (embeddableAccessor == null) {
                    throw ValidationException.invalidEmbeddedAttribute(getJavaClass(), accessor.getAttributeName(), accessor.getReferenceClass());
                } else {
                    // Process the embeddable class now (if it's not already processed)
                    if (!embeddableAccessor.isProcessed()) {
                        embeddableAccessor.process();
                    }
                    // Store this descriptor metadata. It may be needed again
                    // later on to look up a mappedBy attribute etc.
                    addEmbeddableDescriptor(embeddableAccessor.getDescriptor());
                    // accessors have processed.
                    if (accessor.isEmbeddedId() || accessor.isDerivedIdClass()) {
                        accessor.process();
                    } else {
                        // Otherwise defer it because of association overrides.
                        // We can't process this mapping till all the
                        // relationship mappings have been processed.
                        getProject().addEmbeddableMappingAccessor(accessor);
                    }
                }
            } else if (accessor.isDirectCollection()) {
                getProject().addDirectCollectionAccessor(accessor);
            } else if (accessor.isRelationship()) {
                if (accessor.derivesId()) {
                    m_derivedIdAccessors.add((ObjectAccessor) accessor);
                    getProject().addAccessorWithDerivedId(m_classAccessor);
                } else {
                    addRelationshipAccessor((RelationshipAccessor) accessor);
                }
            } else {
                accessor.process();
            }
        }
    }
}
Also used : MappingAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor) MappedKeyMapAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappedKeyMapAccessor) EmbeddableAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EmbeddableAccessor)

Example 4 with MappingAccessor

use of org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor 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 5 with MappingAccessor

use of org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor in project eclipselink by eclipse-ee4j.

the class CanonicalModelProcessor method generateCanonicalModelClass.

/**
 * INTERNAL:
 */
protected void generateCanonicalModelClass(MetadataClass metadataClass, Element element, PersistenceUnit persistenceUnit) throws IOException {
    Writer writer = null;
    try {
        ClassAccessor accessor = persistenceUnit.getClassAccessor(metadataClass);
        String qualifiedName = accessor.getAccessibleObjectName();
        String className = getName(qualifiedName);
        String classPackage = getPackage(qualifiedName);
        String qualifiedCanonicalName = persistenceUnit.getQualifiedCanonicalName(qualifiedName);
        String canonicalName = getName(qualifiedCanonicalName);
        String canonicalpackage = getPackage(qualifiedCanonicalName);
        boolean isNewJava = SourceVersion.RELEASE_8.compareTo(processingEnv.getSourceVersion()) < 0;
        JavaFileObject file = processingEnv.getFiler().createSourceFile(qualifiedCanonicalName, element);
        writer = file.openWriter();
        // Print the package if we have one.
        if (!canonicalpackage.equals("")) {
            writer.append("package " + canonicalpackage + ";\n\n");
        }
        // Go through the accessor list, ignoring any transient accessors
        // to build our attributes and import list.
        ArrayList<String> attributes = new ArrayList<>();
        HashMap<String, String> imports = new HashMap<>();
        if (generateGenerated) {
            if (isNewJava) {
                imports.put("Generated", "javax.annotation.processing.Generated");
            } else {
                imports.put("Generated", "jakarta.annotation.Generated");
            }
        }
        // Import the model class if the canonical class is generated elsewhere.
        if (!classPackage.equals(canonicalpackage)) {
            imports.put(className, qualifiedName);
        }
        for (MappingAccessor mappingAccessor : accessor.getDescriptor().getMappingAccessors()) {
            if (!mappingAccessor.isTransient()) {
                MetadataAnnotatedElement annotatedElement = mappingAccessor.getAnnotatedElement();
                // Must go through the mapping accessor for the raw class
                // since it may be a virtual mapping accessor with an
                // attribute type.
                MetadataClass rawClass = mappingAccessor.getRawClass();
                // NOTE: order of checking is important.
                String attributeType;
                String types = className;
                if (mappingAccessor.isBasic()) {
                    types = types + ", " + getUnqualifiedType(getBoxedType(annotatedElement, rawClass), imports);
                    attributeType = AttributeType.SingularAttribute.name();
                    imports.put(attributeType, "jakarta.persistence.metamodel.SingularAttribute");
                } else {
                    if (rawClass.isList()) {
                        attributeType = AttributeType.ListAttribute.name();
                        imports.put(attributeType, "jakarta.persistence.metamodel.ListAttribute");
                    } else if (rawClass.isSet()) {
                        attributeType = AttributeType.SetAttribute.name();
                        imports.put(attributeType, "jakarta.persistence.metamodel.SetAttribute");
                    } else if (rawClass.isMap()) {
                        attributeType = AttributeType.MapAttribute.name();
                        imports.put(attributeType, "jakarta.persistence.metamodel.MapAttribute");
                    } else if (rawClass.isCollection()) {
                        attributeType = AttributeType.CollectionAttribute.name();
                        imports.put(attributeType, "jakarta.persistence.metamodel.CollectionAttribute");
                    } else {
                        attributeType = AttributeType.SingularAttribute.name();
                        imports.put(attributeType, "jakarta.persistence.metamodel.SingularAttribute");
                    }
                    if (mappingAccessor.isMapAccessor()) {
                        if (mappingAccessor.isMappedKeyMapAccessor()) {
                            MetadataClass mapKeyClass = ((MappedKeyMapAccessor) mappingAccessor).getMapKeyClass();
                            types = types + ", " + getUnqualifiedType(mapKeyClass.getName(), imports) + ", " + getUnqualifiedType(mappingAccessor.getReferenceClassName(), imports);
                        } else {
                            String mapKeyType;
                            if (annotatedElement.isGenericCollectionType()) {
                                // Grab the map key class from the generic.
                                mapKeyType = annotatedElement.getGenericType().get(1);
                            } else {
                                if (mappingAccessor.getReferenceDescriptor().hasIdAccessor()) {
                                    // Grab the id type from the reference descriptor, now there's a handle!
                                    MappingAccessor idAccessor = mappingAccessor.getReferenceDescriptor().getIdAccessors().values().iterator().next();
                                    mapKeyType = idAccessor.getReferenceClassName();
                                } else {
                                    // We don't know at this point so just use the catch all default.
                                    mapKeyType = TypeVisitor.GENERIC_TYPE;
                                }
                            }
                            types = types + ", " + getUnqualifiedType(mapKeyType, imports) + ", " + getUnqualifiedType(mappingAccessor.getReferenceClassName(), imports);
                        }
                    } else {
                        types = types + ", " + getUnqualifiedType(mappingAccessor.getReferenceClassName(), imports);
                    }
                }
                // Add the mapping attribute to the list of attributes for this class.
                attributes.add("    public static volatile " + attributeType + "<" + types + "> " + annotatedElement.getAttributeName() + ";\n");
            }
        }
        // Will import the parent as well if needed.
        String parent = writeImportStatements(imports, accessor, writer, persistenceUnit, canonicalpackage);
        if (generateGenerated) {
            // Write out the generation annotations.
            String elVersion = "EclipseLink-" + Version.getVersion() + ".v" + Version.getBuildDate() + "-r" + Version.getBuildRevision();
            writer.append("@Generated(value=\"");
            if (isNewJava) {
                writer.append(CanonicalModelProcessor.class.getName());
            } else {
                writer.append(elVersion);
            }
            writer.append("\"");
            if (generateTimestamp) {
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                writer.append(", date=\"" + sdf.format(date) + "\"");
            }
            if (isNewJava && generateComments) {
                writer.append(", comments=\"");
                writer.append(elVersion);
                writer.append("\"");
            }
            writer.append(")\n");
        }
        writer.append("@StaticMetamodel(" + className + ".class)\n");
        int modifier = accessor.getAccessibleObject().getModifiers();
        writer.append(java.lang.reflect.Modifier.toString(modifier) + " class " + canonicalName);
        if (parent == null) {
            writer.append(" { \n\n");
        } else {
            writer.append(" extends " + parent + " {\n\n");
        }
        // Go through the attributes and write them out.
        for (String str : attributes) {
            writer.append(str);
        }
        writer.append("\n}");
    } finally {
        if (writer != null) {
            writer.flush();
            writer.close();
            writer = null;
        }
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) MappedKeyMapAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappedKeyMapAccessor) Date(java.util.Date) JavaFileObject(javax.tools.JavaFileObject) MetadataAnnotatedElement(org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAnnotatedElement) MetadataClass(org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass) ClassAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor) MappingAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor) SimpleDateFormat(java.text.SimpleDateFormat) Writer(java.io.Writer)

Aggregations

MappingAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor)11 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 ClassAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor)3 EmbeddableAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EmbeddableAccessor)2 BasicAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicAccessor)2 IdAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.IdAccessor)2 MappedKeyMapAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappedKeyMapAccessor)2 MetadataAccessibleObject (org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAccessibleObject)2 NamedNativeQueryMetadata (org.eclipse.persistence.internal.jpa.metadata.queries.NamedNativeQueryMetadata)2 Writer (java.io.Writer)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Date (java.util.Date)1 List (java.util.List)1 Map (java.util.Map)1 StringTokenizer (java.util.StringTokenizer)1 JavaFileObject (javax.tools.JavaFileObject)1 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)1 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)1 EntityAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor)1