diff options
author | kmoore | 2011-02-28 15:41:11 +0000 |
---|---|---|
committer | kmoore | 2011-02-28 15:41:11 +0000 |
commit | 4a54fea6aeeeb86ef51e38c178b65040371b0b0f (patch) | |
tree | 43bcb6385a19ab0278b792ad768fb0d8068dd7ef /jaxb/plugins | |
parent | 9a033f6a25a9c522411b5589cc25259e96f5e3a5 (diff) | |
download | webtools.dali-4a54fea6aeeeb86ef51e38c178b65040371b0b0f.tar.gz webtools.dali-4a54fea6aeeeb86ef51e38c178b65040371b0b0f.tar.xz webtools.dali-4a54fea6aeeeb86ef51e38c178b65040371b0b0f.zip |
336388 - context model support for XmlTransient and inherited attributes
Diffstat (limited to 'jaxb/plugins')
19 files changed, 1263 insertions, 648 deletions
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/JaxbFactory.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/JaxbFactory.java index 774cbfeb48..1a91dc7acb 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/JaxbFactory.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/JaxbFactory.java @@ -25,7 +25,7 @@ import org.eclipse.jpt.jaxb.core.context.JaxbPersistentField; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentProperty; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentType; import org.eclipse.jpt.jaxb.core.context.JaxbRegistry; -import org.eclipse.jpt.jaxb.core.context.JaxbTransientType; +import org.eclipse.jpt.jaxb.core.context.JaxbTransientClass; import org.eclipse.jpt.jaxb.core.context.XmlAnyAttributeMapping; import org.eclipse.jpt.jaxb.core.context.XmlAnyElementMapping; import org.eclipse.jpt.jaxb.core.context.XmlAttributeMapping; @@ -110,7 +110,7 @@ public interface JaxbFactory { JaxbRegistry buildRegistry(JaxbContextRoot parent, JavaResourceType resourceType); - JaxbTransientType buildJavaTransientType(JaxbContextRoot parent, JavaResourceType resourceType); + JaxbTransientClass buildJavaTransientClass(JaxbContextRoot parent, JavaResourceType resourceType); JaxbPersistentClass buildJavaPersistentClass(JaxbContextRoot parent, JavaResourceType resourceType); diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbAttributesContainer.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbAttributesContainer.java new file mode 100644 index 0000000000..aa3bf40d80 --- /dev/null +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbAttributesContainer.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Oracle - initial API and implementation + *******************************************************************************/ +package org.eclipse.jpt.jaxb.core.context; + +import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode; +import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; + +/** + * Holds the attributes represented by a particular JavaResourceType and XmlAccessType. + * <p> + * Provisional API: This interface is part of an interim API that is still + * under development and expected to change significantly before reaching + * stability. It is available at this early stage to solicit feedback from + * pioneering adopters on the understanding that any code that uses this API + * will almost certainly be broken (repeatedly) as the API evolves. + * + * @version 3.0 + * @since 3.0 + */ +public interface JaxbAttributesContainer + extends JavaContextNode { + + /** + * Return true if this JaxbAtributesContainer contains attributes for the given JavaResourceType. + */ + boolean isFor(JavaResourceType javaResourceType); + + + /********** attributes **********/ + + Iterable<JaxbPersistentAttribute> getAttributes(); + int getAttributesSize(); + + interface Owner { + + /** + * Return the access type of the owner, to be used in determining which attributes to build + */ + XmlAccessType getAccessType(); + + /** + * fire property change event for the added attribute + */ + void fireAttributeAdded(JaxbPersistentAttribute attribute); + + /** + * fire property change event for the removed attribute + */ + void fireAttributeRemoved(JaxbPersistentAttribute attribute); + } +} diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbClass.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbClass.java new file mode 100644 index 0000000000..a1269911c8 --- /dev/null +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbClass.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2011 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Oracle - initial API and implementation + *******************************************************************************/ +package org.eclipse.jpt.jaxb.core.context; + +import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; + +/** + * Represents a JAXB class. + * <p> + * Provisional API: This interface is part of an interim API that is still + * under development and expected to change significantly before reaching + * stability. It is available at this early stage to solicit feedback from + * pioneering adopters on the understanding that any code that uses this API + * will almost certainly be broken (repeatedly) as the API evolves. + * + * @version 3.0 + * @since 3.0 + */ +public interface JaxbClass + extends JaxbType, XmlAccessTypeHolder, XmlAccessOrderHolder { + + /** + * covariant override + */ + JavaResourceType getJavaResourceType(); + + JaxbClass getSuperClass(); + String SUPER_CLASS_PROPERTY = "superClass"; //$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. This includes classes annotated with @XmlTransient. + */ + Iterable<JaxbClass> 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. This includes classes annotated with @XmlTransient. + */ + Iterable<JaxbClass> getAncestors(); + +} 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 c18c160de4..65cdf850ce 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 @@ -101,21 +101,26 @@ public interface JaxbContextRoot Iterable<JaxbRegistry> getRegistries(JaxbPackage jaxbPackage); /** - * The set of transient types. + * The set of transient classes. */ - Iterable<JaxbTransientType> getTransientTypes(); + Iterable<JaxbTransientClass> getTransientClasses(); /** - * Return the set of transient types that are in the given package + * Return the set of transient classes that are in the given package */ - Iterable<JaxbTransientType> getTransientTypes(JaxbPackage jaxbPackage); + Iterable<JaxbTransientClass> getTransientClasses(JaxbPackage jaxbPackage); /** - * Return the transient type with the given fully qualified name + * Return the transient class with the given fully qualified name */ - JaxbTransientType getTransientType(String fullyQualifiedTypeName); + JaxbTransientClass getTransientClass(String fullyQualifiedTypeName); + /** + * Return the persistent class or transient type with the given fully qualified name + */ + JaxbClass getClass(String fullyQualifiedTypeName); + // **************** validation ******************************************** /** diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentAttribute.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentAttribute.java index 1ee2dc497e..9ff13cdf8f 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentAttribute.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentAttribute.java @@ -32,6 +32,20 @@ public interface JaxbPersistentAttribute JaxbPersistentClass getParent(); + /** + * Return true if this JaxbPersistentAttribute is inherited from one of the + * superclasses of the parent JaxbPersistentClass. + */ + boolean isInherited(); + + /** + * Only ask this of inherited persistent attributes. Returns the simple + * type name of the attribute's resource type. + * + * @see JaxbPersistentAttribute#isInherited() + */ + String getInheritedJavaResourceAttributeOwningTypeName(); + // ********** name ********** /** 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 92c790f79e..b88288edc1 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 @@ -9,8 +9,6 @@ *******************************************************************************/ package org.eclipse.jpt.jaxb.core.context; -import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; - /** * Represents a JAXB persistent class. * (A class with either an explicit or implicit @XmlType annotation) @@ -25,37 +23,39 @@ import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; * @since 3.0 */ public interface JaxbPersistentClass - extends JaxbPersistentType, XmlAccessTypeHolder, XmlAccessOrderHolder, XmlAdaptable { + extends JaxbPersistentType, JaxbClass, XmlAdaptable { - /** - * covariant override - */ - JavaResourceType getJavaResourceType(); - JaxbPersistentClass getSuperPersistentClass(); - String SUPER_PERSISTENT_CLASS_PROPERTY = "superPersistentClass"; //$NON-NLS-1$ + /********** attributes **********/ + + Iterable<JaxbPersistentAttribute> getAttributes(); + int getAttributesSize(); + String ATTRIBUTES_COLLECTION = "attributes"; //$NON-NLS-1$ + + + /********** inherited attributes **********/ /** - * 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. + * Inherited attributes come from any superclasses that are mapped as @XmlTransient. + * @see JaxbClass#getSuperClass() + * @see JaxbClass#getInheritanceHierarchy() */ - Iterable<JaxbPersistentClass> getInheritanceHierarchy(); + Iterable<JaxbPersistentAttribute> getInheritedAttributes(); + int getInheritedAttributesSize(); + String INHERITED_ATTRIBUTES_COLLECTION = "inheritedAttributes"; //$NON-NLS-1$ + /** - * 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. + * Return true if the given attribute is one of the inherited attributes. */ - Iterable<JaxbPersistentClass> getAncestors(); - + boolean isInherited(JaxbPersistentAttribute attribute); - /********** attributes **********/ - - Iterable<JaxbPersistentAttribute> getAttributes(); - int getAttributesSize(); - String ATTRIBUTES_COLLECTION = "attributes"; //$NON-NLS-1$ + /** + * Only ask this of inherited persistent attributes. Returns the simple + * type name of the attribute's resource type. + * + * @see JaxbPersistentAttribute#isInherited() + */ + String getJavaResourceAttributeOwningTypeName(JaxbPersistentAttribute attribute); } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbTransientType.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbTransientClass.java index c18a008dea..4714a3e436 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbTransientType.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbTransientClass.java @@ -22,6 +22,6 @@ package org.eclipse.jpt.jaxb.core.context; * @version 3.0 * @since 3.0 */ -public interface JaxbTransientType extends JaxbType { +public interface JaxbTransientClass extends JaxbClass { } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbType.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbType.java index f78ca625ac..b3f65b1f08 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbType.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbType.java @@ -97,7 +97,7 @@ public interface JaxbType REGISTRY, /** - * A JaxbType of {@link Kind} REGISTRY may safely be cast as a {@link JaxbTransientType} + * A JaxbType of {@link Kind} TRANSIENT may safely be cast as a {@link JaxbTransientClass} */ TRANSIENT } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/AbstractJaxbFactory.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/AbstractJaxbFactory.java index f65eb91a8c..d1266ee1bd 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/AbstractJaxbFactory.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/AbstractJaxbFactory.java @@ -29,7 +29,7 @@ import org.eclipse.jpt.jaxb.core.context.JaxbPersistentField; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentProperty; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentType; import org.eclipse.jpt.jaxb.core.context.JaxbRegistry; -import org.eclipse.jpt.jaxb.core.context.JaxbTransientType; +import org.eclipse.jpt.jaxb.core.context.JaxbTransientClass; import org.eclipse.jpt.jaxb.core.context.XmlAnyAttributeMapping; import org.eclipse.jpt.jaxb.core.context.XmlAnyElementMapping; import org.eclipse.jpt.jaxb.core.context.XmlAttributeMapping; @@ -49,7 +49,7 @@ import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaPersistentEnum import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaPersistentField; import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaPersistentProperty; import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaRegistry; -import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaTransientType; +import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaTransientClass; import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaXmlAnyAttributeMapping; import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaXmlAnyElementMapping; import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaXmlAttributeMapping; @@ -112,8 +112,8 @@ public abstract class AbstractJaxbFactory return new GenericJavaRegistry(parent, resourceType); } - public JaxbTransientType buildJavaTransientType(JaxbContextRoot parent, JavaResourceType resourceType) { - return new GenericJavaTransientType(parent, resourceType); + public JaxbTransientClass buildJavaTransientClass(JaxbContextRoot parent, JavaResourceType resourceType) { + return new GenericJavaTransientClass(parent, resourceType); } public JaxbPersistentClass buildJavaPersistentClass(JaxbContextRoot parent, JavaResourceType resourceType) { 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 d07be81ab9..91a92212e9 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 @@ -23,12 +23,13 @@ import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable; import org.eclipse.jpt.common.utility.internal.iterables.SubIterableWrapper; import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable; import org.eclipse.jpt.jaxb.core.JaxbProject; +import org.eclipse.jpt.jaxb.core.context.JaxbClass; import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot; import org.eclipse.jpt.jaxb.core.context.JaxbPackage; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentClass; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentEnum; import org.eclipse.jpt.jaxb.core.context.JaxbRegistry; -import org.eclipse.jpt.jaxb.core.context.JaxbTransientType; +import org.eclipse.jpt.jaxb.core.context.JaxbTransientClass; import org.eclipse.jpt.jaxb.core.context.JaxbType; import org.eclipse.jpt.jaxb.core.context.JaxbType.Kind; import org.eclipse.jpt.jaxb.core.resource.java.AbstractJavaResourceType; @@ -108,7 +109,7 @@ public class GenericContextRoot } for (JavaResourceType resourceType : initialTransientClasses) { - this.types.put(resourceType.getName(), buildTransientType(resourceType)); + this.types.put(resourceType.getName(), buildTransientClass(resourceType)); } for (JavaResourceType resourceType : initialPersistentClasses) { @@ -194,11 +195,11 @@ public class GenericContextRoot } else { this.removeType(className); // this will remove a type of another kind - this.addType(buildTransientType(resourceType)); + this.addType(buildTransientClass(resourceType)); } } else { - this.addType(buildTransientType(resourceType)); + this.addType(buildTransientClass(resourceType)); } } @@ -482,8 +483,8 @@ public class GenericContextRoot // ********** transient types ********** - public Iterable<JaxbTransientType> getTransientTypes() { - return new SubIterableWrapper<JaxbType, JaxbTransientType>( + public Iterable<JaxbTransientClass> getTransientClasses() { + return new SubIterableWrapper<JaxbType, JaxbTransientClass>( new FilteringIterable<JaxbType>(getTypes()) { @Override protected boolean accept(JaxbType o) { @@ -492,21 +493,21 @@ public class GenericContextRoot }); } - protected JaxbTransientType buildTransientType(JavaResourceType resourceType) { - return this.getFactory().buildJavaTransientType(this, resourceType); + protected JaxbTransientClass buildTransientClass(JavaResourceType resourceType) { + return this.getFactory().buildJavaTransientClass(this, resourceType); } - public Iterable<JaxbTransientType> getTransientTypes(final JaxbPackage jaxbPackage) { - return new FilteringIterable<JaxbTransientType>(getTransientTypes()) { + public Iterable<JaxbTransientClass> getTransientClasses(final JaxbPackage jaxbPackage) { + return new FilteringIterable<JaxbTransientClass>(getTransientClasses()) { @Override - protected boolean accept(JaxbTransientType o) { + protected boolean accept(JaxbTransientClass o) { return o.getPackageName().equals(jaxbPackage.getName()); } }; } - public JaxbTransientType getTransientType(String className) { - for (JaxbTransientType jaxbClass : this.getTransientTypes()) { + public JaxbTransientClass getTransientClass(String className) { + for (JaxbTransientClass jaxbClass : this.getTransientClasses()) { if (StringTools.stringsAreEqual(jaxbClass.getFullyQualifiedName(), className)) { return jaxbClass; } @@ -547,7 +548,12 @@ public class GenericContextRoot } return null; } - + + public JaxbClass getClass(String fullyQualifiedTypeName) { + JaxbPersistentClass jaxbClass= this.getPersistentClass(fullyQualifiedTypeName); + return jaxbClass != null ? jaxbClass : this.getTransientClass(fullyQualifiedTypeName); + } + // ********** persistent enums ********** public Iterable<JaxbPersistentEnum> getPersistentEnums() { diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaAttributesContainer.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaAttributesContainer.java new file mode 100644 index 0000000000..5ee0fbf7fc --- /dev/null +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaAttributesContainer.java @@ -0,0 +1,652 @@ +/******************************************************************************* + * Copyright (c) 2011 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.jaxb.core.internal.context.java; + +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.StringTools; +import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable; +import org.eclipse.jpt.common.utility.internal.iterables.ListIterable; +import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable; +import org.eclipse.jpt.jaxb.core.context.JaxbAttributesContainer; +import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute; +import org.eclipse.jpt.jaxb.core.context.JaxbPersistentClass; +import org.eclipse.jpt.jaxb.core.context.JaxbPersistentField; +import org.eclipse.jpt.jaxb.core.context.JaxbPersistentProperty; +import org.eclipse.jpt.jaxb.core.context.XmlAccessType; +import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceField; +import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceMember; +import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceMethod; +import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +public class GenericJavaAttributesContainer + extends AbstractJavaContextNode + implements JaxbAttributesContainer { + + protected JavaResourceType javaResourceType; + + protected JaxbAttributesContainer.Owner owner; + + protected final Vector<JaxbPersistentAttribute> attributes = new Vector<JaxbPersistentAttribute>(); + + public GenericJavaAttributesContainer(JaxbPersistentClass parent, JaxbAttributesContainer.Owner owner, JavaResourceType resourceType) { + super(parent); + this.javaResourceType = resourceType; + this.owner = owner; + this.initializeAttributes(); + } + + @Override + public JaxbPersistentClass getParent() { + return (JaxbPersistentClass) super.getParent(); + } + + public boolean isFor(JavaResourceType javaResourceType) { + return this.javaResourceType == javaResourceType; + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.synchronizeNodesWithResourceModel(this.getAttributes()); + } + + @Override + public void update() { + super.update(); + this.updateAttributes(); + } + + // ********** access type ********** + + protected XmlAccessType getAccessType() { + return this.owner.getAccessType(); + } + + + // ********** attributes ********** + + public Iterable<JaxbPersistentAttribute> getAttributes() { + return new LiveCloneIterable<JaxbPersistentAttribute>(this.attributes); + } + + public int getAttributesSize() { + return this.attributes.size(); + } + + protected void addAttribute(JaxbPersistentAttribute attribute) { + if (this.attributes.add(attribute)) { + this.owner.fireAttributeAdded(attribute); + } + } + + protected void removeAttribute(JaxbPersistentAttribute attribute) { + if (this.attributes.remove(attribute)) { + this.owner.fireAttributeRemoved(attribute); + } + } + + protected JaxbPersistentField buildField(JavaResourceField resourceField) { + return getFactory().buildJavaPersistentField(getParent(), resourceField); + } + + protected JaxbPersistentProperty buildProperty(JavaResourceMethod resourceGetter, JavaResourceMethod resourceSetter) { + return getFactory().buildJavaPersistentProperty(getParent(), resourceGetter, resourceSetter); + } + + protected void initializeAttributes() { + if (getAccessType() == XmlAccessType.PUBLIC_MEMBER) { + this.initializePublicMemberAccessAttributes(); + } + else if (getAccessType() == XmlAccessType.FIELD) { + this.intializeFieldAccessAttributes(); + } + else if (getAccessType() == XmlAccessType.PROPERTY) { + this.intializePropertyAccessAttributes(); + } + else if (getAccessType() == XmlAccessType.NONE) { + this.intializeNoneAccessAttributes(); + } + } + + /** + * Initialize the attributes for XmlAccessType.PUBLIC_MEMBER + * 1. all public, non-static, non-transient fields (transient modifier, @XmlTransient is brought to the context model) + * 2. all annotated fields that aren't public + * 3. all public getter/setter javabeans pairs + * 4. all annotated methods (some will have a matching getter/setter, some will be standalone) + */ + private void initializePublicMemberAccessAttributes() { + this.initializeFieldAttributes(PUBLIC_MEMBER_ACCESS_TYPE_RESOURCE_FIELDS_FILTER); + Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); + //iterate through all persistable resource method getters + for (JavaResourceMethod getterMethod : this.getResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { + JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); + if (methodsArePersistablePublicMemberAccess(getterMethod, setterMethod)) { + this.attributes.add(this.buildProperty(getterMethod, setterMethod)); + } + resourceMethods.remove(getterMethod); + resourceMethods.remove(setterMethod); + } + this.initializeRemainingResourceMethodAttributes(resourceMethods); + } + + /** + * Initialize the attributes for XmlAccessType.FIELD + * 1. all non-transient fields + * 2. all annotated methods getters/setters + */ + private void intializeFieldAccessAttributes() { + this.initializeFieldAttributes(this.buildNonTransientNonStaticResourceFieldsFilter()); + this.initializeAnnotatedPropertyAttributes(); + } + + /** + * Initialize the attributes for XmlAccessType.PROPERTY + * 1. all getter/setter javabeans pairs + * 2. all annotated fields + * 3. all annotated methods getters/setters that don't have a matching pair + */ + private void intializePropertyAccessAttributes() { + this.initializeFieldAttributes(ANNOTATED_RESOURCE_FIELDS_FILTER); + + Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); + //iterate through all resource methods searching for persistable getters + for (JavaResourceMethod getterMethod : this.getResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { + JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); + if (methodsArePersistableProperties(getterMethod, setterMethod)) { + this.attributes.add(this.buildProperty(getterMethod, setterMethod)); + } + resourceMethods.remove(getterMethod); + resourceMethods.remove(setterMethod); + } + this.initializeRemainingResourceMethodAttributes(resourceMethods); + } + + /** + * Initialize the attributes for XmlAccessType.NONE + * 1. all annotated fields + * 2. all annotated methods getters/setters (some will have a matching getter/setter, some will be standalone) + */ + private void intializeNoneAccessAttributes() { + this.initializeFieldAttributes(ANNOTATED_RESOURCE_FIELDS_FILTER); + this.initializeAnnotatedPropertyAttributes(); + } + + private void initializeFieldAttributes(Filter<JavaResourceField> filter) { + for (JavaResourceField resourceField : this.getResourceFields(filter)) { + this.attributes.add(this.buildField(resourceField)); + } + } + + private void initializeRemainingResourceMethodAttributes(Collection<JavaResourceMethod> resourceMethods) { + //iterate through remaining resource methods and search for those that are annotated. + //all getter methods will already be used. + for (JavaResourceMethod resourceMethod : resourceMethods) { + if (resourceMethod.isAnnotated()) { + //annotated setter(or other random method) with no corresponding getter, bring into context model for validation purposes + this.attributes.add(this.buildProperty(null, resourceMethod)); + } + } + } + + private static boolean methodsArePersistableProperties(JavaResourceMethod getterMethod, JavaResourceMethod setterMethod) { + if (setterMethod != null) { + return true; + } + //Lists do not have to have a corresponding setter method + else if (getterMethod.getTypeName().equals("java.util.List")) { //$NON-NLS-1$ + return true; + } + else if (getterMethod.isAnnotated()) { + //annotated getter with no corresponding setter, bring into context model for validation purposes + return true; + } + return false; + } + + private static boolean methodsArePersistablePublicMemberAccess(JavaResourceMethod getterMethod, JavaResourceMethod setterMethod) { + if (getterMethod.isPublic()) { + if (setterMethod != null) { + if (setterMethod.isPublic()) { + return true; + } + } + //Lists do not have to have a corresponding setter method + else if (getterMethod.getTypeName().equals("java.util.List")) { //$NON-NLS-1$ + return true; + } + else if (getterMethod.isAnnotated()) { + //annotated getter with no corresponding setter, bring into context model for validation purposes + return true; + } + } + else if (getterMethod.isAnnotated() || (setterMethod != null && setterMethod.isAnnotated())) { + return true; + } + return false; + } + + private void initializeAnnotatedPropertyAttributes() { + Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); + //iterate through all resource methods searching for persistable getters + for (JavaResourceMethod getterMethod : this.getResourceMethods(buildPersistablePropertyGetterMethodsFilter())) { + JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); + if (getterMethod.isAnnotated() || (setterMethod != null && setterMethod.isAnnotated())) { + this.attributes.add(this.buildProperty(getterMethod, setterMethod)); + } + resourceMethods.remove(getterMethod); + resourceMethods.remove(setterMethod); + } + this.initializeRemainingResourceMethodAttributes(resourceMethods); + } + + protected Iterable<JavaResourceField> getResourceFields() { + return this.javaResourceType.getFields(); + } + + protected Iterable<JavaResourceMethod> getResourceMethods() { + return this.javaResourceType.getMethods(); + } + + protected Iterable<JavaResourceField> getResourceFields(Filter<JavaResourceField> filter) { + return new FilteringIterable<JavaResourceField>(getResourceFields(), filter); + } + + protected Iterable<JavaResourceMethod> getResourceMethods(Filter<JavaResourceMethod> filter) { + return new FilteringIterable<JavaResourceMethod>(getResourceMethods(), filter); + } + + protected Filter<JavaResourceField> buildNonTransientNonStaticResourceFieldsFilter() { + return new Filter<JavaResourceField>() { + public boolean accept(JavaResourceField resourceField) { + return memberIsNonTransientNonStatic(resourceField) || resourceField.isAnnotated(); + } + }; + } + + protected static Filter<JavaResourceField> PUBLIC_MEMBER_ACCESS_TYPE_RESOURCE_FIELDS_FILTER = new Filter<JavaResourceField>() { + public boolean accept(JavaResourceField resourceField) { + return memberIsPublicNonTransientNonStatic(resourceField) || resourceField.isAnnotated(); + } + }; + + protected Filter<JavaResourceMethod> buildPersistablePropertyGetterMethodsFilter() { + return new Filter<JavaResourceMethod>() { + public boolean accept(JavaResourceMethod resourceMethod) { + return methodIsPersistablePropertyGetter(resourceMethod, getResourceMethods()); + } + }; + } + + protected static boolean memberIsPublicNonTransientNonStatic(JavaResourceMember resourceMember) { + return resourceMember.isPublic() && memberIsNonTransientNonStatic(resourceMember); + } + + protected static boolean memberIsNonTransientNonStatic(JavaResourceMember resourceMember) { + return !resourceMember.isTransient() && !resourceMember.isStatic(); + } + + protected static Filter<JavaResourceField> ANNOTATED_RESOURCE_FIELDS_FILTER = + new Filter<JavaResourceField>() { + public boolean accept(JavaResourceField resourceField) { + return resourceField.isAnnotated(); + } + }; + + /** + * The attributes are synchronized during the <em>update</em> because + * the list of resource attributes is determined by the access type + * which can be controlled in a number of different places.... + */ + protected void updateAttributes() { + if (getAccessType() == XmlAccessType.PUBLIC_MEMBER) { + this.syncPublicMemberAccessAttributes(); + } + else if (getAccessType() == XmlAccessType.FIELD) { + this.syncFieldAccessAttributes(); + } + else if (getAccessType() == XmlAccessType.PROPERTY) { + this.syncPropertyAccessAttributes(); + } + else if (getAccessType() == XmlAccessType.NONE) { + this.syncNoneAccessAttributes(); + } + } + + /** + * Sync the attributes for XmlAccessType.PUBLIC_MEMBER + * 1. all public, non-static, non-transient fields (transient modifier, @XmlTransient is brought to the context model) + * 2. all annotated fields that aren't public + * 3. all public getter/setter javabeans pairs + * 4. all annotated methods (some will have a matching getter/setter, some will be standalone) + */ + private void syncPublicMemberAccessAttributes() { + HashSet<JaxbPersistentAttribute> contextAttributes = CollectionTools.set(this.getAttributes()); + + this.syncFieldAttributes(contextAttributes, PUBLIC_MEMBER_ACCESS_TYPE_RESOURCE_FIELDS_FILTER); + + Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); + //iterate through all persistable resource method getters + for (JavaResourceMethod getterMethod : this.getResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { + JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); + if (methodsArePersistablePublicMemberAccess(getterMethod, setterMethod)) { + boolean match = false; + for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { + JaxbPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(getterMethod, setterMethod)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + this.addAttribute(this.buildProperty(getterMethod, setterMethod)); + } + resourceMethods.remove(getterMethod); + resourceMethods.remove(setterMethod); + } + } + this.syncRemainingResourceMethods(contextAttributes, resourceMethods); + } + + /** + * Initialize the attributes for XmlAccessType.FIELD + * 1. all non-transient fields + * 2. all annotated methods getters/setters + */ + private void syncFieldAccessAttributes() { + HashSet<JaxbPersistentAttribute> contextAttributes = CollectionTools.set(this.getAttributes()); + + this.syncFieldAttributes(contextAttributes, this.buildNonTransientNonStaticResourceFieldsFilter()); + this.syncAnnotatedPropertyAttributes(contextAttributes); + } + + /** + * Initialize the attributes for XmlAccessType.PROPERTY + * 1. all getter/setter javabeans pairs + * 2. all annotated fields + * 3. all annotated methods getters/setters that don't have a matching pair + */ + private void syncPropertyAccessAttributes() { + HashSet<JaxbPersistentAttribute> contextAttributes = CollectionTools.set(this.getAttributes()); + + this.syncFieldAttributes(contextAttributes, ANNOTATED_RESOURCE_FIELDS_FILTER); + + Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); + //iterate through all resource methods searching for persistable getters + for (JavaResourceMethod getterMethod : this.getResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { + JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); + if (methodsArePersistableProperties(getterMethod, setterMethod)) { + boolean match = false; + for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { + JaxbPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(getterMethod, setterMethod)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + this.addAttribute(this.buildProperty(getterMethod, setterMethod)); + } + } + resourceMethods.remove(getterMethod); + resourceMethods.remove(setterMethod); + } + this.syncRemainingResourceMethods(contextAttributes, resourceMethods); + } + + /** + * Initialize the attributes for XmlAccessType.NONE + * 1. all annotated fields + * 2. all annotated methods getters/setters (some will have a matching getter/setter, some will be standalone) + */ + private void syncNoneAccessAttributes() { + HashSet<JaxbPersistentAttribute> contextAttributes = CollectionTools.set(this.getAttributes()); + + this.syncFieldAttributes(contextAttributes, ANNOTATED_RESOURCE_FIELDS_FILTER); + this.syncAnnotatedPropertyAttributes(contextAttributes); + } + + private void syncAnnotatedPropertyAttributes(HashSet<JaxbPersistentAttribute> contextAttributes) { + Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); + //iterate through all resource methods searching for persistable getters + for (JavaResourceMethod getterMethod : this.getResourceMethods(buildPersistablePropertyGetterMethodsFilter())) { + JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); + if (getterMethod.isAnnotated() || (setterMethod != null && setterMethod.isAnnotated())) { + boolean match = false; + for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { + JaxbPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(getterMethod, setterMethod)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + this.addAttribute(this.buildProperty(getterMethod, setterMethod)); + } + } + resourceMethods.remove(getterMethod); + resourceMethods.remove(setterMethod); + } + this.syncRemainingResourceMethods(contextAttributes, resourceMethods); + } + + private void syncFieldAttributes(HashSet<JaxbPersistentAttribute> contextAttributes, Filter<JavaResourceField> filter) { + for (JavaResourceField resourceField : this.getResourceFields(filter)) { + boolean match = false; + for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext(); ) { + JaxbPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(resourceField)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + // added elements are sync'ed during construction or will be + // updated during the next "update" (which is triggered by + // their addition to the model) + this.addAttribute(this.buildField(resourceField)); + } + } + } + + private void syncRemainingResourceMethods(HashSet<JaxbPersistentAttribute> contextAttributes, Collection<JavaResourceMethod> resourceMethods) { + //iterate through remaining resource methods and search for those that are annotated. + //all getter methods will already be used. + for (JavaResourceMethod resourceMethod : resourceMethods) { + if (resourceMethod.isAnnotated()) { + boolean match = false; + //annotated setter(or other random method) with no corresponding getter, bring into context model for validation purposes + for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { + JaxbPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(null, resourceMethod)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + this.addAttribute(this.buildProperty(null, resourceMethod)); + } + } + } + + // remove any leftover context attributes + for (JaxbPersistentAttribute contextAttribute : contextAttributes) { + this.removeAttribute(contextAttribute); + } + } + + /** + * Return whether the specified method is a "getter" method that + * represents a property that may be "persisted". + */ + protected static boolean methodIsPersistablePropertyGetter(JavaResourceMethod resourceMethod, Iterable<JavaResourceMethod> allMethods) { + if (methodHasInvalidModifiers(resourceMethod)) { + return false; + } + if (resourceMethod.isConstructor()) { + return false; + } + + String returnTypeName = resourceMethod.getTypeName(); + if (returnTypeName == null) { + return false; // DOM method bindings can have a null name + } + if (returnTypeName.equals("void")) { //$NON-NLS-1$ + return false; + } + if (methodHasParameters(resourceMethod)) { + return false; + } + + boolean booleanGetter = methodIsBooleanGetter(resourceMethod); + + // if the type has both methods: + // boolean isProperty() + // boolean getProperty() + // then #isProperty() takes precedence and we ignore #getProperty(); + // but only having #getProperty() is OK too + // (see the JavaBeans spec 1.01) + if (booleanGetter && methodHasValidSiblingIsMethod(resourceMethod, allMethods)) { + return false; // since the type also defines #isProperty(), ignore #getProperty() + } + return true; + } + + private static boolean methodIsBooleanGetter(JavaResourceMethod resourceMethod) { + String returnTypeName = resourceMethod.getTypeName(); + String name = resourceMethod.getMethodName(); + boolean booleanGetter = false; + if (name.startsWith("is")) { //$NON-NLS-1$ + if (returnTypeName.equals("boolean")) { //$NON-NLS-1$ + } else { + return false; + } + } else if (name.startsWith("get")) { //$NON-NLS-1$ + if (returnTypeName.equals("boolean")) { //$NON-NLS-1$ + booleanGetter = true; + } + } else { + return false; + } + return booleanGetter; + } + + /** + * Return whether the method's modifiers prevent it + * from being a getter or setter for a "persistent" property. + */ + private static boolean methodHasInvalidModifiers(JavaResourceMethod resourceMethod) { + int modifiers = resourceMethod.getModifiers(); + if (Modifier.isStatic(modifiers)) { + return true; + } + return false; + } + + private static boolean methodHasParameters(JavaResourceMethod resourceMethod) { + return resourceMethod.getParametersSize() != 0; + } + + /** + * Return whether the method has a sibling "is" method for the specified + * property and that method is valid for a "persistable" property. + * Pre-condition: the method is a "boolean getter" (e.g. 'public boolean getProperty()'); + * this prevents us from returning true when the method itself is an + * "is" method. + */ + private static boolean methodHasValidSiblingIsMethod(JavaResourceMethod getMethod, Iterable<JavaResourceMethod> resourceMethods) { + String capitalizedAttributeName = StringTools.capitalize(getMethod.getName()); + for (JavaResourceMethod sibling : resourceMethods) { + if ((sibling.getParametersSize() == 0) + && sibling.getMethodName().equals("is" + capitalizedAttributeName)) { //$NON-NLS-1$ + return methodIsValidSibling(sibling, "boolean"); //$NON-NLS-1$ + } + } + return false; + } + + /** + * Return whether the method has a sibling "set" method + * and that method is valid for a "persistable" property. + */ + private static JavaResourceMethod getValidSiblingSetMethod(JavaResourceMethod getMethod, Collection<JavaResourceMethod> resourceMethods) { + String capitalizedAttributeName = StringTools.capitalize(getMethod.getName()); + String parameterTypeErasureName = getMethod.getTypeName(); + for (JavaResourceMethod sibling : resourceMethods) { + ListIterable<String> siblingParmTypeNames = sibling.getParameterTypeNames(); + if ((sibling.getParametersSize() == 1) + && sibling.getMethodName().equals("set" + capitalizedAttributeName) //$NON-NLS-1$ + && siblingParmTypeNames.iterator().next().equals(parameterTypeErasureName)) { + return methodIsValidSibling(sibling, "void") ? sibling : null; //$NON-NLS-1$ + } + } + return null; + } + + /** + * Return whether the specified method is a valid sibling with the + * specified return type. + */ + private static boolean methodIsValidSibling(JavaResourceMethod resourceMethod, String returnTypeName) { + if (resourceMethod == null) { + return false; + } + if (methodHasInvalidModifiers(resourceMethod)) { + return false; + } + if (resourceMethod.isConstructor()) { + return false; + } + String rtName = resourceMethod.getTypeName(); + if (rtName == null) { + return false; // DOM method bindings can have a null name + } + return rtName.equals(returnTypeName); + } + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + for (JaxbPersistentAttribute attribute : getAttributes()) { + attribute.validate(messages, reporter, astRoot); + } + } + + @Override + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return getParent().getValidationTextRange(astRoot); + } +} diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentAttribute.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentAttribute.java index 5dfbc455c5..61ee0c7334 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentAttribute.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentAttribute.java @@ -43,6 +43,14 @@ public abstract class GenericJavaPersistentAttribute return (JaxbPersistentClass) super.getParent(); } + public boolean isInherited() { + return getParent().isInherited(this); + } + + public String getInheritedJavaResourceAttributeOwningTypeName() { + return getParent().getJavaResourceAttributeOwningTypeName(this); + } + /** * subclasses must call this method in their constructor */ 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 d16e5aa51a..ad1a191363 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,28 +9,27 @@ ******************************************************************************/ package org.eclipse.jpt.jaxb.core.internal.context.java; -import java.lang.reflect.Modifier; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Vector; +import java.util.Map; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.common.utility.Filter; import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.StringTools; import org.eclipse.jpt.common.utility.internal.iterables.ChainIterable; +import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable; import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable; -import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable; -import org.eclipse.jpt.common.utility.internal.iterables.ListIterable; import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable; +import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable; import org.eclipse.jpt.jaxb.core.MappingKeys; +import org.eclipse.jpt.jaxb.core.context.JaxbAttributesContainer; +import org.eclipse.jpt.jaxb.core.context.JaxbClass; import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot; import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentClass; -import org.eclipse.jpt.jaxb.core.context.JaxbPersistentField; -import org.eclipse.jpt.jaxb.core.context.JaxbPersistentProperty; import org.eclipse.jpt.jaxb.core.context.XmlAccessOrder; import org.eclipse.jpt.jaxb.core.context.XmlAccessType; import org.eclipse.jpt.jaxb.core.context.XmlAdaptable; @@ -38,9 +37,6 @@ import org.eclipse.jpt.jaxb.core.context.XmlJavaTypeAdapter; import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages; import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages; import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceAnnotatedElement; -import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceField; -import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceMember; -import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceMethod; import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; import org.eclipse.jpt.jaxb.core.resource.java.XmlAccessorOrderAnnotation; import org.eclipse.jpt.jaxb.core.resource.java.XmlAccessorTypeAnnotation; @@ -48,11 +44,24 @@ import org.eclipse.jpt.jaxb.core.resource.java.XmlJavaTypeAdapterAnnotation; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; +/** + * To support inherited attributes in the Generic case I have made some assumptions + * based on the JAXB RIs interpretation of the spec. Any superclass that is + * marked as @XmlTransient will have a corresponding JaxbAttributesContainer for its JaxbClass. + * If that XmlTransient class has no access type specified, the access type will be determined + * by this JaxbPersistentClass's access type. If the XmlTransient class specified an access + * type it will only be used in the case where this class does not specify an access type. + * It will be this class's default access type. The spec states that you are not allowed + * to use other annotations along with XmlTransient, but it appears the reference implementation + * has made an exception for @XmlAccessorType and @XmlAccessorOrder. This is subject to change + * pending a discussion with Blaise and the developers of the RI + * + */ public class GenericJavaPersistentClass extends AbstractJavaPersistentType implements JaxbPersistentClass { - protected JaxbPersistentClass superPersistentClass; + protected JaxbClass superClass; protected XmlAccessType defaultAccessType; protected XmlAccessType specifiedAccessType; @@ -60,19 +69,22 @@ public class GenericJavaPersistentClass protected XmlAccessOrder defaultAccessOrder; protected XmlAccessOrder specifiedAccessOrder; - protected final Vector<JaxbPersistentAttribute> attributes = new Vector<JaxbPersistentAttribute>(); + protected final JaxbAttributesContainer attributesContainer; + + protected final Map<JaxbClass, JaxbAttributesContainer> inheritedAttributesContainers = new HashMap<JaxbClass, JaxbAttributesContainer>(); protected final XmlAdaptable xmlAdaptable; public GenericJavaPersistentClass(JaxbContextRoot parent, JavaResourceType resourceType) { super(parent, resourceType); - this.superPersistentClass = this.buildSuperPersistentClass(); + this.superClass = this.buildSuperClass(); this.specifiedAccessType = this.getResourceAccessType(); this.specifiedAccessOrder = this.getResourceAccessOrder(); this.defaultAccessType = this.buildDefaultAccessType(); this.defaultAccessOrder = this.buildDefaultAccessOrder(); this.xmlAdaptable = this.buildXmlAdaptable(); - this.initializeAttributes(); + this.attributesContainer = new GenericJavaAttributesContainer(this, buildAttributesContainerOwner(), resourceType); + this.initializeInheritedAttributes(); } @Override @@ -88,17 +100,20 @@ public class GenericJavaPersistentClass this.setSpecifiedAccessType_(this.getResourceAccessType()); this.setSpecifiedAccessOrder_(this.getResourceAccessOrder()); this.xmlAdaptable.synchronizeWithResourceModel(); - this.syncAttributes(); + this.attributesContainer.synchronizeWithResourceModel(); + this.syncInheritedAttributes(); } @Override public void update() { super.update(); - this.setSuperPersistentClass(this.buildSuperPersistentClass()); + super.update(); + this.setSuperClass(this.buildSuperClass()); this.setDefaultAccessType(this.buildDefaultAccessType()); this.setDefaultAccessOrder(this.buildDefaultAccessOrder()); this.xmlAdaptable.update(); - this.updateAttributes(); + this.attributesContainer.update(); + this.updateInheritedAttributes(); } @@ -109,22 +124,22 @@ public class GenericJavaPersistentClass } - // ********** super persistent class ********** + // ********** super class ********** - public JaxbPersistentClass getSuperPersistentClass() { - return this.superPersistentClass; + public JaxbClass getSuperClass() { + return this.superClass; } - protected void setSuperPersistentClass(JaxbPersistentClass superPersistentClass) { - JaxbPersistentClass old = this.superPersistentClass; - this.superPersistentClass = superPersistentClass; - this.firePropertyChanged(SUPER_PERSISTENT_CLASS_PROPERTY, old, superPersistentClass); + protected void setSuperClass(JaxbClass superClass) { + JaxbClass old = this.superClass; + this.superClass = superClass; + this.firePropertyChanged(SUPER_CLASS_PROPERTY, old, superClass); } - protected JaxbPersistentClass buildSuperPersistentClass() { + protected JaxbClass buildSuperClass() { HashSet<JavaResourceType> visited = new HashSet<JavaResourceType>(); visited.add(this.getJavaResourceType()); - JaxbPersistentClass spc = this.getSuperPersistentClass(this.getJavaResourceType().getSuperclassQualifiedName(), visited); + JaxbClass spc = this.getSuperClass(this.getJavaResourceType().getSuperclassQualifiedName(), visited); if (spc == null) { return null; } @@ -145,7 +160,7 @@ public class GenericJavaPersistentClass * Any cycles in the *context* type inheritance hierarchy are handled in * #buildSuperPersistentType(). */ - protected JaxbPersistentClass getSuperPersistentClass(String typeName, Collection<JavaResourceType> visited) { + protected JaxbClass getSuperClass(String typeName, Collection<JavaResourceType> visited) { if (typeName == null) { return null; } @@ -154,30 +169,31 @@ public class GenericJavaPersistentClass return null; } visited.add(resourceType); - JaxbPersistentClass spc = this.getPersistentClass(typeName); - return (spc != null && resourceType.isMapped()) ? spc : this.getSuperPersistentClass(resourceType.getSuperclassQualifiedName(), visited); // recurse + JaxbClass spc = this.getClass(typeName); + return (spc != null && resourceType.isMapped()) ? spc : this.getSuperClass(resourceType.getSuperclassQualifiedName(), visited); // recurse } - protected JaxbPersistentClass getPersistentClass(String fullyQualifiedTypeName) { - return this.getParent().getPersistentClass(fullyQualifiedTypeName); + protected JaxbClass getClass(String fullyQualifiedTypeName) { + return this.getParent().getClass(fullyQualifiedTypeName); } + // ********** inheritance ********** - public Iterable<JaxbPersistentClass> getInheritanceHierarchy() { + public Iterable<JaxbClass> getInheritanceHierarchy() { return this.getInheritanceHierarchyOf(this); } - public Iterable<JaxbPersistentClass> getAncestors() { - return this.getInheritanceHierarchyOf(this.superPersistentClass); + public Iterable<JaxbClass> getAncestors() { + return this.getInheritanceHierarchyOf(this.superClass); } - protected Iterable<JaxbPersistentClass> getInheritanceHierarchyOf(JaxbPersistentClass start) { + protected Iterable<JaxbClass> getInheritanceHierarchyOf(JaxbClass start) { // using a chain iterator to traverse up the inheritance tree - return new ChainIterable<JaxbPersistentClass>(start) { + return new ChainIterable<JaxbClass>(start) { @Override - protected JaxbPersistentClass nextLink(JaxbPersistentClass persistentType) { - return persistentType.getSuperPersistentClass(); + protected JaxbClass nextLink(JaxbClass jaxbClass) { + return jaxbClass.getSuperClass(); } }; } @@ -227,7 +243,7 @@ public class GenericJavaPersistentClass * Otherwise, the @XmlAccessorType on a package is inherited. */ protected XmlAccessType buildDefaultAccessType() { - XmlAccessType superAccessType = this.getSuperPersistentClassAccessType(); + XmlAccessType superAccessType = this.getSuperClassAccessType(); if (superAccessType != null) { return superAccessType; } @@ -238,9 +254,9 @@ public class GenericJavaPersistentClass return XmlAccessType.PUBLIC_MEMBER; } - protected XmlAccessType getSuperPersistentClassAccessType() { - JaxbPersistentClass superPersistentClass = this.getSuperPersistentClass(); - return superPersistentClass == null ? null : superPersistentClass.getSpecifiedAccessType(); + protected XmlAccessType getSuperClassAccessType() { + JaxbClass superClass = this.getSuperClass(); + return superClass == null ? null : superClass.getSpecifiedAccessType(); } protected XmlAccessType getPackageAccessType() { @@ -295,7 +311,7 @@ public class GenericJavaPersistentClass * Otherwise XmlAccessOrder.UNDEFINED. */ protected XmlAccessOrder buildDefaultAccessOrder() { - XmlAccessOrder superAccessOrder = this.getSuperPersistentClassAccessOrder(); + XmlAccessOrder superAccessOrder = this.getSuperClassAccessOrder(); if (superAccessOrder != null) { return superAccessOrder; } @@ -306,9 +322,9 @@ public class GenericJavaPersistentClass return XmlAccessOrder.UNDEFINED; } - protected XmlAccessOrder getSuperPersistentClassAccessOrder() { - JaxbPersistentClass superPersistentClass = this.getSuperPersistentClass(); - return superPersistentClass == null ? null : superPersistentClass.getSpecifiedAccessOrder(); + protected XmlAccessOrder getSuperClassAccessOrder() { + JaxbClass superClass = this.getSuperClass(); + return superClass == null ? null : superClass.getSpecifiedAccessOrder(); } protected XmlAccessOrder getPackageAccessOrder() { @@ -320,550 +336,147 @@ public class GenericJavaPersistentClass // ********** attributes ********** public Iterable<JaxbPersistentAttribute> getAttributes() { - return new LiveCloneIterable<JaxbPersistentAttribute>(this.attributes); + return this.attributesContainer.getAttributes(); } public int getAttributesSize() { - return this.attributes.size(); + return this.attributesContainer.getAttributesSize(); } - protected void addAttribute(JaxbPersistentAttribute attribute) { - addItemToCollection(attribute, this.attributes, ATTRIBUTES_COLLECTION); + protected JaxbAttributesContainer.Owner buildAttributesContainerOwner() { + return new JaxbAttributesContainer.Owner() { + public XmlAccessType getAccessType() { + return GenericJavaPersistentClass.this.getAccessType(); + } + + public void fireAttributeAdded(JaxbPersistentAttribute attribute) { + GenericJavaPersistentClass.this.fireItemAdded(ATTRIBUTES_COLLECTION, attribute); + } + + public void fireAttributeRemoved(JaxbPersistentAttribute attribute) { + GenericJavaPersistentClass.this.fireItemRemoved(ATTRIBUTES_COLLECTION, attribute); + } + }; } - protected void removeAttribute(JaxbPersistentAttribute attribute) { - removeItemFromCollection(attribute, this.attributes, ATTRIBUTES_COLLECTION); - } - protected JaxbPersistentField buildField(JavaResourceField resourceField) { - return getFactory().buildJavaPersistentField(this, resourceField); - } + // ********** inherited attributes ********** - protected JaxbPersistentProperty buildProperty(JavaResourceMethod resourceGetter, JavaResourceMethod resourceSetter) { - return getFactory().buildJavaPersistentProperty(this, resourceGetter, resourceSetter); + public Iterable<JaxbPersistentAttribute> getInheritedAttributes() { + return new CompositeIterable<JaxbPersistentAttribute>(this.getInheritedAttributeSets()); } - protected void initializeAttributes() { - if (getAccessType() == XmlAccessType.PUBLIC_MEMBER) { - this.initializePublicMemberAccessAttributes(); - } - else if (getAccessType() == XmlAccessType.FIELD) { - this.intializeFieldAccessAttributes(); - } - else if (getAccessType() == XmlAccessType.PROPERTY) { - this.intializePropertyAccessAttributes(); - } - else if (getAccessType() == XmlAccessType.NONE) { - this.intializeNoneAccessAttributes(); - } - } - - /** - * Initialize the attributes for XmlAccessType.PUBLIC_MEMBER - * 1. all public, non-static, non-transient fields (transient modifier, @XmlTransient is brought to the context model) - * 2. all annotated fields that aren't public - * 3. all public getter/setter javabeans pairs - * 4. all annotated methods (some will have a matching getter/setter, some will be standalone) - */ - private void initializePublicMemberAccessAttributes() { - this.initializeFieldAttributes(this.buildPublicMemberAccessTypeResourceFieldsFilter()); - Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); - //iterate through all persistable resource method getters - for (JavaResourceMethod getterMethod : this.getResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { - JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); - if (methodsArePersistablePublicMemberAccess(getterMethod, setterMethod)) { - this.attributes.add(this.buildProperty(getterMethod, setterMethod)); + protected Iterable<Iterable<JaxbPersistentAttribute>> getInheritedAttributeSets() { + return new TransformationIterable<JaxbAttributesContainer, Iterable<JaxbPersistentAttribute>>(this.getInheritedAttributesContainers()) { + @Override + protected Iterable<JaxbPersistentAttribute> transform(JaxbAttributesContainer attributesContainer) { + return attributesContainer.getAttributes(); } - resourceMethods.remove(getterMethod); - resourceMethods.remove(setterMethod); - } - this.initializeRemainingResourceMethodAttributes(resourceMethods); + }; } - /** - * Initialize the attributes for XmlAccessType.FIELD - * 1. all non-transient fields - * 2. all annotated methods getters/setters - */ - private void intializeFieldAccessAttributes() { - this.initializeFieldAttributes(this.buildNonTransientNonStaticResourceFieldsFilter()); - this.initializeAnnotatedPropertyAttributes(); + protected Iterable<JaxbAttributesContainer> getInheritedAttributesContainers() { + return new LiveCloneIterable<JaxbAttributesContainer>(this.inheritedAttributesContainers.values()); // read-only } - /** - * Initialize the attributes for XmlAccessType.PROPERTY - * 1. all getter/setter javabeans pairs - * 2. all annotated fields - * 3. all annotated methods getters/setters that don't have a matching pair - */ - private void intializePropertyAccessAttributes() { - this.initializeFieldAttributes(this.buildAnnotatedResourceFieldsFilter()); - - Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); - //iterate through all resource methods searching for persistable getters - for (JavaResourceMethod getterMethod : this.getResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { - JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); - if (methodsArePersistableProperties(getterMethod, setterMethod)) { - this.attributes.add(this.buildProperty(getterMethod, setterMethod)); - } - resourceMethods.remove(getterMethod); - resourceMethods.remove(setterMethod); + public int getInheritedAttributesSize() { + int size = 0; + for (JaxbAttributesContainer attributesContainer : getInheritedAttributesContainers()) { + size += attributesContainer.getAttributesSize(); } - this.initializeRemainingResourceMethodAttributes(resourceMethods); + return size; } - /** - * Initialize the attributes for XmlAccessType.NONE - * 1. all annotated fields - * 2. all annotated methods getters/setters (some will have a matching getter/setter, some will be standalone) - */ - private void intializeNoneAccessAttributes() { - this.initializeFieldAttributes(this.buildAnnotatedResourceFieldsFilter()); - this.initializeAnnotatedPropertyAttributes(); - } - - private void initializeFieldAttributes(Filter<JavaResourceField> filter) { - for (JavaResourceField resourceField : this.getResourceFields(filter)) { - this.attributes.add(this.buildField(resourceField)); - } + protected void initializeInheritedAttributes() { + this.addInheritedAttributesContainer(this.getSuperClass()); } - private void initializeRemainingResourceMethodAttributes(Collection<JavaResourceMethod> resourceMethods) { - //iterate through remaining resource methods and search for those that are annotated. - //all getter methods will already be used. - for (JavaResourceMethod resourceMethod : resourceMethods) { - if (resourceMethod.isAnnotated()) { - //annotated setter(or other random method) with no corresponding getter, bring into context model for validation purposes - this.attributes.add(this.buildProperty(null, resourceMethod)); + protected void addInheritedAttributesContainer(JaxbClass superClass) { + if (superClass != null) { + if (superClass.getKind() == Kind.TRANSIENT) { + this.inheritedAttributesContainers.put(superClass, this.buildInheritedAttributesContainer(superClass)); + this.addInheritedAttributesContainer(superClass.getSuperClass()); } } } - private static boolean methodsArePersistableProperties(JavaResourceMethod getterMethod, JavaResourceMethod setterMethod) { - if (setterMethod != null) { - return true; - } - //Lists do not have to have a corresponding setter method - else if (getterMethod.getTypeName().equals("java.util.List")) { //$NON-NLS-1$ - return true; - } - else if (getterMethod.isAnnotated()) { - //annotated getter with no corresponding setter, bring into context model for validation purposes - return true; - } - return false; + protected JaxbAttributesContainer buildInheritedAttributesContainer(JaxbClass jaxbClass) { + return new GenericJavaAttributesContainer(this, buildInheritedAttributesContainerOwner(), jaxbClass.getJavaResourceType()); } - private static boolean methodsArePersistablePublicMemberAccess(JavaResourceMethod getterMethod, JavaResourceMethod setterMethod) { - if (getterMethod.isPublic()) { - if (setterMethod != null) { - if (setterMethod.isPublic()) { - return true; - } - } - //Lists do not have to have a corresponding setter method - else if (getterMethod.getTypeName().equals("java.util.List")) { //$NON-NLS-1$ - return true; + protected JaxbAttributesContainer.Owner buildInheritedAttributesContainerOwner() { + return new JaxbAttributesContainer.Owner() { + public XmlAccessType getAccessType() { + return GenericJavaPersistentClass.this.getAccessType(); } - else if (getterMethod.isAnnotated()) { - //annotated getter with no corresponding setter, bring into context model for validation purposes - return true; + + public void fireAttributeAdded(JaxbPersistentAttribute attribute) { + GenericJavaPersistentClass.this.fireItemAdded(INHERITED_ATTRIBUTES_COLLECTION, attribute); } - } - else if (getterMethod.isAnnotated() || (setterMethod != null && setterMethod.isAnnotated())) { - return true; - } - return false; - } - - private void initializeAnnotatedPropertyAttributes() { - Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); - //iterate through all resource methods searching for persistable getters - for (JavaResourceMethod getterMethod : this.getResourceMethods(buildPersistablePropertyGetterMethodsFilter())) { - JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); - if (getterMethod.isAnnotated() || (setterMethod != null && setterMethod.isAnnotated())) { - this.attributes.add(this.buildProperty(getterMethod, setterMethod)); - } - resourceMethods.remove(getterMethod); - resourceMethods.remove(setterMethod); - } - this.initializeRemainingResourceMethodAttributes(resourceMethods); - } - - protected Iterable<JavaResourceField> getResourceFields() { - return getJavaResourceType().getFields(); - } - - protected Iterable<JavaResourceMethod> getResourceMethods() { - return getJavaResourceType().getMethods(); - } - - protected Iterable<JavaResourceField> getResourceFields(Filter<JavaResourceField> filter) { - return new FilteringIterable<JavaResourceField>(getResourceFields(), filter); - } - - protected Iterable<JavaResourceMethod> getResourceMethods(Filter<JavaResourceMethod> filter) { - return new FilteringIterable<JavaResourceMethod>(getResourceMethods(), filter); - } - - protected Filter<JavaResourceField> buildNonTransientNonStaticResourceFieldsFilter() { - return new Filter<JavaResourceField>() { - public boolean accept(JavaResourceField resourceField) { - return memberIsNonTransientNonStatic(resourceField) || resourceField.isAnnotated(); - } - }; - } - - protected Filter<JavaResourceField> buildPublicMemberAccessTypeResourceFieldsFilter() { - return new Filter<JavaResourceField>() { - public boolean accept(JavaResourceField resourceField) { - return memberIsPublicNonTransientNonStatic(resourceField) || resourceField.isAnnotated(); - } - }; - } - - protected Filter<JavaResourceMethod> buildPersistablePropertyGetterMethodsFilter() { - return new Filter<JavaResourceMethod>() { - public boolean accept(JavaResourceMethod resourceMethod) { - return methodIsPersistablePropertyGetter(resourceMethod, getResourceMethods()); - } - }; - } - - protected static boolean memberIsPublicNonTransientNonStatic(JavaResourceMember resourceMember) { - return resourceMember.isPublic() && memberIsNonTransientNonStatic(resourceMember); - } - - protected static boolean memberIsNonTransientNonStatic(JavaResourceMember resourceMember) { - return !resourceMember.isTransient() && !resourceMember.isStatic(); - } - - protected Filter<JavaResourceField> buildAnnotatedResourceFieldsFilter() { - return new Filter<JavaResourceField>() { - public boolean accept(JavaResourceField resourceField) { - return resourceField.isAnnotated(); + + public void fireAttributeRemoved(JaxbPersistentAttribute attribute) { + GenericJavaPersistentClass.this.fireItemRemoved(INHERITED_ATTRIBUTES_COLLECTION, attribute); } }; } - protected void syncAttributes() { - if (getAccessType() == XmlAccessType.PUBLIC_MEMBER) { - this.syncPublicMemberAccessAttributes(); - } - else if (getAccessType() == XmlAccessType.FIELD) { - this.syncFieldAccessAttributes(); - } - else if (getAccessType() == XmlAccessType.PROPERTY) { - this.syncPropertyAccessAttributes(); - } - else if (getAccessType() == XmlAccessType.NONE) { - this.syncNoneAccessAttributes(); - } - } - - /** - * Sync the attributes for XmlAccessType.PUBLIC_MEMBER - * 1. all public, non-static, non-transient fields (transient modifier, @XmlTransient is brought to the context model) - * 2. all annotated fields that aren't public - * 3. all public getter/setter javabeans pairs - * 4. all annotated methods (some will have a matching getter/setter, some will be standalone) - */ - private void syncPublicMemberAccessAttributes() { - HashSet<JaxbPersistentAttribute> contextAttributes = CollectionTools.set(this.getAttributes()); - - this.syncFieldAttributes(contextAttributes, this.buildPublicMemberAccessTypeResourceFieldsFilter()); - - Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); - //iterate through all persistable resource method getters - for (JavaResourceMethod getterMethod : this.getResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { - JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); - if (methodsArePersistablePublicMemberAccess(getterMethod, setterMethod)) { - boolean match = false; - for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { - JaxbPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(getterMethod, setterMethod)) { - match = true; - contextAttribute.synchronizeWithResourceModel(); - stream.remove(); - break; - } - } - if (!match) { - this.addAttribute(this.buildProperty(getterMethod, setterMethod)); - } - resourceMethods.remove(getterMethod); - resourceMethods.remove(setterMethod); - } - } - this.syncRemainingResourceMethods(contextAttributes, resourceMethods); - } - - /** - * Initialize the attributes for XmlAccessType.FIELD - * 1. all non-transient fields - * 2. all annotated methods getters/setters - */ - private void syncFieldAccessAttributes() { - HashSet<JaxbPersistentAttribute> contextAttributes = CollectionTools.set(this.getAttributes()); - - this.syncFieldAttributes(contextAttributes, this.buildNonTransientNonStaticResourceFieldsFilter()); - this.syncAnnotatedPropertyAttributes(contextAttributes); - } - - /** - * Initialize the attributes for XmlAccessType.PROPERTY - * 1. all getter/setter javabeans pairs - * 2. all annotated fields - * 3. all annotated methods getters/setters that don't have a matching pair - */ - private void syncPropertyAccessAttributes() { - HashSet<JaxbPersistentAttribute> contextAttributes = CollectionTools.set(this.getAttributes()); - - this.syncFieldAttributes(contextAttributes, this.buildAnnotatedResourceFieldsFilter()); - - Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); - //iterate through all resource methods searching for persistable getters - for (JavaResourceMethod getterMethod : this.getResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { - JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); - if (methodsArePersistableProperties(getterMethod, setterMethod)) { - boolean match = false; - for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { - JaxbPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(getterMethod, setterMethod)) { - match = true; - contextAttribute.synchronizeWithResourceModel(); - stream.remove(); - break; - } - } - if (!match) { - this.addAttribute(this.buildProperty(getterMethod, setterMethod)); - } - } - resourceMethods.remove(getterMethod); - resourceMethods.remove(setterMethod); + protected void syncInheritedAttributes() { + for (JaxbAttributesContainer attributesContainer : this.inheritedAttributesContainers.values()) { + attributesContainer.synchronizeWithResourceModel(); } - this.syncRemainingResourceMethods(contextAttributes, resourceMethods); } /** - * Initialize the attributes for XmlAccessType.NONE - * 1. all annotated fields - * 2. all annotated methods getters/setters (some will have a matching getter/setter, some will be standalone) + * The attributes are synchronized during the <em>update</em> because + * the list of resource attributes is determined by the access type + * which can be controlled in a number of different places.... */ - private void syncNoneAccessAttributes() { - HashSet<JaxbPersistentAttribute> contextAttributes = CollectionTools.set(this.getAttributes()); - - this.syncFieldAttributes(contextAttributes, this.buildAnnotatedResourceFieldsFilter()); - this.syncAnnotatedPropertyAttributes(contextAttributes); - } - - private void syncAnnotatedPropertyAttributes(HashSet<JaxbPersistentAttribute> contextAttributes) { - Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getResourceMethods()); - //iterate through all resource methods searching for persistable getters - for (JavaResourceMethod getterMethod : this.getResourceMethods(buildPersistablePropertyGetterMethodsFilter())) { - JavaResourceMethod setterMethod = getValidSiblingSetMethod(getterMethod, resourceMethods); - if (getterMethod.isAnnotated() || (setterMethod != null && setterMethod.isAnnotated())) { + protected void updateInheritedAttributes() { + HashSet<JaxbClass> contextSuperclasses = CollectionTools.set(this.inheritedAttributesContainers.keySet()); + for (JaxbClass superClass : getAncestors()) { + if (superClass.getKind() == Kind.TRANSIENT) { boolean match = false; - for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { - JaxbPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(getterMethod, setterMethod)) { - match = true; - contextAttribute.synchronizeWithResourceModel(); + for (Iterator<JaxbClass> stream = contextSuperclasses.iterator(); stream.hasNext(); ) { + JaxbClass contextSuperclass = stream.next(); + if (contextSuperclass == superClass) { stream.remove(); - break; - } - } - if (!match) { - this.addAttribute(this.buildProperty(getterMethod, setterMethod)); - } - } - resourceMethods.remove(getterMethod); - resourceMethods.remove(setterMethod); - } - this.syncRemainingResourceMethods(contextAttributes, resourceMethods); - } - - private void syncFieldAttributes(HashSet<JaxbPersistentAttribute> contextAttributes, Filter<JavaResourceField> filter) { - for (JavaResourceField resourceField : this.getResourceFields(filter)) { - boolean match = false; - for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext(); ) { - JaxbPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(resourceField)) { - match = true; - contextAttribute.synchronizeWithResourceModel(); - stream.remove(); - break; - } - } - if (!match) { - // added elements are sync'ed during construction or will be - // updated during the next "update" (which is triggered by - // their addition to the model) - this.addAttribute(this.buildField(resourceField)); - } - } - } - - private void syncRemainingResourceMethods(HashSet<JaxbPersistentAttribute> contextAttributes, Collection<JavaResourceMethod> resourceMethods) { - //iterate through remaining resource methods and search for those that are annotated. - //all getter methods will already be used. - for (JavaResourceMethod resourceMethod : resourceMethods) { - if (resourceMethod.isAnnotated()) { - boolean match = false; - //annotated setter(or other random method) with no corresponding getter, bring into context model for validation purposes - for (Iterator<JaxbPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { - JaxbPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(null, resourceMethod)) { + this.inheritedAttributesContainers.get(contextSuperclass).update(); match = true; - contextAttribute.synchronizeWithResourceModel(); - stream.remove(); break; } } - if (!match) { - this.addAttribute(this.buildProperty(null, resourceMethod)); + if ( ! match) { + JaxbAttributesContainer container = this.buildInheritedAttributesContainer(superClass); + this.inheritedAttributesContainers.put(superClass, container); + this.fireItemsAdded(INHERITED_ATTRIBUTES_COLLECTION, CollectionTools.collection(container.getAttributes())); } } } - // remove any leftover context attributes - for (JaxbPersistentAttribute contextAttribute : contextAttributes) { - this.removeAttribute(contextAttribute); - } - } - - protected void updateAttributes() { - this.updateNodes(this.attributes); - } - - /** - * Return whether the specified method is a "getter" method that - * represents a property that may be "persisted". - */ - protected static boolean methodIsPersistablePropertyGetter(JavaResourceMethod resourceMethod, Iterable<JavaResourceMethod> allMethods) { - if (methodHasInvalidModifiers(resourceMethod)) { - return false; - } - if (resourceMethod.isConstructor()) { - return false; - } - - String returnTypeName = resourceMethod.getTypeName(); - if (returnTypeName == null) { - return false; // DOM method bindings can have a null name - } - if (returnTypeName.equals("void")) { //$NON-NLS-1$ - return false; - } - if (methodHasParameters(resourceMethod)) { - return false; - } - - boolean booleanGetter = methodIsBooleanGetter(resourceMethod); - - // if the type has both methods: - // boolean isProperty() - // boolean getProperty() - // then #isProperty() takes precedence and we ignore #getProperty(); - // but only having #getProperty() is OK too - // (see the JavaBeans spec 1.01) - if (booleanGetter && methodHasValidSiblingIsMethod(resourceMethod, allMethods)) { - return false; // since the type also defines #isProperty(), ignore #getProperty() + for (JaxbClass superClass : contextSuperclasses) { + JaxbAttributesContainer container = this.inheritedAttributesContainers.remove(superClass); + this.fireItemsRemoved(INHERITED_ATTRIBUTES_COLLECTION, CollectionTools.collection(container.getAttributes())); } - return true; } - private static boolean methodIsBooleanGetter(JavaResourceMethod resourceMethod) { - String returnTypeName = resourceMethod.getTypeName(); - String name = resourceMethod.getMethodName(); - boolean booleanGetter = false; - if (name.startsWith("is")) { //$NON-NLS-1$ - if (returnTypeName.equals("boolean")) { //$NON-NLS-1$ - } else { - return false; - } - } else if (name.startsWith("get")) { //$NON-NLS-1$ - if (returnTypeName.equals("boolean")) { //$NON-NLS-1$ - booleanGetter = true; - } - } else { - return false; - } - return booleanGetter; - } - /** - * Return whether the method's modifiers prevent it - * from being a getter or setter for a "persistent" property. - */ - private static boolean methodHasInvalidModifiers(JavaResourceMethod resourceMethod) { - int modifiers = resourceMethod.getModifiers(); - if (Modifier.isStatic(modifiers)) { - return true; + public boolean isInherited(JaxbPersistentAttribute attribute) { + if (attribute.getParent() != this) { + throw new IllegalArgumentException("The attribute is not owned by this GenericJavaPersistentClass"); //$NON-NLS-1$ } - return false; - } - - private static boolean methodHasParameters(JavaResourceMethod resourceMethod) { - return resourceMethod.getParametersSize() != 0; + return !CollectionTools.contains(this.getAttributes(), attribute); } - /** - * Return whether the method has a sibling "is" method for the specified - * property and that method is valid for a "persistable" property. - * Pre-condition: the method is a "boolean getter" (e.g. 'public boolean getProperty()'); - * this prevents us from returning true when the method itself is an - * "is" method. - */ - private static boolean methodHasValidSiblingIsMethod(JavaResourceMethod getMethod, Iterable<JavaResourceMethod> resourceMethods) { - String capitalizedAttributeName = StringTools.capitalize(getMethod.getName()); - for (JavaResourceMethod sibling : resourceMethods) { - if ((sibling.getParametersSize() == 0) - && sibling.getMethodName().equals("is" + capitalizedAttributeName)) { //$NON-NLS-1$ - return methodIsValidSibling(sibling, "boolean"); //$NON-NLS-1$ - } + public String getJavaResourceAttributeOwningTypeName(JaxbPersistentAttribute attribute) { + if (attribute.getParent() != this) { + throw new IllegalArgumentException("The attribute is not owned by this GenericJavaPersistentClass"); //$NON-NLS-1$ } - return false; - } - - /** - * Return whether the method has a sibling "set" method - * and that method is valid for a "persistable" property. - */ - private static JavaResourceMethod getValidSiblingSetMethod(JavaResourceMethod getMethod, Collection<JavaResourceMethod> resourceMethods) { - String capitalizedAttributeName = StringTools.capitalize(getMethod.getName()); - String parameterTypeErasureName = getMethod.getTypeName(); - for (JavaResourceMethod sibling : resourceMethods) { - ListIterable<String> siblingParmTypeNames = sibling.getParameterTypeNames(); - if ((sibling.getParametersSize() == 1) - && sibling.getMethodName().equals("set" + capitalizedAttributeName) //$NON-NLS-1$ - && siblingParmTypeNames.iterator().next().equals(parameterTypeErasureName)) { - return methodIsValidSibling(sibling, "void") ? sibling : null; //$NON-NLS-1$ + for (JaxbClass inheritedClass : this.inheritedAttributesContainers.keySet()) { + if (CollectionTools.contains(this.inheritedAttributesContainers.get(inheritedClass).getAttributes(), attribute)) { + return inheritedClass.getSimpleName(); } } - return null; - } - - /** - * Return whether the specified method is a valid sibling with the - * specified return type. - */ - private static boolean methodIsValidSibling(JavaResourceMethod resourceMethod, String returnTypeName) { - if (resourceMethod == null) { - return false; - } - if (methodHasInvalidModifiers(resourceMethod)) { - return false; - } - if (resourceMethod.isConstructor()) { - return false; - } - String rtName = resourceMethod.getTypeName(); - if (rtName == null) { - return false; // DOM method bindings can have a null name - } - return rtName.equals(returnTypeName); + throw new IllegalArgumentException("The attribute is not an inherited attribute"); //$NON-NLS-1$ } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientClass.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientClass.java new file mode 100644 index 0000000000..89e097b2b3 --- /dev/null +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientClass.java @@ -0,0 +1,235 @@ +/******************************************************************************* + * Copyright (c) 2011 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Oracle - initial API and implementation + *******************************************************************************/ +package org.eclipse.jpt.jaxb.core.internal.context.java; + +import java.util.Collection; +import java.util.HashSet; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.iterables.ChainIterable; +import org.eclipse.jpt.jaxb.core.context.JaxbClass; +import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot; +import org.eclipse.jpt.jaxb.core.context.JaxbTransientClass; +import org.eclipse.jpt.jaxb.core.context.XmlAccessOrder; +import org.eclipse.jpt.jaxb.core.context.XmlAccessType; +import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; +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.XmlTransientAnnotation; + + +public class GenericJavaTransientClass + extends AbstractJavaType + implements JaxbTransientClass { + + protected JaxbClass superClass; + + protected XmlAccessType specifiedAccessType; + + protected XmlAccessOrder specifiedAccessOrder; + + public GenericJavaTransientClass(JaxbContextRoot parent, JavaResourceType resourceType) { + super(parent, resourceType); + this.superClass = this.buildSuperClass(); + this.specifiedAccessType = this.getResourceAccessType(); + this.specifiedAccessOrder = this.getResourceAccessOrder(); + } + + @Override + public JavaResourceType getJavaResourceType() { + return (JavaResourceType) super.getJavaResourceType(); + } + + @Override + public JaxbContextRoot getParent() { + return (JaxbContextRoot) super.getParent(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setSpecifiedAccessType_(this.getResourceAccessType()); + this.setSpecifiedAccessOrder_(this.getResourceAccessOrder()); + } + + @Override + public void update() { + super.update(); + this.setSuperClass(this.buildSuperClass()); + } + + + // ********** xml transient annotation ********** + + protected XmlTransientAnnotation getXmlTransientAnnotation() { + return (XmlTransientAnnotation) this.getJavaResourceType().getNonNullAnnotation(XmlTransientAnnotation.ANNOTATION_NAME); + } + + + // ********** JaxbType impl ********** + + public Kind getKind() { + return Kind.TRANSIENT; + } + + + // ********** super class ********** + + public JaxbClass getSuperClass() { + return this.superClass; + } + + protected void setSuperClass(JaxbClass superClass) { + JaxbClass old = this.superClass; + this.superClass = superClass; + this.firePropertyChanged(SUPER_CLASS_PROPERTY, old, superClass); + } + + protected JaxbClass buildSuperClass() { + HashSet<JavaResourceType> visited = new HashSet<JavaResourceType>(); + visited.add(this.getJavaResourceType()); + JaxbClass spc = this.getSuperClass(this.getJavaResourceType().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 JaxbClass getSuperClass(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); + JaxbClass spc = this.getClass(typeName); + return (spc != null && resourceType.isMapped()) ? spc : this.getSuperClass(resourceType.getSuperclassQualifiedName(), visited); // recurse + } + + protected JaxbClass getClass(String fullyQualifiedTypeName) { + return this.getParent().getClass(fullyQualifiedTypeName); + } + + + // ********** inheritance ********** + + public Iterable<JaxbClass> getInheritanceHierarchy() { + return this.getInheritanceHierarchyOf(this); + } + + public Iterable<JaxbClass> getAncestors() { + return this.getInheritanceHierarchyOf(this.superClass); + } + + protected Iterable<JaxbClass> getInheritanceHierarchyOf(JaxbClass start) { + // using a chain iterator to traverse up the inheritance tree + return new ChainIterable<JaxbClass>(start) { + @Override + protected JaxbClass nextLink(JaxbClass jaxbClass) { + return jaxbClass.getSuperClass(); + } + }; + } + + + // ********** access type ********** + + public XmlAccessType getAccessType() { + return (this.specifiedAccessType != null) ? this.specifiedAccessType : this.getDefaultAccessType(); + } + + public XmlAccessType getSpecifiedAccessType() { + return this.specifiedAccessType; + } + + public void setSpecifiedAccessType(XmlAccessType access) { + this.getAccessorTypeAnnotation().setValue(XmlAccessType.toJavaResourceModel(access)); + this.setSpecifiedAccessType_(access); + } + + protected void setSpecifiedAccessType_(XmlAccessType access) { + XmlAccessType old = this.specifiedAccessType; + this.specifiedAccessType = access; + this.firePropertyChanged(SPECIFIED_ACCESS_TYPE_PROPERTY, old, access); + } + + public XmlAccessType getDefaultAccessType() { + return null; + } + + protected XmlAccessType getResourceAccessType() { + return XmlAccessType.fromJavaResourceModel(this.getAccessorTypeAnnotation().getValue()); + } + + protected XmlAccessorTypeAnnotation getAccessorTypeAnnotation() { + return (XmlAccessorTypeAnnotation) getJavaResourceType().getNonNullAnnotation(XmlAccessorTypeAnnotation.ANNOTATION_NAME); + } + + + // ********** access order ********** + + public XmlAccessOrder getAccessOrder() { + return (this.specifiedAccessOrder != null) ? this.specifiedAccessOrder : this.getDefaultAccessOrder(); + } + + public XmlAccessOrder getSpecifiedAccessOrder() { + return this.specifiedAccessOrder; + } + + public void setSpecifiedAccessOrder(XmlAccessOrder accessOrder) { + this.getAccessorOrderAnnotation().setValue(XmlAccessOrder.toJavaResourceModel(accessOrder)); + this.setSpecifiedAccessOrder_(accessOrder); + } + + protected void setSpecifiedAccessOrder_(XmlAccessOrder accessOrder) { + XmlAccessOrder old = this.specifiedAccessOrder; + this.specifiedAccessOrder = accessOrder; + this.firePropertyChanged(SPECIFIED_ACCESS_ORDER_PROPERTY, old, accessOrder); + } + + public XmlAccessOrder getDefaultAccessOrder() { + return null; + } + + protected XmlAccessOrder getResourceAccessOrder() { + return XmlAccessOrder.fromJavaResourceModel(this.getAccessorOrderAnnotation().getValue()); + } + + protected XmlAccessorOrderAnnotation getAccessorOrderAnnotation() { + return (XmlAccessorOrderAnnotation) getJavaResourceType().getNonNullAnnotation(XmlAccessorOrderAnnotation.ANNOTATION_NAME); + } + + // **************** validation ******************************************** + + @Override + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return getXmlTransientAnnotation().getTextRange(astRoot); + } +} diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientType.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientType.java deleted file mode 100644 index 4344d9af2e..0000000000 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientType.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Oracle - initial API and implementation - *******************************************************************************/ -package org.eclipse.jpt.jaxb.core.internal.context.java; - -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jpt.common.core.utility.TextRange; -import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot; -import org.eclipse.jpt.jaxb.core.context.JaxbTransientType; -import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType; -import org.eclipse.jpt.jaxb.core.resource.java.XmlTransientAnnotation; - - -public class GenericJavaTransientType - extends AbstractJavaType - implements JaxbTransientType { - - - public GenericJavaTransientType(JaxbContextRoot parent, JavaResourceType resourceType) { - super(parent, resourceType); - } - - @Override - public JavaResourceType getJavaResourceType() { - return (JavaResourceType) super.getJavaResourceType(); - } - - - // ********** xml transient annotation ********** - - protected XmlTransientAnnotation getXmlTransientAnnotation() { - return (XmlTransientAnnotation) this.getJavaResourceType().getNonNullAnnotation(XmlTransientAnnotation.ANNOTATION_NAME); - } - - - // ********** JaxbType impl ********** - - public Kind getKind() { - return Kind.TRANSIENT; - } - - - // **************** validation ******************************************** - - @Override - public TextRange getValidationTextRange(CompilationUnit astRoot) { - return getXmlTransientAnnotation().getTextRange(astRoot); - } -} diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/GenericJaxb_2_1_NavigatorItemLabelProviderFactory.java b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/GenericJaxb_2_1_NavigatorItemLabelProviderFactory.java index 12ddba7c75..7734572337 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/GenericJaxb_2_1_NavigatorItemLabelProviderFactory.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/GenericJaxb_2_1_NavigatorItemLabelProviderFactory.java @@ -20,7 +20,7 @@ import org.eclipse.jpt.jaxb.core.context.JaxbPersistentEnum; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentField; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentProperty; import org.eclipse.jpt.jaxb.core.context.JaxbRegistry; -import org.eclipse.jpt.jaxb.core.context.JaxbTransientType; +import org.eclipse.jpt.jaxb.core.context.JaxbTransientClass; public class GenericJaxb_2_1_NavigatorItemLabelProviderFactory @@ -61,8 +61,8 @@ public class GenericJaxb_2_1_NavigatorItemLabelProviderFactory else if (item instanceof JaxbPersistentEnum) { return new JaxbPersistentEnumItemLabelProvider((JaxbPersistentEnum) item, contentAndLabelProvider); } - else if (item instanceof JaxbTransientType) { - return new JaxbTransientTypeItemLabelProvider((JaxbTransientType) item, contentAndLabelProvider); + else if (item instanceof JaxbTransientClass) { + return new JaxbTransientClassItemLabelProvider((JaxbTransientClass) item, contentAndLabelProvider); } else if (item instanceof JaxbPersistentField) { return new JaxbPersistentFieldItemLabelProvider((JaxbPersistentField) item, contentAndLabelProvider); diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbPersistentAttributeItemLabelProvider.java b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbPersistentAttributeItemLabelProvider.java index 2bbec7003d..efe5f0f7d7 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbPersistentAttributeItemLabelProvider.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbPersistentAttributeItemLabelProvider.java @@ -48,7 +48,13 @@ public abstract class JaxbPersistentAttributeItemLabelProvider @Override protected PropertyValueModel<String> buildTextModel() { - return new StaticPropertyValueModel<String>(getModel().getName()); + StringBuffer sb = new StringBuffer(); + if (getModel().isInherited()) { + sb.append(getModel().getInheritedJavaResourceAttributeOwningTypeName()); + sb.append('.'); + } + sb.append(getModel().getName()); + return new StaticPropertyValueModel<String>(sb.toString()); } @Override diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbPersistentClassItemContentProvider.java b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbPersistentClassItemContentProvider.java index 76e5837ac9..dfcf97e383 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbPersistentClassItemContentProvider.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbPersistentClassItemContentProvider.java @@ -9,9 +9,12 @@ *******************************************************************************/ package org.eclipse.jpt.jaxb.ui.internal.jaxb21; +import java.util.ArrayList; +import java.util.List; import org.eclipse.jpt.common.ui.internal.jface.AbstractTreeItemContentProvider; import org.eclipse.jpt.common.ui.internal.jface.DelegatingTreeContentAndLabelProvider; import org.eclipse.jpt.common.utility.internal.model.value.CollectionAspectAdapter; +import org.eclipse.jpt.common.utility.internal.model.value.CompositeCollectionValueModel; import org.eclipse.jpt.common.utility.model.value.CollectionValueModel; import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot; import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute; @@ -40,6 +43,13 @@ public class JaxbPersistentClassItemContentProvider @Override protected CollectionValueModel<JaxbPersistentAttribute> buildChildrenModel() { + List<CollectionValueModel<JaxbPersistentAttribute>> list = new ArrayList<CollectionValueModel<JaxbPersistentAttribute>>(); + list.add(buildAttributesModel()); + list.add(buildInheritedAttributesModel()); + return new CompositeCollectionValueModel<CollectionValueModel<JaxbPersistentAttribute>, JaxbPersistentAttribute>(list); + } + + protected CollectionValueModel<JaxbPersistentAttribute> buildAttributesModel() { return new CollectionAspectAdapter<JaxbPersistentClass, JaxbPersistentAttribute>( JaxbPersistentClass.ATTRIBUTES_COLLECTION, getModel()) { @Override @@ -48,4 +58,14 @@ public class JaxbPersistentClassItemContentProvider } }; } + + protected CollectionValueModel<JaxbPersistentAttribute> buildInheritedAttributesModel() { + return new CollectionAspectAdapter<JaxbPersistentClass, JaxbPersistentAttribute>( + JaxbPersistentClass.INHERITED_ATTRIBUTES_COLLECTION, getModel()) { + @Override + protected Iterable<JaxbPersistentAttribute> getIterable() { + return this.subject.getInheritedAttributes(); + } + }; + } } diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbTransientTypeItemLabelProvider.java b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbTransientClassItemLabelProvider.java index a699bcf74c..5f79b33805 100644 --- a/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbTransientTypeItemLabelProvider.java +++ b/jaxb/plugins/org.eclipse.jpt.jaxb.ui/src/org/eclipse/jpt/jaxb/ui/internal/jaxb21/JaxbTransientClassItemLabelProvider.java @@ -12,17 +12,17 @@ package org.eclipse.jpt.jaxb.ui.internal.jaxb21; import org.eclipse.jpt.common.ui.jface.DelegatingContentAndLabelProvider; import org.eclipse.jpt.common.utility.internal.model.value.StaticPropertyValueModel; import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.jaxb.core.context.JaxbTransientType; +import org.eclipse.jpt.jaxb.core.context.JaxbTransientClass; import org.eclipse.jpt.jaxb.ui.JptJaxbUiPlugin; import org.eclipse.jpt.jaxb.ui.internal.JptJaxbUiIcons; import org.eclipse.swt.graphics.Image; -public class JaxbTransientTypeItemLabelProvider +public class JaxbTransientClassItemLabelProvider extends JaxbTypeItemLabelProvider { - public JaxbTransientTypeItemLabelProvider( - JaxbTransientType jaxbTransientType, DelegatingContentAndLabelProvider labelProvider) { + public JaxbTransientClassItemLabelProvider( + JaxbTransientClass jaxbTransientType, DelegatingContentAndLabelProvider labelProvider) { super(jaxbTransientType, labelProvider); } |