XmlEnumValue validation and content assist
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jaxb_validation.properties b/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jaxb_validation.properties
index 8d38751..6c655ec 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jaxb_validation.properties
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jaxb_validation.properties
@@ -30,6 +30,8 @@
XML_ROOT_ELEMENT_TYPE_CONFLICTS_WITH_XML_TYPE = The xml type of the element declaration with name ''{0}'' and namespace ''{1}'' conflicts with the xml type of the associated class
+XML_ENUM_VALUE__INVALID_LEXICAL_VALUE = Invalid lexical value \"{0}\" for schema type ''{1}''.
+
ATTRIBUTE_MAPPING__UNSUPPORTED_ANNOTATION = The annotation ''{0}'' is not allowed to be used in conjunction with ''{1}''.
ATTRIBUTE_MAPPING_XML_JAVA_TYPE_ADAPTER_TYPE_NOT_DEFINED = The type for XML Java type adapter is not defined.
XML_ELEMENT_WRAPPER_DEFINED_ON_NON_ARRAY_NON_COLLECTION = An XML element wrapper may only be defined on a collection or array property
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbEnumConstant.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbEnumConstant.java
index 3914128..f84439f 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbEnumConstant.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbEnumConstant.java
@@ -10,6 +10,7 @@
package org.eclipse.jpt.jaxb.core.context;
import org.eclipse.jpt.common.core.resource.java.JavaResourceEnumConstant;
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
/**
* Represents a JAXB enum constant.
@@ -25,7 +26,7 @@
* @since 3.0
*/
public interface JaxbEnumConstant
- extends JaxbContextNode {
+ extends JavaContextNode {
JavaResourceEnumConstant getResourceEnumConstant();
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbEnumMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbEnumMapping.java
index 68ce328..7d3b1db 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbEnumMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbEnumMapping.java
@@ -9,6 +9,8 @@
*******************************************************************************/
package org.eclipse.jpt.jaxb.core.context;
+import org.eclipse.jpt.jaxb.core.xsd.XsdSimpleTypeDefinition;
+
/**
* Represents mapping metadata on an enum (specified or implied).
* <p>
@@ -54,5 +56,10 @@
Iterable<JaxbEnumConstant> getEnumConstants();
- int getEnumConstantsSize();
+ int getEnumConstantsSize();
+
+
+ // ***** misc *****
+
+ XsdSimpleTypeDefinition getValueXsdTypeDefinition();
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaEnumConstant.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaEnumConstant.java
index ff13847..fcfebe0 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaEnumConstant.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaEnumConstant.java
@@ -9,15 +9,26 @@
******************************************************************************/
package org.eclipse.jpt.jaxb.core.internal.context.java;
+import java.util.List;
+import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.resource.java.JavaResourceEnumConstant;
+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.iterables.EmptyIterable;
import org.eclipse.jpt.jaxb.core.context.JaxbEnumConstant;
import org.eclipse.jpt.jaxb.core.context.JaxbEnumMapping;
-import org.eclipse.jpt.jaxb.core.internal.context.AbstractJaxbContextNode;
+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.JAXB;
import org.eclipse.jpt.jaxb.core.resource.java.XmlEnumValueAnnotation;
+import org.eclipse.jpt.jaxb.core.xsd.XsdSimpleTypeDefinition;
+import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
public class GenericJavaEnumConstant
- extends AbstractJaxbContextNode
+ extends AbstractJavaContextNode
implements JaxbEnumConstant {
final protected JavaResourceEnumConstant resourceEnumConstant;
@@ -29,7 +40,12 @@
this.resourceEnumConstant = resourceEnumConstant;
this.specifiedValue = this.getResourceEnumValue();
}
-
+
+
+ protected JaxbEnumMapping getEnumMapping() {
+ return (JaxbEnumMapping) getParent();
+ }
+
public JavaResourceEnumConstant getResourceEnumConstant() {
return this.resourceEnumConstant;
}
@@ -85,4 +101,63 @@
protected String getResourceEnumValue() {
return this.getXmlEnumValueAnnotation().getValue();
}
+
+
+ // ***** 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;
+ }
+
+ if (valueTouches(pos, astRoot)) {
+ XsdTypeDefinition xsdType = getEnumMapping().getXsdTypeDefinition();
+ if (xsdType != null && xsdType.getKind() == XsdTypeDefinition.Kind.SIMPLE) {
+ XsdSimpleTypeDefinition xsdSimpleType = (XsdSimpleTypeDefinition) xsdType;
+ return xsdSimpleType.getEnumValueProposals(filter);
+ }
+ }
+
+ return EmptyIterable.instance();
+ }
+
+ protected boolean valueTouches(int pos, CompilationUnit astRoot) {
+ return getXmlEnumValueAnnotation().valueTouches(pos, astRoot);
+ }
+
+
+ // ***** validation *****
+
+ @Override
+ public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+ super.validate(messages, reporter, astRoot);
+
+ String value = getValue();
+ XsdTypeDefinition xsdType = getEnumMapping().getXsdTypeDefinition();
+
+ if (xsdType == null || xsdType.getKind() != XsdTypeDefinition.Kind.SIMPLE) {
+ return;
+ }
+
+ if (! ((XsdSimpleTypeDefinition) xsdType).getXSDComponent().isValidLiteral(value)) {
+ messages.add(
+ DefaultValidationMessages.buildMessage(
+ IMessage.HIGH_SEVERITY,
+ JaxbValidationMessages.XML_ENUM_VALUE__INVALID_LEXICAL_VALUE,
+ new String[] { value, xsdType.getName() },
+ this,
+ getValueTextRange(astRoot)));
+ }
+ }
+
+ @Override
+ public TextRange getValidationTextRange(CompilationUnit astRoot) {
+ return getResourceEnumConstant().getTextRange(astRoot);
+ }
+
+ protected TextRange getValueTextRange(CompilationUnit astRoot) {
+ return getXmlEnumValueAnnotation().getValueTextRange(astRoot);
+ }
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaEnumMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaEnumMapping.java
index 80f026f..00d5997 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaEnumMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaEnumMapping.java
@@ -14,8 +14,10 @@
import org.eclipse.jpt.common.core.resource.java.JavaResourceEnum;
import org.eclipse.jpt.common.core.resource.java.JavaResourceEnumConstant;
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.iterables.CompositeIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable;
import org.eclipse.jpt.jaxb.core.context.JaxbEnum;
import org.eclipse.jpt.jaxb.core.context.JaxbEnumConstant;
@@ -28,6 +30,7 @@
import org.eclipse.jpt.jaxb.core.resource.java.XmlEnumAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlTypeAnnotation;
import org.eclipse.jpt.jaxb.core.xsd.XsdSchema;
+import org.eclipse.jpt.jaxb.core.xsd.XsdSimpleTypeDefinition;
import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
@@ -161,6 +164,57 @@
return super.getNonTransientReferencedXmlTypeNames();
}
+ public XsdSimpleTypeDefinition getValueXsdTypeDefinition() {
+ XsdTypeDefinition xsdType = getValueXsdTypeDefinition_();
+ if (xsdType == null || xsdType.getKind() != XsdTypeDefinition.Kind.SIMPLE) {
+ return null;
+ }
+ return (XsdSimpleTypeDefinition) xsdType;
+ }
+
+ protected XsdTypeDefinition getValueXsdTypeDefinition_() {
+ String fqXmlEnumValue = getFullyQualifiedXmlEnumValue();
+
+ JaxbType jaxbType = getContextRoot().getType(fqXmlEnumValue);
+ if (jaxbType != null) {
+ JaxbTypeMapping typeMapping = jaxbType.getMapping();
+ if (typeMapping != null) {
+ return typeMapping.getXsdTypeDefinition();
+ }
+ }
+ else {
+ String typeMapping = getJaxbProject().getPlatform().getDefinition().getSchemaTypeMapping(fqXmlEnumValue);
+ if (typeMapping != null) {
+ XsdSchema xsdSchema = getJaxbPackage().getXsdSchema();
+ if (xsdSchema != null) {
+ return xsdSchema.getTypeDefinition(XSDUtil.SCHEMA_FOR_SCHEMA_URI_2001, typeMapping);
+ }
+ }
+ }
+
+ return null;
+ }
+
+
+ // ***** 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 (JaxbEnumConstant constant : getEnumConstants()) {
+ result = constant.getJavaCompletionProposals(pos, filter, astRoot);
+ if (! CollectionTools.isEmpty(result)) {
+ return result;
+ }
+ }
+
+ return EmptyIterable.instance();
+ }
+
// ***** validation *****
@@ -170,6 +224,10 @@
validateXmlType(messages, reporter, astRoot);
validateXmlEnum(messages, reporter, astRoot);
+
+ for (JaxbEnumConstant constant : getEnumConstants()) {
+ constant.validate(messages, reporter, astRoot);
+ }
}
protected void validateXmlType(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
@@ -204,44 +262,16 @@
}
protected void validateXmlEnum(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
- String fqXmlEnumValue = getFullyQualifiedXmlEnumValue();
- boolean nonSimpleSchemaType = false;
+ XsdSchema xsdSchema = getJaxbPackage().getXsdSchema();
+ XsdTypeDefinition xsdType = getValueXsdTypeDefinition_();
- JaxbType jaxbType = getContextRoot().getType(fqXmlEnumValue);
- if (jaxbType != null) {
- JaxbTypeMapping typeMapping = jaxbType.getMapping();
- if (typeMapping != null) {
- XsdTypeDefinition xsdType = typeMapping.getXsdTypeDefinition();
- if (xsdType != null) {
- nonSimpleSchemaType = xsdType.getKind() != XsdTypeDefinition.Kind.SIMPLE;
- }
- }
- }
- else {
- String typeMapping = getJaxbProject().getPlatform().getDefinition().getSchemaTypeMapping(fqXmlEnumValue);
- if (typeMapping == null) {
- nonSimpleSchemaType = true;
- }
- else {
- XsdSchema xsdSchema = getJaxbPackage().getXsdSchema();
- if (xsdSchema != null) {
- XsdTypeDefinition xsdType = xsdSchema.getTypeDefinition(XSDUtil.SCHEMA_FOR_SCHEMA_URI_2001, typeMapping);
- if (xsdType == null) {
- nonSimpleSchemaType = true;
- }
- else {
- nonSimpleSchemaType = xsdType.getKind() != XsdTypeDefinition.Kind.SIMPLE;
- }
- }
- }
- }
-
- if (nonSimpleSchemaType) {
+ if ((xsdSchema != null && xsdType == null)
+ || (xsdType != null && xsdType.getKind() != XsdTypeDefinition.Kind.SIMPLE)) {
messages.add(
DefaultValidationMessages.buildMessage(
IMessage.HIGH_SEVERITY,
JaxbValidationMessages.XML_ENUM__NON_SIMPLE_SCHEMA_TYPE,
- new String[] { fqXmlEnumValue },
+ new String[] { getFullyQualifiedXmlEnumValue() },
this,
getXmlEnumValueTextRange(astRoot)));
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/NullXmlEnumValueAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/NullXmlEnumValueAnnotation.java
index 61f33b2..ba178b4 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/NullXmlEnumValueAnnotation.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/NullXmlEnumValueAnnotation.java
@@ -53,4 +53,8 @@
public TextRange getValueTextRange(CompilationUnit astRoot) {
return null;
}
+
+ public boolean valueTouches(int pos, CompilationUnit astRoot) {
+ return false;
+ }
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/binary/BinaryXmlEnumValueAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/binary/BinaryXmlEnumValueAnnotation.java
index f9860c0..53cc480 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/binary/BinaryXmlEnumValueAnnotation.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/binary/BinaryXmlEnumValueAnnotation.java
@@ -66,5 +66,8 @@
public TextRange getValueTextRange(CompilationUnit astRoot) {
throw new UnsupportedOperationException();
}
-
+
+ public boolean valueTouches(int pos, CompilationUnit astRoot) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/source/SourceXmlEnumValueAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/source/SourceXmlEnumValueAnnotation.java
index e783539..f7b4421 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/source/SourceXmlEnumValueAnnotation.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/source/SourceXmlEnumValueAnnotation.java
@@ -89,8 +89,12 @@
public TextRange getValueTextRange(CompilationUnit astRoot) {
return this.getElementTextRange(VALUE_ADAPTER, astRoot);
}
-
-
+
+ public boolean valueTouches(int pos, CompilationUnit astRoot) {
+ return elementTouches(VALUE_ADAPTER, pos, astRoot);
+ }
+
+
//*********** static methods ****************
private static DeclarationAnnotationElementAdapter<String> buildValueAdapter() {
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/validation/JaxbValidationMessages.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/validation/JaxbValidationMessages.java
index e5136d7..f4b9bc8 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/validation/JaxbValidationMessages.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/validation/JaxbValidationMessages.java
@@ -47,6 +47,11 @@
String XML_ROOT_ELEMENT_TYPE_CONFLICTS_WITH_XML_TYPE = "XML_ROOT_ELEMENT_TYPE_CONFLICTS_WITH_XML_TYPE";
+ // validation on enum constant
+
+ String XML_ENUM_VALUE__INVALID_LEXICAL_VALUE = "XML_ENUM_VALUE__INVALID_LEXICAL_VALUE";
+
+
// validation on attribute
String ATTRIBUTE_MAPPING__UNSUPPORTED_ANNOTATION = "ATTRIBUTE_MAPPING__UNSUPPORTED_ANNOTATION";
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/resource/java/XmlEnumValueAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/resource/java/XmlEnumValueAnnotation.java
index 16a67aa..6d70a28 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/resource/java/XmlEnumValueAnnotation.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/resource/java/XmlEnumValueAnnotation.java
@@ -29,23 +29,28 @@
public interface XmlEnumValueAnnotation
extends Annotation {
+ String VALUE_PROPERTY = "value"; //$NON-NLS-1$
+
/**
* Corresponds to the 'value' element of the XmlEnumValue annotation.
* Return null if the element does not exist in Java.
*/
String getValue();
- String VALUE_PROPERTY = "value"; //$NON-NLS-1$
-
+
/**
* Corresponds to the 'value' element of the XmlEnumValue annotation.
* Set to null to remove the element.
*/
void setValue(String value);
-
+
/**
* Return the {@link TextRange} for the 'value' element. If the element
* does not exist return the {@link TextRange} for the XmlEnumValue annotation.
*/
TextRange getValueTextRange(CompilationUnit astRoot);
+ /**
+ * Return whether the given position touches the 'value' element value.
+ */
+ boolean valueTouches(int pos, CompilationUnit astRoot);
}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSimpleTypeDefinition.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSimpleTypeDefinition.java
index f8d1eb4..c6e5adc 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSimpleTypeDefinition.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSimpleTypeDefinition.java
@@ -10,7 +10,11 @@
package org.eclipse.jpt.jaxb.core.xsd;
import org.eclipse.jpt.common.utility.Filter;
+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.FilteringIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
+import org.eclipse.xsd.XSDEnumerationFacet;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
@@ -50,4 +54,16 @@
// simple types have no elements
return EmptyIterable.instance();
}
+
+ public Iterable<String> getEnumValueProposals(Filter<String> filter) {
+ return StringTools.convertToJavaStringLiterals(
+ new FilteringIterable<String>(
+ new TransformationIterable<XSDEnumerationFacet, String>(getXSDComponent().getEnumerationFacets()) {
+ @Override
+ protected String transform(XSDEnumerationFacet enumFacet) {
+ return enumFacet.getLexicalValue();
+ }
+ },
+ filter));
+ }
}