diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context')
21 files changed, 964 insertions, 900 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaAttributeMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaAttributeMapping.java index 9d2348efe7..bd856bfd80 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaAttributeMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaAttributeMapping.java @@ -12,6 +12,7 @@ package org.eclipse.jpt.core.internal.context.java; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Vector; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.context.AttributeMapping; @@ -33,7 +34,6 @@ import org.eclipse.jpt.core.resource.java.Annotation; import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute; import org.eclipse.jpt.core.utility.TextRange; import org.eclipse.jpt.db.Table; -import org.eclipse.jpt.utility.internal.iterators.ArrayListIterator; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; import org.eclipse.jpt.utility.internal.iterators.SingleElementIterator; import org.eclipse.wst.validation.internal.provisional.core.IMessage; @@ -48,13 +48,33 @@ public abstract class AbstractJavaAttributeMapping<T extends Annotation> { protected T mappingAnnotation; - private String[] supportingAnnotationNames; + protected Vector<String> supportingAnnotationNames; protected AbstractJavaAttributeMapping(JavaPersistentAttribute parent) { super(parent); } + @SuppressWarnings("unchecked") + public void initialize(Annotation annotation) { + this.mappingAnnotation = (T) annotation; + this.initialize(); + } + + protected void initialize() { + // do nothing by default + } + + @SuppressWarnings("unchecked") + public void update(Annotation annotation) { + this.mappingAnnotation = (T) annotation; + this.update(); + } + + protected void update() { + // do nothing by default + } + @Override public JavaPersistentAttribute getParent() { return (JavaPersistentAttribute) super.getParent(); @@ -167,47 +187,29 @@ public abstract class AbstractJavaAttributeMapping<T extends Annotation> return null; } - // ********** supporting annotation names ********** - - public Iterator<String> supportingAnnotationNames() { - return new ArrayListIterator<String>(getSupportingAnnotationNames()); + @Override + public void toString(StringBuilder sb) { + sb.append(this.getName()); } - - protected synchronized String[] getSupportingAnnotationNames() { + + + // ********** supporting annotation names ********** + + public Iterable<String> getSupportingAnnotationNames() { if (this.supportingAnnotationNames == null) { this.supportingAnnotationNames = this.buildSupportingAnnotationNames(); } return this.supportingAnnotationNames; } - - protected String[] buildSupportingAnnotationNames() { - return new String[0]; - } - - - @SuppressWarnings("unchecked") - public void initialize(Annotation annotation) { - this.mappingAnnotation = (T) annotation; - this.initialize(); - } - protected void initialize() { - // do nothing by default + protected Vector<String> buildSupportingAnnotationNames() { + Vector<String> names = new Vector<String>(); + this.addSupportingAnnotationNamesTo(names); + return names; } - @SuppressWarnings("unchecked") - public void update(Annotation annotation) { - this.mappingAnnotation = (T) annotation; - this.update(); - } - - protected void update() { - // do nothing by default - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getName()); + protected void addSupportingAnnotationNamesTo(@SuppressWarnings("unused") Vector<String> names) { + // the default is none } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaBaseEmbeddedMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaBaseEmbeddedMapping.java index b7181fc07f..84b65f332f 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaBaseEmbeddedMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaBaseEmbeddedMapping.java @@ -11,6 +11,8 @@ package org.eclipse.jpt.core.internal.context.java; import java.util.Iterator; import java.util.List; +import java.util.Vector; + import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.JptCorePlugin; import org.eclipse.jpt.core.context.AttributeMapping; @@ -25,7 +27,6 @@ import org.eclipse.jpt.core.context.java.JavaPersistentAttribute; import org.eclipse.jpt.core.resource.java.Annotation; import org.eclipse.jpt.core.resource.java.JPA; import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; @@ -58,11 +59,10 @@ public abstract class AbstractJavaBaseEmbeddedMapping<T extends Annotation> //****************** JavaAttributeMapping implementation ******************* @Override - protected String[] buildSupportingAnnotationNames() { - return ArrayTools.addAll( - super.buildSupportingAnnotationNames(), - JPA.ATTRIBUTE_OVERRIDE, - JPA.ATTRIBUTE_OVERRIDES); + protected void addSupportingAnnotationNamesTo(Vector<String> names) { + super.addSupportingAnnotationNamesTo(names); + names.add(JPA.ATTRIBUTE_OVERRIDE); + names.add(JPA.ATTRIBUTE_OVERRIDES); } public Embeddable getEmbeddable() { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaBasicMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaBasicMapping.java index 95c7c29a94..b4630cbc31 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaBasicMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaBasicMapping.java @@ -11,6 +11,7 @@ package org.eclipse.jpt.core.internal.context.java; import java.util.Iterator; import java.util.List; +import java.util.Vector; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.MappingKeys; @@ -31,7 +32,6 @@ import org.eclipse.jpt.core.resource.java.JPA; import org.eclipse.jpt.core.resource.java.LobAnnotation; import org.eclipse.jpt.core.resource.java.TemporalAnnotation; import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; @@ -81,13 +81,12 @@ public abstract class AbstractJavaBasicMapping } @Override - protected String[] buildSupportingAnnotationNames() { - return ArrayTools.addAll( - super.buildSupportingAnnotationNames(), - JPA.COLUMN, - JPA.LOB, - JPA.TEMPORAL, - JPA.ENUMERATED); + protected void addSupportingAnnotationNamesTo(Vector<String> names) { + super.addSupportingAnnotationNamesTo(names); + names.add(JPA.COLUMN); + names.add(JPA.LOB); + names.add(JPA.TEMPORAL); + names.add(JPA.ENUMERATED); } public String getDefaultColumnName() { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaEmbeddable.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaEmbeddable.java index 272d0f0cd3..0bcff08ea6 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaEmbeddable.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaEmbeddable.java @@ -9,12 +9,11 @@ ******************************************************************************/ package org.eclipse.jpt.core.internal.context.java; -import java.util.Iterator; import org.eclipse.jpt.core.MappingKeys; import org.eclipse.jpt.core.context.java.JavaEmbeddable; import org.eclipse.jpt.core.context.java.JavaPersistentType; import org.eclipse.jpt.core.resource.java.EmbeddableAnnotation; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; +import org.eclipse.jpt.utility.internal.iterables.EmptyIterable; public abstract class AbstractJavaEmbeddable @@ -33,8 +32,8 @@ public abstract class AbstractJavaEmbeddable return EmbeddableAnnotation.ANNOTATION_NAME; } - public Iterator<String> supportingAnnotationNames() { - return EmptyIterator.instance(); + public Iterable<String> getSupportingAnnotationNames() { + return EmptyIterable.instance(); } public boolean isMapped() { 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 e5ace7151e..5023cfb1f1 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 @@ -67,7 +67,7 @@ import org.eclipse.jpt.db.Schema; import org.eclipse.jpt.utility.Filter; import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.jpt.utility.internal.CollectionTools; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; +import org.eclipse.jpt.utility.internal.iterables.ArrayIterable; import org.eclipse.jpt.utility.internal.iterators.CloneListIterator; import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; @@ -360,8 +360,10 @@ public abstract class AbstractJavaEntity return EntityAnnotation.ANNOTATION_NAME; } - public Iterator<String> supportingAnnotationNames() { - return new ArrayIterator<String>( + public Iterable<String> getSupportingAnnotationNames() { + return SUPPORTING_ANNOTATION_NAMES; + } + protected static final String[] SUPPORTING_ANNOTATION_NAMES_ARRAY = new String[] { JPA.TABLE, JPA.SECONDARY_TABLE, JPA.SECONDARY_TABLES, @@ -391,8 +393,9 @@ public abstract class AbstractJavaEntity JPA.ATTRIBUTE_OVERRIDE, JPA.ATTRIBUTE_OVERRIDES, JPA.ASSOCIATION_OVERRIDE, - JPA.ASSOCIATION_OVERRIDES); - } + JPA.ASSOCIATION_OVERRIDES + }; + protected static final Iterable<String> SUPPORTING_ANNOTATION_NAMES = new ArrayIterable<String>(SUPPORTING_ANNOTATION_NAMES_ARRAY); //****************** Entity implementation ******************* @@ -886,7 +889,7 @@ public abstract class AbstractJavaEntity * and has no descendants and no specified inheritance strategy has been defined. */ protected boolean isRootNoDescendantsNoStrategyDefined() { - return isRoot() && !getPersistenceUnit().isRootWithSubEntities(this.getName()) && getSpecifiedInheritanceStrategy() == null; + return isRoot() && !getPersistenceUnit().entityIsRootWithSubEntities(this.getName()) && getSpecifiedInheritanceStrategy() == null; } /** @@ -1159,7 +1162,7 @@ public abstract class AbstractJavaEntity } public void addSubEntity(Entity subEntity) { - getPersistenceUnit().addRootWithSubEntities(getName()); + getPersistenceUnit().addRootEntityWithSubEntities(getName()); } protected void updateDiscriminatorColumn() { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaIdMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaIdMapping.java index 47725d019c..b52c20ffb7 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaIdMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaIdMapping.java @@ -11,6 +11,7 @@ package org.eclipse.jpt.core.internal.context.java; import java.util.Iterator; import java.util.List; +import java.util.Vector; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.MappingKeys; @@ -31,7 +32,6 @@ import org.eclipse.jpt.core.resource.java.SequenceGeneratorAnnotation; import org.eclipse.jpt.core.resource.java.TableGeneratorAnnotation; import org.eclipse.jpt.core.resource.java.TemporalAnnotation; import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.StringTools; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; @@ -98,14 +98,13 @@ public abstract class AbstractJavaIdMapping } @Override - protected String[] buildSupportingAnnotationNames() { - return ArrayTools.addAll( - super.buildSupportingAnnotationNames(), - JPA.COLUMN, - JPA.GENERATED_VALUE, - JPA.TEMPORAL, - JPA.TABLE_GENERATOR, - JPA.SEQUENCE_GENERATOR); + protected void addSupportingAnnotationNamesTo(Vector<String> names) { + super.addSupportingAnnotationNamesTo(names); + names.add(JPA.COLUMN); + names.add(JPA.GENERATED_VALUE); + names.add(JPA.TEMPORAL); + names.add(JPA.TABLE_GENERATOR); + names.add(JPA.SEQUENCE_GENERATOR); } public String getDefaultColumnName() { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaMappedSuperclass.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaMappedSuperclass.java index f8eccaa765..afb7f125fc 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaMappedSuperclass.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaMappedSuperclass.java @@ -9,8 +9,6 @@ ******************************************************************************/ package org.eclipse.jpt.core.internal.context.java; -import java.util.Iterator; - import org.eclipse.jpt.core.MappingKeys; import org.eclipse.jpt.core.context.java.JavaMappedSuperclass; import org.eclipse.jpt.core.context.java.JavaPersistentType; @@ -18,7 +16,7 @@ import org.eclipse.jpt.core.resource.java.IdClassAnnotation; import org.eclipse.jpt.core.resource.java.JPA; import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType; import org.eclipse.jpt.core.resource.java.MappedSuperclassAnnotation; -import org.eclipse.jpt.utility.internal.iterators.ArrayIterator; +import org.eclipse.jpt.utility.internal.iterables.ArrayIterable; public abstract class AbstractJavaMappedSuperclass extends AbstractJavaTypeMapping implements JavaMappedSuperclass @@ -42,8 +40,10 @@ public abstract class AbstractJavaMappedSuperclass extends AbstractJavaTypeMappi return MappedSuperclassAnnotation.ANNOTATION_NAME; } - public Iterator<String> supportingAnnotationNames() { - return new ArrayIterator<String>( + public Iterable<String> getSupportingAnnotationNames() { + return SUPPORTING_ANNOTATION_NAMES; + } + protected static final String[] SUPPORTING_ANNOTATION_NAMES_ARRAY = new String[] { JPA.ID_CLASS, JPA.EXCLUDE_DEFAULT_LISTENERS, JPA.EXCLUDE_SUPERCLASS_LISTENERS, @@ -54,8 +54,9 @@ public abstract class AbstractJavaMappedSuperclass extends AbstractJavaTypeMappi JPA.POST_REMOVE, JPA.PRE_UPDATE, JPA.POST_UPDATE, - JPA.POST_LOAD); - } + JPA.POST_LOAD + }; + protected static final Iterable<String> SUPPORTING_ANNOTATION_NAMES = new ArrayIterable<String>(SUPPORTING_ANNOTATION_NAMES_ARRAY); public char getIdClassEnclosingTypeSeparator() { return '.'; diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaMultiRelationshipMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaMultiRelationshipMapping.java index 438aa8caa9..17006f6fbc 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaMultiRelationshipMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaMultiRelationshipMapping.java @@ -11,6 +11,7 @@ package org.eclipse.jpt.core.internal.context.java; import java.util.ArrayList; import java.util.Iterator; +import java.util.Vector; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.JptCorePlugin; @@ -26,7 +27,6 @@ import org.eclipse.jpt.core.resource.java.JPA; import org.eclipse.jpt.core.resource.java.MapKeyAnnotation; import org.eclipse.jpt.core.resource.java.RelationshipMappingAnnotation; import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.jpt.utility.internal.StringTools; import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; @@ -72,20 +72,14 @@ public abstract class AbstractJavaMultiRelationshipMapping<T extends Relationshi // ********** AbstractJavaAttributeMapping implementation ********** @Override - protected String[] buildSupportingAnnotationNames() { - String[] annotationNames = ArrayTools.addAll( - super.buildSupportingAnnotationNames(), - JPA.JOIN_TABLE, - JPA.MAP_KEY, - JPA.ORDER_BY); - - if (getJpaPlatformVersion().isCompatibleWithJpaVersion(JptCorePlugin.JPA_FACET_VERSION_2_0)) { - annotationNames = ArrayTools.addAll( - annotationNames, - JPA2_0.ORDER_COLUMN); + protected void addSupportingAnnotationNamesTo(Vector<String> names) { + super.addSupportingAnnotationNamesTo(names); + names.add(JPA.JOIN_TABLE); + names.add(JPA.MAP_KEY); + names.add(JPA.ORDER_BY); + if (this.getJpaPlatformVersion().isCompatibleWithJpaVersion(JptCorePlugin.JPA_FACET_VERSION_2_0)) { + names.add(JPA2_0.ORDER_COLUMN); } - - return annotationNames; } // ********** AbstractJavaRelationshipMapping implementation ********** diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaOneToManyMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaOneToManyMapping.java index f0fcc2128c..b936a215f1 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaOneToManyMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaOneToManyMapping.java @@ -9,7 +9,8 @@ ******************************************************************************/ package org.eclipse.jpt.core.internal.context.java; -import org.eclipse.jpt.core.JptCorePlugin; +import java.util.Vector; + import org.eclipse.jpt.core.MappingKeys; import org.eclipse.jpt.core.context.java.JavaOneToManyRelationshipReference; import org.eclipse.jpt.core.context.java.JavaPersistentAttribute; @@ -17,10 +18,8 @@ import org.eclipse.jpt.core.jpa2.JpaFactory2_0; import org.eclipse.jpt.core.jpa2.context.java.JavaOneToManyMapping2_0; import org.eclipse.jpt.core.jpa2.context.java.JavaOrphanRemovable2_0; import org.eclipse.jpt.core.jpa2.context.java.JavaOrphanRemovalHolder2_0; -import org.eclipse.jpt.core.jpa2.resource.java.JPA2_0; import org.eclipse.jpt.core.resource.java.JPA; import org.eclipse.jpt.core.resource.java.OneToManyAnnotation; -import org.eclipse.jpt.utility.internal.ArrayTools; public abstract class AbstractJavaOneToManyMapping<T extends OneToManyAnnotation> @@ -54,19 +53,10 @@ public abstract class AbstractJavaOneToManyMapping<T extends OneToManyAnnotation } @Override - protected String[] buildSupportingAnnotationNames() { - String[] annotationNames = ArrayTools.addAll( - super.buildSupportingAnnotationNames(), - JPA.JOIN_COLUMN, - JPA.JOIN_COLUMNS); - - if (getJpaPlatformVersion().isCompatibleWithJpaVersion(JptCorePlugin.JPA_FACET_VERSION_2_0)) { - annotationNames = ArrayTools.addAll( - annotationNames, - JPA2_0.ONE_TO_MANY__ORPHAN_REMOVAL); - } - - return annotationNames; + protected void addSupportingAnnotationNamesTo(Vector<String> names) { + super.addSupportingAnnotationNamesTo(names); + names.add(JPA.JOIN_COLUMN); + names.add(JPA.JOIN_COLUMNS); } public String getKey() { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaOneToOneMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaOneToOneMapping.java index 1932fff04a..a5e9c49144 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaOneToOneMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaOneToOneMapping.java @@ -9,7 +9,8 @@ ******************************************************************************/ package org.eclipse.jpt.core.internal.context.java; -import org.eclipse.jpt.core.JptCorePlugin; +import java.util.Vector; + import org.eclipse.jpt.core.MappingKeys; import org.eclipse.jpt.core.context.java.JavaOneToOneRelationshipReference; import org.eclipse.jpt.core.context.java.JavaPersistentAttribute; @@ -18,10 +19,8 @@ import org.eclipse.jpt.core.jpa2.JpaFactory2_0; import org.eclipse.jpt.core.jpa2.context.java.JavaOneToOneMapping2_0; import org.eclipse.jpt.core.jpa2.context.java.JavaOrphanRemovable2_0; import org.eclipse.jpt.core.jpa2.context.java.JavaOrphanRemovalHolder2_0; -import org.eclipse.jpt.core.jpa2.resource.java.JPA2_0; import org.eclipse.jpt.core.resource.java.JPA; import org.eclipse.jpt.core.resource.java.OneToOneAnnotation; -import org.eclipse.jpt.utility.internal.ArrayTools; public abstract class AbstractJavaOneToOneMapping @@ -60,21 +59,12 @@ public abstract class AbstractJavaOneToOneMapping } @Override - protected String[] buildSupportingAnnotationNames() { - String[] annotationNames = ArrayTools.addAll( - super.buildSupportingAnnotationNames(), - JPA.PRIMARY_KEY_JOIN_COLUMN, - JPA.PRIMARY_KEY_JOIN_COLUMNS); - - if (getJpaPlatformVersion().isCompatibleWithJpaVersion(JptCorePlugin.JPA_FACET_VERSION_2_0)) { - annotationNames = ArrayTools.addAll( - annotationNames, - JPA2_0.ONE_TO_ONE__ORPHAN_REMOVAL); - } - - return annotationNames; + protected void addSupportingAnnotationNamesTo(Vector<String> names) { + super.addSupportingAnnotationNamesTo(names); + names.add(JPA.PRIMARY_KEY_JOIN_COLUMN); + names.add(JPA.PRIMARY_KEY_JOIN_COLUMNS); } - + public String getKey() { return MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY; } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaPersistentAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaPersistentAttribute.java index 6e70385954..a66f6f2cad 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaPersistentAttribute.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaPersistentAttribute.java @@ -36,7 +36,7 @@ import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.jpt.utility.internal.ClassTools; import org.eclipse.jpt.utility.internal.Tools; import org.eclipse.jpt.utility.internal.iterables.ArrayIterable; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; +import org.eclipse.jpt.utility.internal.iterables.EmptyIterable; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; @@ -456,8 +456,7 @@ public abstract class AbstractJavaPersistentAttribute String newAnnotation = (newMapping == null) ? null : newMapping.getAnnotationName(); JavaAttributeMapping mapping = (newMapping == null) ? this.defaultMapping : newMapping; - String[] newSupportingAnnotationNames = ArrayTools.array(mapping.supportingAnnotationNames(), EMPTY_STRING_ARRAY); - this.resourcePersistentAttribute.setPrimaryAnnotation(newAnnotation, newSupportingAnnotationNames); + this.resourcePersistentAttribute.setPrimaryAnnotation(newAnnotation, mapping.getSupportingAnnotationNames()); this.firePropertyChanged(SPECIFIED_MAPPING_PROPERTY, old, newMapping); } protected static final String[] EMPTY_STRING_ARRAY = new String[0]; @@ -478,9 +477,9 @@ public abstract class AbstractJavaPersistentAttribute return mapping; } - protected Iterator<String> supportingAnnotationNames() { + protected Iterable<String> getSupportingAnnotationNames() { JavaAttributeMapping mapping = this.getMapping(); - return (mapping != null) ? mapping.supportingAnnotationNames() : EmptyIterator.<String>instance(); + return (mapping != null) ? mapping.getSupportingAnnotationNames() : EmptyIterable.<String>instance(); } protected void updateSpecifiedMapping() { 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 3b13e6599f..b9b7003fac 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 @@ -32,12 +32,10 @@ import org.eclipse.jpt.core.context.java.JavaStructureNodes; import org.eclipse.jpt.core.context.java.JavaTypeMapping; import org.eclipse.jpt.core.context.java.JavaTypeMappingDefinition; import org.eclipse.jpt.core.internal.resource.java.source.SourceNode; -import org.eclipse.jpt.core.jpa2.JpaProject2_0; import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute; import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType; import org.eclipse.jpt.core.utility.TextRange; import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.HashBag; import org.eclipse.jpt.utility.internal.iterables.LiveCloneIterable; @@ -51,80 +49,176 @@ import org.eclipse.jst.j2ee.model.internal.validation.ValidationCancelledExcepti import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; +/** + * Java persistent type:<ul> + * <li>name + * <li>access + * <li>mapping + * <li>attributes + * <li>super persistent type + * </ul> + */ public abstract class AbstractJavaPersistentType extends AbstractJavaJpaContextNode implements JavaPersistentType { protected JavaResourcePersistentType resourcePersistentType; - - protected PersistentType superPersistentType; - + protected String name; - + protected AccessType defaultAccess; protected AccessType specifiedAccess; - + protected JavaTypeMapping mapping; - - protected final Vector<JavaPersistentAttribute> attributes = - new Vector<JavaPersistentAttribute>(); - - + + protected final Vector<JavaPersistentAttribute> attributes = new Vector<JavaPersistentAttribute>(); + + protected PersistentType superPersistentType; + + protected AbstractJavaPersistentType(PersistentType.Owner parent, JavaResourcePersistentType jrpt) { super(parent); this.initialize(jrpt); } - - + + protected void initialize(JavaResourcePersistentType jrpt) { + this.resourcePersistentType = jrpt; + this.superPersistentType = this.buildSuperPersistentType(); + this.name = this.buildName(); + this.defaultAccess = buildDefaultAccess(); + this.specifiedAccess = buildSpecifiedAccess(); + this.mapping = buildMapping(); + this.initializeAttributes(); + } + + + // ********** update ********** + + public void update(JavaResourcePersistentType jrpt) { + this.resourcePersistentType = jrpt; + this.update(); + } + + public void update() { + JpaFile jpaFile = this.getJpaFile(); + if (jpaFile != null) { + // the JPA file can be null if the resource type is "external" + jpaFile.addRootStructureNode(this.resourcePersistentType.getQualifiedName(), this); + } + this.setSuperPersistentType(this.buildSuperPersistentType()); + this.setName(this.buildName()); + this.updateAccess(); + this.updateMapping(); + this.updateAttributes(); + } + + @Override + public void postUpdate() { + super.postUpdate(); + this.mapping.postUpdate(); + for (PersistentAttribute attribute : this.getAttributes()) { + attribute.postUpdate(); + } + } + + + // ********** AbstractJpaNode overrides ********** + + @Override + public PersistentType.Owner getParent() { + return (PersistentType.Owner) super.getParent(); + } + @Override public IResource getResource() { return this.resourcePersistentType.getFile(); } - - - //****************** JpaStructureNode implementation ******************* - + + + // ********** JpaStructureNode implementation ********** + public String getId() { return JavaStructureNodes.PERSISTENT_TYPE_ID; } - - - //****************** PersistentType implementation ******************* - + + // it would be nice if the we passed in an astRoot here, but then we + // would need to pass it to the XML structure nodes too... + public JpaStructureNode getStructureNode(int offset) { + CompilationUnit astRoot = this.buildASTRoot(); + + if (this.contains(offset, astRoot)) { + for (JavaPersistentAttribute persistentAttribute : this.getAttributes()) { + if (persistentAttribute.contains(offset, astRoot)) { + return persistentAttribute; + } + } + return this; + } + return null; + } + + protected boolean contains(int offset, CompilationUnit astRoot) { + TextRange fullTextRange = this.getFullTextRange(astRoot); + // 'fullTextRange' will be null if the type no longer exists in the java; + // the context model can be out of synch with the resource model + // when a selection event occurs before the context model has a + // chance to synch with the resource model via the update thread + return (fullTextRange == null) ? false : fullTextRange.includes(offset); + } + + protected TextRange getFullTextRange(CompilationUnit astRoot) { + return this.resourcePersistentType.getTextRange(astRoot); + } + + public TextRange getSelectionTextRange() { + return this.getSelectionTextRange(this.buildASTRoot()); + } + + protected TextRange getSelectionTextRange(CompilationUnit astRoot) { + return this.resourcePersistentType.getNameTextRange(astRoot); + } + + public void dispose() { + JpaFile jpaFile = this.getJpaFile(); + if (jpaFile != null) { + // the JPA file can be null if the .java file was deleted + // or the resource type is "external" + jpaFile.removeRootStructureNode(this.resourcePersistentType.getQualifiedName()); + } + } + + + // ********** PersistentType implementation ********** + public JavaResourcePersistentType getResourcePersistentType() { return this.resourcePersistentType; } - - @Override - public PersistentType.Owner getParent() { - return (PersistentType.Owner) super.getParent(); - } - - - // **************** name ************************************************** - + + + // ********** name ********** + public String getName() { return this.name; } - + public String getShortName(){ - return getName().substring(getName().lastIndexOf('.') + 1); + return this.name.substring(this.name.lastIndexOf('.') + 1); } - - protected void setName(String newName) { - String oldName = this.name; - this.name = newName; - firePropertyChanged(NAME_PROPERTY, oldName, newName); + + protected void setName(String name) { + String old = this.name; + this.name = name; + this.firePropertyChanged(NAME_PROPERTY, old, name); } - + protected String buildName() { return this.resourcePersistentType.getQualifiedName(); } - - - // **************** access ************************************************ - + + + // ********** access ********** + public AccessType getAccess() { return (this.specifiedAccess != null) ? this.specifiedAccess : this.defaultAccess; } @@ -132,25 +226,29 @@ public abstract class AbstractJavaPersistentType public AccessType getDefaultAccess() { return this.defaultAccess; } - - protected void setDefaultAccess(AccessType newDefaultAccess) { - AccessType oldAccess = this.defaultAccess; - this.defaultAccess = newDefaultAccess; - firePropertyChanged(DEFAULT_ACCESS_PROPERTY, oldAccess, newDefaultAccess); + + protected void setDefaultAccess(AccessType defaultAccess) { + AccessType old = this.defaultAccess; + this.defaultAccess = defaultAccess; + this.firePropertyChanged(DEFAULT_ACCESS_PROPERTY, old, defaultAccess); } - + public AccessType getSpecifiedAccess() { return this.specifiedAccess; } - + /** - * Check the access "specified" by the java resource model. - * Check java annotations first. - * If still null check xml mapping specified access - * If still null then set to superPersistentType access. - * If still null check entity-mappings specified access setting if this persistent-type is listed in an orm.xml file - * If still null check the persistence-unit default Access - * Default to FIELD if all else fails. + * Check the access "specified" by the Java resource model:<ul> + * <li>Check Java annotations first + * <li>If <code>null</code>, check XML mapping specified access + * <li>If still <code>null</code>, check {@link #superPersistentType} access + * <li>If still <code>null</code>, check <code>entity-mappings</code> + * specified access setting if the corresponding <code>persistent-type</code> + * is listed in a mapping (<code>orm.xml</code>) file + * <li>If still <code>null</code>, check the <code>persistence-unit</code> + * default Access + * <li>Default to <code>FIELD</code> if all else fails. + * </ul> */ protected AccessType buildDefaultAccess() { AccessType accessType = AccessType.fromJavaResourceModel(this.resourcePersistentType.getAccess()); @@ -177,132 +275,109 @@ public abstract class AbstractJavaPersistentType // last ditch attempt to allow the user to annotate *something* return AccessType.FIELD; } - + + protected void updateAccess() { + this.setDefaultAccess(this.buildDefaultAccess()); + } + /** * Build an access type based on annotations from the resource model. - * (This is platform dependent) + * (This is JPA platform-dependent.) */ protected abstract AccessType buildSpecifiedAccess(); - - - // **************** mapping *********************************************** - + + + // ********** mapping ********** + public JavaTypeMapping getMapping() { return this.mapping; } public String getMappingKey() { - return getMapping().getKey(); + return this.mapping.getKey(); } - + public void setMappingKey(String key) { - if (this.valuesAreEqual(key, this.getMapping().getKey())) { + if (this.valuesAreEqual(key, this.mapping.getKey())) { return; } - JavaTypeMapping oldMapping = getMapping(); - JavaTypeMapping newMapping = buildMappingFromMappingKey(key); - + JavaTypeMapping oldMapping = this.mapping; + JavaTypeMapping newMapping = this.buildMappingFromMappingKey(key); + this.mapping = newMapping; - this.resourcePersistentType.setPrimaryAnnotation( - newMapping.getAnnotationName(), - ArrayTools.array(newMapping.supportingAnnotationNames(), new String[0])); - firePropertyChanged(MAPPING_PROPERTY, oldMapping, newMapping); + this.resourcePersistentType.setPrimaryAnnotation(newMapping.getAnnotationName(), newMapping.getSupportingAnnotationNames()); + this.firePropertyChanged(MAPPING_PROPERTY, oldMapping, newMapping); } - - protected void setMapping(JavaTypeMapping newMapping) { - JavaTypeMapping oldMapping = this.mapping; - this.mapping = newMapping; - firePropertyChanged(MAPPING_PROPERTY, oldMapping, newMapping); + + protected void setMapping(JavaTypeMapping mapping) { + JavaTypeMapping old = this.mapping; + this.mapping = mapping; + this.firePropertyChanged(MAPPING_PROPERTY, old, mapping); } - + protected JavaTypeMapping buildMapping() { - JavaTypeMappingDefinition mappingDefinition = - getJpaPlatform().getJavaTypeMappingDefinition(this); - return buildMapping(mappingDefinition); + JavaTypeMappingDefinition mappingDefinition = this.getJpaPlatform().getJavaTypeMappingDefinition(this); + return this.buildMapping(mappingDefinition); } - + protected JavaTypeMapping buildMapping(JavaTypeMappingDefinition mappingDefinition) { - JavaTypeMapping jtMapping = mappingDefinition.buildMapping(this, getJpaFactory()); + JavaTypeMapping jtMapping = mappingDefinition.buildMapping(this, this.getJpaFactory()); // mapping may be null if (jtMapping != null) { jtMapping.initialize(this.resourcePersistentType); } return jtMapping; } - + protected JavaTypeMapping buildMappingFromMappingKey(String key) { - JavaTypeMappingDefinition mappingDefinition = - getJpaPlatform().getJavaTypeMappingDefinition(key); - JavaTypeMapping jtMapping = mappingDefinition.buildMapping(this, getJpaFactory()); + JavaTypeMappingDefinition mappingDefinition = this.getJpaPlatform().getJavaTypeMappingDefinition(key); + JavaTypeMapping jtMapping = mappingDefinition.buildMapping(this, this.getJpaFactory()); //no mapping.initialize(JavaResourcePersistentType) call here //we do not yet have a mapping annotation so we can't call initialize return jtMapping; } - - - public boolean isMapped() { - return getMapping().isMapped(); - } - - public AccessType getOwnerOverrideAccess() { - return this.getParent().getOverridePersistentTypeAccess(); - } - public AccessType getOwnerDefaultAccess() { - return this.getParent().getDefaultPersistentTypeAccess(); + protected void updateMapping() { + // There will always be a mapping definition, even if it is a "null" mapping definition ... + JavaTypeMappingDefinition mappingDefinition = this.getJpaPlatform().getJavaTypeMappingDefinition(this); + if ((this.mapping != null) && this.valuesAreEqual(this.mapping.getKey(), mappingDefinition.getKey())) { + this.mapping.update(this.resourcePersistentType); + } else { + this.setMapping(this.buildMapping(mappingDefinition)); + } } - protected Iterator<JavaPersistentAttribute> attributesNamed(final String attributeName) { - return new FilteringIterator<JavaPersistentAttribute, JavaPersistentAttribute>(attributes()) { - @Override - protected boolean accept(JavaPersistentAttribute o) { - return attributeName.equals(o.getName()); - } - }; - } - public JavaPersistentAttribute getAttributeNamed(String attributeName) { - Iterator<JavaPersistentAttribute> stream = attributesNamed(attributeName); - return stream.hasNext() ? stream.next() : null; - } + // ********** attributes ********** - public PersistentAttribute resolveAttribute(String attributeName) { - Iterator<JavaPersistentAttribute> stream = attributesNamed(attributeName); - if (stream.hasNext()) { - JavaPersistentAttribute attribute = stream.next(); - return stream.hasNext() ? null /*more than one*/: attribute; - } - return (this.superPersistentType == null) ? null : this.superPersistentType.resolveAttribute(attributeName); - } - public ListIterator<JavaPersistentAttribute> attributes() { return new CloneListIterator<JavaPersistentAttribute>(this.attributes); } - + protected Iterable<JavaPersistentAttribute> getAttributes() { return new LiveCloneIterable<JavaPersistentAttribute>(this.attributes); } - + public int attributesSize() { return this.attributes.size(); } - + private void addAttribute(int index, JavaPersistentAttribute attribute) { - addItemToList(index, attribute, this.attributes, ATTRIBUTES_LIST); + this.addItemToList(index, attribute, this.attributes, ATTRIBUTES_LIST); } private void removeAttribute(JavaPersistentAttribute attribute) { - removeItemFromList(attribute, this.attributes, ATTRIBUTES_LIST); + this.removeItemFromList(attribute, this.attributes, ATTRIBUTES_LIST); } - + private void moveAttribute(int index, JavaPersistentAttribute attribute) { - moveItemInList(index, this.attributes.indexOf(attribute), this.attributes, ATTRIBUTES_LIST); + this.moveItemInList(index, this.attributes.indexOf(attribute), this.attributes, ATTRIBUTES_LIST); } - + public Iterator<String> attributeNames() { return this.attributeNames(this.attributes()); } - + protected Iterator<String> attributeNames(Iterator<? extends PersistentAttribute> attrs) { return new TransformationIterator<PersistentAttribute, String>(attrs) { @Override @@ -311,136 +386,45 @@ public abstract class AbstractJavaPersistentType } }; } - - public Iterator<PersistentAttribute> allAttributes() { - return new CompositeIterator<PersistentAttribute>(new TransformationIterator<PersistentType, Iterator<PersistentAttribute>>(this.inheritanceHierarchy()) { - @Override - protected Iterator<PersistentAttribute> transform(PersistentType pt) { - return pt.attributes(); - } - }); - } - - public Iterator<String> allAttributeNames() { - return this.attributeNames(this.allAttributes()); - } - - @Override - public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { - Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); - if (result != null) { - return result; - } - Iterator<String> values = this.mapping.javaCompletionProposals(pos, filter, astRoot); - if (values != null) { - return values; - } - for (JavaPersistentAttribute attribute : this.getAttributes()) { - values = attribute.javaCompletionProposals(pos, filter, astRoot); - if (values != null) { - return values; - } - } - return EmptyIterator.instance(); - } - - // it would be nice if the we passed in an astRoot here, but then we - // would need to pass it to the XML structure nodes too... - public JpaStructureNode getStructureNode(int offset) { - CompilationUnit astRoot = this.buildASTRoot(); - - if (this.contains(offset, astRoot)) { - for (JavaPersistentAttribute persistentAttribute : this.getAttributes()) { - if (persistentAttribute.contains(offset, astRoot)) { - return persistentAttribute; - } - } - return this; - } - return null; - } - - protected CompilationUnit buildASTRoot() { - return this.resourcePersistentType.getJavaResourceCompilationUnit().buildASTRoot(); - } - - public boolean contains(int offset, CompilationUnit astRoot) { - TextRange fullTextRange = this.getFullTextRange(astRoot); - // 'fullTextRange' will be null if the type no longer exists in the java; - // the context model can be out of synch with the resource model - // when a selection event occurs before the context model has a - // chance to synch with the resource model via the update thread - return (fullTextRange == null) ? false : fullTextRange.includes(offset); - } - - - protected TextRange getFullTextRange(CompilationUnit astRoot) { - return this.resourcePersistentType.getTextRange(astRoot); - } - public TextRange getValidationTextRange(CompilationUnit astRoot) { - return this.getSelectionTextRange(astRoot); - } - - public TextRange getSelectionTextRange(CompilationUnit astRoot) { - return this.resourcePersistentType.getNameTextRange(astRoot); - } - - public TextRange getSelectionTextRange() { - return this.getSelectionTextRange(this.buildASTRoot()); - } - - - public Iterator<PersistentType> inheritanceHierarchy() { - return this.inheritanceHierarchyOf(this); + public JavaPersistentAttribute getAttributeNamed(String attributeName) { + Iterator<JavaPersistentAttribute> stream = this.attributesNamed(attributeName); + return stream.hasNext() ? stream.next() : null; } - public Iterator<PersistentType> ancestors() { - return this.inheritanceHierarchyOf(this.superPersistentType); + public PersistentAttribute resolveAttribute(String attributeName) { + Iterator<JavaPersistentAttribute> stream = this.attributesNamed(attributeName); + if (stream.hasNext()) { + JavaPersistentAttribute attribute = stream.next(); + return stream.hasNext() ? null /*more than one*/: attribute; + } + return (this.superPersistentType == null) ? null : this.superPersistentType.resolveAttribute(attributeName); } - protected Iterator<PersistentType> inheritanceHierarchyOf(PersistentType start) { - // using a chain iterator to traverse up the inheritance tree - return new ChainIterator<PersistentType>(start) { + protected Iterator<JavaPersistentAttribute> attributesNamed(final String attributeName) { + return new FilteringIterator<JavaPersistentAttribute, JavaPersistentAttribute>(this.attributes()) { @Override - protected PersistentType nextLink(PersistentType persistentType) { - return persistentType.getSuperPersistentType(); + protected boolean accept(JavaPersistentAttribute o) { + return attributeName.equals(o.getName()); } }; } - public PersistentType getSuperPersistentType() { - return this.superPersistentType; + public Iterator<PersistentAttribute> allAttributes() { + return new CompositeIterator<PersistentAttribute>( + new TransformationIterator<PersistentType, Iterator<PersistentAttribute>>(this.inheritanceHierarchy()) { + @Override + protected Iterator<PersistentAttribute> transform(PersistentType pt) { + return pt.attributes(); + } + } + ); } - protected void setSuperPersistentType(PersistentType superPersistentType) { - PersistentType old = this.superPersistentType; - this.superPersistentType = superPersistentType; - this.firePropertyChanged(SUPER_PERSISTENT_TYPE_PROPERTY, old, superPersistentType); - } - - public boolean hasAnyAnnotatedAttributes() { - return this.resourcePersistentType.hasAnyAnnotatedAttributes(); - } - - // **************** metamodel ***************************** - - public void synchronizeMetamodel() { - ((JpaProject2_0) this.getJpaProject()).synchronizeMetamodel(this); - } - - // **************** initialization / updating ***************************** - - protected void initialize(JavaResourcePersistentType jrpt) { - this.resourcePersistentType = jrpt; - this.superPersistentType = this.buildSuperPersistentType(); - this.name = this.buildName(); - this.defaultAccess = buildDefaultAccess(); - this.specifiedAccess = buildSpecifiedAccess(); - this.mapping = buildMapping(); - this.initializeAttributes(); + public Iterator<String> allAttributeNames() { + return this.attributeNames(this.allAttributes()); } - + protected void initializeAttributes() { for (Iterator<JavaResourcePersistentAttribute> stream = this.resourceAttributes(); stream.hasNext(); ) { this.attributes.add(this.createAttribute(stream.next())); @@ -453,52 +437,11 @@ public abstract class AbstractJavaPersistentType this.resourcePersistentType.persistableFields(); } - public void update(JavaResourcePersistentType jrpt) { - this.resourcePersistentType = jrpt; - this.update(); - } - - public void update() { - JpaFile jpaFile = this.getJpaFile(); - if (jpaFile != null) { - // the JPA file can be null if the resource type is "external" - jpaFile.addRootStructureNode(this.resourcePersistentType.getQualifiedName(), this); - } - this.setSuperPersistentType(this.buildSuperPersistentType()); - this.setName(this.buildName()); - this.updateAccess(); - this.updateMapping(); - this.updateAttributes(); - } - - protected JpaFile getJpaFile() { - return this.getJpaFile(this.resourcePersistentType.getFile()); - } - - protected void updateAccess() { - this.setDefaultAccess(this.buildDefaultAccess()); - - } - - protected void updateMapping() { - // There will always be a mapping definition, even if it is a "null" mapping definition ... - JavaTypeMappingDefinition mappingDefinition = - getJpaPlatform().getJavaTypeMappingDefinition(this); - String mappingKey = mappingDefinition.getKey(); - if (this.mapping != null - && valuesAreEqual(this.mapping.getKey(), mappingKey)) { - this.mapping.update(this.resourcePersistentType); - } - else { - setMapping(buildMapping(mappingDefinition)); - } - } - protected void updateAttributes() { HashBag<JavaPersistentAttribute> contextAttributesToRemove = CollectionTools.bag(this.attributes(), this.attributesSize()); ArrayList<JavaPersistentAttribute> contextAttributesToUpdate = new ArrayList<JavaPersistentAttribute>(this.attributesSize()); int resourceIndex = 0; - + for (Iterator<JavaResourcePersistentAttribute> resourceAttributes = this.resourceAttributes(); resourceAttributes.hasNext(); ) { JavaResourcePersistentAttribute resourceAttribute = resourceAttributes.next(); boolean match = false; @@ -526,9 +469,26 @@ public abstract class AbstractJavaPersistentType contextAttribute.update(); } } - + protected JavaPersistentAttribute createAttribute(JavaResourcePersistentAttribute jrpa) { - return getJpaFactory().buildJavaPersistentAttribute(this, jrpa); + return this.getJpaFactory().buildJavaPersistentAttribute(this, jrpa); + } + + public boolean hasAnyAnnotatedAttributes() { + return this.resourcePersistentType.hasAnyAnnotatedAttributes(); + } + + + // ********** super persistent type ********** + + public PersistentType getSuperPersistentType() { + return this.superPersistentType; + } + + protected void setSuperPersistentType(PersistentType superPersistentType) { + PersistentType old = this.superPersistentType; + this.superPersistentType = superPersistentType; + this.firePropertyChanged(SUPER_PERSISTENT_TYPE_PROPERTY, old, superPersistentType); } protected PersistentType buildSuperPersistentType() { @@ -568,19 +528,54 @@ public abstract class AbstractJavaPersistentType return (spt != null) ? spt : this.getSuperPersistentType(resourceType.getSuperclassQualifiedName(), visited); // recurse } - protected PersistentType getPersistentType(String fullyQualifiedTypeName) { - return getPersistenceUnit().getPersistentType(fullyQualifiedTypeName); + protected PersistentType getPersistentType(String typeName) { + return this.getPersistenceUnit().getPersistentType(typeName); } + + // ********** inheritance ********** + + public Iterator<PersistentType> inheritanceHierarchy() { + return this.inheritanceHierarchyOf(this); + } + + public Iterator<PersistentType> ancestors() { + return this.inheritanceHierarchyOf(this.superPersistentType); + } + + protected Iterator<PersistentType> inheritanceHierarchyOf(PersistentType start) { + // using a chain iterator to traverse up the inheritance tree + return new ChainIterator<PersistentType>(start) { + @Override + protected PersistentType nextLink(PersistentType persistentType) { + return persistentType.getSuperPersistentType(); + } + }; + } + + + // ********** code completion ********** + @Override - public void postUpdate() { - super.postUpdate(); - getMapping().postUpdate(); - for (PersistentAttribute attribute : CollectionTools.iterable(attributes())) { - attribute.postUpdate(); + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + Iterator<String> values = this.mapping.javaCompletionProposals(pos, filter, astRoot); + if (values != null) { + return values; + } + for (JavaPersistentAttribute attribute : this.getAttributes()) { + values = attribute.javaCompletionProposals(pos, filter, astRoot); + if (values != null) { + return values; + } } + return EmptyIterator.instance(); } - + + // ********** validation ********** public void validate(List<IMessage> messages, IReporter reporter) { @@ -600,14 +595,14 @@ public abstract class AbstractJavaPersistentType this.validate(messages, reporter, this.buildASTRoot()); } } - + @Override public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { super.validate(messages, reporter, astRoot); this.validateMapping(messages, reporter, astRoot); this.validateAttributes(messages, reporter, astRoot); } - + protected void validateMapping(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { try { this.mapping.validate(messages, reporter, astRoot); @@ -615,13 +610,13 @@ public abstract class AbstractJavaPersistentType JptCorePlugin.log(t); } } - + protected void validateAttributes(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { for (JavaPersistentAttribute attribute : this.getAttributes()) { this.validateAttribute(attribute, reporter, messages, astRoot); } } - + protected void validateAttribute(JavaPersistentAttribute attribute, IReporter reporter, List<IMessage> messages, CompilationUnit astRoot) { try { attribute.validate(messages, reporter, astRoot); @@ -629,23 +624,38 @@ public abstract class AbstractJavaPersistentType JptCorePlugin.log(t); } } - + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.getSelectionTextRange(astRoot); + } + // ********** misc ********** + public boolean isMapped() { + return this.mapping.isMapped(); + } + + public AccessType getOwnerOverrideAccess() { + return this.getParent().getOverridePersistentTypeAccess(); + } + + public AccessType getOwnerDefaultAccess() { + return this.getParent().getDefaultPersistentTypeAccess(); + } + @Override public void toString(StringBuilder sb) { super.toString(sb); sb.append(this.name); } - public void dispose() { - JpaFile jpaFile = this.getJpaFile(); - if (jpaFile != null) { - // the JPA file can be null if the .java file was deleted - // or the resource type is "external" - jpaFile.removeRootStructureNode(this.resourcePersistentType.getQualifiedName()); - } + protected CompilationUnit buildASTRoot() { + return this.resourcePersistentType.getJavaResourceCompilationUnit().buildASTRoot(); + } + + protected JpaFile getJpaFile() { + return this.getJpaFile(this.resourcePersistentType.getFile()); } } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaSingleRelationshipMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaSingleRelationshipMapping.java index 09135771bc..c31c4a4ca6 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaSingleRelationshipMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaSingleRelationshipMapping.java @@ -10,6 +10,8 @@ package org.eclipse.jpt.core.internal.context.java; import java.util.List; +import java.util.Vector; + import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.JptCorePlugin; import org.eclipse.jpt.core.context.FetchType; @@ -23,7 +25,6 @@ import org.eclipse.jpt.core.jpa2.context.java.JavaSingleRelationshipMapping2_0; import org.eclipse.jpt.core.jpa2.resource.java.JPA2_0; import org.eclipse.jpt.core.resource.java.JPA; import org.eclipse.jpt.core.resource.java.RelationshipMappingAnnotation; -import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; @@ -64,21 +65,15 @@ public abstract class AbstractJavaSingleRelationshipMapping<T extends Relationsh } @Override - protected String[] buildSupportingAnnotationNames() { - String[] annotationNames = ArrayTools.addAll( - super.buildSupportingAnnotationNames(), - JPA.JOIN_COLUMN, - JPA.JOIN_COLUMNS, - JPA.JOIN_TABLE); - - if (getJpaPlatformVersion().isCompatibleWithJpaVersion(JptCorePlugin.JPA_FACET_VERSION_2_0)) { - annotationNames = ArrayTools.addAll( - annotationNames, - JPA.ID, - JPA2_0.MAPS_ID); + protected void addSupportingAnnotationNamesTo(Vector<String> names) { + super.addSupportingAnnotationNamesTo(names); + names.add(JPA.JOIN_COLUMN); + names.add(JPA.JOIN_COLUMNS); + names.add(JPA.JOIN_TABLE); + if (this.getJpaPlatformVersion().isCompatibleWithJpaVersion(JptCorePlugin.JPA_FACET_VERSION_2_0)) { + names.add(JPA.ID); + names.add(JPA2_0.MAPS_ID); } - - return annotationNames; } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaTypeMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaTypeMapping.java index 3a29a3dff0..fe52e1e5e7 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaTypeMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaTypeMapping.java @@ -10,7 +10,7 @@ package org.eclipse.jpt.core.internal.context.java; import java.util.Iterator; -import java.util.ListIterator; + import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.context.AttributeMapping; import org.eclipse.jpt.core.context.Column; @@ -30,14 +30,13 @@ import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationListIterator; public abstract class AbstractJavaTypeMapping extends AbstractJavaJpaContextNode implements JavaTypeMapping { protected JavaResourcePersistentType javaResourcePersistentType; - + protected AbstractJavaTypeMapping(JavaPersistentType parent) { super(parent); @@ -103,8 +102,8 @@ public abstract class AbstractJavaTypeMapping extends AbstractJavaJpaContextNode }; } - public ListIterator<JavaAttributeMapping> attributeMappings() { - return new TransformationListIterator<JavaPersistentAttribute, JavaAttributeMapping>(getPersistentType().attributes()) { + public Iterator<JavaAttributeMapping> attributeMappings() { + return new TransformationIterator<JavaPersistentAttribute, JavaAttributeMapping>(getPersistentType().attributes()) { @Override protected JavaAttributeMapping transform(JavaPersistentAttribute attribute) { return attribute.getMapping(); diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaVersionMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaVersionMapping.java index 4eb847c3a5..9c6fba30fa 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaVersionMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/AbstractJavaVersionMapping.java @@ -11,6 +11,8 @@ package org.eclipse.jpt.core.internal.context.java; import java.util.Iterator; import java.util.List; +import java.util.Vector; + import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.MappingKeys; import org.eclipse.jpt.core.context.Converter; @@ -25,7 +27,6 @@ import org.eclipse.jpt.core.resource.java.JPA; import org.eclipse.jpt.core.resource.java.TemporalAnnotation; import org.eclipse.jpt.core.resource.java.VersionAnnotation; import org.eclipse.jpt.utility.Filter; -import org.eclipse.jpt.utility.internal.ArrayTools; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; @@ -70,11 +71,10 @@ public abstract class AbstractJavaVersionMapping @Override - protected String[] buildSupportingAnnotationNames() { - return ArrayTools.addAll( - super.buildSupportingAnnotationNames(), - JPA.COLUMN, - JPA.TEMPORAL); + protected void addSupportingAnnotationNamesTo(Vector<String> names) { + super.addSupportingAnnotationNamesTo(names); + names.add(JPA.COLUMN); + names.add(JPA.TEMPORAL); } //************** NamedColumn.Owner implementation *************** diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/JavaNullTypeMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/JavaNullTypeMapping.java index fefecbf43f..cbb5e22867 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/JavaNullTypeMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/JavaNullTypeMapping.java @@ -9,15 +9,15 @@ ******************************************************************************/ package org.eclipse.jpt.core.internal.context.java; -import java.util.Iterator; import java.util.List; + import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.MappingKeys; import org.eclipse.jpt.core.context.java.JavaPersistentType; import org.eclipse.jpt.core.internal.validation.DefaultJpaValidationMessages; import org.eclipse.jpt.core.internal.validation.JpaValidationMessages; import org.eclipse.jpt.core.utility.TextRange; -import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; +import org.eclipse.jpt.utility.internal.iterables.EmptyIterable; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; @@ -40,8 +40,8 @@ public class JavaNullTypeMapping extends AbstractJavaTypeMapping return false; } - public Iterator<String> supportingAnnotationNames() { - return EmptyIterator.instance(); + public Iterable<String> getSupportingAnnotationNames() { + return EmptyIterable.instance(); } public boolean tableNameIsInvalid(String tableName) { 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 94eb087afd..1e4d6cb603 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 @@ -1025,7 +1025,7 @@ public abstract class AbstractOrmEntity * and has no descendants and no specified inheritance strategy has been defined. */ protected boolean isRootNoDescendantsNoStrategyDefined() { - return isRoot() && !getPersistenceUnit().isRootWithSubEntities(this.getName()) && getSpecifiedInheritanceStrategy() == null; + return isRoot() && !getPersistenceUnit().entityIsRootWithSubEntities(this.getName()) && getSpecifiedInheritanceStrategy() == null; } /** @@ -1409,7 +1409,7 @@ public abstract class AbstractOrmEntity } public void addSubEntity(Entity subEntity) { - getPersistenceUnit().addRootWithSubEntities(getName()); + getPersistenceUnit().addRootEntityWithSubEntities(getName()); } protected void updateSpecifiedSecondaryTables() { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmPersistentAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmPersistentAttribute.java index 559a160528..a44bcc569d 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmPersistentAttribute.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmPersistentAttribute.java @@ -137,14 +137,14 @@ public abstract class AbstractOrmPersistentAttribute } public boolean isVirtual() { - return getPersistentType().containsVirtualPersistentAttribute(this); + return getPersistentType().containsVirtualAttribute(this); } public void makeVirtual() { if (isVirtual()) { throw new IllegalStateException("Attribute is already virtual"); //$NON-NLS-1$ } - getPersistentType().makePersistentAttributeVirtual(this); + getPersistentType().makeAttributeVirtual(this); } public void makeSpecified() { @@ -154,14 +154,14 @@ public abstract class AbstractOrmPersistentAttribute if (getMappingKey() == MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY) { throw new IllegalStateException("Use makeSpecified(String) instead and specify a mapping type"); //$NON-NLS-1$ } - getPersistentType().makePersistentAttributeSpecified(this); + getPersistentType().makeAttributeSpecified(this); } public void makeSpecified(String mappingKey) { if (!isVirtual()) { throw new IllegalStateException("Attribute is already specified"); //$NON-NLS-1$ } - getPersistentType().makePersistentAttributeSpecified(this, mappingKey); + getPersistentType().makeAttributeSpecified(this, mappingKey); } public String getPrimaryKeyColumnName() { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmTypeMapping.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmTypeMapping.java index e19c5ff449..45ccf0df02 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmTypeMapping.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmTypeMapping.java @@ -11,7 +11,7 @@ package org.eclipse.jpt.core.internal.context.orm; import java.util.Iterator; import java.util.List; -import java.util.ListIterator; + import org.eclipse.jpt.core.JpaStructureNode; import org.eclipse.jpt.core.context.AttributeMapping; import org.eclipse.jpt.core.context.Column; @@ -33,7 +33,6 @@ import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.StringTools; import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; -import org.eclipse.jpt.utility.internal.iterators.TransformationListIterator; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; @@ -152,8 +151,8 @@ public abstract class AbstractOrmTypeMapping<T extends XmlTypeMapping> return true; } - public ListIterator<OrmAttributeMapping> attributeMappings() { - return new TransformationListIterator<OrmPersistentAttribute, OrmAttributeMapping>(getPersistentType().attributes()) { + public Iterator<OrmAttributeMapping> attributeMappings() { + return new TransformationIterator<OrmPersistentAttribute, OrmAttributeMapping>(getPersistentType().attributes()) { @Override protected OrmAttributeMapping transform(OrmPersistentAttribute attribute) { return attribute.getMapping(); diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmXmlContextNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmXmlContextNode.java index c57fd8a5f5..cd85274c5d 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmXmlContextNode.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/orm/AbstractOrmXmlContextNode.java @@ -11,7 +11,6 @@ package org.eclipse.jpt.core.internal.context.orm; import org.eclipse.emf.ecore.EFactory; import org.eclipse.jpt.core.context.JpaContextNode; -import org.eclipse.jpt.core.context.XmlContextNode; import org.eclipse.jpt.core.context.orm.OrmXmlContextNodeFactory; import org.eclipse.jpt.core.context.orm.OrmXmlDefinition; import org.eclipse.jpt.core.internal.context.AbstractXmlContextNode; @@ -22,7 +21,6 @@ import org.eclipse.jpt.core.internal.context.AbstractXmlContextNode; */ public abstract class AbstractOrmXmlContextNode extends AbstractXmlContextNode - implements XmlContextNode { // ********** constructor ********** 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 8b07cdb747..2db8dd80d9 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 @@ -10,6 +10,7 @@ package org.eclipse.jpt.core.internal.context.persistence; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -18,6 +19,12 @@ import java.util.ListIterator; import java.util.Set; import java.util.Vector; +import org.eclipse.jpt.core.context.persistence.PersistenceUnitProperties; +import org.eclipse.jpt.core.jpa2.context.persistence.PersistenceUnit2_0; +import org.eclipse.jpt.core.jpa2.context.persistence.options.SharedCacheMode; +import org.eclipse.jpt.core.jpa2.context.persistence.options.ValidationMode; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; import org.eclipse.jpt.core.JpaStructureNode; import org.eclipse.jpt.core.JptCorePlugin; import org.eclipse.jpt.core.context.AccessType; @@ -34,14 +41,14 @@ import org.eclipse.jpt.core.context.persistence.MappingFileRef; import org.eclipse.jpt.core.context.persistence.Persistence; import org.eclipse.jpt.core.context.persistence.PersistenceStructureNodes; import org.eclipse.jpt.core.context.persistence.PersistenceUnit; -import org.eclipse.jpt.core.context.persistence.PersistenceUnitProperties; import org.eclipse.jpt.core.context.persistence.PersistenceUnitTransactionType; import org.eclipse.jpt.core.context.persistence.PersistentTypeContainer; import org.eclipse.jpt.core.internal.validation.DefaultJpaValidationMessages; import org.eclipse.jpt.core.internal.validation.JpaValidationMessages; -import org.eclipse.jpt.core.jpa2.context.persistence.PersistenceUnit2_0; -import org.eclipse.jpt.core.jpa2.context.persistence.options.SharedCacheMode; -import org.eclipse.jpt.core.jpa2.context.persistence.options.ValidationMode; +import org.eclipse.jpt.core.jpa2.JpaProject2_0; +import org.eclipse.jpt.core.jpa2.context.PersistentType2_0; +import org.eclipse.jpt.core.resource.java.JavaResourceCompilationUnit; +import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType; import org.eclipse.jpt.core.resource.persistence.PersistenceFactory; import org.eclipse.jpt.core.resource.persistence.XmlJarFileRef; import org.eclipse.jpt.core.resource.persistence.XmlJavaClassRef; @@ -59,7 +66,6 @@ import org.eclipse.jpt.utility.internal.iterables.LiveCloneIterable; import org.eclipse.jpt.utility.internal.iterables.TransformationIterable; import org.eclipse.jpt.utility.internal.iterators.CloneIterator; import org.eclipse.jpt.utility.internal.iterators.CloneListIterator; -import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; import org.eclipse.jpt.utility.internal.iterators.CompositeListIterator; import org.eclipse.jpt.utility.internal.iterators.EmptyIterator; import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; @@ -105,9 +111,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 final Set<String> rootEntityNames = Collections.synchronizedSet(new HashSet<String>()); + protected AccessType defaultAccess; protected String defaultCatalog; protected String defaultSchema; @@ -123,6 +129,9 @@ public abstract class AbstractPersistenceUnit protected ValidationMode specifiedValidationMode; protected ValidationMode defaultValidationMode; + protected final Set<IFile> metamodelFiles = Collections.synchronizedSet(new HashSet<IFile>()); + + // ********** construction/initialization ********** /** @@ -163,6 +172,8 @@ public abstract class AbstractPersistenceUnit this.specifiedValidationMode = this.buildSpecifiedValidationMode(); this.defaultValidationMode = this.buildDefaultValidationMode(); + + this.initializeMetamodelFiles(); } /** @@ -177,83 +188,73 @@ public abstract class AbstractPersistenceUnit nonUpdateAspectNames.add(QUERIES_LIST); } - protected void initializeJarFileRefs() { - for (XmlJarFileRef xmlJarFileRef : this.xmlPersistenceUnit.getJarFiles()) { - this.jarFileRefs.add(this.buildJarFileRef(xmlJarFileRef)); - } - } - - protected void initializeProperties() { - this.connection = getContextNodeFactory().buildConnection(this); - this.options = getContextNodeFactory().buildOptions(this); - - XmlProperties xmlProperties = this.xmlPersistenceUnit.getProperties(); - if (xmlProperties == null) { - return; - } - for (XmlProperty xmlProperty : xmlProperties.getProperties()) { - this.properties.add(this.buildProperty(xmlProperty)); - } - } + + // ********** updating ********** - protected void initializeSpecifiedClassRefs() { - for (XmlJavaClassRef xmlJavaClassRef : this.xmlPersistenceUnit.getClasses()) { - this.specifiedClassRefs.add(this.buildClassRef(xmlJavaClassRef)); - } - } + public void update(XmlPersistenceUnit xpu) { + this.xmlPersistenceUnit = xpu; - protected void initializeMappingFileRefs() { - for (XmlMappingFileRef xmlMappingFileRef : this.xmlPersistenceUnit.getMappingFiles()) { - this.specifiedMappingFileRefs.add(this.buildSpecifiedMappingFileRef(xmlMappingFileRef)); - } - if ( ! this.impliedMappingFileIsSpecified() && this.impliedMappingFileExists()) { - this.impliedMappingFileRef = this.buildImpliedMappingFileRef(); - } - } + // the 'generators' and 'queries' lists are simply cleared out with each + // "update" and completely rebuilt as the "update" cascades through + // the persistence unit. When the persistence unit's "update" is + // complete, the lists have been populated and we fire the change event. + // @see #addGenerator(Generator) (and references) + // @see #addQuery(Query) (and references) + this.generators.clear(); + this.queries.clear(); - protected void initializeImpliedClassRefs() { - if ( ! this.excludesUnlistedClasses()) { - this.initializeImpliedClassRefs_(); - } - } + this.rootEntityNames.clear(); + + this.setName(xpu.getName()); + this.setSpecifiedTransactionType(this.buildSpecifiedTransactionType()); + this.setDefaultTransactionType(this.buildDefaultTransactionType()); + this.setDescription(xpu.getDescription()); + this.setProvider(xpu.getProvider()); + this.setJtaDataSource(xpu.getJtaDataSource()); + this.setNonJtaDataSource(xpu.getNonJtaDataSource()); + this.updateJarFileRefs(); - protected void initializeImpliedClassRefs_() { - for (Iterator<String> stream = this.getJpaProject().mappedJavaSourceClassNames(); stream.hasNext(); ) { - String typeName = stream.next(); - if ( ! this.specifiesPersistentType(typeName)) { - this.impliedClassRefs.add(this.buildClassRef(typeName)); - } - } - } + // update 'specifiedClassRefs' before 'mappingFileRefs' because of + // JpaFile rootStructureNode, we want the mapping file to "win", + // as it would in a JPA runtime implementation + this.updateSpecifiedClassRefs(); + this.updateMappingFileRefs(); - protected void initializePersistenceUnitDefaults() { - MappingFilePersistenceUnitDefaults defaults = this.getDefaults(); - this.defaultAccess = this.buildDefaultAccess(defaults); - this.defaultCatalog = this.buildDefaultCatalog(defaults); - this.defaultSchema = this.buildDefaultSchema(defaults); - this.defaultCascadePersist = this.buildDefaultCascadePersist(defaults); - } + // update 'impliedClassRefs' last since it depends on the contents of + // both 'specifiedClassRefs' and 'mappingFileRefs' + this.updateImpliedClassRefs(); - protected XmlPersistenceUnit getXmlPersistenceUnit() { - return this.xmlPersistenceUnit; - } + this.setSpecifiedExcludeUnlistedClasses(xpu.getExcludeUnlistedClasses()); + this.updateProperties(); + this.updatePersistenceUnitDefaults(); + + this.setSpecifiedSharedCacheMode(this.buildSpecifiedSharedCacheMode()); + this.setDefaultSharedCacheMode(this.buildDefaultSharedCacheMode()); + this.setSpecifiedValidationMode(this.buildSpecifiedValidationMode()); + this.setDefaultValidationMode(this.buildDefaultValidationMode()); - protected SharedCacheMode buildSpecifiedSharedCacheMode() { - return SharedCacheMode.fromXmlResourceModel(this.getXmlPersistenceUnit().getSharedCacheMode()); + // see comment at top of method + this.fireListChanged(GENERATORS_LIST, this.generators); + this.fireListChanged(QUERIES_LIST, this.queries); } - protected SharedCacheMode buildDefaultSharedCacheMode() { - return SharedCacheMode.UNSPECIFIED; - } - - protected ValidationMode buildSpecifiedValidationMode() { - return ValidationMode.fromXmlResourceModel(this.getXmlPersistenceUnit().getValidationMode()); + @Override + public void postUpdate() { + super.postUpdate(); + for (ClassRef classRef : this.getSpecifiedClassRefs()) { + classRef.postUpdate(); + } + for (ClassRef classRef : this.getImpliedClassRefs()) { + classRef.postUpdate(); + } + for (MappingFileRef mappingFileRef : CollectionTools.iterable(this.specifiedMappingFileRefs())) { + mappingFileRef.postUpdate(); + } + if (this.impliedMappingFileRef != null) { + this.impliedMappingFileRef.postUpdate(); + } } - protected ValidationMode buildDefaultValidationMode() { - return DEFAULT_VALIDATION_MODE; - } - // ********** JpaContextNode implementation ********** @@ -329,6 +330,20 @@ public abstract class AbstractPersistenceUnit this.firePropertyChanged(DEFAULT_TRANSACTION_TYPE_PROPERTY, old, defaultTransactionType); } + protected PersistenceUnitTransactionType buildSpecifiedTransactionType() { + return PersistenceUnitTransactionType.fromXmlResourceModel(this.xmlPersistenceUnit.getTransactionType()); + } + + /** + * TODO - calculate default + * From the JPA spec: "In a Java EE environment, if this element is not + * specified, the default is JTA. In a Java SE environment, if this element + * is not specified, a default of RESOURCE_LOCAL may be assumed." + */ + protected PersistenceUnitTransactionType buildDefaultTransactionType() { + return PersistenceUnitTransactionType.JTA; //return JTA for now, fixing regression in bug 277524 + } + // ********** description ********** @@ -418,6 +433,75 @@ public abstract class AbstractPersistenceUnit }; } + protected void initializeMappingFileRefs() { + for (XmlMappingFileRef xmlMappingFileRef : this.xmlPersistenceUnit.getMappingFiles()) { + this.specifiedMappingFileRefs.add(this.buildSpecifiedMappingFileRef(xmlMappingFileRef)); + } + if ( ! this.impliedMappingFileIsSpecified() && this.impliedMappingFileExists()) { + this.impliedMappingFileRef = this.buildImpliedMappingFileRef(); + } + } + + /** + * Since this is a *list*, we simply loop through the elements and match + * the context to the resource element by index, not by name like we do + * with 'impliedClassRefs'. + */ + protected void updateMappingFileRefs() { + // first update the specified mapping file refs... + // make a copy of the XML file refs (to prevent ConcurrentModificationException) + Iterator<XmlMappingFileRef> xmlFileRefs = new CloneIterator<XmlMappingFileRef>(this.xmlPersistenceUnit.getMappingFiles()); + + for (Iterator<MappingFileRef> contextFileRefs = this.specifiedMappingFileRefs(); contextFileRefs.hasNext(); ) { + MappingFileRef contextFileRef = contextFileRefs.next(); + if (xmlFileRefs.hasNext()) { + contextFileRef.update(xmlFileRefs.next()); + } else { + this.removeSpecifiedMappingFileRef_(contextFileRef); + } + } + + while (xmlFileRefs.hasNext()) { + this.addSpecifiedMappingFileRef_(this.buildSpecifiedMappingFileRef(xmlFileRefs.next())); + } + + // ...then update the implied mapping file ref + if (this.impliedMappingFileIsSpecified()) { + if (this.impliedMappingFileRef != null) { + this.unsetImpliedMappingFileRef(); + } + } else { + if (this.impliedMappingFileExists()) { + if (this.impliedMappingFileRef == null) { + this.setImpliedMappingFileRef(); + } + this.impliedMappingFileRef.update(null); + } else { + if (this.impliedMappingFileRef != null) { + this.unsetImpliedMappingFileRef(); + } + } + } + } + + protected MappingFileRef buildSpecifiedMappingFileRef(XmlMappingFileRef xmlMappingFileRef) { + return this.getContextNodeFactory().buildMappingFileRef(this, xmlMappingFileRef); + } + + protected boolean impliedMappingFileIsSpecified() { + String impliedMappingFileName = JptCorePlugin.DEFAULT_ORM_XML_FILE_PATH; + for (Iterator<MappingFileRef> stream = this.specifiedMappingFileRefs(); stream.hasNext(); ) { + if (impliedMappingFileName.equals(stream.next().getFileName())) { + return true; + } + } + return false; + } + + protected boolean impliedMappingFileExists() { + return getJpaProject().getDefaultOrmXmlResource() != null; + } + // ********** specified mapping file refs ********** @@ -552,15 +636,44 @@ public abstract class AbstractPersistenceUnit this.removeItemFromList(jarFileRef, this.jarFileRefs, JAR_FILE_REFS_LIST); } + protected void initializeJarFileRefs() { + for (XmlJarFileRef xmlJarFileRef : this.xmlPersistenceUnit.getJarFiles()) { + this.jarFileRefs.add(this.buildJarFileRef(xmlJarFileRef)); + } + } + + /** + * Since this is a *list*, we simply loop through the elements and match + * the context to the resource element by index, not by name like we do + * with 'impliedClassRefs'. + */ + protected void updateJarFileRefs() { + // make a copy of the XML file refs (to prevent ConcurrentModificationException) + Iterator<XmlJarFileRef> xmlFileRefs = new CloneIterator<XmlJarFileRef>(this.xmlPersistenceUnit.getJarFiles()); + + for (Iterator<JarFileRef> contextFileRefs = this.jarFileRefs(); contextFileRefs.hasNext(); ) { + JarFileRef contextFileRef = contextFileRefs.next(); + if (xmlFileRefs.hasNext()) { + contextFileRef.update(xmlFileRefs.next()); + } else { + this.removeJarFileRef_(contextFileRef); + } + } + + while (xmlFileRefs.hasNext()) { + this.addJarFileRef_(this.buildJarFileRef(xmlFileRefs.next())); + } + } + + protected JarFileRef buildJarFileRef(XmlJarFileRef xmlJarFileRef) { + return this.getContextNodeFactory().buildJarFileRef(this, xmlJarFileRef); + } + // ********** class refs ********** - @SuppressWarnings("unchecked") public Iterator<ClassRef> classRefs() { - return new CompositeIterator<ClassRef>( - this.specifiedClassRefs(), - this.impliedClassRefs() - ); + return this.getClassRefs().iterator(); } @SuppressWarnings("unchecked") @@ -640,6 +753,38 @@ public abstract class AbstractPersistenceUnit this.removeItemFromList(classRef, this.specifiedClassRefs, SPECIFIED_CLASS_REFS_LIST); } + protected void initializeSpecifiedClassRefs() { + for (XmlJavaClassRef xmlJavaClassRef : this.xmlPersistenceUnit.getClasses()) { + this.specifiedClassRefs.add(this.buildClassRef(xmlJavaClassRef)); + } + } + + /** + * Since this is a *list*, we simply loop through the elements and match + * the context to the resource element by index, not by name like we do + * with 'impliedClassRefs'. + */ + protected void updateSpecifiedClassRefs() { + // make a copy of the XML class refs (to prevent ConcurrentModificationException) + Iterator<XmlJavaClassRef> xmlClassRefs = new CloneIterator<XmlJavaClassRef>(this.xmlPersistenceUnit.getClasses()); + + for (ClassRef contextClassRef : this.getSpecifiedClassRefs()) { + if (xmlClassRefs.hasNext()) { + contextClassRef.update(xmlClassRefs.next()); + } else { + this.removeSpecifiedClassRef_(contextClassRef); + } + } + + while (xmlClassRefs.hasNext()) { + this.addSpecifiedClassRef_(this.buildClassRef(xmlClassRefs.next())); + } + } + + protected ClassRef buildClassRef(XmlJavaClassRef xmlClassRef) { + return this.getContextNodeFactory().buildClassRef(this, xmlClassRef); + } + // ********** implied class refs ********** @@ -670,6 +815,67 @@ public abstract class AbstractPersistenceUnit this.removeItemFromCollection(classRef, this.impliedClassRefs, IMPLIED_CLASS_REFS_COLLECTION); } + protected void initializeImpliedClassRefs() { + if ( ! this.excludesUnlistedClasses()) { + this.initializeImpliedClassRefs_(); + } + } + + protected void initializeImpliedClassRefs_() { + for (Iterator<String> stream = this.getJpaProject().mappedJavaSourceClassNames(); stream.hasNext(); ) { + String typeName = stream.next(); + if ( ! this.specifiesPersistentType(typeName)) { + this.impliedClassRefs.add(this.buildClassRef(typeName)); + } + } + } + + protected void updateImpliedClassRefs() { + if (this.excludesUnlistedClasses()) { + this.clearImpliedClassRefs_(); + } else { + this.updateImpliedClassRefs_(); + } + } + + protected void updateImpliedClassRefs_() { + HashBag<ClassRef> impliedRefsToRemove = CollectionTools.bag(this.impliedClassRefs(), this.impliedClassRefsSize()); + ArrayList<ClassRef> impliedRefsToUpdate = new ArrayList<ClassRef>(this.impliedClassRefsSize()); + + for (Iterator<String> mappedClassNames = this.getJpaProject().mappedJavaSourceClassNames(); mappedClassNames.hasNext(); ) { + String mappedClassName = mappedClassNames.next(); + if ( ! this.specifiesPersistentType(mappedClassName)) { + boolean match = false; + for (Iterator<ClassRef> classRefs = impliedRefsToRemove.iterator(); classRefs.hasNext(); ) { + ClassRef classRef = classRefs.next(); + if (mappedClassName.equals(classRef.getClassName())) { + classRefs.remove(); + impliedRefsToUpdate.add(classRef); + match = true; + break; + } + } + if ( ! match) { + this.addImpliedClassRef(mappedClassName); + } + } + } + for (ClassRef classRef : impliedRefsToRemove) { + this.removeImpliedClassRef(classRef); + } + // handle adding and removing implied class refs first, update the + // remaining implied class refs last; this reduces the churn during "update" + for (ClassRef classRef : impliedRefsToUpdate) { + classRef.update(classRef.getClassName()); + } + } + + protected void clearImpliedClassRefs_() { + for (ClassRef classRef : this.getImpliedClassRefs()) { + this.removeImpliedClassRef(classRef); + } + } + // ********** exclude unlisted classes ********** @@ -898,13 +1104,61 @@ public abstract class AbstractPersistenceUnit this.options.propertyRemoved(propertyName); } - public PersistenceUnitProperties getConnection() { - return this.connection; + protected void initializeProperties() { + this.connection = this.getContextNodeFactory().buildConnection(this); + this.options = this.getContextNodeFactory().buildOptions(this); + + XmlProperties xmlProperties = this.xmlPersistenceUnit.getProperties(); + if (xmlProperties == null) { + return; + } + for (XmlProperty xmlProperty : xmlProperties.getProperties()) { + this.properties.add(this.buildProperty(xmlProperty)); + } } - public PersistenceUnitProperties getOptions() { - return this.options; + /** + * Match the elements based on the XmlProperty resource object and also keep the order + * the same as the source. + */ + protected void updateProperties() { + HashBag<Property> contextPropertiesToRemove = CollectionTools.bag(this.properties(), this.propertiesSize()); + int resourceIndex = 0; + + for (Iterator<XmlProperty> xmlProperties = this.xmlProperties(); xmlProperties.hasNext(); ) { + XmlProperty xmlProperty = xmlProperties.next(); + boolean match = false; + for (Iterator<Property> contextProperties = contextPropertiesToRemove.iterator(); contextProperties.hasNext();) { + Property contextProperty = contextProperties.next(); + if (contextProperty.getXmlProperty() == xmlProperty) { + contextProperties.remove(); + this.moveProperty_(resourceIndex, contextProperty); + contextProperty.update(); + match = true; + break; + } + } + if ( ! match) { + this.addProperty_(resourceIndex, this.buildProperty(xmlProperty)); + } + resourceIndex++; + } + for (Property contextProperty : contextPropertiesToRemove) { + this.removeProperty_(contextProperty); + } + } + + protected Iterator<XmlProperty> xmlProperties() { + XmlProperties xmlProperties = this.xmlPersistenceUnit.getProperties(); + // make a copy of the XML properties (to prevent ConcurrentModificationException) + return (xmlProperties != null) ? new CloneIterator<XmlProperty>(xmlProperties.getProperties()) : EmptyIterator.<XmlProperty>instance(); } + + protected int xmlPropertiesSize() { + XmlProperties xmlProperties = this.xmlPersistenceUnit.getProperties(); + return xmlProperties == null ? 0 : xmlProperties.getProperties().size(); + } + // ********** ORM persistence unit defaults ********** @@ -918,6 +1172,10 @@ public abstract class AbstractPersistenceUnit this.firePropertyChanged(DEFAULT_ACCESS_PROPERTY, old, defaultAccess); } + protected AccessType buildDefaultAccess(MappingFilePersistenceUnitDefaults defaults) { + return (defaults == null) ? null : defaults.getAccess(); + } + public String getDefaultCatalog() { return this.defaultCatalog; } @@ -928,6 +1186,11 @@ public abstract class AbstractPersistenceUnit this.firePropertyChanged(DEFAULT_CATALOG_PROPERTY, old, defaultCatalog); } + protected String buildDefaultCatalog(MappingFilePersistenceUnitDefaults defaults) { + String catalog = (defaults == null) ? null : defaults.getCatalog(); + return (catalog != null) ? catalog : this.getJpaProject().getDefaultCatalog(); + } + public String getDefaultSchema() { return this.defaultSchema; } @@ -938,6 +1201,11 @@ public abstract class AbstractPersistenceUnit this.firePropertyChanged(DEFAULT_SCHEMA_PROPERTY, old, defaultSchema); } + protected String buildDefaultSchema(MappingFilePersistenceUnitDefaults defaults) { + String schema = (defaults == null) ? null : defaults.getSchema(); + return (schema != null) ? schema : this.getJpaProject().getDefaultSchema(); + } + public boolean getDefaultCascadePersist() { return this.defaultCascadePersist; } @@ -948,61 +1216,49 @@ public abstract class AbstractPersistenceUnit this.firePropertyChanged(DEFAULT_CASCADE_PERSIST_PROPERTY, old, defaultCascadePersist); } - - // ********** generators ********** - - public ListIterator<Generator> generators() { - return new CloneListIterator<Generator>(this.generators); - } - - public int generatorsSize() { - return this.generators.size(); + protected boolean buildDefaultCascadePersist(MappingFilePersistenceUnitDefaults defaults) { + return (defaults == null) ? false : defaults.isCascadePersist(); } - public void addGenerator(Generator generator) { - this.generators.add(generator); + protected void initializePersistenceUnitDefaults() { + MappingFilePersistenceUnitDefaults defaults = this.getDefaults(); + this.defaultAccess = this.buildDefaultAccess(defaults); + this.defaultCatalog = this.buildDefaultCatalog(defaults); + this.defaultSchema = this.buildDefaultSchema(defaults); + this.defaultCascadePersist = this.buildDefaultCascadePersist(defaults); } - public String[] uniqueGeneratorNames() { - HashSet<String> names = new HashSet<String>(this.generators.size()); - this.addNonNullGeneratorNamesTo(names); - return names.toArray(new String[names.size()]); + protected void updatePersistenceUnitDefaults() { + MappingFilePersistenceUnitDefaults defaults = this.getDefaults(); + this.setDefaultAccess(this.buildDefaultAccess(defaults)); + this.setDefaultCatalog(this.buildDefaultCatalog(defaults)); + this.setDefaultSchema(this.buildDefaultSchema(defaults)); + this.setDefaultCascadePersist(this.buildDefaultCascadePersist(defaults)); } - protected void addNonNullGeneratorNamesTo(Set<String> names) { - for (Iterator<Generator> stream = this.generators(); stream.hasNext(); ) { - String generatorName = stream.next().getName(); - if (generatorName != null) { - names.add(generatorName); + /** + * return the first persistence unit defaults we encounter in a mapping file + */ + protected MappingFilePersistenceUnitDefaults getDefaults() { + for (Iterator<MappingFileRef> stream = this.mappingFileRefs(); stream.hasNext(); ) { + MappingFileRef mappingFileRef = stream.next(); + if (mappingFileRef.persistenceUnitDefaultsExists()) { + return mappingFileRef.getPersistenceUnitDefaults(); } } + return null; } + + //************** PersistenceUnit2_0 implementation *********** - // ********** queries ********** - - public ListIterator<Query> queries() { - return new CloneListIterator<Query>(this.queries); - } - - public int queriesSize() { - return this.queries.size(); - } - - public void addQuery(Query query) { - this.queries.add(query); + public PersistenceUnitProperties getConnection() { + return this.connection; } - public void addRootWithSubEntities(String entityName) { - this.rootEntities.add(entityName); - } - - public boolean isRootWithSubEntities(String entityName) { - return this.rootEntities.contains(entityName); + public PersistenceUnitProperties getOptions() { + return this.options; } - - - //************** PersistenceUnit2_0 implementation *********** // ********** shared cache mode ********** @@ -1017,7 +1273,7 @@ public abstract class AbstractPersistenceUnit public void setSpecifiedSharedCacheMode(SharedCacheMode specifiedSharedCacheMode) { SharedCacheMode old = this.specifiedSharedCacheMode; this.specifiedSharedCacheMode = specifiedSharedCacheMode; - this.getXmlPersistenceUnit().setSharedCacheMode(SharedCacheMode.toXmlResourceModel(specifiedSharedCacheMode)); + this.xmlPersistenceUnit.setSharedCacheMode(SharedCacheMode.toXmlResourceModel(specifiedSharedCacheMode)); this.firePropertyChanged(SPECIFIED_SHARED_CACHE_MODE_PROPERTY, old, specifiedSharedCacheMode); } @@ -1044,6 +1300,14 @@ public abstract class AbstractPersistenceUnit return false;//null } + protected SharedCacheMode buildSpecifiedSharedCacheMode() { + return SharedCacheMode.fromXmlResourceModel(this.xmlPersistenceUnit.getSharedCacheMode()); + } + + protected SharedCacheMode buildDefaultSharedCacheMode() { + return SharedCacheMode.UNSPECIFIED; + } + // ********** validation mode ********** public ValidationMode getValidationMode() { @@ -1057,7 +1321,7 @@ public abstract class AbstractPersistenceUnit public void setSpecifiedValidationMode(ValidationMode specifiedValidationMode) { ValidationMode old = this.specifiedValidationMode; this.specifiedValidationMode = specifiedValidationMode; - this.getXmlPersistenceUnit().setValidationMode(ValidationMode.toXmlResourceModel(specifiedValidationMode)); + this.xmlPersistenceUnit.setValidationMode(ValidationMode.toXmlResourceModel(specifiedValidationMode)); this.firePropertyChanged(SPECIFIED_VALIDATION_MODE_PROPERTY, old, specifiedValidationMode); } @@ -1070,325 +1334,69 @@ public abstract class AbstractPersistenceUnit this.defaultValidationMode = defaultValidationMode; this.firePropertyChanged(DEFAULT_VALIDATION_MODE_PROPERTY, old, defaultValidationMode); } - // ********** updating ********** - - public void update(XmlPersistenceUnit xpu) { - this.xmlPersistenceUnit = xpu; - // the 'generators' and 'queries' lists are simply cleared out with each - // "update" and completely rebuilt as the "update" cascades through - // the persistence unit. When the persistence unit's "update" is - // complete, the lists have been populated and we fire the change event. - // @see #addGenerator(Generator) (and references) - // @see #addQuery(Query) (and references) - this.generators.clear(); - this.queries.clear(); - - this.rootEntities.clear(); - - this.setName(xpu.getName()); - this.setSpecifiedTransactionType(this.buildSpecifiedTransactionType()); - this.setDefaultTransactionType(this.buildDefaultTransactionType()); - this.setDescription(xpu.getDescription()); - this.setProvider(xpu.getProvider()); - this.setJtaDataSource(xpu.getJtaDataSource()); - this.setNonJtaDataSource(xpu.getNonJtaDataSource()); - this.updateJarFileRefs(); - - // update 'specifiedClassRefs' before 'mappingFileRefs' because of - // JpaFile rootStructureNode, we want the mapping file to "win", - // as it would in a JPA runtime implementation - this.updateSpecifiedClassRefs(); - this.updateMappingFileRefs(); - - // update 'impliedClassRefs' last since it depends on the contents of - // both 'specifiedClassRefs' and 'mappingFileRefs' - this.updateImpliedClassRefs(); - - this.setSpecifiedExcludeUnlistedClasses(xpu.getExcludeUnlistedClasses()); - this.updateProperties(); - this.updatePersistenceUnitDefaults(); - - this.setSpecifiedSharedCacheMode(this.buildSpecifiedSharedCacheMode()); - this.setDefaultSharedCacheMode(this.buildDefaultSharedCacheMode()); - this.setSpecifiedValidationMode(this.buildSpecifiedValidationMode()); - this.setDefaultValidationMode(this.buildDefaultValidationMode()); - - // see comment at top of method - this.fireListChanged(GENERATORS_LIST, this.generators); - this.fireListChanged(QUERIES_LIST, this.queries); - } - - @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 ValidationMode buildSpecifiedValidationMode() { + return ValidationMode.fromXmlResourceModel(this.xmlPersistenceUnit.getValidationMode()); } - protected PersistenceUnitTransactionType buildSpecifiedTransactionType() { - return PersistenceUnitTransactionType.fromXmlResourceModel(this.xmlPersistenceUnit.getTransactionType()); + protected ValidationMode buildDefaultValidationMode() { + return DEFAULT_VALIDATION_MODE; } - /** - * TODO - calculate default - * From the JPA spec: "In a Java EE environment, if this element is not - * specified, the default is JTA. In a Java SE environment, if this element - * is not specified, a default of RESOURCE_LOCAL may be assumed." - */ - protected PersistenceUnitTransactionType buildDefaultTransactionType() { - return PersistenceUnitTransactionType.JTA; //return JTA for now, fixing regression in bug 277524 - } - /** - * Since this is a *list*, we simply loop through the elements and match - * the context to the resource element by index, not by name like we do - * with 'impliedClassRefs'. - */ - protected void updateJarFileRefs() { - // make a copy of the XML file refs (to prevent ConcurrentModificationException) - Iterator<XmlJarFileRef> xmlFileRefs = new CloneIterator<XmlJarFileRef>(this.xmlPersistenceUnit.getJarFiles()); - - for (Iterator<JarFileRef> contextFileRefs = this.jarFileRefs(); contextFileRefs.hasNext(); ) { - JarFileRef contextFileRef = contextFileRefs.next(); - if (xmlFileRefs.hasNext()) { - contextFileRef.update(xmlFileRefs.next()); - } else { - this.removeJarFileRef_(contextFileRef); - } - } + // ********** generators ********** - while (xmlFileRefs.hasNext()) { - this.addJarFileRef_(this.buildJarFileRef(xmlFileRefs.next())); - } + public ListIterator<Generator> generators() { + return new CloneListIterator<Generator>(this.generators); } - protected JarFileRef buildJarFileRef(XmlJarFileRef xmlJarFileRef) { - return this.getContextNodeFactory().buildJarFileRef(this, xmlJarFileRef); + public int generatorsSize() { + return this.generators.size(); } - /** - * Since this is a *list*, we simply loop through the elements and match - * the context to the resource element by index, not by name like we do - * with 'impliedClassRefs'. - */ - protected void updateSpecifiedClassRefs() { - // make a copy of the XML class refs (to prevent ConcurrentModificationException) - Iterator<XmlJavaClassRef> xmlClassRefs = new CloneIterator<XmlJavaClassRef>(this.xmlPersistenceUnit.getClasses()); - - for (Iterator<ClassRef> contextClassRefs = this.specifiedClassRefs(); contextClassRefs.hasNext(); ) { - ClassRef contextClassRef = contextClassRefs.next(); - if (xmlClassRefs.hasNext()) { - contextClassRef.update(xmlClassRefs.next()); - } else { - this.removeSpecifiedClassRef_(contextClassRef); - } - } - - while (xmlClassRefs.hasNext()) { - this.addSpecifiedClassRef_(this.buildClassRef(xmlClassRefs.next())); - } + public void addGenerator(Generator generator) { + this.generators.add(generator); } - protected ClassRef buildClassRef(XmlJavaClassRef xmlClassRef) { - return this.getContextNodeFactory().buildClassRef(this, xmlClassRef); + public String[] uniqueGeneratorNames() { + HashSet<String> names = new HashSet<String>(this.generators.size()); + this.addNonNullGeneratorNamesTo(names); + return names.toArray(new String[names.size()]); } - /** - * Since this is a *list*, we simply loop through the elements and match - * the context to the resource element by index, not by name like we do - * with 'impliedClassRefs'. - */ - protected void updateMappingFileRefs() { - // first update the specified mapping file refs... - // make a copy of the XML file refs (to prevent ConcurrentModificationException) - Iterator<XmlMappingFileRef> xmlFileRefs = new CloneIterator<XmlMappingFileRef>(this.xmlPersistenceUnit.getMappingFiles()); - - for (Iterator<MappingFileRef> contextFileRefs = this.specifiedMappingFileRefs(); contextFileRefs.hasNext(); ) { - MappingFileRef contextFileRef = contextFileRefs.next(); - if (xmlFileRefs.hasNext()) { - contextFileRef.update(xmlFileRefs.next()); - } else { - this.removeSpecifiedMappingFileRef_(contextFileRef); - } - } - - while (xmlFileRefs.hasNext()) { - this.addSpecifiedMappingFileRef_(this.buildSpecifiedMappingFileRef(xmlFileRefs.next())); - } - - // ...then update the implied mapping file ref - if (this.impliedMappingFileIsSpecified()) { - if (this.impliedMappingFileRef != null) { - this.unsetImpliedMappingFileRef(); - } - } else { - if (this.impliedMappingFileExists()) { - if (this.impliedMappingFileRef == null) { - this.setImpliedMappingFileRef(); - } - this.impliedMappingFileRef.update(null); - } else { - if (this.impliedMappingFileRef != null) { - this.unsetImpliedMappingFileRef(); - } + protected void addNonNullGeneratorNamesTo(Set<String> names) { + for (Iterator<Generator> stream = this.generators(); stream.hasNext(); ) { + String generatorName = stream.next().getName(); + if (generatorName != null) { + names.add(generatorName); } } } - protected MappingFileRef buildSpecifiedMappingFileRef(XmlMappingFileRef xmlMappingFileRef) { - return this.getContextNodeFactory().buildMappingFileRef(this, xmlMappingFileRef); - } - protected boolean impliedMappingFileIsSpecified() { - String impliedMappingFileName = JptCorePlugin.DEFAULT_ORM_XML_FILE_PATH; - for (Iterator<MappingFileRef> stream = this.specifiedMappingFileRefs(); stream.hasNext(); ) { - if (impliedMappingFileName.equals(stream.next().getFileName())) { - return true; - } - } - return false; - } + // ********** queries ********** - protected boolean impliedMappingFileExists() { - return getJpaProject().getDefaultOrmXmlResource() != null; + public ListIterator<Query> queries() { + return new CloneListIterator<Query>(this.queries); } - protected void updateImpliedClassRefs() { - if (this.excludesUnlistedClasses()) { - this.clearImpliedClassRefs_(); - } else { - this.updateImpliedClassRefs_(); - } + public int queriesSize() { + return this.queries.size(); } - protected void updateImpliedClassRefs_() { - HashBag<ClassRef> impliedRefsToRemove = CollectionTools.bag(this.impliedClassRefs(), this.impliedClassRefsSize()); - ArrayList<ClassRef> impliedRefsToUpdate = new ArrayList<ClassRef>(this.impliedClassRefsSize()); - - for (Iterator<String> mappedClassNames = this.getJpaProject().mappedJavaSourceClassNames(); mappedClassNames.hasNext(); ) { - String mappedClassName = mappedClassNames.next(); - if ( ! this.specifiesPersistentType(mappedClassName)) { - boolean match = false; - for (Iterator<ClassRef> classRefs = impliedRefsToRemove.iterator(); classRefs.hasNext(); ) { - ClassRef classRef = classRefs.next(); - if (mappedClassName.equals(classRef.getClassName())) { - classRefs.remove(); - impliedRefsToUpdate.add(classRef); - match = true; - break; - } - } - if ( ! match) { - this.addImpliedClassRef(mappedClassName); - } - } - } - for (ClassRef classRef : impliedRefsToRemove) { - this.removeImpliedClassRef(classRef); - } - // handle adding and removing implied class refs first, update the - // remaining implied class refs last; this reduces the churn during "update" - for (ClassRef classRef : impliedRefsToUpdate) { - classRef.update(classRef.getClassName()); - } + public void addQuery(Query query) { + this.queries.add(query); } - protected void clearImpliedClassRefs_() { - for (Iterator<ClassRef> stream = this.impliedClassRefs(); stream.hasNext(); ) { - this.removeImpliedClassRef(stream.next()); - } - } - /** - * Match the elements based on the XmlProperty resource object and also keep the order - * the same as the source. - */ - protected void updateProperties() { - HashBag<Property> contextPropertiesToRemove = CollectionTools.bag(this.properties(), this.propertiesSize()); - int resourceIndex = 0; - - for (Iterator<XmlProperty> xmlProperties = this.xmlProperties(); xmlProperties.hasNext(); ) { - XmlProperty xmlProperty = xmlProperties.next(); - boolean match = false; - for (Iterator<Property> contextProperties = contextPropertiesToRemove.iterator(); contextProperties.hasNext();) { - Property contextProperty = contextProperties.next(); - if (contextProperty.getXmlProperty() == xmlProperty) { - contextProperties.remove(); - this.moveProperty_(resourceIndex, contextProperty); - contextProperty.update(); - match = true; - break; - } - } - if ( ! match) { - this.addProperty_(resourceIndex, this.buildProperty(xmlProperty)); - } - resourceIndex++; - } - for (Property contextProperty : contextPropertiesToRemove) { - this.removeProperty_(contextProperty); - } - } + // ********** root entities ********** - protected Iterator<XmlProperty> xmlProperties() { - XmlProperties xmlProperties = this.xmlPersistenceUnit.getProperties(); - // make a copy of the XML properties (to prevent ConcurrentModificationException) - return (xmlProperties != null) ? new CloneIterator<XmlProperty>(xmlProperties.getProperties()) : EmptyIterator.<XmlProperty>instance(); + public void addRootEntityWithSubEntities(String entityName) { + this.rootEntityNames.add(entityName); } - protected int xmlPropertiesSize() { - XmlProperties xmlProperties = this.xmlPersistenceUnit.getProperties(); - return xmlProperties == null ? 0 : xmlProperties.getProperties().size(); - } - - protected void updatePersistenceUnitDefaults() { - MappingFilePersistenceUnitDefaults defaults = this.getDefaults(); - this.setDefaultAccess(this.buildDefaultAccess(defaults)); - this.setDefaultCatalog(this.buildDefaultCatalog(defaults)); - this.setDefaultSchema(this.buildDefaultSchema(defaults)); - this.setDefaultCascadePersist(this.buildDefaultCascadePersist(defaults)); - } - - /** - * return the first persistence unit defaults we encounter in a mapping file - */ - protected MappingFilePersistenceUnitDefaults getDefaults() { - for (Iterator<MappingFileRef> stream = this.mappingFileRefs(); stream.hasNext(); ) { - MappingFileRef mappingFileRef = stream.next(); - if (mappingFileRef.persistenceUnitDefaultsExists()) { - return mappingFileRef.getPersistenceUnitDefaults(); - } - } - return null; - } - - protected AccessType buildDefaultAccess(MappingFilePersistenceUnitDefaults defaults) { - return (defaults == null) ? null : defaults.getAccess(); - } - - protected String buildDefaultCatalog(MappingFilePersistenceUnitDefaults defaults) { - String catalog = (defaults == null) ? null : defaults.getCatalog(); - return (catalog != null) ? catalog : this.getJpaProject().getDefaultCatalog(); - } - - protected String buildDefaultSchema(MappingFilePersistenceUnitDefaults defaults) { - String schema = (defaults == null) ? null : defaults.getSchema(); - return (schema != null) ? schema : this.getJpaProject().getDefaultSchema(); - } - - protected boolean buildDefaultCascadePersist(MappingFilePersistenceUnitDefaults defaults) { - return (defaults == null) ? false : defaults.isCascadePersist(); + public boolean entityIsRootWithSubEntities(String entityName) { + return this.rootEntityNames.contains(entityName); } @@ -1588,8 +1596,8 @@ public abstract class AbstractPersistenceUnit } public boolean specifiesPersistentType(String className) { - for (Iterator<ClassRef> stream = this.specifiedClassRefs(); stream.hasNext(); ) { - if (className.equals(stream.next().getClassName())) { + for (ClassRef classRef : this.getSpecifiedClassRefs()) { + if (className.equals(classRef.getClassName())) { return true; } } @@ -1631,31 +1639,110 @@ public abstract class AbstractPersistenceUnit // ********** metamodel ********** + // put metamodel stuff here so it can be shared by Generic and EclipseLink implementations + + public void initializeMetamodel() { + this.initializeMetamodelFiles(); + } + + protected void initializeMetamodelFiles() { + CollectionTools.addAll(this.metamodelFiles, this.getGeneratedMetamodelFiles()); + } + + protected Iterable<IFile> getGeneratedMetamodelFiles() { + return new TransformationIterable<JavaResourcePersistentType, IFile>(this.getGeneratedMetamodelTypes()) { + @Override + protected IFile transform(JavaResourcePersistentType jrpt) { + return jrpt.getFile(); + } + }; + } + + protected Iterable<JavaResourcePersistentType> getGeneratedMetamodelTypes() { + return ((JpaProject2_0) this.getJpaProject()).getGeneratedMetamodelTypes(); + } /** * If we have the same persistent type in multiple locations, the last one * we encounter wins (i.e. the classes in the orm.xml take precedence). */ public void synchronizeMetamodel() { - HashMap<String, PersistentType> persistentTypes = new HashMap<String, PersistentType>(); + // gather the persistent unit's types (eliminating duplicates, ignoring case) + HashMap<String, PersistentType2_0> persistentTypes = new HashMap<String, PersistentType2_0>(); this.addContainerPersistentTypesTo(this.getJarFileRefs(), persistentTypes); this.addPersistentTypesTo(this.getNonNullClassRefPersistentTypes(), persistentTypes); this.addContainerPersistentTypesTo(this.getMappingFileRefs(), persistentTypes); - for (PersistentType persistentType : persistentTypes.values()) { + + // copy the list of metamodel files... + HashSet<IFile> deadMetamodelFiles = new HashSet<IFile>(this.metamodelFiles); + this.metamodelFiles.clear(); + for (PersistentType2_0 persistentType : persistentTypes.values()) { + IFile metamodelFile = persistentType.getMetamodelFile(); + // ...remove whatever files are still present... + deadMetamodelFiles.remove(metamodelFile); + // ...rebuild the list of metamodel files... + if (this.fileIsGeneratedMetamodel(metamodelFile)) { // only add files with the Dali tag + this.metamodelFiles.add(metamodelFile); + } + } + // ...delete the files that are now gone + // [perform the deletes first - this is critical when a file has been + // renamed by only altering its name's case; since we will try to write + // out a new file that, on Windows, collides with the old file :-( ] + for (IFile deadMetamodelFile : deadMetamodelFiles) { + this.deleteMetamodelFile(deadMetamodelFile); + } + // now generate the metamodel classes + for (PersistentType2_0 persistentType : persistentTypes.values()) { persistentType.synchronizeMetamodel(); } } - protected void addContainerPersistentTypesTo(Iterable<? extends PersistentTypeContainer> ptContainers, HashMap<String, PersistentType> persistentTypeMap) { + protected void addContainerPersistentTypesTo(Iterable<? extends PersistentTypeContainer> ptContainers, HashMap<String, PersistentType2_0> persistentTypeMap) { for (PersistentTypeContainer ptContainer : ptContainers) { this.addPersistentTypesTo(ptContainer.getPersistentTypes(), persistentTypeMap); } } - protected void addPersistentTypesTo(Iterable<? extends PersistentType> persistentTypes, HashMap<String, PersistentType> persistentTypeMap) { + protected void addPersistentTypesTo(Iterable<? extends PersistentType> persistentTypes, HashMap<String, PersistentType2_0> persistentTypeMap) { for (PersistentType persistentType : persistentTypes) { - persistentTypeMap.put(persistentType.getName(), persistentType); + // hopefully this is case-insensitive enough... + persistentTypeMap.put(persistentType.getName().toLowerCase(), (PersistentType2_0) persistentType); } } + protected void deleteMetamodelFile(IFile file) { + try { + this.deleteMetamodelFile_(file); + } catch (CoreException ex) { + JptCorePlugin.log(ex); + } + } + + protected void deleteMetamodelFile_(IFile file) throws CoreException { + if (this.fileIsGeneratedMetamodel(file)) { + file.delete(true, null); // true = force + } + } + + protected boolean fileIsGeneratedMetamodel(IFile file) { + JavaResourceCompilationUnit jrcu = this.getJpaProject().getJavaResourceCompilationUnit(file); + if (jrcu == null) { + return false; // hmmm... + } + Iterator<JavaResourcePersistentType> types = jrcu.persistentTypes(); + if ( ! types.hasNext()) { + return false; // no types in the file + } + JavaResourcePersistentType jrpt = types.next(); + if (types.hasNext()) { + return false; // should have only a single type in the file + } + return jrpt.isGeneratedMetamodel(); + } + + public void disposeMetamodel() { + this.metamodelFiles.clear(); + } + } |