Author: aadamchik
Date: Tue Nov 11 23:21:05 2008
New Revision: 713286
URL: http://svn.apache.org/viewvc?rev=713286&view=rev
Log:
CAY-795 Horizontal inheritance
encoding attribute override information in the AttributeProperties
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java?rev=713286&r1=713285&r2=713286&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java
Tue Nov 11 23:21:05 2008
@@ -49,13 +49,17 @@
// compiled properties ...
protected Class<?> objectClass;
protected Map<String, Property> declaredProperties;
+ protected Map<String, Property> superProperties;
protected Map<String, ClassDescriptor> subclassDescriptors;
protected Accessor persistenceStateAccessor;
protected ObjEntity entity;
- protected Collection<Property> declaredIdProperties;
- protected Collection<ArcProperty> declaredMapArcProperties;
+ // combines declared and super properties
+ protected Collection<Property> idProperties;
+
+ // combines declared and super properties
+ protected Collection<ArcProperty> mapArcProperties;
// inheritance information
protected Collection<DbAttribute> allDiscriminatorColumns;
@@ -66,6 +70,7 @@
*/
public PersistentDescriptor() {
this.declaredProperties = new HashMap<String, Property>();
+ this.superProperties = new HashMap<String, Property>();
this.subclassDescriptors = new HashMap<String, ClassDescriptor>();
}
@@ -79,21 +84,32 @@
}
/**
+ * Registers a superclass property.
+ */
+ public void addSuperProperty(Property property) {
+ superProperties.put(property.getName(), property);
+ indexAddedProperty(property);
+ }
+
+ /**
* Registers a property. This method is useful to customize default
ClassDescriptor
* generated from ObjEntity by adding new properties or overriding the
standard ones.
*/
public void addDeclaredProperty(Property property) {
declaredProperties.put(property.getName(), property);
+ indexAddedProperty(property);
+ }
+ void indexAddedProperty(Property property) {
if (property instanceof AttributeProperty) {
ObjAttribute attribute = ((AttributeProperty)
property).getAttribute();
if (attribute.isPrimaryKey()) {
- if (declaredIdProperties == null) {
- declaredIdProperties = new ArrayList<Property>(2);
+ if (idProperties == null) {
+ idProperties = new ArrayList<Property>(2);
}
- declaredIdProperties.add(property);
+ idProperties.add(property);
}
}
else if (property instanceof ArcProperty) {
@@ -102,11 +118,11 @@
if (reverseRelationship != null
&&
"java.util.Map".equals(reverseRelationship.getCollectionType())) {
- if (declaredMapArcProperties == null) {
- declaredMapArcProperties = new ArrayList<ArcProperty>(2);
+ if (mapArcProperties == null) {
+ mapArcProperties = new ArrayList<ArcProperty>(2);
}
- declaredMapArcProperties.add((ArcProperty) property);
+ mapArcProperties.add((ArcProperty) property);
}
}
}
@@ -119,20 +135,25 @@
Object removed = declaredProperties.remove(propertyName);
if (removed != null) {
- if (declaredIdProperties != null) {
- declaredIdProperties.remove(removed);
+ if (idProperties != null) {
+ idProperties.remove(removed);
}
- if (declaredMapArcProperties != null) {
- declaredMapArcProperties.remove(removed);
+ if (mapArcProperties != null) {
+ mapArcProperties.remove(removed);
}
}
}
- public void addSubclassDescriptor(ClassDescriptor subclassDescriptor) {
- subclassDescriptors.put(
- subclassDescriptor.getEntity().getClassName(),
- subclassDescriptor);
+ /**
+ * Adds a subclass descriptor that maps to a given class name.
+ */
+ public void addSubclassDescriptor(String className, ClassDescriptor
subclassDescriptor) {
+ // note that 'className' should be used instead of
+ // "subclassDescriptor.getEntity().getClassName()", as this method is
called in
+ // the early phases of descriptor initialization and we do not want to
trigger
+ // subclassDescriptor resolution just yet to prevent stack overflow.
+ subclassDescriptors.put(className, subclassDescriptor);
}
public ObjEntity getEntity() {
@@ -209,35 +230,20 @@
public Iterator<Property> getIdProperties() {
- Iterator<Property> it = null;
-
- if (getSuperclassDescriptor() != null) {
- it = getSuperclassDescriptor().getIdProperties();
- }
-
- if (declaredIdProperties != null) {
- it = (it != null) ? IteratorUtils.chainedIterator(it,
declaredIdProperties
- .iterator()) : declaredIdProperties.iterator();
+ if (idProperties != null) {
+ return idProperties.iterator();
}
- return it != null ? it : IteratorUtils.EMPTY_ITERATOR;
+ return IteratorUtils.EMPTY_ITERATOR;
}
public Iterator<ArcProperty> getMapArcProperties() {
- Iterator<ArcProperty> it = null;
-
- if (getSuperclassDescriptor() != null) {
- it = getSuperclassDescriptor().getMapArcProperties();
- }
- if (declaredMapArcProperties != null) {
- it = (it != null) ? IteratorUtils.chainedIterator(
- it,
- declaredMapArcProperties.iterator()) :
declaredMapArcProperties
- .iterator();
+ if (mapArcProperties != null) {
+ return mapArcProperties.iterator();
}
- return it != null ? it : IteratorUtils.EMPTY_ITERATOR;
+ return IteratorUtils.EMPTY_ITERATOR;
}
/**
@@ -331,6 +337,19 @@
/**
* @since 3.0
*/
+ boolean visitSuperProperties(PropertyVisitor visitor) {
+ for (Property next : superProperties.values()) {
+ if (!next.visit(visitor)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @since 3.0
+ */
public boolean visitDeclaredProperties(PropertyVisitor visitor) {
for (Property next : declaredProperties.values()) {
@@ -362,8 +381,7 @@
}
public boolean visitProperties(PropertyVisitor visitor) {
- if (superclassDescriptor != null
- && !superclassDescriptor.visitProperties(visitor)) {
+ if (!visitSuperProperties(visitor)) {
return false;
}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java?rev=713286&r1=713285&r2=713286&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java
Tue Nov 11 23:21:05 2008
@@ -125,6 +125,7 @@
.lookupInheritanceTree(descriptor.getEntity());
indexSubclassDescriptors(descriptor, inheritanceTree);
indexQualifiers(descriptor, inheritanceTree);
+ indexSuperclassProperties(descriptor);
return descriptor;
}
@@ -205,9 +206,10 @@
if (inheritanceTree != null) {
for (EntityInheritanceTree child : inheritanceTree.getChildren()) {
-
descriptor.addSubclassDescriptor(descriptorMap.getDescriptor(child
- .getEntity()
- .getName()));
+ ObjEntity childEntity = child.getEntity();
+ descriptor.addSubclassDescriptor(
+ childEntity.getClassName(),
+ descriptorMap.getDescriptor(childEntity.getName()));
indexSubclassDescriptors(descriptor, child);
}
@@ -252,6 +254,36 @@
}
/**
+ * Adds superclass properties to the descriptor, applying proper overrides.
+ */
+ protected void indexSuperclassProperties(final PersistentDescriptor
descriptor) {
+ ClassDescriptor superDescriptor = descriptor.getSuperclassDescriptor();
+ if (superDescriptor != null) {
+
+ superDescriptor.visitProperties(new PropertyVisitor() {
+
+ public boolean visitAttribute(AttributeProperty property) {
+ // decorate super property to return an overridden
attribute
+ descriptor.addSuperProperty(new AttributePropertyDecorator(
+ descriptor,
+ property));
+ return true;
+ }
+
+ public boolean visitToMany(ToManyProperty property) {
+ descriptor.addSuperProperty(property);
+ return true;
+ }
+
+ public boolean visitToOne(ToOneProperty property) {
+ descriptor.addSuperProperty(property);
+ return true;
+ }
+ });
+ }
+ }
+
+ /**
* Creates an accessor for the property.
*/
protected Accessor createAccessor(