use of org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo in project eclipselink by eclipse-ee4j.
the class ExtensibilityTests method testDescriptors.
public void testDescriptors() {
EntityManagerFactory emf = getEntityManagerFactory();
ServerSession session = (ServerSession) getDatabaseSession();
RelationalDescriptor empDescriptor = (RelationalDescriptor) session.getProject().getDescriptor(Employee.class);
assertTrue(empDescriptor.getMappingForAttributeName("phoneNumbers") != null);
if (isWeavingEnabled()) {
assertTrue(empDescriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy());
}
assertTrue(empDescriptor.getVirtualAttributeMethods() != null);
assertTrue(empDescriptor.getVirtualAttributeMethods().size() == 1);
VirtualAttributeMethodInfo info = empDescriptor.getVirtualAttributeMethods().get(0);
assertTrue(info.getGetMethodName().equals("getExt"));
assertTrue(info.getSetMethodName().equals("putExt"));
RelationalDescriptor addDescriptor = (RelationalDescriptor) session.getProject().getDescriptor(Address.class);
assertTrue(addDescriptor.getMappingForAttributeName("pobox") != null);
if (isWeavingEnabled()) {
assertTrue(addDescriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy());
}
assertTrue(addDescriptor.getVirtualAttributeMethods() != null);
assertTrue(addDescriptor.getVirtualAttributeMethods().size() == 1);
info = addDescriptor.getVirtualAttributeMethods().get(0);
assertTrue(info.getGetMethodName().equals("get"));
assertTrue(info.getSetMethodName().equals("set"));
}
use of org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo in project eclipselink by eclipse-ee4j.
the class MetadataDescriptor method setDefaultAccessMethods.
/**
* INTERNAL:
* Default access methods can come from the following locations
* (in XML only) :
* - persistence-unit-defaults
* - entity-mappings
* - entity
* - embeddable
*
* Be default, the default access methods are set to use "get" and "set"
* unless they are overridden by discovering access methods specified at
* one of the locations above.
*/
public void setDefaultAccessMethods(AccessMethodsMetadata accessMethods) {
m_defaultAccessMethods = accessMethods;
getClassDescriptor().getVirtualAttributeMethods().add(new VirtualAttributeMethodInfo(accessMethods.getGetMethodName(), accessMethods.getSetMethodName()));
}
use of org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo 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);
}
}
}
}
}
use of org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo in project eclipselink by eclipse-ee4j.
the class TransformerFactory method storeAttributeMappings.
/**
* INTERNAL:
* Store a set of attribute mappings on the given ClassDetails that correspond to the given class.
* Return the list of mappings that is not specifically found on the given class. These attributes will
* be found on MappedSuperclasses.
*/
protected List<DatabaseMapping> storeAttributeMappings(MetadataClass metadataClass, ClassDetails classDetails, List<DatabaseMapping> mappings, boolean weaveValueHolders) {
List<DatabaseMapping> unMappedAttributes = new ArrayList<>();
Map<String, AttributeDetails> attributesMap = new HashMap<String, AttributeDetails>();
Map<String, AttributeDetails> settersMap = new HashMap<String, AttributeDetails>();
Map<String, AttributeDetails> gettersMap = new HashMap<String, AttributeDetails>();
for (Iterator<DatabaseMapping> iterator = mappings.iterator(); iterator.hasNext(); ) {
DatabaseMapping mapping = iterator.next();
// Can't weave something that isn't really there and not going to be there.
if (mapping.isMultitenantPrimaryKeyMapping()) {
continue;
}
String attribute = mapping.getAttributeName();
AttributeDetails attributeDetails = new AttributeDetails(attribute, mapping);
if (mapping.getAttributeAccessor().isVirtualAttributeAccessor()) {
attributeDetails.setVirtualProperty(mapping.getAttributeAccessor().isVirtualAttributeAccessor());
if ((classDetails.getInfoForVirtualGetMethod(mapping.getGetMethodName()) == null) && (classDetails.getInfoForVirtualSetMethod(mapping.getSetMethodName()) == null)) {
VirtualAttributeMethodInfo info = new VirtualAttributeMethodInfo(mapping.getGetMethodName(), mapping.getSetMethodName());
classDetails.getVirtualAccessMethods().add(info);
}
}
// Initial look for the type of this attribute.
MetadataClass typeClass = getAttributeTypeFromClass(metadataClass, attribute, mapping, false);
if (typeClass == null) {
attributeDetails.setAttributeOnSuperClass(true);
unMappedAttributes.add(mapping);
}
// Set the getter and setter method names if the mapping uses property access.
if (mapping.getGetMethodName() != null) {
gettersMap.put(mapping.getGetMethodName(), attributeDetails);
attributeDetails.setGetterMethodName(mapping.getGetMethodName());
if (mapping.getSetMethodName() != null) {
settersMap.put(mapping.getSetMethodName(), attributeDetails);
attributeDetails.setSetterMethodName(mapping.getSetMethodName());
}
if (mapping.isForeignReferenceMapping() && ((ForeignReferenceMapping) mapping).requiresTransientWeavedFields()) {
attributeDetails.setWeaveTransientFieldValueHolders();
}
// If the property has a matching field, then weave it instead (unless internal weaving is disabled).
if (this.weaveInternal) {
attributeDetails.setHasField(hasFieldInClass(metadataClass, attribute));
}
} else {
attributeDetails.setHasField(true);
}
// If the attribute has a field, then the weaver needs to know in which class it was defined.
if (attributeDetails.hasField()) {
attributeDetails.setDeclaringType(Type.getType(getAttributeDeclaringClass(metadataClass, attribute).getTypeName()));
}
// Check for lazy/value-holder indirection.
if (mapping.isForeignReferenceMapping()) {
ForeignReferenceMapping foreignReferenceMapping = (ForeignReferenceMapping) mapping;
// repopulate the reference class with the target of this mapping
attributeDetails.setReferenceClassName(foreignReferenceMapping.getReferenceClassName());
if (attributeDetails.getReferenceClassName() != null) {
MetadataClass referenceClass = metadataClass.getMetadataFactory().getMetadataClass(attributeDetails.getReferenceClassName());
attributeDetails.setReferenceClassType(Type.getType(referenceClass.getTypeName()));
}
// This time, look up the type class and include the superclass so we can check for lazy.
if (typeClass == null) {
typeClass = getAttributeTypeFromClass(metadataClass, attribute, foreignReferenceMapping, true);
}
if (weaveValueHolders && (foreignReferenceMapping.getIndirectionPolicy() instanceof BasicIndirectionPolicy) && (typeClass != null) && (!typeClass.extendsInterface(ValueHolderInterface.class))) {
if (mapping.isObjectReferenceMapping() && attributeDetails.isVirtualProperty()) {
classDetails.setShouldWeaveValueHolders(false);
log(SessionLog.WARNING, CANNOT_WEAVE_VIRTUAL_ONE_TO_ONE, new Object[] { classDetails.getClassName(), attributeDetails.getAttributeName() });
} else {
attributeDetails.weaveVH(weaveValueHolders, foreignReferenceMapping);
}
}
}
if (attributeDetails.getReferenceClassType() == null) {
if (typeClass == null) {
typeClass = getAttributeTypeFromClass(metadataClass, attribute, mapping, true);
}
}
if (typeClass != null) {
attributeDetails.setReferenceClassName(typeClass.getName());
attributeDetails.setReferenceClassType(Type.getType(typeClass.getTypeName()));
}
attributesMap.put(attribute, attributeDetails);
}
classDetails.setAttributesMap(attributesMap);
classDetails.setGetterMethodToAttributeDetails(gettersMap);
classDetails.setSetterMethodToAttributeDetails(settersMap);
return unMappedAttributes;
}
Aggregations