Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpfullbright2012-04-03 17:24:40 -0400
committerpfullbright2012-04-03 17:24:40 -0400
commita8c296ee167f0fc315d310049d37f536ebb972ed (patch)
treeee9cc61f058d20d3f56a0a2876f1d32498622483
parentf3f7412ac0097ad3fac7b43ea75c13db828ba154 (diff)
downloadwebtools.dali-a8c296ee167f0fc315d310049d37f536ebb972ed.tar.gz
webtools.dali-a8c296ee167f0fc315d310049d37f536ebb972ed.tar.xz
webtools.dali-a8c296ee167f0fc315d310049d37f536ebb972ed.zip
bug 366901 - XmlJoinNode support
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPackageInfo.java2
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPackageInfo.java11
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/property_files/el_jaxb_validation.properties28
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELClassMapping.java10
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNode.java58
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNodesMapping.java23
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaClassMapping.java45
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNode.java314
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNodesMapping.java253
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/xpath/java/XPath.java41
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/validation/ELJaxbValidationMessages.java27
-rw-r--r--jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/resource/java/XmlJoinNodeAnnotation.java11
-rw-r--r--jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJavaXmlJoinNodeTests.java209
-rw-r--r--jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJavaXmlJoinNodesMappingTests.java197
-rw-r--r--jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJaxbCoreJavaContextModelTests.java3
15 files changed, 1202 insertions, 30 deletions
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPackageInfo.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPackageInfo.java
index 0ce4d2fc3c..062c95439f 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPackageInfo.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPackageInfo.java
@@ -87,6 +87,8 @@ public interface JaxbPackageInfo
String getNamespaceForPrefix(String prefix);
+ String getPrefixForNamespace(String namespace);
+
// ***** validation *****
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPackageInfo.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPackageInfo.java
index 53b86a8cb2..df21aa2d69 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPackageInfo.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPackageInfo.java
@@ -313,6 +313,17 @@ public class GenericJavaPackageInfo
return null;
}
+ public String getPrefixForNamespace(String namespace) {
+ if (this.xmlSchema != null) {
+ for (XmlNs xmlns : this.xmlSchema.getXmlNsPrefixes()) {
+ if (StringTools.stringsAreEqual(xmlns.getNamespaceURI(), namespace)) {
+ return xmlns.getPrefix();
+ }
+ }
+ }
+ return null;
+ }
+
// ***** content assist ******
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/property_files/el_jaxb_validation.properties b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/property_files/el_jaxb_validation.properties
index b21b7d8f4b..b9f8f38304 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/property_files/el_jaxb_validation.properties
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/property_files/el_jaxb_validation.properties
@@ -11,25 +11,33 @@
PROJECT_MISSING_ECLIPSELINK_JAXB_CONTEXT_FACTORY = Project is missing a jaxb.properties file specifying the EclipseLink JAXB context factory
XML_DISCRIMINATOR_NODE__NOT_SPECIFIED = XmlDiscriminatorNode not specified.
-XML_DISCRIMINATOR_NODE__ROOT_NOT_SUPPORTED = Root XPath not supported.
XML_DISCRIMINATOR_VALUE__NOT_SPECIFIED = XmlDiscriminatorValue not specified.
XML_ELEMENT_DECL__INVALID_METHOD_SIGNATURE_RETURN_TYPE = An element factory method must have a return type consistent with ''javax.xml.bind.JAXBElement''.
+XML_JOIN_NODE__XML_PATH_NOT_SPECIFIED = XmlJoinNode xmlPath not specified.
+XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_SPECIFIED = XmlJoinNode referencedXmlPath not specified.
+XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_IN_REFERENCED_CLASS_KEYS = There is no XmlKey or XmlID on the target class ''{0}'' with XPath \"{1}\".
+
+XML_JOIN_NODES__INVALID_REFERENCED_CLASS = The referenced class ''{0}'' is invalid for use with XmlJoinNodes.
+XML_JOIN_NODES__DUPLICATE_XML_PATH = Duplicate xmlPath ''{0}'' in XmlJoinNodes.
+XML_JOIN_NODES__DUPLICATE_REFERENCED_XML_PATH = Duplicate referencedXmlpath ''{0}'' in XmlJoinNodes.
+
XML_PATH__NOT_SPECIFIED = XmlPath not specified.
-XML_PATH__ROOT_NOT_SUPPORTED = Root XmlPath is not supported.
-XML_PATH__INVALID_FORM_ILLEGAL_SEGMENT = Illegal XmlPath step \"{0}\".
-XML_PATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT = Self XmlPath step must be first step.
-XML_PATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT = Text XmlPath step must be last step.
-XML_PATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT = An attribute XmlPath step must be the last step.
-XML_PATH__INVALID_NS_PREFIX = Cannot resolve a namespace for the prefix \"{0}\".
-XML_PATH__UNRESOLVED_ELEMENT = Cannot resolve element with namespace \"{0}\" and local name \"{1}\" in this context.
-XML_PATH__UNRESOLVED_ATTRIBUTE = Cannot resolve attribute with namespace \"{0}\" and local name \"{1}\" in this context.
XML_PATH__INSUFFICIENT_XML_PATHS_FOR_XML_ELEMENTS = Insufficient XmlPaths specified. There must be an XmlPath for each XmlElement.
XML_PATH__INSUFFICIENT_XML_ELEMENTS_FOR_XML_PATHS = There is no XmlElement to match this XmlPath. There must be an XmlElement for each Xmlpath.
XML_INVERSE_REFERENCE__MAPPED_BY_NOT_SPECIFIED = The 'mappedBy' property must be specified on an XmlInverseReference.
XML_INVERSE_REFERENCE__MAPPED_BY_NOT_RESOLVED = Cannot resolve the attribute ''{0}'' on the class ''{1}''.
-XML_INVERSE_REFERENCE__MAPPED_BY_ILLEGAL_MAPPING_TYPE = The attribute ''{0}'' on the class ''{1}'' must be mapped as XmlElement, XmlElements, XmlAttribute, or XmlValue. \ No newline at end of file
+XML_INVERSE_REFERENCE__MAPPED_BY_ILLEGAL_MAPPING_TYPE = The attribute ''{0}'' on the class ''{1}'' must be mapped as XmlElement, XmlElements, XmlAttribute, or XmlValue.j
+
+XPATH__INVALID_FORM_ILLEGAL_SEGMENT = Illegal XPath step \"{0}\".
+XPATH__ROOT_NOT_SUPPORTED = Root XPath is not supported in this context.
+XPATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT = Self XPath step must be first step.
+XPATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT = Text XPath step must be last step.
+XPATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT = An attribute XPath step must be the last step.
+XPATH__INVALID_NS_PREFIX = Cannot resolve a namespace for the prefix \"{0}\".
+XPATH__UNRESOLVED_ELEMENT = Cannot resolve element with namespace \"{0}\" and local name \"{1}\" in this context.
+XPATH__UNRESOLVED_ATTRIBUTE = Cannot resolve attribute with namespace \"{0}\" and local name \"{1}\" in this context.
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELClassMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELClassMapping.java
index c1fb95d5bb..253472585f 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELClassMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELClassMapping.java
@@ -46,4 +46,14 @@ public interface ELClassMapping
ELXmlDiscriminatorValue addXmlDiscriminatorValue();
void removeXmlDiscriminatorValue();
+
+
+ // ***** misc *****
+
+ /**
+ * Return an {@link Iterable} of XPaths that represent the attributes annotated with XmlID or
+ * XmlKey. (Includes those attributes that are not annotated with XmlPath - those XPaths
+ * will be calculated.)
+ */
+ Iterable<String> getKeyXPaths();
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNode.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNode.java
new file mode 100644
index 0000000000..0166f05684
--- /dev/null
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNode.java
@@ -0,0 +1,58 @@
+package org.eclipse.jpt.jaxb.eclipselink.core.context.java;
+
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
+
+/**
+ * Represents an @XmlJoinNode, whether at top level or nested in @XmlJoinNodes
+ * <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.2
+ * @since 3.2
+ */
+public interface ELXmlJoinNode
+ extends JavaContextNode {
+
+ // ***** xmlPath *****
+
+ /**
+ * String associated with changes to the xmlPath property
+ */
+ String XML_PATH_PROPERTY = "xmlPath"; ///$NON-NLS-1$
+
+ /**
+ * Return the xmlPath property value.
+ * A null indicates it is not specified.
+ */
+ String getXmlPath();
+
+ /**
+ * Set the xmlPath property value.
+ * Null unspecifies the value.
+ */
+ void setXmlPath(String value);
+
+
+ // ***** referencedXmlPath *****
+
+ /**
+ * String associated with changes to the referencedXmlPath property
+ */
+ String REFERENCED_XML_PATH_PROPERTY = "referencedXmlPath"; ///$NON-NLS-1$
+
+ /**
+ * Return the referencedXmlPath property value.
+ * A null indicates it is not specified.
+ */
+ String getReferencedXmlPath();
+
+ /**
+ * Set the referencedXmlPath property value.
+ * Null unspecifies the value.
+ */
+ void setReferencedXmlPath(String value);
+}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNodesMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNodesMapping.java
index e65f928ff2..f821fa18fb 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNodesMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/context/java/ELXmlJoinNodesMapping.java
@@ -9,7 +9,9 @@
*******************************************************************************/
package org.eclipse.jpt.jaxb.eclipselink.core.context.java;
+import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
+import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
/**
* Represents an EclipseLink XmlJoinNodes attribute mapping in either
@@ -27,4 +29,25 @@ import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
public interface ELXmlJoinNodesMapping
extends JaxbAttributeMapping {
+
+ // ***** XmlJoinNodes *****
+
+ String XML_JOIN_NODES_LIST = "xmlJoinNodes"; //$NON-NLS-1$
+
+ ListIterable<ELXmlJoinNode> getXmlJoinNodes();
+
+ int getXmlJoinNodesSize();
+
+ ELXmlJoinNode addXmlJoinNode(int index);
+
+ void removeXmlJoinNode(int index);
+
+ void moveXmlJoinNode(int targetIndex, int sourceIndex);
+
+
+ // ***** misc *****
+
+ ELClassMapping getReferencedClassMapping();
+
+ XsdTypeDefinition getReferencedXsdTypeDefinition();
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaClassMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaClassMapping.java
index 2fcc36fcd6..1065f4fd69 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaClassMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaClassMapping.java
@@ -4,12 +4,20 @@ import java.util.List;
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.NotNullFilter;
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.SubIterableWrapper;
+import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
+import org.eclipse.jpt.jaxb.core.MappingKeys;
+import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbClass;
+import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaClassMapping;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELClassMapping;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlDiscriminatorNode;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlDiscriminatorValue;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlNamedNodeMapping;
import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.ELJaxb;
import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.XmlDiscriminatorNodeAnnotation;
import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.XmlDiscriminatorValueAnnotation;
@@ -180,6 +188,43 @@ public class ELJavaClassMapping
}
+ // ***** misc *****
+
+ public Iterable<String> getKeyXPaths() {
+ return new FilteringIterable(
+ new TransformationIterable<ELXmlNamedNodeMapping, String>(getAllKeyMappings()) {
+ @Override
+ protected String transform(ELXmlNamedNodeMapping o) {
+ return o.getXPath();
+ }
+ },
+ NotNullFilter.instance());
+ }
+
+ protected Iterable<ELXmlNamedNodeMapping> getAllKeyMappings() {
+ return new FilteringIterable<ELXmlNamedNodeMapping>(
+ new SubIterableWrapper<JaxbAttributeMapping, ELXmlNamedNodeMapping>(
+ new FilteringIterable<JaxbAttributeMapping>(
+ new TransformationIterable<JaxbPersistentAttribute, JaxbAttributeMapping>(getAllAttributes()) {
+ @Override
+ protected JaxbAttributeMapping transform(JaxbPersistentAttribute o) {
+ return o.getMapping();
+ }
+ }) {
+ @Override
+ protected boolean accept(JaxbAttributeMapping o) {
+ return (o.getKey() == MappingKeys.XML_ELEMENT_ATTRIBUTE_MAPPING_KEY
+ || o.getKey() == MappingKeys.XML_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY);
+ }
+ })) {
+ @Override
+ protected boolean accept(ELXmlNamedNodeMapping o) {
+ return o.getXmlID() != null || o.getXmlKey() != null;
+ }
+ };
+ }
+
+
// ***** content assist *****
@Override
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNode.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNode.java
new file mode 100644
index 0000000000..8c7a989c4a
--- /dev/null
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNode.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.eclipselink.core.internal.context.java;
+
+import java.util.List;
+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.CompositeIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.jaxb.core.JaxbNode;
+import org.eclipse.jpt.jaxb.core.context.JaxbClassMapping;
+import org.eclipse.jpt.jaxb.core.context.JaxbPackage;
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
+import org.eclipse.jpt.jaxb.core.internal.context.java.AbstractJavaContextNode;
+import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELClassMapping;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNode;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNodesMapping;
+import org.eclipse.jpt.jaxb.eclipselink.core.internal.context.xpath.java.XPath;
+import org.eclipse.jpt.jaxb.eclipselink.core.internal.context.xpath.java.XPathFactory;
+import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessageBuilder;
+import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessages;
+import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.XmlJoinNodeAnnotation;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+
+
+public class ELJavaXmlJoinNode
+ extends AbstractJavaContextNode
+ implements ELXmlJoinNode {
+
+ protected String xmlPath;
+
+ protected String referencedXmlPath;
+
+ protected Context context;
+
+
+ public ELJavaXmlJoinNode(JavaContextNode parent, Context context) {
+ super(parent);
+ this.context = context;
+ initXmlPath();
+ initReferencedXmlPath();
+ }
+
+
+ protected JaxbPackage getJaxbPackage() {
+ return getClassMapping().getJaxbType().getJaxbPackage();
+ }
+
+
+ // ***** sync/update *****
+
+ @Override
+ public void synchronizeWithResourceModel() {
+ super.synchronizeWithResourceModel();
+ syncXmlPath();
+ syncReferencedXmlPath();
+ }
+
+
+ // ***** xmlPath *****
+
+ public String getXmlPath() {
+ return this.xmlPath;
+ }
+
+ public void setXmlPath(String xmlPath) {
+ getAnnotation().setXmlPath(xmlPath);
+ setXmlPath_(xmlPath);
+ }
+
+ protected void setXmlPath_(String xmlPath) {
+ String old = this.xmlPath;
+ this.xmlPath = xmlPath;
+ firePropertyChanged(XML_PATH_PROPERTY, old, this.xmlPath);
+ }
+
+ protected void initXmlPath() {
+ this.xmlPath = getAnnotation().getXmlPath();
+ }
+
+ protected void syncXmlPath() {
+ setXmlPath_(getAnnotation().getXmlPath());
+ }
+
+
+ // ***** referencedXmlPath *****
+
+ public String getReferencedXmlPath() {
+ return this.referencedXmlPath;
+ }
+
+ public void setReferencedXmlPath(String referencedXmlPath) {
+ getAnnotation().setReferencedXmlPath(referencedXmlPath);
+ setReferencedXmlPath_(referencedXmlPath);
+ }
+
+ protected void setReferencedXmlPath_(String referencedXmlPath) {
+ String old = this.referencedXmlPath;
+ this.referencedXmlPath = referencedXmlPath;
+ firePropertyChanged(REFERENCED_XML_PATH_PROPERTY, old, this.referencedXmlPath);
+ }
+
+ protected void initReferencedXmlPath() {
+ this.referencedXmlPath = getAnnotation().getReferencedXmlPath();
+ }
+
+ protected void syncReferencedXmlPath() {
+ setReferencedXmlPath_(getAnnotation().getReferencedXmlPath());
+ }
+
+
+ protected XmlJoinNodeAnnotation getAnnotation() {
+ return this.context.getAnnotation();
+ }
+
+ protected ELXmlJoinNodesMapping getAttributeMapping() {
+ return this.context.getAttributeMapping();
+ }
+
+ protected JaxbClassMapping getClassMapping() {
+ return getAttributeMapping().getClassMapping();
+ }
+
+
+ // ***** content assist *****
+
+ @Override
+ public Iterable<String> getJavaCompletionProposals(
+ int pos, Filter<String> filter, CompilationUnit astRoot) {
+
+ if (getAnnotation().xmlPathTouches(pos, astRoot) && this.xmlPath != null) {
+ XsdTypeDefinition xsdType = getClassMapping().getXsdTypeDefinition();
+ XPath xpath = XPathFactory.instance().getXpath(this.xmlPath);
+ return xpath.getCompletionProposals(new XmlPathContext(astRoot), xsdType, pos, filter);
+ }
+
+ if (getAnnotation().referencedXmlPathTouches(pos, astRoot) && this.referencedXmlPath != null) {
+
+
+ XsdTypeDefinition xsdType = getAttributeMapping().getReferencedXsdTypeDefinition();
+ XPath xpath = XPathFactory.instance().getXpath(this.referencedXmlPath);
+ Iterable<String> result = xpath.getCompletionProposals(new ReferencedXmlPathContext(astRoot), xsdType, pos, filter);
+
+ ELClassMapping referencedClassMapping = this.context.getAttributeMapping().getReferencedClassMapping();
+ if (referencedClassMapping != null) {
+ result = new CompositeIterable<String>(
+ result,
+ StringTools.convertToJavaStringLiterals(referencedClassMapping.getKeyXPaths()));
+ }
+
+ return CollectionTools.sortedSet(result);
+ }
+
+ return EmptyIterable.instance();
+ }
+
+
+ // ***** validation *****
+
+ @Override
+ public TextRange getValidationTextRange(CompilationUnit astRoot) {
+ return getAnnotation().getTextRange(astRoot);
+ }
+
+ @Override
+ public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+ super.validate(messages, reporter, astRoot);
+
+ validateXmlPath(messages, astRoot);
+ validateReferencedXmlPath(messages, astRoot);
+ }
+
+ protected void validateXmlPath(List<IMessage> messages, CompilationUnit astRoot) {
+ if (StringTools.stringIsEmpty(this.xmlPath)) {
+ messages.add(
+ ELJaxbValidationMessageBuilder.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ ELJaxbValidationMessages.XML_JOIN_NODE__XML_PATH_NOT_SPECIFIED,
+ ELJavaXmlJoinNode.this,
+ getXmlPathTextRange(astRoot)));
+ return;
+ }
+
+ if (this.xmlPath.startsWith(XPath.DELIM)) {
+ messages.add(
+ ELJaxbValidationMessageBuilder.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ ELJaxbValidationMessages.XPATH__ROOT_NOT_SUPPORTED,
+ ELJavaXmlJoinNode.this,
+ getXmlPathTextRange(astRoot)));
+ return;
+ }
+
+ XsdTypeDefinition xsdType = getClassMapping().getXsdTypeDefinition();
+ XPath xpath = XPathFactory.instance().getXpath(this.xmlPath);
+ xpath.validate(new XmlPathContext(astRoot), xsdType, messages);
+ }
+
+ protected void validateReferencedXmlPath(List<IMessage> messages, CompilationUnit astRoot) {
+ if (StringTools.stringIsEmpty(this.referencedXmlPath)) {
+ messages.add(
+ ELJaxbValidationMessageBuilder.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ ELJaxbValidationMessages.XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_SPECIFIED,
+ ELJavaXmlJoinNode.this,
+ getReferencedXmlPathTextRange(astRoot)));
+ return;
+ }
+
+ if (this.referencedXmlPath.startsWith(XPath.DELIM)) {
+ messages.add(
+ ELJaxbValidationMessageBuilder.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ ELJaxbValidationMessages.XPATH__ROOT_NOT_SUPPORTED,
+ ELJavaXmlJoinNode.this,
+ getReferencedXmlPathTextRange(astRoot)));
+ return;
+ }
+
+ ELClassMapping referencedClassMapping = this.context.getAttributeMapping().getReferencedClassMapping();
+ if (referencedClassMapping != null &&
+ ! CollectionTools.contains(referencedClassMapping.getKeyXPaths(), this.referencedXmlPath)) {
+ messages.add(
+ ELJaxbValidationMessageBuilder.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ ELJaxbValidationMessages.XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_IN_REFERENCED_CLASS_KEYS,
+ new String[] { referencedClassMapping.getJaxbType().getFullyQualifiedName(), this.referencedXmlPath },
+ ELJavaXmlJoinNode.this,
+ getReferencedXmlPathTextRange(astRoot)));
+ }
+
+ XsdTypeDefinition xsdType = getAttributeMapping().getReferencedXsdTypeDefinition();
+ XPath xpath = XPathFactory.instance().getXpath(this.referencedXmlPath);
+ xpath.validate(new ReferencedXmlPathContext(astRoot), xsdType, messages);
+ }
+
+ protected TextRange getXmlPathTextRange(CompilationUnit astRoot) {
+ // should never be null
+ return getAnnotation().getXmlPathTextRange(astRoot);
+ }
+
+ protected TextRange getReferencedXmlPathTextRange(CompilationUnit astRoot) {
+ // should never be null
+ return getAnnotation().getReferencedXmlPathTextRange(astRoot);
+ }
+
+
+ public interface Context {
+
+ XmlJoinNodeAnnotation getAnnotation();
+
+ ELXmlJoinNodesMapping getAttributeMapping();
+ }
+
+
+ protected abstract class XPathContext
+ implements XPath.Context {
+
+ protected CompilationUnit astRoot;
+
+ protected XPathContext(CompilationUnit astRoot) {
+ this.astRoot = astRoot;
+ }
+
+
+ public JaxbNode getContextObject() {
+ return ELJavaXmlJoinNode.this;
+ }
+
+ public JaxbPackage getJaxbPackage() {
+ return ELJavaXmlJoinNode.this.getJaxbPackage();
+ }
+ }
+
+
+ protected class XmlPathContext
+ extends XPathContext {
+
+ protected XmlPathContext(CompilationUnit astRoot) {
+ super(astRoot);
+ }
+
+
+ public TextRange getTextRange() {
+ return ELJavaXmlJoinNode.this.getXmlPathTextRange(this.astRoot);
+ }
+ }
+
+
+ protected class ReferencedXmlPathContext
+ extends XPathContext {
+
+ protected ReferencedXmlPathContext(CompilationUnit astRoot) {
+ super(astRoot);
+ }
+
+
+ public TextRange getTextRange() {
+ return ELJavaXmlJoinNode.this.getReferencedXmlPathTextRange(this.astRoot);
+ }
+ }
+}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNodesMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNodesMapping.java
index 7715ef9dd4..2752036b04 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNodesMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/java/ELJavaXmlJoinNodesMapping.java
@@ -9,20 +9,47 @@
*******************************************************************************/
package org.eclipse.jpt.jaxb.eclipselink.core.internal.context.java;
+import java.util.List;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jpt.common.core.resource.java.Annotation;
+import org.eclipse.jpt.common.core.resource.java.NestableAnnotation;
+import org.eclipse.jpt.common.core.utility.TextRange;
+import org.eclipse.jpt.common.utility.Filter;
+import org.eclipse.jpt.common.utility.internal.Bag;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
+import org.eclipse.jpt.common.utility.internal.HashBag;
+import org.eclipse.jpt.common.utility.internal.StringTools;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.SubListIterableWrapper;
+import org.eclipse.jpt.common.utility.internal.iterables.SuperListIterableWrapper;
+import org.eclipse.jpt.jaxb.core.context.JaxbClassMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
import org.eclipse.jpt.jaxb.core.internal.context.java.AbstractJavaAttributeMapping;
+import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
import org.eclipse.jpt.jaxb.eclipselink.core.ELJaxbMappingKeys;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELClassMapping;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlElementsMapping;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNode;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNodesMapping;
+import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessageBuilder;
+import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessages;
import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.ELJaxb;
+import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.XmlJoinNodeAnnotation;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
public class ELJavaXmlJoinNodesMapping
extends AbstractJavaAttributeMapping
implements ELXmlJoinNodesMapping {
+ protected final ContextListContainer<ELJavaXmlJoinNode, XmlJoinNodeAnnotation> xmlJoinNodeContainer;
+
+
public ELJavaXmlJoinNodesMapping(JaxbPersistentAttribute parent) {
super(parent);
+ this.xmlJoinNodeContainer = buildXmlJoinNodeContainer();
}
@@ -43,4 +70,230 @@ public class ELJavaXmlJoinNodesMapping
return getAnnotation() == null
&& CollectionTools.isEmpty(getPersistentAttribute().getJavaResourceAttribute().getAnnotations(ELJaxb.XML_JOIN_NODE));
}
+
+
+ // ***** sync/update *****
+
+ @Override
+ public void synchronizeWithResourceModel() {
+ super.synchronizeWithResourceModel();
+ this.xmlJoinNodeContainer.synchronizeWithResourceModel();
+ }
+
+ @Override
+ public void update() {
+ super.update();
+ this.xmlJoinNodeContainer.update();
+ }
+
+
+ // ***** xmlJoinNodes *****
+
+ public ListIterable<ELXmlJoinNode> getXmlJoinNodes() {
+ return new SuperListIterableWrapper<ELXmlJoinNode>(this.xmlJoinNodeContainer.getContextElements());
+ }
+
+ public int getXmlJoinNodesSize() {
+ return this.xmlJoinNodeContainer.getContextElementsSize();
+ }
+
+ public ELXmlJoinNode addXmlJoinNode(int index) {
+ XmlJoinNodeAnnotation annotation =
+ (XmlJoinNodeAnnotation) getJavaResourceAttribute().addAnnotation(index, ELJaxb.XML_JOIN_NODE);
+ return this.xmlJoinNodeContainer.addContextElement(index, annotation);
+ }
+
+ public void removeXmlJoinNode(int index) {
+ getJavaResourceAttribute().removeAnnotation(index, ELJaxb.XML_JOIN_NODE);
+ this.xmlJoinNodeContainer.removeContextElement(index);
+ }
+
+ public void moveXmlJoinNode(int targetIndex, int sourceIndex) {
+ getJavaResourceAttribute().moveAnnotation(targetIndex, sourceIndex, ELJaxb.XML_JOIN_NODE);
+ this.xmlJoinNodeContainer.moveContextElement(targetIndex, sourceIndex);
+ }
+
+ protected ELJavaXmlJoinNode buildXmlJoinNode(XmlJoinNodeAnnotation xmlJoinNodeAnnotation) {
+ return new ELJavaXmlJoinNode(this, new XmlJoinNodeContext(xmlJoinNodeAnnotation));
+ }
+
+ protected ContextListContainer<ELJavaXmlJoinNode, XmlJoinNodeAnnotation> buildXmlJoinNodeContainer() {
+ XmlJoinNodeContainer container = new XmlJoinNodeContainer();
+ container.initialize();
+ return container;
+ }
+
+ protected ListIterable<XmlJoinNodeAnnotation> getXmlJoinNodeAnnotations() {
+ return new SubListIterableWrapper<NestableAnnotation, XmlJoinNodeAnnotation>(
+ getJavaResourceAttribute().getAnnotations(ELJaxb.XML_JOIN_NODE));
+ }
+
+
+ // ***** misc *****
+
+ public ELClassMapping getReferencedClassMapping() {
+ String valueType = getValueTypeName();
+ if (StringTools.stringIsEmpty(valueType)) {
+ return null;
+ }
+
+ return (ELClassMapping) getContextRoot().getClassMapping(valueType);
+ }
+
+ public XsdTypeDefinition getReferencedXsdTypeDefinition() {
+ JaxbClassMapping classMapping = getReferencedClassMapping();
+ return (classMapping == null) ? null : classMapping.getXsdTypeDefinition();
+ }
+
+
+ // ***** content assist *****
+
+ @Override
+ public Iterable<String> getJavaCompletionProposals(
+ int pos, Filter<String> filter, CompilationUnit astRoot) {
+
+ Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
+ if (! CollectionTools.isEmpty(result)) {
+ return result;
+ }
+
+ for (ELJavaXmlJoinNode xmlJoinNode : this.xmlJoinNodeContainer.getContextElements()) {
+ result = xmlJoinNode.getJavaCompletionProposals(pos, filter, astRoot);
+ if (! CollectionTools.isEmpty(result)) {
+ return result;
+ }
+ }
+
+ return EmptyIterable.instance();
+ }
+
+
+ // ***** validation *****
+
+ @Override
+ public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+ super.validate(messages, reporter, astRoot);
+
+ JaxbClassMapping referencedClass = getReferencedClassMapping();
+
+ if (referencedClass == null) {
+ messages.add(
+ ELJaxbValidationMessageBuilder.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ ELJaxbValidationMessages.XML_JOIN_NODES__INVALID_REFERENCED_CLASS,
+ new String[] { getValueTypeName() },
+ ELJavaXmlJoinNodesMapping.this,
+ getValidationTextRange(astRoot)));
+ }
+
+ validateDuplicateXmlPaths(messages, reporter, astRoot);
+
+ for (ELJavaXmlJoinNode xmlJoinNode : this.xmlJoinNodeContainer.getContextElements()) {
+ xmlJoinNode.validate(messages, reporter, astRoot);
+ }
+ }
+
+ protected void validateDuplicateXmlPaths(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+ Bag<String> xmlPaths = new HashBag<String>();
+ Bag<String> referencedXmlPaths = new HashBag<String>();
+
+ for (ELJavaXmlJoinNode joinNode : this.xmlJoinNodeContainer.getContextElements()) {
+ String xmlPath = joinNode.getXmlPath();
+ if (! StringTools.stringIsEmpty(xmlPath)) {
+ xmlPaths.add(xmlPath);
+ }
+ String referencedXmlPath = joinNode.getReferencedXmlPath();
+ if (! StringTools.stringIsEmpty(referencedXmlPath)) {
+ referencedXmlPaths.add(referencedXmlPath);
+ }
+ }
+
+ for (ELJavaXmlJoinNode joinNode : this.xmlJoinNodeContainer.getContextElements()) {
+ validateDuplicateXmlPath(joinNode, xmlPaths, messages, astRoot);
+ validateDuplicateReferencedXmlPath(joinNode, referencedXmlPaths, messages, astRoot);
+ }
+ }
+
+ protected void validateDuplicateXmlPath(ELJavaXmlJoinNode joinNode, Bag<String> xmlPaths,
+ List<IMessage> messages, CompilationUnit astRoot) {
+ String xmlPath = joinNode.getXmlPath();
+ if (xmlPaths.count(xmlPath) > 1) {
+ messages.add(
+ ELJaxbValidationMessageBuilder.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ ELJaxbValidationMessages.XML_JOIN_NODES__DUPLICATE_XML_PATH,
+ new String[] { xmlPath },
+ joinNode,
+ joinNode.getXmlPathTextRange(astRoot)));
+ }
+ }
+
+ protected void validateDuplicateReferencedXmlPath(ELJavaXmlJoinNode joinNode, Bag<String> referencedXmlPaths,
+ List<IMessage> messages, CompilationUnit astRoot) {
+ String referencedXmlPath = joinNode.getReferencedXmlPath();
+ if (referencedXmlPaths.count(referencedXmlPath) > 1) {
+ messages.add(
+ ELJaxbValidationMessageBuilder.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ ELJaxbValidationMessages.XML_JOIN_NODES__DUPLICATE_REFERENCED_XML_PATH,
+ new String[] { referencedXmlPath },
+ joinNode,
+ joinNode.getReferencedXmlPathTextRange(astRoot)));
+ }
+ }
+
+ @Override
+ public TextRange getValidationTextRange(CompilationUnit astRoot) {
+ Annotation annotation = getAnnotation();
+ if (annotation == null) {
+ annotation = getJavaResourceAttribute().getAnnotation(0, ELJaxb.XML_JOIN_NODE);
+ }
+ return annotation.getTextRange(astRoot);
+ }
+
+
+ protected class XmlJoinNodeContainer
+ extends ContextListContainer<ELJavaXmlJoinNode, XmlJoinNodeAnnotation> {
+
+ @Override
+ protected String getContextElementsPropertyName() {
+ return ELXmlElementsMapping.XML_PATHS_LIST;
+ }
+
+ @Override
+ protected ELJavaXmlJoinNode buildContextElement(XmlJoinNodeAnnotation resourceElement) {
+ return ELJavaXmlJoinNodesMapping.this.buildXmlJoinNode(resourceElement);
+ }
+
+ @Override
+ protected ListIterable<XmlJoinNodeAnnotation> getResourceElements() {
+ return ELJavaXmlJoinNodesMapping.this.getXmlJoinNodeAnnotations();
+ }
+
+ @Override
+ protected XmlJoinNodeAnnotation getResourceElement(ELJavaXmlJoinNode contextElement) {
+ // in the context of this mapping, there will never be an ELXmlJoinNode without an annotation
+ return contextElement.getAnnotation();
+ }
+ }
+
+
+ protected class XmlJoinNodeContext
+ implements ELJavaXmlJoinNode.Context {
+
+ protected XmlJoinNodeAnnotation annotation;
+
+
+ protected XmlJoinNodeContext(XmlJoinNodeAnnotation annotation) {
+ this.annotation = annotation;
+ }
+
+ public XmlJoinNodeAnnotation getAnnotation() {
+ return this.annotation;
+ }
+
+ public ELXmlJoinNodesMapping getAttributeMapping() {
+ return ELJavaXmlJoinNodesMapping.this;
+ }
+ }
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/xpath/java/XPath.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/xpath/java/XPath.java
index c451848dbe..0415dbb21d 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/xpath/java/XPath.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/context/xpath/java/XPath.java
@@ -52,6 +52,21 @@ public class XPath {
public static char CLOSE_BRACKET = ']';
+ public static String attributeXPath(String prefix, String localName) {
+ if (prefix == null) {
+ return StringTools.concatenate(ATT_PREFIX, localName);
+ }
+ return StringTools.concatenate(ATT_PREFIX, prefix, COLON, localName);
+ }
+
+ public static String elementXPath(String prefix, String localName) {
+ if (prefix == null) {
+ return localName;
+ }
+ return StringTools.concatenate(prefix, COLON, localName);
+ }
+
+
List<Step> steps;
@@ -224,7 +239,7 @@ public class XPath {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
- ELJaxbValidationMessages.XML_PATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT,
+ ELJaxbValidationMessages.XPATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT,
context.getContextObject(),
getTextRange(context)));
return;
@@ -242,7 +257,7 @@ public class XPath {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
- ELJaxbValidationMessages.XML_PATH__UNRESOLVED_ATTRIBUTE,
+ ELJaxbValidationMessages.XPATH__UNRESOLVED_ATTRIBUTE,
new String[] { namespace, this.localName },
context.getContextObject(),
getTextRange(context)));
@@ -292,7 +307,7 @@ public class XPath {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
- ELJaxbValidationMessages.XML_PATH__UNRESOLVED_ELEMENT,
+ ELJaxbValidationMessages.XPATH__UNRESOLVED_ELEMENT,
new String[] { namespace, this.localName },
context.getContextObject(),
getTextRange(context)));
@@ -339,7 +354,7 @@ public class XPath {
messages. add(ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
- ELJaxbValidationMessages.XML_PATH__INVALID_FORM_ILLEGAL_SEGMENT,
+ ELJaxbValidationMessages.XPATH__INVALID_FORM_ILLEGAL_SEGMENT,
new String[] { getValue() },
context.getContextObject(),
getTextRange(context)));
@@ -402,7 +417,7 @@ public class XPath {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
- ELJaxbValidationMessages.XML_PATH__INVALID_NS_PREFIX,
+ ELJaxbValidationMessages.XPATH__INVALID_NS_PREFIX,
new String[] { this.nsPrefix },
context.getContextObject(),
getTextRange(context)));
@@ -451,7 +466,7 @@ public class XPath {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
- ELJaxbValidationMessages.XML_PATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT,
+ ELJaxbValidationMessages.XPATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT,
context.getContextObject(),
getTextRange(context)));
return;
@@ -486,7 +501,7 @@ public class XPath {
new FilteringIterable<String>(
new TransformationIterable<String, String>(
new CompositeIterable<String>(
- new SingleElementIterable(TEXT),
+ getTextProposals(context, previousType),
getAttributeProposals(context, previousType),
getElementProposals(context, previousType))) {
@Override
@@ -506,6 +521,10 @@ public class XPath {
return new SingleElementIterable(TEXT);
}
+ protected Iterable<String> getTextProposals(Context context, final XsdTypeDefinition xsdType) {
+ return (xsdType.hasTextContent()) ? new SingleElementIterable(TEXT) : EmptyIterable.instance();
+ }
+
protected Iterable<String> getAttributeProposals(Context context, final XsdTypeDefinition xsdType) {
return new CompositeIterable<String>(
new CompositeIterable<String>(
@@ -515,7 +534,7 @@ public class XPath {
return new TransformationIterable<String, String>(xsdType.getAttributeNames(xmlns.getNamespaceURI())) {
@Override
protected String transform(String o) {
- return StringTools.concatenate(ATT_PREFIX, xmlns.getPrefix(), COLON, o);
+ return XPath.attributeXPath(xmlns.getPrefix(), o);
}
};
}
@@ -523,7 +542,7 @@ public class XPath {
new TransformationIterable<String, String>(xsdType.getAttributeNames("")) {
@Override
protected String transform(String o) {
- return StringTools.concatenate(ATT_PREFIX, o);
+ return XPath.attributeXPath(null, o);
}
});
}
@@ -537,7 +556,7 @@ public class XPath {
return new TransformationIterable<String, String>(xsdType.getElementNames(xmlns.getNamespaceURI(), false)) {
@Override
protected String transform(String o) {
- return StringTools.concatenate(xmlns.getPrefix(), COLON, o);
+ return XPath.elementXPath(xmlns.getPrefix(), o);
}
};
}
@@ -587,7 +606,7 @@ public class XPath {
messages.add(
ELJaxbValidationMessageBuilder.buildMessage(
IMessage.HIGH_SEVERITY,
- ELJaxbValidationMessages.XML_PATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT,
+ ELJaxbValidationMessages.XPATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT,
context.getContextObject(),
getTextRange(context)));
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/validation/ELJaxbValidationMessages.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/validation/ELJaxbValidationMessages.java
index 45f25e7d65..cbf6e5780e 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/validation/ELJaxbValidationMessages.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/internal/validation/ELJaxbValidationMessages.java
@@ -20,21 +20,20 @@ public interface ELJaxbValidationMessages {
String PROJECT_MISSING_ECLIPSELINK_JAXB_CONTEXT_FACTORY = "PROJECT_MISSING_ECLIPSELINK_JAXB_CONTEXT_FACTORY";
String XML_DISCRIMINATOR_NODE__NOT_SPECIFIED = "XML_DISCRIMINATOR_NODE__NOT_SPECIFIED";
- String XML_DISCRIMINATOR_NODE__ROOT_NOT_SUPPORTED = "XML_DISCRIMINATOR_NODE__ROOT_NOT_SUPPORTED";
String XML_DISCRIMINATOR_VALUE__NOT_SPECIFIED = "XML_DISCRIMINATOR_VALUE__NOT_SPECIFIED";
String XML_ELEMENT_DECL__INVALID_METHOD_SIGNATURE_RETURN_TYPE = "XML_ELEMENT_DECL__INVALID_METHOD_SIGNATURE_RETURN_TYPE";
+ String XML_JOIN_NODE__XML_PATH_NOT_SPECIFIED = "XML_JOIN_NODE__XML_PATH_NOT_SPECIFIED";
+ String XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_SPECIFIED = "XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_SPECIFIED";
+ String XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_IN_REFERENCED_CLASS_KEYS = "XML_JOIN_NODE__REFERENCED_XML_PATH_NOT_IN_REFERENCED_CLASS_KEYS";
+
+ String XML_JOIN_NODES__INVALID_REFERENCED_CLASS = "XML_JOIN_NODES__INVALID_REFERENCED_CLASS";
+ String XML_JOIN_NODES__DUPLICATE_XML_PATH = "XML_JOIN_NODES__DUPLICATE_XML_PATH";
+ String XML_JOIN_NODES__DUPLICATE_REFERENCED_XML_PATH = "XML_JOIN_NODES__DUPLICATE_REFERENCED_XML_PATH";
+
String XML_PATH__NOT_SPECIFIED = "XML_PATH__NOT_SPECIFIED";
- String XML_PATH__ROOT_NOT_SUPPORTED = "XML_PATH__ROOT_NOT_SUPPORTED";
- String XML_PATH__INVALID_FORM_ILLEGAL_SEGMENT = "XML_PATH__INVALID_FORM_ILLEGAL_SEGMENT";
- String XML_PATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT = "XML_PATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT";
- String XML_PATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT = "XML_PATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT";
- String XML_PATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT = "XML_PATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT";
- String XML_PATH__INVALID_NS_PREFIX = "XML_PATH__INVALID_NS_PREFIX";
- String XML_PATH__UNRESOLVED_ELEMENT = "XML_PATH__UNRESOLVED_ELEMENT";
- String XML_PATH__UNRESOLVED_ATTRIBUTE = "XML_PATH__UNRESOLVED_ATTRIBUTE";
// used on XmlElements mapping
String XML_PATH__INSUFFICIENT_XML_PATHS_FOR_XML_ELEMENTS = "XML_PATH__INSUFFICIENT_XML_PATHS_FOR_XML_ELEMENTS";
@@ -43,4 +42,14 @@ public interface ELJaxbValidationMessages {
String XML_INVERSE_REFERENCE__MAPPED_BY_NOT_SPECIFIED = "XML_INVERSE_REFERENCE__MAPPED_BY_NOT_SPECIFIED";
String XML_INVERSE_REFERENCE__MAPPED_BY_NOT_RESOLVED = "XML_INVERSE_REFERENCE__MAPPED_BY_NOT_RESOLVED";
String XML_INVERSE_REFERENCE__MAPPED_BY_ILLEGAL_MAPPING_TYPE = "XML_INVERSE_REFERENCE__MAPPED_BY_ILLEGAL_MAPPING_TYPE";
+
+ // for all XPath usage
+ String XPATH__INVALID_FORM_ILLEGAL_SEGMENT = "XPATH__INVALID_FORM_ILLEGAL_SEGMENT";
+ String XPATH__ROOT_NOT_SUPPORTED = "XPATH__ROOT_NOT_SUPPORTED";
+ String XPATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT = "XPATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT";
+ String XPATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT = "XPATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT";
+ String XPATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT = "XPATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT";
+ String XPATH__INVALID_NS_PREFIX = "XPATH__INVALID_NS_PREFIX";
+ String XPATH__UNRESOLVED_ELEMENT = "XPATH__UNRESOLVED_ELEMENT";
+ String XPATH__UNRESOLVED_ATTRIBUTE = "XPATH__UNRESOLVED_ATTRIBUTE";
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/resource/java/XmlJoinNodeAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/resource/java/XmlJoinNodeAnnotation.java
index 1b4b37c6f3..7e8ff12345 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/resource/java/XmlJoinNodeAnnotation.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.eclipselink.core/src/org/eclipse/jpt/jaxb/eclipselink/core/resource/java/XmlJoinNodeAnnotation.java
@@ -53,6 +53,12 @@ public interface XmlJoinNodeAnnotation
TextRange getXmlPathTextRange(CompilationUnit astRoot);
/**
+ * Return whether the specified text position is within the 'xmlPath' element.
+ */
+ boolean xmlPathTouches(int pos, CompilationUnit astRoot);
+
+
+ /**
* String associated with change events to the 'referencedXmlPath' property
*/
String REFERENCED_XML_PATH_PROPERTY = "referencedXmlPath"; //$NON-NLS-1$
@@ -74,4 +80,9 @@ public interface XmlJoinNodeAnnotation
* Return the text range of this annotation if the element is absent.
*/
TextRange getReferencedXmlPathTextRange(CompilationUnit astRoot);
+
+ /**
+ * Return whether the specified text position is within the 'referencedXmlPath' element.
+ */
+ boolean referencedXmlPathTouches(int pos, CompilationUnit astRoot);
}
diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJavaXmlJoinNodeTests.java b/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJavaXmlJoinNodeTests.java
new file mode 100644
index 0000000000..0cbe7d3f3e
--- /dev/null
+++ b/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJavaXmlJoinNodeTests.java
@@ -0,0 +1,209 @@
+package org.eclipse.jpt.jaxb.eclipselink.core.tests.internal.context.java;
+
+import java.util.Iterator;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jpt.common.core.resource.java.JavaResourceAttribute;
+import org.eclipse.jpt.common.core.utility.jdt.AnnotatedElement;
+import org.eclipse.jpt.common.core.utility.jdt.Member;
+import org.eclipse.jpt.common.core.utility.jdt.ModifiedDeclaration;
+import org.eclipse.jpt.common.utility.internal.CollectionTools;
+import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator;
+import org.eclipse.jpt.jaxb.core.context.JaxbClass;
+import org.eclipse.jpt.jaxb.core.context.JaxbClassMapping;
+import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
+import org.eclipse.jpt.jaxb.core.platform.JaxbPlatformDescription;
+import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
+import org.eclipse.jpt.jaxb.eclipselink.core.ELJaxbPlatform;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNode;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNodesMapping;
+import org.eclipse.jpt.jaxb.eclipselink.core.internal.context.java.ELJavaXmlJoinNodesMapping;
+import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.ELJaxb;
+import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.XmlJoinNodeAnnotation;
+import org.eclipse.jpt.jaxb.eclipselink.core.tests.internal.context.ELJaxbContextModelTestCase;
+
+
+public class ELJavaXmlJoinNodeTests
+ extends ELJaxbContextModelTestCase {
+
+ public ELJavaXmlJoinNodeTests(String name) {
+ super(name);
+ }
+
+
+ @Override
+ protected JaxbPlatformDescription getPlatform() {
+ return ELJaxbPlatform.VERSION_2_2;
+ }
+
+ private ICompilationUnit createTypeWithXmlJoinNode() throws Exception {
+ return this.createTestType(new DefaultAnnotationWriter() {
+ @Override
+ public Iterator<String> imports() {
+ return new ArrayIterator<String>(JAXB.XML_TYPE, ELJaxb.XML_JOIN_NODE);
+ }
+
+ @Override
+ public void appendTypeAnnotationTo(StringBuilder sb) {
+ sb.append("@XmlType");
+ }
+
+ @Override
+ public void appendIdFieldAnnotationTo(StringBuilder sb) {
+ sb.append("@XmlJoinNode");
+ }
+ });
+ }
+
+
+ public void testModifyXmlPath() throws Exception {
+ createTypeWithXmlJoinNode();
+
+ JaxbClass jaxbClass = (JaxbClass) CollectionTools.get(getContextRoot().getTypes(), 0);
+ JaxbClassMapping classMapping = jaxbClass.getMapping();
+ JaxbPersistentAttribute persistentAttribute = CollectionTools.get(classMapping.getAttributes(), 0);
+ ELXmlJoinNodesMapping mapping = (ELXmlJoinNodesMapping) persistentAttribute.getMapping();
+ JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
+ ELXmlJoinNode xmlJoinNode = CollectionTools.get(mapping.getXmlJoinNodes(), 0);
+ XmlJoinNodeAnnotation annotation = (XmlJoinNodeAnnotation) resourceAttribute.getAnnotation(0, ELJaxb.XML_JOIN_NODE);
+
+ assertNull(annotation.getXmlPath());
+ assertNull(xmlJoinNode.getXmlPath());
+
+ xmlJoinNode.setXmlPath("foo");
+
+ assertEquals("foo", annotation.getXmlPath());
+ assertEquals("foo", xmlJoinNode.getXmlPath());
+
+ xmlJoinNode.setXmlPath("");
+
+ assertEquals("", annotation.getXmlPath());
+ assertEquals("", xmlJoinNode.getXmlPath());
+
+ xmlJoinNode.setXmlPath(null);
+
+ assertNull(annotation.getXmlPath());
+ assertNull(xmlJoinNode.getXmlPath());
+ }
+
+ public void testUpdateXmlPath() throws Exception {
+ createTypeWithXmlJoinNode();
+
+ JaxbClass jaxbClass = (JaxbClass) CollectionTools.get(getContextRoot().getTypes(), 0);
+ JaxbClassMapping classMapping = jaxbClass.getMapping();
+ JaxbPersistentAttribute persistentAttribute = CollectionTools.get(classMapping.getAttributes(), 0);
+ ELJavaXmlJoinNodesMapping mapping = (ELJavaXmlJoinNodesMapping) persistentAttribute.getMapping();
+ JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
+ ELXmlJoinNode xmlJoinNode = CollectionTools.get(mapping.getXmlJoinNodes(), 0);
+ XmlJoinNodeAnnotation annotation = (XmlJoinNodeAnnotation) resourceAttribute.getAnnotation(0, ELJaxb.XML_JOIN_NODE);
+
+ assertNull(annotation.getXmlPath());
+ assertNull(xmlJoinNode.getXmlPath());
+
+ AnnotatedElement annotatedElement = this.annotatedElement(resourceAttribute);
+ annotatedElement.edit(new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodeTests.this.setMemberValuePair(
+ declaration, ELJaxb.XML_JOIN_NODE, ELJaxb.XML_JOIN_NODE__XML_PATH, "foo");
+ }
+ });
+
+ assertEquals("foo", annotation.getXmlPath());
+ assertEquals("foo", xmlJoinNode.getXmlPath());
+
+ annotatedElement.edit(new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodeTests.this.setMemberValuePair(
+ declaration, ELJaxb.XML_JOIN_NODE, ELJaxb.XML_JOIN_NODE__XML_PATH, "");
+ }
+ });
+
+ assertEquals("", annotation.getXmlPath());
+ assertEquals("", xmlJoinNode.getXmlPath());
+
+ annotatedElement.edit(new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodeTests.this.removeMemberValuePair(
+ declaration, ELJaxb.XML_JOIN_NODE, ELJaxb.XML_JOIN_NODE__XML_PATH);
+ }
+ });
+
+ assertNull(annotation.getXmlPath());
+ assertNull(xmlJoinNode.getXmlPath());
+ }
+
+ public void testModifyReferencedXmlPath() throws Exception {
+ createTypeWithXmlJoinNode();
+
+ JaxbClass jaxbClass = (JaxbClass) CollectionTools.get(getContextRoot().getTypes(), 0);
+ JaxbClassMapping classMapping = jaxbClass.getMapping();
+ JaxbPersistentAttribute persistentAttribute = CollectionTools.get(classMapping.getAttributes(), 0);
+ ELXmlJoinNodesMapping mapping = (ELXmlJoinNodesMapping) persistentAttribute.getMapping();
+ JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
+ ELXmlJoinNode xmlJoinNode = CollectionTools.get(mapping.getXmlJoinNodes(), 0);
+ XmlJoinNodeAnnotation annotation = (XmlJoinNodeAnnotation) resourceAttribute.getAnnotation(0, ELJaxb.XML_JOIN_NODE);
+
+ assertNull(annotation.getReferencedXmlPath());
+ assertNull(xmlJoinNode.getReferencedXmlPath());
+
+ xmlJoinNode.setReferencedXmlPath("foo");
+
+ assertEquals("foo", annotation.getReferencedXmlPath());
+ assertEquals("foo", xmlJoinNode.getReferencedXmlPath());
+
+ xmlJoinNode.setReferencedXmlPath("");
+
+ assertEquals("", annotation.getReferencedXmlPath());
+ assertEquals("", xmlJoinNode.getReferencedXmlPath());
+
+ xmlJoinNode.setReferencedXmlPath(null);
+
+ assertNull(annotation.getReferencedXmlPath());
+ assertNull(xmlJoinNode.getReferencedXmlPath());
+ }
+
+ public void testUpdateReferencedXmlPath() throws Exception {
+ createTypeWithXmlJoinNode();
+
+ JaxbClass jaxbClass = (JaxbClass) CollectionTools.get(getContextRoot().getTypes(), 0);
+ JaxbClassMapping classMapping = jaxbClass.getMapping();
+ JaxbPersistentAttribute persistentAttribute = CollectionTools.get(classMapping.getAttributes(), 0);
+ ELJavaXmlJoinNodesMapping mapping = (ELJavaXmlJoinNodesMapping) persistentAttribute.getMapping();
+ JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
+ ELXmlJoinNode xmlJoinNode = CollectionTools.get(mapping.getXmlJoinNodes(), 0);
+ XmlJoinNodeAnnotation annotation = (XmlJoinNodeAnnotation) resourceAttribute.getAnnotation(0, ELJaxb.XML_JOIN_NODE);
+
+ assertNull(annotation.getReferencedXmlPath());
+ assertNull(xmlJoinNode.getReferencedXmlPath());
+
+ AnnotatedElement annotatedElement = this.annotatedElement(resourceAttribute);
+ annotatedElement.edit(new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodeTests.this.setMemberValuePair(
+ declaration, ELJaxb.XML_JOIN_NODE, ELJaxb.XML_JOIN_NODE__REFERENCED_XML_PATH, "foo");
+ }
+ });
+
+ assertEquals("foo", annotation.getReferencedXmlPath());
+ assertEquals("foo", xmlJoinNode.getReferencedXmlPath());
+
+ annotatedElement.edit(new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodeTests.this.setMemberValuePair(
+ declaration, ELJaxb.XML_JOIN_NODE, ELJaxb.XML_JOIN_NODE__REFERENCED_XML_PATH, "");
+ }
+ });
+
+ assertEquals("", annotation.getReferencedXmlPath());
+ assertEquals("", xmlJoinNode.getReferencedXmlPath());
+
+ annotatedElement.edit(new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodeTests.this.removeMemberValuePair(
+ declaration, ELJaxb.XML_JOIN_NODE, ELJaxb.XML_JOIN_NODE__REFERENCED_XML_PATH);
+ }
+ });
+
+ assertNull(annotation.getReferencedXmlPath());
+ assertNull(xmlJoinNode.getReferencedXmlPath());
+ }
+} \ No newline at end of file
diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJavaXmlJoinNodesMappingTests.java b/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJavaXmlJoinNodesMappingTests.java
new file mode 100644
index 0000000000..ce0559ae6a
--- /dev/null
+++ b/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJavaXmlJoinNodesMappingTests.java
@@ -0,0 +1,197 @@
+package org.eclipse.jpt.jaxb.eclipselink.core.tests.internal.context.java;
+
+import java.util.Iterator;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.NormalAnnotation;
+import org.eclipse.jpt.common.core.resource.java.JavaResourceAttribute;
+import org.eclipse.jpt.common.core.utility.jdt.AnnotatedElement;
+import org.eclipse.jpt.common.core.utility.jdt.Member;
+import org.eclipse.jpt.common.core.utility.jdt.ModifiedDeclaration;
+import org.eclipse.jpt.common.utility.internal.CollectionTools;
+import org.eclipse.jpt.common.utility.internal.iterables.SubIterableWrapper;
+import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator;
+import org.eclipse.jpt.jaxb.core.context.JaxbClass;
+import org.eclipse.jpt.jaxb.core.context.JaxbClassMapping;
+import org.eclipse.jpt.jaxb.core.platform.JaxbPlatformDescription;
+import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
+import org.eclipse.jpt.jaxb.eclipselink.core.ELJaxbPlatform;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNode;
+import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlJoinNodesMapping;
+import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.ELJaxb;
+import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.XmlJoinNodeAnnotation;
+import org.eclipse.jpt.jaxb.eclipselink.core.tests.internal.context.ELJaxbContextModelTestCase;
+
+
+public class ELJavaXmlJoinNodesMappingTests
+ extends ELJaxbContextModelTestCase {
+
+ public ELJavaXmlJoinNodesMappingTests(String name) {
+ super(name);
+ }
+
+
+ @Override
+ protected JaxbPlatformDescription getPlatform() {
+ return ELJaxbPlatform.VERSION_2_2;
+ }
+
+ private ICompilationUnit createTypeWithXmlJoinNodes() throws Exception {
+ return this.createTestType(new DefaultAnnotationWriter() {
+ @Override
+ public Iterator<String> imports() {
+ return new ArrayIterator<String>(JAXB.XML_TYPE, ELJaxb.XML_JOIN_NODES);
+ }
+
+ @Override
+ public void appendTypeAnnotationTo(StringBuilder sb) {
+ sb.append("@XmlType");
+ }
+
+ @Override
+ public void appendIdFieldAnnotationTo(StringBuilder sb) {
+ sb.append("@XmlJoinNodes");
+ }
+ });
+ }
+
+ protected NormalAnnotation newXmlJoinNodeAnnotation(AST ast, String xmlPath, String referencedXmlPath) {
+ NormalAnnotation annotation = newNormalAnnotation(ast, ELJaxb.XML_JOIN_NODE);
+ addMemberValuePair(annotation, ELJaxb.XML_JOIN_NODE__XML_PATH, xmlPath);
+ addMemberValuePair(annotation, ELJaxb.XML_JOIN_NODE__REFERENCED_XML_PATH, referencedXmlPath);
+ return annotation;
+ }
+
+ protected void addXmlJoinNode(ModifiedDeclaration declaration, int index, String xmlPath, String referencedXmlPath) {
+ NormalAnnotation annotation = newXmlJoinNodeAnnotation(declaration.getAst(), xmlPath, referencedXmlPath);
+ addArrayElement(declaration, ELJaxb.XML_JOIN_NODES, index, "value", annotation);
+ }
+
+ protected void moveXmlJoinNode(ModifiedDeclaration declaration, int targetIndex, int sourceIndex) {
+ moveArrayElement((NormalAnnotation) declaration.getAnnotationNamed(ELJaxb.XML_JOIN_NODES), "value", targetIndex, sourceIndex);
+ }
+
+ protected void removeXmlJoinNode(ModifiedDeclaration declaration, int index) {
+ removeArrayElement((NormalAnnotation) declaration.getAnnotationNamed(ELJaxb.XML_JOIN_NODES), "value", index);
+ }
+
+
+ public void testUpdateXmlJoinNodes() throws Exception {
+ createTypeWithXmlJoinNodes();
+ JaxbClass jaxbClass = (JaxbClass) CollectionTools.get(getContextRoot().getTypes(), 0);
+ JaxbClassMapping classMapping = jaxbClass.getMapping();
+ ELXmlJoinNodesMapping mapping = (ELXmlJoinNodesMapping) CollectionTools.get(classMapping.getAttributes(), 0).getMapping();
+ JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
+
+ Iterable<ELXmlJoinNode> xmlJoinNodes = mapping.getXmlJoinNodes();
+ assertTrue(CollectionTools.isEmpty(xmlJoinNodes));
+ assertEquals(0, mapping.getXmlJoinNodesSize());
+
+ //add 2 XmlJoinNode annotations
+ AnnotatedElement annotatedElement = annotatedElement(resourceAttribute);
+ annotatedElement.edit(
+ new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodesMappingTests.this.addXmlJoinNode(declaration, 0, "foo", "@foo");
+ ELJavaXmlJoinNodesMappingTests.this.addXmlJoinNode(declaration, 1, "bar", "@bar");
+ }
+ });
+
+ xmlJoinNodes = mapping.getXmlJoinNodes();
+
+ assertFalse(CollectionTools.isEmpty(xmlJoinNodes));
+ assertEquals(2, mapping.getXmlJoinNodesSize());
+ assertEquals("foo", CollectionTools.get(xmlJoinNodes, 0).getXmlPath());
+ assertEquals("@foo", CollectionTools.get(xmlJoinNodes, 0).getReferencedXmlPath());
+ assertEquals("bar", CollectionTools.get(xmlJoinNodes, 1).getXmlPath());
+ assertEquals("@bar", CollectionTools.get(xmlJoinNodes, 1).getReferencedXmlPath());
+
+ // switch XmlJoinNode annotations
+ annotatedElement.edit(
+ new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodesMappingTests.this.moveXmlJoinNode(declaration, 0, 1);
+ }
+ });
+
+ xmlJoinNodes = mapping.getXmlJoinNodes();
+
+ assertFalse(CollectionTools.isEmpty(xmlJoinNodes));
+ assertEquals(2, mapping.getXmlJoinNodesSize());
+ assertEquals("bar", CollectionTools.get(xmlJoinNodes, 0).getXmlPath());
+ assertEquals("@bar", CollectionTools.get(xmlJoinNodes, 0).getReferencedXmlPath());
+ assertEquals("foo", CollectionTools.get(xmlJoinNodes, 1).getXmlPath());
+ assertEquals("@foo", CollectionTools.get(xmlJoinNodes, 1).getReferencedXmlPath());
+
+ // remove XmlJoinNode annotations
+ annotatedElement.edit(
+ new Member.Editor() {
+ public void edit(ModifiedDeclaration declaration) {
+ ELJavaXmlJoinNodesMappingTests.this.removeXmlJoinNode(declaration, 1);
+ ELJavaXmlJoinNodesMappingTests.this.removeXmlJoinNode(declaration, 0);
+ }
+ });
+
+ xmlJoinNodes = mapping.getXmlJoinNodes();
+
+ assertTrue(CollectionTools.isEmpty(xmlJoinNodes));
+ assertEquals(0, mapping.getXmlJoinNodesSize());
+ }
+
+ public void testModifyXmlJoinNodes() throws Exception {
+ createTypeWithXmlJoinNodes();
+ JaxbClass jaxbClass = (JaxbClass) CollectionTools.get(getContextRoot().getTypes(), 0);
+ JaxbClassMapping classMapping = jaxbClass.getMapping();
+ ELXmlJoinNodesMapping mapping = (ELXmlJoinNodesMapping) CollectionTools.get(classMapping.getAttributes(), 0).getMapping();
+ JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
+
+ assertEquals(0, resourceAttribute.getAnnotationsSize(ELJaxb.XML_JOIN_NODE));
+ assertEquals(0, mapping.getXmlJoinNodesSize());
+
+ ELXmlJoinNode joinNode = mapping.addXmlJoinNode(0);
+ joinNode.setXmlPath("foo");
+ joinNode.setReferencedXmlPath("@foo");
+ joinNode = mapping.addXmlJoinNode(1);
+ joinNode.setXmlPath("baz");
+ joinNode.setReferencedXmlPath("@baz");
+ joinNode = mapping.addXmlJoinNode(1);
+ joinNode.setXmlPath("bar");
+ joinNode.setReferencedXmlPath("@bar");
+
+ Iterable<XmlJoinNodeAnnotation> xmlJoinNodeAnnotations =
+ new SubIterableWrapper(resourceAttribute.getAnnotations(ELJaxb.XML_JOIN_NODE));
+
+ assertEquals(3, CollectionTools.size(xmlJoinNodeAnnotations));
+ assertEquals(3, mapping.getXmlJoinNodesSize());
+ assertEquals("foo", CollectionTools.get(xmlJoinNodeAnnotations, 0).getXmlPath());
+ assertEquals("@foo", CollectionTools.get(xmlJoinNodeAnnotations, 0).getReferencedXmlPath());
+ assertEquals("bar", CollectionTools.get(xmlJoinNodeAnnotations, 1).getXmlPath());
+ assertEquals("@bar", CollectionTools.get(xmlJoinNodeAnnotations, 1).getReferencedXmlPath());
+ assertEquals("baz", CollectionTools.get(xmlJoinNodeAnnotations, 2).getXmlPath());
+ assertEquals("@baz", CollectionTools.get(xmlJoinNodeAnnotations, 2).getReferencedXmlPath());
+
+ mapping.moveXmlJoinNode(1, 2);
+
+ xmlJoinNodeAnnotations =
+ new SubIterableWrapper(resourceAttribute.getAnnotations(ELJaxb.XML_JOIN_NODE));
+
+ assertEquals(3, CollectionTools.size(xmlJoinNodeAnnotations));
+ assertEquals(3, mapping.getXmlJoinNodesSize());
+ assertEquals("foo", CollectionTools.get(xmlJoinNodeAnnotations, 0).getXmlPath());
+ assertEquals("@foo", CollectionTools.get(xmlJoinNodeAnnotations, 0).getReferencedXmlPath());
+ assertEquals("baz", CollectionTools.get(xmlJoinNodeAnnotations, 1).getXmlPath());
+ assertEquals("@baz", CollectionTools.get(xmlJoinNodeAnnotations, 1).getReferencedXmlPath());
+ assertEquals("bar", CollectionTools.get(xmlJoinNodeAnnotations, 2).getXmlPath());
+ assertEquals("@bar", CollectionTools.get(xmlJoinNodeAnnotations, 2).getReferencedXmlPath());
+
+ mapping.removeXmlJoinNode(2);
+ mapping.removeXmlJoinNode(0);
+ mapping.removeXmlJoinNode(0);
+
+ xmlJoinNodeAnnotations =
+ new SubIterableWrapper(resourceAttribute.getAnnotations(ELJaxb.XML_JOIN_NODE));
+
+ assertEquals(0, CollectionTools.size(xmlJoinNodeAnnotations));
+ assertEquals(0, mapping.getXmlJoinNodesSize());
+ }
+}
diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJaxbCoreJavaContextModelTests.java b/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJaxbCoreJavaContextModelTests.java
index aa4e37152c..29bc7f62f8 100644
--- a/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJaxbCoreJavaContextModelTests.java
+++ b/jaxb/tests/org.eclipse.jpt.jaxb.eclipselink.core.tests/src/org/eclipse/jpt/jaxb/eclipselink/core/tests/internal/context/java/ELJaxbCoreJavaContextModelTests.java
@@ -28,7 +28,10 @@ public class ELJaxbCoreJavaContextModelTests
suite.addTestSuite(ELJavaXmlElementMappingTests.class);
suite.addTestSuite(ELJavaXmlElementsMappingTests.class);
suite.addTestSuite(ELJavaXmlInverseReferenceMappingTests.class);
+ suite.addTestSuite(ELJavaXmlJoinNodesMappingTests.class);
+ suite.addTestSuite(ELJavaXmlJoinNodeTests.class);
suite.addTestSuite(ELJavaXmlPathTests.class);
+ suite.addTestSuite(ELJavaXmlValueMappingTests.class);
return suite;
}

Back to the top