diff options
author | kmoore | 2010-11-29 21:54:25 +0000 |
---|---|---|
committer | kmoore | 2010-11-29 21:54:25 +0000 |
commit | 4c79891da427a3fe700078d696ff3d3ac8e19df5 (patch) | |
tree | 2c42e6b0a4f4b22d287f01690d5b81f92692db9d | |
parent | b336e803b522da6827257b1cbc786160f8f8e367 (diff) | |
download | webtools.dali-4c79891da427a3fe700078d696ff3d3ac8e19df5.tar.gz webtools.dali-4c79891da427a3fe700078d696ff3d3ac8e19df5.tar.xz webtools.dali-4c79891da427a3fe700078d696ff3d3ac8e19df5.zip |
support for superPersistentClass so we can use it for defining the default access type.
6 files changed, 215 insertions, 66 deletions
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbContextRoot.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbContextRoot.java index 356793dcd2..5ad56accb8 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbContextRoot.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbContextRoot.java @@ -31,6 +31,11 @@ public interface JaxbContextRoot public final static String PACKAGES_COLLECTION = "packages"; //$NON-NLS-1$ int getPackagesSize(); + + /** + * Return the package with the given name + */ + JaxbPackage getPackage(String packageName); /** * Return the set of all JAXB types within this context root. @@ -54,6 +59,11 @@ public interface JaxbContextRoot * Return the set of persistent classes that are in the given package */ Iterable<JaxbPersistentClass> getPersistentClasses(JaxbPackage jaxbPackage); + + /** + * Return the persistent class with the given fully qualified name + */ + JaxbPersistentClass getPersistentClass(String fullyQualifiedTypeName); /** * The set of registries. diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentClass.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentClass.java index 2235226b17..d7d50ad675 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentClass.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentClass.java @@ -31,6 +31,22 @@ public interface JaxbPersistentClass JaxbPersistentClass getSuperPersistentClass(); String SUPER_PERSISTENT_CLASS_PROPERTY = "superPersistentClass"; //$NON-NLS-1$ + /** + * Return the persistent type's "persistence" inheritance hierarchy, + * <em>including</em> the persistent type itself. + * The returned iterator will return elements infinitely if the hierarchy + * has a loop. + */ + Iterable<JaxbPersistentClass> getInheritanceHierarchy(); + + /** + * Return the persistent type's "persistence" inheritance hierarchy, + * <em>excluding</em> the persistent type itself. + * The returned iterator will return elements infinitely if the hierarchy + * has a loop. + */ + Iterable<JaxbPersistentClass> getAncestors(); + /**************** factory class *****************/ diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericContextRoot.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericContextRoot.java index 7e5e78f567..fd37fec96d 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericContextRoot.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericContextRoot.java @@ -26,6 +26,7 @@ import org.eclipse.jpt.jaxb.core.resource.java.JAXB; import org.eclipse.jpt.jaxb.core.resource.java.JavaResourcePackage; import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; import org.eclipse.jpt.utility.internal.CollectionTools; +import org.eclipse.jpt.utility.internal.StringTools; import org.eclipse.jpt.utility.internal.iterables.FilteringIterable; import org.eclipse.jpt.utility.internal.iterables.LiveCloneIterable; import org.eclipse.jpt.utility.internal.iterables.SubIterableWrapper; @@ -268,6 +269,15 @@ public class GenericContextRoot public int getPackagesSize() { return this.packages.size(); } + + public JaxbPackage getPackage(String packageName) { + for (JaxbPackage jaxbPackage : this.getPackages()) { + if (StringTools.stringsAreEqual(jaxbPackage.getName(), packageName)) { + return jaxbPackage; + } + } + return null; + } protected JaxbPackage addPackage(JaxbPackage contextPackage) { if (this.packages.containsKey(contextPackage.getName())) { @@ -390,6 +400,15 @@ public class GenericContextRoot }; } + public JaxbPersistentClass getPersistentClass(String className) { + for (JaxbPersistentClass jaxbClass : this.getPersistentClasses()) { + if (StringTools.stringsAreEqual(jaxbClass.getFullyQualifiedName(), className)) { + return jaxbClass; + } + } + return null; + } + @Override public void stateChanged() { super.stateChanged(); diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericPackage.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericPackage.java index 118ccb36e0..a77a2ea424 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericPackage.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericPackage.java @@ -34,23 +34,25 @@ public class GenericPackage public void synchronizeWithResourceModel() { + if (this.packageInfo != null) { + this.packageInfo.synchronizeWithResourceModel(); + } + } + + //Building/removing of the packageInfo is in the update because this is dependent + //on a JaxbFile being added/removed which only causes an update of the model. + public void update() { JavaResourcePackage jrp = getJaxbProject().getAnnotatedJavaResourcePackage(this.name); if (jrp == null) { - if (this.packageInfo != null) { - setPackageInfo_(null); - } + this.setPackageInfo_(null); } else { if (this.packageInfo == null) { - setPackageInfo_(buildPackageInfo(jrp)); + this.setPackageInfo_(this.buildPackageInfo(jrp)); + } + else { + this.packageInfo.update(); } - this.packageInfo.synchronizeWithResourceModel(); - } - } - - public void update() { - if (this.packageInfo != null) { - this.packageInfo.update(); } } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentClass.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentClass.java index cfcfc84f03..986303ec84 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentClass.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentClass.java @@ -9,7 +9,10 @@ ******************************************************************************/ package org.eclipse.jpt.jaxb.core.internal.context.java; +import java.util.Collection; +import java.util.HashSet; import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot; +import org.eclipse.jpt.jaxb.core.context.JaxbPackage; import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentClass; import org.eclipse.jpt.jaxb.core.context.XmlAccessOrder; @@ -20,6 +23,8 @@ import org.eclipse.jpt.jaxb.core.resource.java.XmlAccessorOrderAnnotation; import org.eclipse.jpt.jaxb.core.resource.java.XmlAccessorTypeAnnotation; import org.eclipse.jpt.jaxb.core.resource.java.XmlRootElementAnnotation; import org.eclipse.jpt.jaxb.core.resource.java.XmlTypeAnnotation; +import org.eclipse.jpt.utility.internal.CollectionTools; +import org.eclipse.jpt.utility.internal.iterables.ChainIterable; import org.eclipse.jpt.utility.internal.iterables.ListIterable; public class GenericJavaPersistentClass @@ -64,9 +69,8 @@ public class GenericJavaPersistentClass } protected JaxbPackageInfo getPackageInfo() { - //TODO - return null; - //return this.getParent().getPackageInfo(); + JaxbPackage jaxbPackage = getParent().getPackage(this.getPackageName()); + return jaxbPackage == null ? null : jaxbPackage.getPackageInfo(); } // ********** synchronize/update ********** @@ -237,48 +241,66 @@ public class GenericJavaPersistentClass this.firePropertyChanged(SUPER_PERSISTENT_CLASS_PROPERTY, old, superPersistentClass); } - //TODO super persistent class protected JaxbPersistentClass buildSuperPersistentClass() { - return null; -// HashSet<JavaResourcePersistentType> visited = new HashSet<JavaResourcePersistentType>(); -// visited.add(this.resourcePersistentType); -// PersistentType spt = this.getSuperPersistentType(this.resourcePersistentType.getSuperclassQualifiedName(), visited); -// if (spt == null) { -// return null; -// } -// if (CollectionTools.contains(spt.inheritanceHierarchy(), this)) { -// return null; // short-circuit in this case, we have circular inheritance -// } -// return spt.isMapped() ? spt : spt.getSuperPersistentType(); - } -// -// /** -// * The JPA spec allows non-persistent types in a persistent type's -// * inheritance hierarchy. We check for a persistent type with the -// * specified name in the persistence unit. If it is not found we use -// * resource persistent type and look for *its* super type. -// * -// * The 'visited' collection is used to detect a cycle in the *resource* type -// * inheritance hierarchy and prevent the resulting stack overflow. -// * Any cycles in the *context* type inheritance hierarchy are handled in -// * #buildSuperPersistentType(). -// */ -// protected PersistentType getSuperPersistentType(String typeName, Collection<JavaResourcePersistentType> visited) { -// if (typeName == null) { -// return null; -// } -// JavaResourcePersistentType resourceType = this.getJpaProject().getJavaResourcePersistentType(typeName); -// if ((resourceType == null) || visited.contains(resourceType)) { -// return null; -// } -// visited.add(resourceType); -// PersistentType spt = this.getPersistentType(typeName); -// return (spt != null) ? spt : this.getSuperPersistentType(resourceType.getSuperclassQualifiedName(), visited); // recurse -// } -// -// protected PersistentType getPersistentType(String typeName) { -// return this.getPersistenceUnit().getPersistentType(typeName); -// } + HashSet<JavaResourceType> visited = new HashSet<JavaResourceType>(); + visited.add(this.resourceType); + JaxbPersistentClass spc = this.getSuperPersistentClass(this.resourceType.getSuperclassQualifiedName(), visited); + if (spc == null) { + return null; + } + if (CollectionTools.contains(spc.getInheritanceHierarchy(), this)) { + return null; // short-circuit in this case, we have circular inheritance + } + return spc; + } + + /** + * The JPA spec allows non-persistent types in a persistent type's + * inheritance hierarchy. We check for a persistent type with the + * specified name in the persistence unit. If it is not found we use + * resource persistent type and look for *its* super type. + * + * The 'visited' collection is used to detect a cycle in the *resource* type + * inheritance hierarchy and prevent the resulting stack overflow. + * Any cycles in the *context* type inheritance hierarchy are handled in + * #buildSuperPersistentType(). + */ + protected JaxbPersistentClass getSuperPersistentClass(String typeName, Collection<JavaResourceType> visited) { + if (typeName == null) { + return null; + } + JavaResourceType resourceType = this.getJaxbProject().getJavaResourceType(typeName); + if ((resourceType == null) || visited.contains(resourceType)) { + return null; + } + visited.add(resourceType); + JaxbPersistentClass spc = this.getPersistentClass(typeName); + return (spc != null && resourceType.isMapped()) ? spc : this.getSuperPersistentClass(resourceType.getSuperclassQualifiedName(), visited); // recurse + } + + protected JaxbPersistentClass getPersistentClass(String fullyQualifiedTypeName) { + return this.getParent().getPersistentClass(fullyQualifiedTypeName); + } + + // ********** inheritance ********** + + public Iterable<JaxbPersistentClass> getInheritanceHierarchy() { + return this.getInheritanceHierarchyOf(this); + } + + public Iterable<JaxbPersistentClass> getAncestors() { + return this.getInheritanceHierarchyOf(this.superPersistentClass); + } + + protected Iterable<JaxbPersistentClass> getInheritanceHierarchyOf(JaxbPersistentClass start) { + // using a chain iterator to traverse up the inheritance tree + return new ChainIterable<JaxbPersistentClass>(start) { + @Override + protected JaxbPersistentClass nextLink(JaxbPersistentClass persistentType) { + return persistentType.getSuperPersistentClass(); + } + }; + } // ********** access type ********** @@ -472,6 +494,12 @@ public class GenericJavaPersistentClass return (XmlRootElementAnnotation) this.getJavaResourceType().getAnnotation(XmlRootElementAnnotation.ANNOTATION_NAME); } + @Override + public void toString(StringBuilder sb) { + super.toString(sb); + sb.append(this.getFullyQualifiedName()); + } + /** * xml java type adapter container */ diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaPersistentClassTests.java b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaPersistentClassTests.java index 75e4190ce8..8b150d798b 100644 --- a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaPersistentClassTests.java +++ b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaPersistentClassTests.java @@ -16,9 +16,11 @@ import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.MarkerAnnotation; import org.eclipse.jdt.core.dom.NormalAnnotation; +import org.eclipse.jpt.core.tests.internal.projects.TestJavaProject.SourceWriter; import org.eclipse.jpt.core.utility.jdt.AnnotatedElement; import org.eclipse.jpt.core.utility.jdt.Member; import org.eclipse.jpt.core.utility.jdt.ModifiedDeclaration; +import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentClass; import org.eclipse.jpt.jaxb.core.context.XmlAccessOrder; import org.eclipse.jpt.jaxb.core.context.XmlAccessType; @@ -53,6 +55,24 @@ public class GenericJavaPersistentClassTests extends JaxbContextModelTestCase } }); } + + private void createTestSubType() throws Exception { + SourceWriter sourceWriter = new SourceWriter() { + public void appendSourceTo(StringBuilder sb) { + sb.append(CR); + sb.append("import "); + sb.append(JAXB.XML_TYPE); + sb.append(";"); + sb.append(CR); + sb.append("@XmlType"); + sb.append(CR); + sb.append("public class ").append("AnnotationTestTypeChild").append(" "); + sb.append("extends " + TYPE_NAME + " "); + sb.append("{}").append(CR); + } + }; + this.javaProject.createCompilationUnit(PACKAGE_NAME, "AnnotationTestTypeChild.java", sourceWriter); + } private ICompilationUnit createXmlTypeWithAccessorType() throws CoreException { return this.createTestType(new DefaultAnnotationWriter() { @@ -82,6 +102,12 @@ public class GenericJavaPersistentClassTests extends JaxbContextModelTestCase }); } + private ICompilationUnit createPackageInfoWithAccessorType() throws CoreException { + return createTestPackageInfo( + "@XmlAccessorType(value = XmlAccessType.PROPERTY)", + JAXB.XML_ACCESS_TYPE, JAXB.XML_ACCESSOR_TYPE); + } + public void testModifyFactoryClass() throws Exception { createTypeWithXmlType(); @@ -309,9 +335,7 @@ public class GenericJavaPersistentClassTests extends JaxbContextModelTestCase }); assertNull(persistentClass.getNamespace()); } - - //TODO test super type with @XmlAccessorType - //TODO test package-info.java with @XmlAccessorType + public void testModifyAccessType() throws Exception { createXmlTypeWithAccessorType(); @@ -387,21 +411,71 @@ public class GenericJavaPersistentClassTests extends JaxbContextModelTestCase assertEquals(XmlAccessType.PUBLIC_MEMBER, persistentClass.getAccessType()); assertEquals(XmlAccessType.PUBLIC_MEMBER, persistentClass.getDefaultAccessType()); } - + + /** + * If there is a @XmlAccessorType on a class, then it is used. + * Otherwise, if a @XmlAccessorType exists on one of its super classes, then it is inherited. + * Otherwise, the @XmlAccessorType on a package is inherited. + */ + public void testGetDefaultAccessType() throws Exception { + this.createTypeWithXmlType(); + this.createTestSubType(); + JaxbPersistentClass persistentClass = CollectionTools.get(getContextRoot().getPersistentClasses(), 0); + JaxbPersistentClass childPersistentClass = CollectionTools.get(getContextRoot().getPersistentClasses(), 0); + + assertEquals(XmlAccessType.PUBLIC_MEMBER, childPersistentClass.getDefaultAccessType()); + + this.createPackageInfoWithAccessorType(); + assertEquals(XmlAccessType.PROPERTY, childPersistentClass.getDefaultAccessType()); + + persistentClass.setSpecifiedAccessType(XmlAccessType.FIELD); + assertEquals(XmlAccessType.PROPERTY, childPersistentClass.getDefaultAccessType()); + + JaxbPackageInfo contextPackageInfo = CollectionTools.get(getContextRoot().getPackages(), 0).getPackageInfo(); + persistentClass.setSpecifiedAccessType(null); + assertEquals(XmlAccessType.PROPERTY, childPersistentClass.getDefaultAccessType()); + contextPackageInfo.setSpecifiedAccessType(XmlAccessType.FIELD); + assertEquals(XmlAccessType.FIELD, childPersistentClass.getDefaultAccessType()); + + contextPackageInfo.setSpecifiedAccessType(XmlAccessType.NONE); + assertEquals(XmlAccessType.NONE, childPersistentClass.getDefaultAccessType()); + + contextPackageInfo.setSpecifiedAccessType(null); + assertEquals(XmlAccessType.PUBLIC_MEMBER, childPersistentClass.getDefaultAccessType()); + } + + public void testGetSuperPersistentClass() throws Exception { + this.createTypeWithXmlType(); + this.createTestSubType(); + JaxbPersistentClass persistentClass = getContextRoot().getPersistentClass(FULLY_QUALIFIED_TYPE_NAME); + JaxbPersistentClass childPersistentClass = getContextRoot().getPersistentClass(PACKAGE_NAME + ".AnnotationTestTypeChild"); + + assertEquals(persistentClass, childPersistentClass.getSuperPersistentClass()); + + //This test will change when we no longer depend on there being an @XmlType annotation for something to be persistent + AnnotatedElement annotatedElement = this.annotatedElement(persistentClass.getJavaResourceType()); + annotatedElement.edit(new Member.Editor() { + public void edit(ModifiedDeclaration declaration) { + GenericJavaPersistentClassTests.this.removeAnnotation(declaration, XmlTypeAnnotation.ANNOTATION_NAME); + } + }); + assertNull(childPersistentClass.getSuperPersistentClass()); + } + public void testModifyAccessOrder() throws Exception { createXmlTypeWithAccessorOrder(); JaxbPersistentClass persistentClass = CollectionTools.get(getContextRoot().getPersistentClasses(), 0); JavaResourceType resourceType = persistentClass.getJavaResourceType(); - + assertEquals(XmlAccessOrder.ALPHABETICAL, persistentClass.getSpecifiedAccessOrder()); assertEquals(XmlAccessOrder.ALPHABETICAL, persistentClass.getAccessOrder()); assertEquals(XmlAccessOrder.UNDEFINED, persistentClass.getDefaultAccessOrder()); - + persistentClass.setSpecifiedAccessOrder(XmlAccessOrder.UNDEFINED); XmlAccessorOrderAnnotation accessorOrderAnnotation = (XmlAccessorOrderAnnotation) resourceType.getAnnotation(XmlAccessorOrderAnnotation.ANNOTATION_NAME); assertEquals(org.eclipse.jpt.jaxb.core.resource.java.XmlAccessOrder.UNDEFINED, accessorOrderAnnotation.getValue()); assertEquals(XmlAccessOrder.UNDEFINED, persistentClass.getAccessOrder()); - + persistentClass.setSpecifiedAccessOrder(null); accessorOrderAnnotation = (XmlAccessorOrderAnnotation) resourceType.getAnnotation(XmlAccessorOrderAnnotation.ANNOTATION_NAME); assertNull(accessorOrderAnnotation); @@ -409,16 +483,16 @@ public class GenericJavaPersistentClassTests extends JaxbContextModelTestCase assertEquals(XmlAccessOrder.UNDEFINED, persistentClass.getAccessOrder()); assertEquals(XmlAccessOrder.UNDEFINED, persistentClass.getDefaultAccessOrder()); } - + public void testUpdateAccessOrder() throws Exception { createXmlTypeWithAccessorOrder(); JaxbPersistentClass persistentClass = CollectionTools.get(getContextRoot().getPersistentClasses(), 0); JavaResourceType resourceType = persistentClass.getJavaResourceType(); - + assertEquals(XmlAccessOrder.ALPHABETICAL, persistentClass.getSpecifiedAccessOrder()); assertEquals(XmlAccessOrder.ALPHABETICAL, persistentClass.getAccessOrder()); assertEquals(XmlAccessOrder.UNDEFINED, persistentClass.getDefaultAccessOrder()); - + //set the access order value to UNDEFINED AnnotatedElement annotatedElement = this.annotatedElement(resourceType); annotatedElement.edit(new Member.Editor() { @@ -460,7 +534,7 @@ public class GenericJavaPersistentClassTests extends JaxbContextModelTestCase assertEquals("foo", props.next()); assertFalse(props.hasNext()); } - + protected void addProp(ModifiedDeclaration declaration, int index, String prop) { this.addArrayElement(declaration, JAXB.XML_TYPE, index, JAXB.XML_TYPE__PROP_ORDER, this.newStringLiteral(declaration.getAst(), prop)); } |