diff options
author | kmoore | 2009-03-11 17:19:17 +0000 |
---|---|---|
committer | kmoore | 2009-03-11 17:19:17 +0000 |
commit | 8293550e8a3313b3674bc6cbb26a82d66222b300 (patch) | |
tree | a0389722419cb0348f631fb763630f1ff03d91a6 /jpa/plugins | |
parent | e4c7db1015dfada9fd31dfed7913546d6da21039 (diff) | |
download | webtools.dali-8293550e8a3313b3674bc6cbb26a82d66222b300.tar.gz webtools.dali-8293550e8a3313b3674bc6cbb26a82d66222b300.tar.xz webtools.dali-8293550e8a3313b3674bc6cbb26a82d66222b300.zip |
267260 - discriminator column validated on an entity with no actual inheritance
Diffstat (limited to 'jpa/plugins')
20 files changed, 364 insertions, 80 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/Entity.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/Entity.java index 02de8f3353..02ced05bdb 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/Entity.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/Entity.java @@ -147,17 +147,6 @@ public interface Entity String SPECIFIED_INHERITANCE_STRATEGY_PROPERTY = "specifiedInheritanceStrategy"; //$NON-NLS-1$ /** - * Return the ultimate top of the inheritance hierarchy - * This method should never return null. The root - * is defined as the persistent type in the inheritance hierarchy - * that has no parent. The root should be an entity - * - * Non-entities in the hierarchy should be ignored, ie skip - * over them in the search for the root. - */ - Entity getRootEntity(); - - /** * The first parent in the class hierarchy that is an entity. * This is the parent in the entity (persistent) inheritance hierarchy * (vs class inheritance hierarchy) @@ -175,7 +164,15 @@ public interface Entity void setSpecifiedDiscriminatorValue(String value); String SPECIFIED_DISCRIMINATOR_VALUE_PROPERTY = "specifiedDiscriminatorValue"; //$NON-NLS-1$ - /** + /** + * Return whether a DiscriminatorValue is allowed for this Entity. + * It is allowed if the entity is not abstract and not part of + * a table-per-class inheritance hierarchy + */ + boolean specifiedDiscriminatorValueIsAllowed(); + String SPECIFIED_DISCRIMINATOR_VALUE_IS_ALLOWED_PROPERTY = "discriminatorValueIsAllowed"; //$NON-NLS-1$ + + /** * Return whether a DiscriminatorValue is undefined for this Entity. * It is undefined if the entity is abstract or if it * is part of a table-per-class inheritance hierarchy @@ -185,7 +182,7 @@ public interface Entity /** * Return whether a DiscriminatorColumn is allowed for this Entity. - * It is allowed if the entity is the root of the inheritance hierarchy + * It is allowed if the entity is the root of the inheritance hierarchy (with descendant entities) * and the strategy is not table-per-class */ boolean specifiedDiscriminatorColumnIsAllowed(); @@ -334,5 +331,12 @@ public interface Entity void moveSpecifiedAssociationOverride(int targetIndex, int sourceIndex); String SPECIFIED_ASSOCIATION_OVERRIDES_LIST = "specifiedAssociationOverrides"; //$NON-NLS-1$ String VIRTUAL_ASSOCIATION_OVERRIDES_LIST = "virtualAssociationOverrides"; //$NON-NLS-1$ - + + + /** + * The given Entity has this entity as its root entity, add + * it as a sub entity. + * @see org.eclipse.jpt.core.context.persistence.PersistenceUnit#addRootWithSubEntities(String) + */ + void addSubEntity(Entity subEntity); } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/JpaContextNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/JpaContextNode.java index d59071805b..63f01fa295 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/JpaContextNode.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/JpaContextNode.java @@ -45,4 +45,9 @@ public interface JpaContextNode Catalog getContextDefaultDbCatalog(); Schema getContextDefaultDbSchema(); + + /** + * Called after the update is called. + */ + void postUpdate(); } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/persistence/PersistenceUnit.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/persistence/PersistenceUnit.java index 7b18e994d8..f93fb622bf 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/persistence/PersistenceUnit.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/context/persistence/PersistenceUnit.java @@ -617,6 +617,22 @@ public interface PersistenceUnit */ void addQuery(Query query); + + // ********** root entities ********** + + /** + * The entity with the given name should be a root entity that has sub entities. + * This will be stored by the persistence unit so that the entity can later + * call {@link #isRootWithSubEntities(String)} + */ + void addRootWithSubEntities(String entityName); + + /** + * Return whether the entity with the given name is a root entity + * that also has sub entities. + * @see #addRootWithSubEntities(String) + */ + boolean isRootWithSubEntities(String entityName); // ********** updating ********** diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractJpaProject.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractJpaProject.java index 897c481db5..97ca8f9c04 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractJpaProject.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractJpaProject.java @@ -61,7 +61,6 @@ import org.eclipse.jpt.utility.internal.ThreadLocalCommandExecutor; import org.eclipse.jpt.utility.internal.iterators.CloneIterator; import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; -import org.eclipse.jpt.utility.internal.iterators.ReadOnlyCompositeListIterator; import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; import org.eclipse.jst.j2ee.model.internal.validation.ValidationCancelledException; import org.eclipse.wst.validation.internal.provisional.core.IMessage; @@ -1004,6 +1003,7 @@ public abstract class AbstractJpaProject // update runs again as a result of the concurrent Java source changes. JptCorePlugin.log(ex); } + this.rootContextNode.postUpdate(); return Status.OK_STATUS; } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/AbstractJpaContextNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/AbstractJpaContextNode.java index 952387dbfe..5b35a9e908 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/AbstractJpaContextNode.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/AbstractJpaContextNode.java @@ -89,4 +89,7 @@ public abstract class AbstractJpaContextNode MappingFileRoot mfr = this.getMappingFileRoot(); return (mfr != null) ? mfr.getCatalog() : this.getPersistenceUnit().getDefaultCatalog(); } + + public void postUpdate() { + } } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java index 9821f92d96..c2109dea0b 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java @@ -122,6 +122,14 @@ public class GenericRootContextNode } } + @Override + public void postUpdate() { + super.postUpdate(); + if (this.persistenceXml != null) { + this.persistenceXml.postUpdate(); + } + } + protected JpaXmlResource getPersistenceXmlResource() { return this.jpaProject.getPersistenceXmlResource(); } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaEntity.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaEntity.java index 83c7f46e3d..c9ee60fefe 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaEntity.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaEntity.java @@ -122,10 +122,12 @@ public abstract class AbstractJavaEntity protected String defaultDiscriminatorValue; - protected boolean discriminatorValueIsUndefined; - protected String specifiedDiscriminatorValue; + protected boolean specifiedDiscriminatorValueIsAllowed; + + protected boolean discriminatorValueIsUndefined; + protected final JavaDiscriminatorColumn discriminatorColumn; protected boolean specifiedDiscriminatorColumnIsAllowed; @@ -149,7 +151,8 @@ public abstract class AbstractJavaEntity protected final List<JavaNamedNativeQuery> namedNativeQueries; protected String idClass; - + + protected Entity rootEntity; protected AbstractJavaEntity(JavaPersistentType parent) { super(parent); @@ -191,7 +194,7 @@ public abstract class AbstractJavaEntity return isDescendant() ? getRootEntity().getDiscriminatorColumn().getName() : - isTablePerClass() ? + discriminatorColumnIsUndefined()? null : DiscriminatorColumn.DEFAULT_NAME; @@ -201,7 +204,7 @@ public abstract class AbstractJavaEntity return isDescendant() ? getRootEntity().getDiscriminatorColumn().getLength() : - isTablePerClass() ? + discriminatorColumnIsUndefined()? 0//TODO think i want to return null here : DiscriminatorColumn.DEFAULT_LENGTH; @@ -211,7 +214,7 @@ public abstract class AbstractJavaEntity return isDescendant() ? getRootEntity().getDiscriminatorColumn().getDiscriminatorType() : - isTablePerClass() ? + discriminatorColumnIsUndefined()? null : DiscriminatorColumn.DEFAULT_DISCRIMINATOR_TYPE; @@ -225,8 +228,10 @@ public abstract class AbstractJavaEntity this.specifiedName = this.getResourceName(); this.defaultName = this.getResourceDefaultName(); + this.rootEntity = calculateRootEntity(); this.defaultInheritanceStrategy = this.buildDefaultInheritanceStrategy(); this.specifiedInheritanceStrategy = this.getResourceInheritanceStrategy(getResourceInheritance()); + this.specifiedDiscriminatorValueIsAllowed = this.buildSpecifiedDiscriminatorValueIsAllowed(); this.discriminatorValueIsUndefined = this.buildDiscriminatorValueIsUndefined(); this.specifiedDiscriminatorValue = this.getResourceDiscriminatorValue().getValue(); this.defaultDiscriminatorValue = this.buildDefaultDiscriminatorValue(); @@ -620,6 +625,16 @@ public abstract class AbstractJavaEntity public String getDiscriminatorValue() { return (this.getSpecifiedDiscriminatorValue() == null) ? getDefaultDiscriminatorValue() : this.getSpecifiedDiscriminatorValue(); } + + public boolean specifiedDiscriminatorValueIsAllowed() { + return this.specifiedDiscriminatorValueIsAllowed; + } + + protected void setSpecifiedDiscriminatorValueIsAllowed(boolean specifiedDiscriminatorValueIsAllowed) { + boolean old = this.specifiedDiscriminatorValueIsAllowed; + this.specifiedDiscriminatorValueIsAllowed = specifiedDiscriminatorValueIsAllowed; + firePropertyChanged(Entity.SPECIFIED_DISCRIMINATOR_VALUE_IS_ALLOWED_PROPERTY, old, specifiedDiscriminatorValueIsAllowed); + } public boolean discriminatorValueIsUndefined() { return this.discriminatorValueIsUndefined; @@ -1279,15 +1294,17 @@ public abstract class AbstractJavaEntity return this; } - public Entity getRootEntity() { - Entity rootEntity = this; - for (Iterator<PersistentType> stream = getPersistentType().inheritanceHierarchy(); stream.hasNext();) { - PersistentType persistentType = stream.next(); - if (persistentType.getMapping() instanceof Entity) { - rootEntity = (Entity) persistentType.getMapping(); - } - } - return rootEntity; + /** + * Return the ultimate top of the inheritance hierarchy + * This method should never return null. The root + * is defined as the persistent type in the inheritance hierarchy + * that has no parent. The root should be an entity + * + * Non-entities in the hierarchy should be ignored, ie skip + * over them in the search for the root. + */ + protected Entity getRootEntity() { + return this.rootEntity; } /** @@ -1352,6 +1369,14 @@ public abstract class AbstractJavaEntity } /** + * Return whether the entity is the top of an inheritance hierarchy + * and has no descendants and no specified inheritance strategy has been defined. + */ + protected boolean isRootNoDescendantsNoStrategyDefined() { + return isRoot() && !getPersistenceUnit().isRootWithSubEntities(this.getName()) && getSpecifiedInheritanceStrategy() == null; + } + + /** * Return whether the entity is abstract and is a part of a * "table per class" inheritance hierarchy. */ @@ -1545,11 +1570,9 @@ public abstract class AbstractJavaEntity this.setSpecifiedName_(this.getResourceName()); this.setDefaultName(this.getResourceDefaultName()); + this.updateRootEntity(); this.updateInheritance(this.getResourceInheritance()); - this.setSpecifiedDiscriminatorColumnIsAllowed(this.buildSpecifiedDiscriminatorColumnIsAllowed()); - this.setDiscriminatorColumnIsUndefined(this.buildDiscriminatorColumnIsUndefined()); this.updateDiscriminatorColumn(); - this.setDiscriminatorValueIsUndefined(this.buildDiscriminatorValueIsUndefined()); this.updateDiscriminatorValue(this.getResourceDiscriminatorValue()); this.setSpecifiedTableIsAllowed(this.buildSpecifiedTableIsAllowed()); this.setTableIsUndefined(this.buildTableIsUndefined()); @@ -1567,7 +1590,14 @@ public abstract class AbstractJavaEntity this.updateNamedNativeQueries(); this.updateIdClass(); } - + + @Override + public void postUpdate() { + super.postUpdate(); + postUpdateDiscriminatorColumn(); + postUpdateDiscriminatorValue(); + } + protected String getResourceName() { return this.getResourceMapping().getName(); } @@ -1593,12 +1623,46 @@ public abstract class AbstractJavaEntity return this.isRoot() ? InheritanceType.SINGLE_TABLE : this.getRootEntity().getInheritanceStrategy(); } + protected void updateRootEntity() { + //I am making an assumption here that we don't need property change notification for rootEntity, this might be wrong + this.rootEntity = calculateRootEntity(); + if (this.rootEntity != this) { + this.rootEntity.addSubEntity(this); + } + } + + protected Entity calculateRootEntity() { + Entity rootEntity = this; + for (Iterator<PersistentType> stream = getPersistentType().inheritanceHierarchy(); stream.hasNext();) { + PersistentType persistentType = stream.next(); + if (persistentType.getMapping() instanceof Entity) { + rootEntity = (Entity) persistentType.getMapping(); + } + } + return rootEntity; + } + + public void addSubEntity(Entity subEntity) { + getPersistenceUnit().addRootWithSubEntities(getName()); + } + protected void updateDiscriminatorColumn() { + this.setSpecifiedDiscriminatorColumnIsAllowed(this.buildSpecifiedDiscriminatorColumnIsAllowed()); getDiscriminatorColumn().update(this.javaResourcePersistentType); } + protected void postUpdateDiscriminatorColumn() { + this.setDiscriminatorColumnIsUndefined(this.buildDiscriminatorColumnIsUndefined()); + getDiscriminatorColumn().postUpdate(); + } + protected void updateDiscriminatorValue(DiscriminatorValueAnnotation discriminatorValueResource) { + this.setSpecifiedDiscriminatorValueIsAllowed(this.buildSpecifiedDiscriminatorValueIsAllowed()); this.setSpecifiedDiscriminatorValue_(discriminatorValueResource.getValue()); + } + + protected void postUpdateDiscriminatorValue() { + this.setDiscriminatorValueIsUndefined(this.buildDiscriminatorValueIsUndefined()); this.setDefaultDiscriminatorValue(this.buildDefaultDiscriminatorValue()); } @@ -1626,8 +1690,12 @@ public abstract class AbstractJavaEntity return this.getDiscriminatorColumn().getDiscriminatorType(); } + protected boolean buildSpecifiedDiscriminatorValueIsAllowed() { + return !isTablePerClass() && !isAbstract(); + } + protected boolean buildDiscriminatorValueIsUndefined() { - return isTablePerClass() || isAbstract(); + return isTablePerClass() || isAbstract() || isRootNoDescendantsNoStrategyDefined(); } protected boolean buildSpecifiedDiscriminatorColumnIsAllowed() { @@ -1635,7 +1703,7 @@ public abstract class AbstractJavaEntity } protected boolean buildDiscriminatorColumnIsUndefined() { - return isTablePerClass(); + return isTablePerClass() || isRootNoDescendantsNoStrategyDefined(); } protected boolean buildSpecifiedTableIsAllowed() { @@ -2066,7 +2134,7 @@ public abstract class AbstractJavaEntity } protected void validateDiscriminatorColumn(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { - if (specifiedDiscriminatorColumnIsAllowed()) { + if (specifiedDiscriminatorColumnIsAllowed() && !discriminatorColumnIsUndefined()) { getDiscriminatorColumn().validate(messages, reporter, astRoot); } else if (getDiscriminatorColumn().isResourceSpecified()) { @@ -2079,7 +2147,7 @@ public abstract class AbstractJavaEntity this, this.getDiscriminatorColumnTextRange(astRoot) ) - ); + ); } else if (isTablePerClass()) { messages.add( @@ -2090,8 +2158,7 @@ public abstract class AbstractJavaEntity this, this.getDiscriminatorColumnTextRange(astRoot) ) - ); - + ); } } } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaPersistentType.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaPersistentType.java index 7c29b31ae0..e34ab23a69 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaPersistentType.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaPersistentType.java @@ -529,7 +529,12 @@ public abstract class AbstractJavaPersistentType return getPersistenceUnit().getPersistentType(fullyQualifiedTypeName); } - + @Override + public void postUpdate() { + super.postUpdate(); + getMapping().postUpdate(); + } + // ********** validation ********** public void validate(List<IMessage> messages, IReporter reporter) { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaDiscriminatorColumn.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaDiscriminatorColumn.java index de4b570b89..f16e8cee36 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaDiscriminatorColumn.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaDiscriminatorColumn.java @@ -171,13 +171,20 @@ public class GenericJavaDiscriminatorColumn extends AbstractJavaNamedColumn<Disc @Override public void update(DiscriminatorColumnAnnotation discriminatorColumn) { - super.update(discriminatorColumn); - this.setDefaultDiscriminatorType(this.buildDefaultDiscriminatorType()); - this.setDefaultLength(this.buildDefaultLength()); + this.setSpecifiedName_(discriminatorColumn.getName()); + this.setColumnDefinition_(discriminatorColumn.getColumnDefinition()); this.setSpecifiedDiscriminatorType_(this.getResourceDiscriminatorType(discriminatorColumn)); this.setSpecifiedLength_(this.getResourceLength(discriminatorColumn)); } + @Override + public void postUpdate() { + super.postUpdate(); + this.setDefaultName(this.buildDefaultName()); + this.setDefaultLength(this.buildDefaultLength()); + this.setDefaultDiscriminatorType(this.buildDefaultDiscriminatorType()); + } + protected DiscriminatorType getResourceDiscriminatorType(DiscriminatorColumnAnnotation discriminatorColumn) { return DiscriminatorType.fromJavaResourceModel(discriminatorColumn.getDiscriminatorType()); } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractEntityMappings.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractEntityMappings.java index dc6514fdfb..02da8b8d68 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractEntityMappings.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractEntityMappings.java @@ -24,6 +24,7 @@ import org.eclipse.jpt.core.context.Generator; import org.eclipse.jpt.core.context.MappingFileRoot; import org.eclipse.jpt.core.context.NamedNativeQuery; import org.eclipse.jpt.core.context.NamedQuery; +import org.eclipse.jpt.core.context.PersistentType; import org.eclipse.jpt.core.context.Query; import org.eclipse.jpt.core.context.orm.EntityMappings; import org.eclipse.jpt.core.context.orm.OrmGenerator; @@ -817,6 +818,13 @@ public abstract class AbstractEntityMappings return getJpaFactory().buildOrmNamedNativeQuery(this, resourceNamedQuery); } + @Override + public void postUpdate() { + super.postUpdate(); + for (PersistentType persistentType : CollectionTools.iterable(this.persistentTypes())) { + persistentType.postUpdate(); + } + } // ********** text ********** diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmEntity.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmEntity.java index 7e38b936e1..01abbd23c9 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmEntity.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmEntity.java @@ -121,6 +121,8 @@ public abstract class AbstractOrmEntity protected String specifiedDiscriminatorValue; + protected boolean specifiedDiscriminatorValueIsAllowed; + protected boolean discriminatorValueIsUndefined; protected final OrmDiscriminatorColumn discriminatorColumn; @@ -145,6 +147,8 @@ public abstract class AbstractOrmEntity protected final List<OrmNamedNativeQuery> namedNativeQueries; + protected Entity rootEntity; + protected AbstractOrmEntity(OrmPersistentType parent, XmlEntity resourceMapping) { super(parent, resourceMapping); this.table = getJpaFactory().buildOrmTable(this); @@ -161,10 +165,12 @@ public abstract class AbstractOrmEntity this.namedNativeQueries = new ArrayList<OrmNamedNativeQuery>(); this.specifiedName = this.resourceTypeMapping.getName(); this.defaultName = this.buildDefaultName(); + this.rootEntity = this.calculateRootEntity(); this.initializeInheritance(this.getResourceInheritance()); this.specifiedDiscriminatorColumnIsAllowed = this.buildSpecifiedDiscriminatorColumnIsAllowed(); this.discriminatorColumnIsUndefined = this.buildDiscriminatorColumnIsUndefined(); this.discriminatorColumn.initialize(this.resourceTypeMapping); //TODO pass in to constructor + this.specifiedDiscriminatorValueIsAllowed = this.buildSpecifiedDiscriminatorValueIsAllowed(); this.discriminatorValueIsUndefined = this.buildDiscriminatorValueIsUndefined(); this.specifiedDiscriminatorValue = this.resourceTypeMapping.getDiscriminatorValue(); this.defaultDiscriminatorValue = this.buildDefaultDiscriminatorValue(); @@ -736,6 +742,16 @@ public abstract class AbstractOrmEntity return (this.getSpecifiedDiscriminatorValue() == null) ? getDefaultDiscriminatorValue() : this.getSpecifiedDiscriminatorValue(); } + public boolean specifiedDiscriminatorValueIsAllowed() { + return this.specifiedDiscriminatorValueIsAllowed; + } + + protected void setSpecifiedDiscriminatorValueIsAllowed(boolean specifiedDiscriminatorValueIsAllowed) { + boolean old = this.specifiedDiscriminatorValueIsAllowed; + this.specifiedDiscriminatorValueIsAllowed = specifiedDiscriminatorValueIsAllowed; + firePropertyChanged(Entity.SPECIFIED_DISCRIMINATOR_VALUE_IS_ALLOWED_PROPERTY, old, specifiedDiscriminatorValueIsAllowed); + } + public boolean discriminatorValueIsUndefined() { return this.discriminatorValueIsUndefined; } @@ -1229,15 +1245,17 @@ public abstract class AbstractOrmEntity return this; } - public Entity getRootEntity() { - Entity rootEntity = this; - for (Iterator<PersistentType> stream = getPersistentType().inheritanceHierarchy(); stream.hasNext();) { - PersistentType persistentType = stream.next(); - if (persistentType.getMapping() instanceof Entity) { - rootEntity = (Entity) persistentType.getMapping(); - } - } - return rootEntity; + /** + * Return the ultimate top of the inheritance hierarchy + * This method should never return null. The root + * is defined as the persistent type in the inheritance hierarchy + * that has no parent. The root should be an entity + * + * Non-entities in the hierarchy should be ignored, ie skip + * over them in the search for the root. + */ + protected Entity getRootEntity() { + return this.rootEntity; } public String getDefaultTableName() { @@ -1321,6 +1339,15 @@ public abstract class AbstractOrmEntity protected boolean isRoot() { return this == this.getRootEntity(); } + + /** + * Return whether the entity is the top of an inheritance hierarchy + * and has no descendants and no specified inheritance strategy has been defined. + */ + protected boolean isRootNoDescendantsNoStrategyDefined() { + return isRoot() && !getPersistenceUnit().isRootWithSubEntities(this.getName()) && getSpecifiedInheritanceStrategy() == null; + } + /** * Return whether the entity is abstract and is a part of a * "table per class" inheritance hierarchy. @@ -1639,12 +1666,9 @@ public abstract class AbstractOrmEntity this.setSpecifiedName(this.resourceTypeMapping.getName()); this.setDefaultName(this.buildDefaultName()); this.updateInheritance(this.getResourceInheritance()); - this.setSpecifiedDiscriminatorColumnIsAllowed(this.buildSpecifiedDiscriminatorColumnIsAllowed()); - this.setDiscriminatorColumnIsUndefined(this.buildDiscriminatorColumnIsUndefined()); - this.discriminatorColumn.update(this.resourceTypeMapping); - this.setDiscriminatorValueIsUndefined(this.buildDiscriminatorValueIsUndefined()); - this.setSpecifiedDiscriminatorValue(this.resourceTypeMapping.getDiscriminatorValue()); - this.setDefaultDiscriminatorValue(this.buildDefaultDiscriminatorValue()); + this.updateRootEntity(); + this.updateDiscriminatorColumn(); + this.updateDiscriminatorValue(); this.setSpecifiedTableIsAllowed(this.buildSpecifiedTableIsAllowed()); this.setTableIsUndefined(this.buildTableIsUndefined()); this.table.update(this.resourceTypeMapping); @@ -1661,6 +1685,14 @@ public abstract class AbstractOrmEntity this.updateNamedNativeQueries(); this.updateIdClass(this.getResourceIdClass()); } + + @Override + public void postUpdate() { + super.postUpdate(); + this.setDiscriminatorColumnIsUndefined(this.buildDiscriminatorColumnIsUndefined()); + getDiscriminatorColumn().postUpdate(); + postUpdateDiscriminatorValue(); + } protected String buildDefaultName() { if (!isMetadataComplete()) { @@ -1676,6 +1708,26 @@ public abstract class AbstractOrmEntity return null; } + protected void updateDiscriminatorColumn() { + this.setSpecifiedDiscriminatorColumnIsAllowed(this.buildSpecifiedDiscriminatorColumnIsAllowed()); + getDiscriminatorColumn().update(this.resourceTypeMapping); + } + + protected void postUpdateDiscriminatorColumn() { + this.setDiscriminatorColumnIsUndefined(this.buildDiscriminatorColumnIsUndefined()); + getDiscriminatorColumn().postUpdate(); + } + + protected void updateDiscriminatorValue() { + this.setSpecifiedDiscriminatorValueIsAllowed(this.buildSpecifiedDiscriminatorValueIsAllowed()); + this.setSpecifiedDiscriminatorValue(this.resourceTypeMapping.getDiscriminatorValue()); + } + + protected void postUpdateDiscriminatorValue() { + this.setDiscriminatorValueIsUndefined(this.buildDiscriminatorValueIsUndefined()); + this.setDefaultDiscriminatorValue(this.buildDefaultDiscriminatorValue()); + } + /** * From the Spec: * If the DiscriminatorValue annotation is not specified, a @@ -1710,8 +1762,12 @@ public abstract class AbstractOrmEntity return null; } + protected boolean buildSpecifiedDiscriminatorValueIsAllowed() { + return !isTablePerClass() && !isAbstract(); + } + protected boolean buildDiscriminatorValueIsUndefined() { - return isTablePerClass() || isAbstract(); + return isTablePerClass() || isAbstract() || isRootNoDescendantsNoStrategyDefined(); } protected boolean buildSpecifiedDiscriminatorColumnIsAllowed() { @@ -1719,7 +1775,7 @@ public abstract class AbstractOrmEntity } protected boolean buildDiscriminatorColumnIsUndefined() { - return isTablePerClass(); + return isTablePerClass() || isRootNoDescendantsNoStrategyDefined(); } protected boolean buildSpecifiedTableIsAllowed() { @@ -1733,7 +1789,30 @@ public abstract class AbstractOrmEntity protected void updateInheritance(Inheritance inheritanceResource) { this.setSpecifiedInheritanceStrategy_(this.getResourceInheritanceStrategy(inheritanceResource)); - this.setDefaultInheritanceStrategy(this.defaultInheritanceStrategy()); + this.setDefaultInheritanceStrategy(this.buildDefaultInheritanceStrategy()); + } + + protected void updateRootEntity() { + //I am making an assumption here that we don't need property change notification for rootEntity, this might be wrong + this.rootEntity = calculateRootEntity(); + if (this.rootEntity != this) { + this.rootEntity.addSubEntity(this); + } + } + + protected Entity calculateRootEntity() { + Entity rootEntity = this; + for (Iterator<PersistentType> stream = getPersistentType().inheritanceHierarchy(); stream.hasNext();) { + PersistentType persistentType = stream.next(); + if (persistentType.getMapping() instanceof Entity) { + rootEntity = (Entity) persistentType.getMapping(); + } + } + return rootEntity; + } + + public void addSubEntity(Entity subEntity) { + getPersistenceUnit().addRootWithSubEntities(getName()); } protected void updateSpecifiedSecondaryTables() { @@ -1827,7 +1906,7 @@ public abstract class AbstractOrmEntity return InheritanceType.fromOrmResourceModel(inheritanceResource.getStrategy()); } - protected InheritanceType defaultInheritanceStrategy() { + protected InheritanceType buildDefaultInheritanceStrategy() { if ((this.getResourceInheritance() == null) && ! this.isMetadataComplete() && (this.getJavaEntity() != null)) { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmPersistentType.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmPersistentType.java index b7d971556e..4a65099487 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmPersistentType.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmPersistentType.java @@ -638,7 +638,7 @@ public abstract class AbstractOrmPersistentType protected OrmPersistentAttribute.Owner buildVirtualPersistentAttributeOwner(final JavaPersistentAttribute javaPersistentAttribute) { return new OrmPersistentAttribute.Owner() { - public JavaPersistentAttribute findJavaPersistentAttribute(@SuppressWarnings("unused") OrmPersistentAttribute ormPersistentAttribute) { + public JavaPersistentAttribute findJavaPersistentAttribute(OrmPersistentAttribute ormPersistentAttribute) { return javaPersistentAttribute; } @@ -854,7 +854,16 @@ public abstract class AbstractOrmPersistentType return null; } } - + + @Override + public void postUpdate() { + super.postUpdate(); + if (getJavaPersistentType() != null) { + getJavaPersistentType().postUpdate(); + } + getMapping().postUpdate(); + } + public JpaStructureNode getStructureNode(int textOffset) { for (OrmPersistentAttribute attribute : CollectionTools.iterable(specifiedAttributes())) { if (attribute.contains(textOffset)) { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmXml.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmXml.java index 0e4a336124..475d3d47d4 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmXml.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmXml.java @@ -174,6 +174,14 @@ public abstract class AbstractOrmXml protected abstract EntityMappings buildEntityMappings(XmlEntityMappings xmlEntityMappings); + @Override + public void postUpdate() { + super.postUpdate(); + if (this.entityMappings != null) { + this.entityMappings.postUpdate(); + } + } + // ********** text ********** diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/GenericOrmDiscriminatorColumn.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/GenericOrmDiscriminatorColumn.java index 04a304ea41..59067cb62a 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/GenericOrmDiscriminatorColumn.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/GenericOrmDiscriminatorColumn.java @@ -177,13 +177,20 @@ public class GenericOrmDiscriminatorColumn extends AbstractOrmNamedColumn<XmlDis @Override protected void update(XmlDiscriminatorColumn column) { - super.update(column); - this.setDefaultDiscriminatorType(this.buildDefaultDiscriminatorType()); - this.setDefaultLength(this.buildDefaultLength()); + this.setSpecifiedName_(this.getResourceColumnName(column)); + this.setColumnDefinition_(this.getResourceColumnDefinition(column)); this.setSpecifiedLength_(this.getResourceLength(column)); this.setSpecifiedDiscriminatorType_(this.getResourceDiscriminatorType(column)); } + @Override + public void postUpdate() { + super.postUpdate(); + this.setDefaultName(this.getOwnerDefaultColumnName()); + this.setDefaultDiscriminatorType(this.buildDefaultDiscriminatorType()); + this.setDefaultLength(this.buildDefaultLength()); + } + protected Integer getResourceLength(XmlDiscriminatorColumn column) { return column == null ? null : column.getLength(); } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/AbstractMappingFileRef.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/AbstractMappingFileRef.java index ebd28b98ac..f1683edb14 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/AbstractMappingFileRef.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/AbstractMappingFileRef.java @@ -165,7 +165,15 @@ public abstract class AbstractMappingFileRef return this.getJpaPlatform().buildMappingFile(this, resource); } - + @Override + public void postUpdate() { + super.postUpdate(); + if (this.mappingFile != null) { + this.mappingFile.postUpdate(); + } + } + + // ********** validation ********** @Override diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/AbstractPersistenceUnit.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/AbstractPersistenceUnit.java index 42438761b9..3be35ac1eb 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/AbstractPersistenceUnit.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/AbstractPersistenceUnit.java @@ -16,7 +16,6 @@ import java.util.List; import java.util.ListIterator; import java.util.Set; import java.util.Vector; - import org.eclipse.core.runtime.content.IContentType; import org.eclipse.jpt.core.JpaStructureNode; import org.eclipse.jpt.core.JptCorePlugin; @@ -96,7 +95,9 @@ public abstract class AbstractPersistenceUnit /* global query definitions, defined elsewhere in model */ protected final Vector<Query> queries = new Vector<Query>(); - + + protected final Set<String> rootEntities = new HashSet<String>(); + protected AccessType defaultAccess; protected String defaultCatalog; protected String defaultSchema; @@ -851,7 +852,14 @@ public abstract class AbstractPersistenceUnit this.queries.add(query); } - + public void addRootWithSubEntities(String entityName) { + this.rootEntities.add(entityName); + } + + public boolean isRootWithSubEntities(String entityName) { + return this.rootEntities.contains(entityName); + } + // ********** updating ********** public void update(XmlPersistenceUnit xpu) { @@ -866,6 +874,8 @@ public abstract class AbstractPersistenceUnit this.generators.clear(); this.queries.clear(); + this.rootEntities.clear(); + this.setName(xpu.getName()); this.setSpecifiedTransactionType(this.buildSpecifiedTransactionType()); this.setDefaultTransactionType(this.buildDefaultTransactionType()); @@ -893,7 +903,24 @@ public abstract class AbstractPersistenceUnit this.fireListChanged(GENERATORS_LIST); this.fireListChanged(QUERIES_LIST); } - + + @Override + public void postUpdate() { + super.postUpdate(); + for (ClassRef classRef : CollectionTools.iterable(this.specifiedClassRefs())) { + classRef.postUpdate(); + } + for (ClassRef classRef : CollectionTools.iterable(this.impliedClassRefs())) { + classRef.postUpdate(); + } + for (MappingFileRef mappingFileRef : CollectionTools.iterable(this.specifiedMappingFileRefs())) { + mappingFileRef.postUpdate(); + } + if (this.impliedMappingFileRef != null) { + this.impliedMappingFileRef.postUpdate(); + } + } + protected PersistenceUnitTransactionType buildSpecifiedTransactionType() { return PersistenceUnitTransactionType.fromXmlResourceModel(this.xmlPersistenceUnit.getTransactionType()); } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericClassRef.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericClassRef.java index 063552a0ae..4f751f7d31 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericClassRef.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericClassRef.java @@ -213,7 +213,14 @@ public class GenericClassRef return this.getJpaFactory().buildJavaPersistentType(this, jrpt); } - + @Override + public void postUpdate() { + super.postUpdate(); + if (this.javaPersistentType != null) { + this.javaPersistentType.postUpdate(); + } + } + // ********** XmlContextNode implementation ********** public TextRange getValidationTextRange() { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistence.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistence.java index 6c9210dcbc..6d0e3743b4 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistence.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistence.java @@ -86,7 +86,7 @@ public class GenericPersistence extends AbstractXmlContextNode throw new IllegalStateException("This implementation does not support multiple persistence units."); //$NON-NLS-1$ } XmlPersistenceUnit xmlPersistenceUnit = PersistenceFactory.eINSTANCE.createXmlPersistenceUnit(); - this.persistenceUnit = createPersistenceUnit(xmlPersistenceUnit); + this.persistenceUnit = buildPersistenceUnit(xmlPersistenceUnit); this.xmlPersistence.getPersistenceUnits().add(xmlPersistenceUnit); fireItemAdded(PERSISTENCE_UNITS_LIST, index, this.persistenceUnit); return this.persistenceUnit; @@ -127,7 +127,7 @@ public class GenericPersistence extends AbstractXmlContextNode protected void initializePersistenceUnits() { // only adding one here, until we support multiple persistence units if (this.xmlPersistence.getPersistenceUnits().size() > 0) { - this.persistenceUnit = createPersistenceUnit(this.xmlPersistence.getPersistenceUnits().get(0)); + this.persistenceUnit = buildPersistenceUnit(this.xmlPersistence.getPersistenceUnits().get(0)); } } @@ -148,12 +148,20 @@ public class GenericPersistence extends AbstractXmlContextNode } else { if (xmlPersistenceUnit != null) { - addPersistenceUnit_(createPersistenceUnit(xmlPersistenceUnit)); + addPersistenceUnit_(buildPersistenceUnit(xmlPersistenceUnit)); } } } - protected PersistenceUnit createPersistenceUnit(XmlPersistenceUnit xmlPersistenceUnit) { + @Override + public void postUpdate() { + super.postUpdate(); + if (this.persistenceUnit != null) { + this.persistenceUnit.postUpdate(); + } + } + + protected PersistenceUnit buildPersistenceUnit(XmlPersistenceUnit xmlPersistenceUnit) { return getJpaFactory().buildPersistenceUnit(this, xmlPersistenceUnit); } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceXml.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceXml.java index 46ab33b35d..67214fb9fc 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceXml.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceXml.java @@ -155,6 +155,14 @@ public class GenericPersistenceXml } } + @Override + public void postUpdate() { + super.postUpdate(); + if (this.persistence != null) { + this.persistence.postUpdate(); + } + } + protected Persistence buildPersistence(XmlPersistence xmlPersistence) { return getJpaFactory().buildPersistence(this, xmlPersistence); } diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/AbstractInheritanceComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/AbstractInheritanceComposite.java index b3c2672c89..0dc6803be0 100644 --- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/AbstractInheritanceComposite.java +++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/AbstractInheritanceComposite.java @@ -139,10 +139,10 @@ public abstract class AbstractInheritanceComposite<T extends Entity> extends For } protected WritablePropertyValueModel<Boolean> buildDiscriminatorValueEnabledHolder() { - return new PropertyAspectAdapter<Entity, Boolean>(getSubjectHolder(), Entity.DISCRIMINATOR_VALUE_IS_UNDEFINED_PROPERTY) { + return new PropertyAspectAdapter<Entity, Boolean>(getSubjectHolder(), Entity.SPECIFIED_DISCRIMINATOR_VALUE_IS_ALLOWED_PROPERTY) { @Override protected Boolean buildValue_() { - return Boolean.valueOf(!this.subject.discriminatorValueIsUndefined()); + return Boolean.valueOf(this.subject.specifiedDiscriminatorValueIsAllowed()); } }; } |