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);
}
}
}
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;
}
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();
}
}
}
}
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();
}
}
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;
}
}
}
Aggregations