diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/Term.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/Term.java index 6cb3351bb..839c46469 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/Term.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/Term.java @@ -1,5 +1,7 @@ package com.sap.olingo.jpa.metadata.core.edm.mapper.annotation; +import static com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException.MessageKeys.VARIABLE_NOT_SUPPORTED; + import java.util.ArrayList; import java.util.List; @@ -8,6 +10,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; @JsonIgnoreProperties(ignoreUnknown = true) class Term extends CsdlTerm { @@ -70,16 +73,39 @@ public CsdlTerm setMaxLength(final Integer maxLength) { public CsdlTerm setPrecision(final Integer precision) { return super.setPrecision(precision); } - - @Override + /** + * A non negative integer or floating or variable.

+ * The value floating means that the decimal property represents a decimal floating-point number whose number + * of + * significant digits is the value of the Precision facet. OData 4.0 responses MUST NOT specify the value floating. + *

+ * The value variable means that the number of digits to the right of the decimal point may vary from zero to + * the value of the Precision facet. + * {@link https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_Scale} + * @throws ODataJPAModelException + */ @JacksonXmlProperty(localName = "Scale", isAttribute = true) - public CsdlTerm setScale(final Integer scale) { - return super.setScale(scale); + public CsdlTerm setScale(final String scaleValue) throws ODataJPAModelException { + try { + final Integer scale = Integer.valueOf(scaleValue); + return super.setScale(scale); + } catch (final NumberFormatException e) { + throw new ODataJPAModelException(VARIABLE_NOT_SUPPORTED, e, "Scale"); + } } + /** + * For a geometry or geography property the SRID facet identifies which spatial reference system is applied to values + * of the property on type instances. + *

+ * The value of the SRID facet MUST be a non-negative integer or the special value variable. If no value is specified, + * the attribute defaults to 0 for Geometry types or 4326 for Geography types. + *

+ * The valid values of the SRID facet and their meanings are as defined by the European Petroleum Survey Group [EPSG]. + * @param srid + */ @JacksonXmlProperty(localName = "SRID", isAttribute = true) - void setSrid(final String srid) { - if (srid != null) - super.setSrid(SRID.valueOf(srid)); + void setSrid(final String srid) throws ODataJPAModelException { + super.setSrid(SRID.valueOf(srid)); } } diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/exception/ODataJPAModelException.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/exception/ODataJPAModelException.java index c4a6ab56f..a2d5a3865 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/exception/ODataJPAModelException.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/exception/ODataJPAModelException.java @@ -68,6 +68,7 @@ public enum MessageKeys implements ODataJPAMessageKey { ANNOTATION_STREAM_INCOMPLETE, ANNOTATION_PARSE_ERROR, ANNOTATION_PATH_NOT_FOUND, + VARIABLE_NOT_SUPPORTED, ODATA_ANNOTATION_TWO_EXPRESSIONS, NAVI_PROPERTY_NOT_FOUND, ON_LEFT_ATTRIBUTE_NULL, diff --git a/jpa/odata-jpa-metadata/src/main/resources/metadata-exceptions-i18n.properties b/jpa/odata-jpa-metadata/src/main/resources/metadata-exceptions-i18n.properties index 247be8574..2bc5d7e7b 100644 --- a/jpa/odata-jpa-metadata/src/main/resources/metadata-exceptions-i18n.properties +++ b/jpa/odata-jpa-metadata/src/main/resources/metadata-exceptions-i18n.properties @@ -76,6 +76,7 @@ ODataJPAModelException.ANNOTATION_STREAM_INCOMPLETE = Either contentType or cont ODataJPAModelException.ANNOTATION_PARSE_ERROR = Parsing of '%1$s' failed with message '%2$s' ODataJPAModelException.ANNOTATION_PATH_NOT_FOUND = Path '%1$s' to read the file containing vocabulary '%2$s' is wrong. ODataJPAModelException.ODATA_ANNOTATION_TWO_EXPRESSIONS = OData annotation only supports either a constant or a dynamic expression. See '%1$s' +ODataJPAModelException.VARIABLE_NOT_SUPPORTED = OData V4.01 string values for attribute '%1$s' are not supported. ODataJPAModelException.ON_LEFT_ATTRIBUTE_NULL = ON condition left attribute is null / not found ODataJPAModelException.ON_RIGHT_ATTRIBUTE_NULL = ON condition right attribute is null / not found diff --git a/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/AppliesToTest.java b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/AppliesToTest.java new file mode 100644 index 000000000..084c7d81b --- /dev/null +++ b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/AppliesToTest.java @@ -0,0 +1,22 @@ +package com.sap.olingo.jpa.metadata.core.edm.mapper.annotation; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; + +class AppliesToTest { + + @TestFactory + Stream checkEnumHasValue() { + return Stream.of(AppliesTo.values()) + .map(a -> dynamicTest(a.name(), () -> { + assertNotNull(a.value()); + assertFalse(a.value().isEmpty()); + })); + } +} diff --git a/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/TermTest.java b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/TermTest.java new file mode 100644 index 000000000..29e083be3 --- /dev/null +++ b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/TermTest.java @@ -0,0 +1,117 @@ +package com.sap.olingo.jpa.metadata.core.edm.mapper.annotation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Map; + +import org.apache.olingo.commons.api.edm.geo.SRID; +import org.apache.olingo.commons.api.edm.provider.CsdlTerm; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; + +class TermTest { + private static final String TEST_ANNOTATIONS = "annotations/Org.Olingo.Test.V1.xml"; + private static final String CORE_ANNOTATIONS = "annotations/Org.OData.Core.V1.xml"; + private CsdlDocument cutCore; + private CsdlDocument cutTest; + private Charset charset; + + @BeforeEach + void setup() throws ODataJPAModelException, IOException { + final CsdlDocumentReader reader = new CsdlDocumentReader(); + charset = Charset.defaultCharset(); + cutCore = reader.readFromResource(CORE_ANNOTATIONS, charset); + cutTest = reader.readFromResource(TEST_ANNOTATIONS, charset); + } + + @Test + void testGetTermsOneSchemaFromPath() throws JsonParseException, JsonMappingException, IOException, + ODataJPAModelException { + + final Map> act = cutCore.getTerms(); + assertNotNull(act.get("Org.OData.Core.V1")); + final Map terms = act.get("Org.OData.Core.V1"); + assertEquals(28, terms.size()); + } + + @Test + void testGetAppliesTo() throws JsonParseException, JsonMappingException, IOException, ODataJPAModelException { + final Map> act = cutCore.getTerms(); + assertNotNull(act.get("Org.OData.Core.V1")); + final Map terms = act.get("Org.OData.Core.V1"); + final CsdlTerm term = terms.get("IsLanguageDependent"); + assertEquals(2, term.getAppliesTo().size()); + assertTrue("Term".equals(term.getAppliesTo().get(0)) || "Term".equals(term.getAppliesTo().get(1))); + assertTrue("Property".equals(term.getAppliesTo().get(0)) || "Property".equals(term.getAppliesTo().get(1))); + assertEquals("true", term.getDefaultValue()); + } + + @Test + void testGetTermsTwoSchemaFromPath() throws JsonParseException, JsonMappingException, IOException, + ODataJPAModelException { + final Map> act = cutTest.getTerms(); + assertNotNull(act.get("Org.OData.Measures.V1")); + assertNotNull(act.get("Org.OData.Capabilities.V1")); + } + + @Test + void testGetTermWithScalePresition() throws JsonParseException, JsonMappingException, IOException, + ODataJPAModelException { + final Map> act = cutTest.getTerms(); + + final Map terms = act.get("Org.OData.Measures.V1"); + final CsdlTerm term = terms.get("MultipleOf"); + assertNotNull(term); + assertEquals(10, term.getScale()); + assertEquals(5, term.getPrecision()); + } + + @Test + void testGetTermWithBaseTypeMaxLength() throws JsonParseException, JsonMappingException, IOException, + ODataJPAModelException { + final Map> act = cutTest.getTerms(); + + final Map terms = act.get("Org.OData.Measures.V1"); + final CsdlTerm term = terms.get("Unit2"); + assertNotNull(term); + assertEquals("Unit", term.getBaseTerm()); + assertEquals(2, term.getMaxLength()); + } + + @Test + void testGetTermWithSrid() throws JsonParseException, JsonMappingException, IOException, + ODataJPAModelException { + final Map> act = cutTest.getTerms(); + + final Map terms = act.get("Org.OData.Measures.V1"); + final CsdlTerm term = terms.get("Geo"); + assertNotNull(term); + assertEquals(SRID.valueOf("1234"), term.getSrid()); + } + + @Test + void testGetTermWithSridVariableNotSupported() throws JsonParseException, JsonMappingException, IOException, + ODataJPAModelException { + + final Term cut = new Term(); + cut.setSrid("variable"); + assertTrue(cut.getSrid().toString().contains("variable")); + } + + @Test + void testGetTermWithScaleVariableNotSupported() throws JsonParseException, JsonMappingException, IOException, + ODataJPAModelException { + + final Term cut = new Term(); + assertThrows(ODataJPAModelException.class, () -> cut.setScale("variable")); + } +} diff --git a/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/TestAnnotationTerm.java b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/TestAnnotationTerm.java deleted file mode 100644 index ac8decea2..000000000 --- a/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/annotation/TestAnnotationTerm.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.sap.olingo.jpa.metadata.core.edm.mapper.annotation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Map; - -import org.apache.olingo.commons.api.edm.provider.CsdlTerm; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; - -public class TestAnnotationTerm { - private static final String TEST_ANNOTATIONS = "annotations/Org.Olingo.Test.V1.xml"; - private static final String CORE_ANNOTATIONS = "annotations/Org.OData.Core.V1.xml"; - private CsdlDocument cutCore; - private CsdlDocument cutTest; - private Charset charset; - - @BeforeEach - public void setup() throws ODataJPAModelException, IOException { - final CsdlDocumentReader reader = new CsdlDocumentReader(); - charset = Charset.defaultCharset(); - cutCore = reader.readFromResource(CORE_ANNOTATIONS, charset); - cutTest = reader.readFromResource(TEST_ANNOTATIONS, charset); - } - - @Test - public void testGetTermsOneSchemaFromPath() throws JsonParseException, JsonMappingException, IOException, - ODataJPAModelException { - - final Map> act = cutCore.getTerms(); - assertNotNull(act.get("Org.OData.Core.V1")); - final Map terms = act.get("Org.OData.Core.V1"); - assertEquals(28, terms.size()); - } - - @Test - public void testGetAppliesTo() throws JsonParseException, JsonMappingException, IOException, ODataJPAModelException { - final Map> act = cutCore.getTerms(); - assertNotNull(act.get("Org.OData.Core.V1")); - final Map terms = act.get("Org.OData.Core.V1"); - final CsdlTerm term = terms.get("IsLanguageDependent"); - assertEquals(2, term.getAppliesTo().size()); - assertTrue("Term".equals(term.getAppliesTo().get(0)) || "Term".equals(term.getAppliesTo().get(1))); - assertTrue("Property".equals(term.getAppliesTo().get(0)) || "Property".equals(term.getAppliesTo().get(1))); - } - - @Test - public void testGetTermsTwoSchemaFromPath() throws JsonParseException, JsonMappingException, IOException, - ODataJPAModelException { - final Map> act = cutTest.getTerms(); - assertNotNull(act.get("Org.OData.Measures.V1")); - assertNotNull(act.get("Org.OData.Capabilities.V1")); - } - -} diff --git a/jpa/odata-jpa-metadata/src/test/resources/annotations/Org.Olingo.Test.V1.xml b/jpa/odata-jpa-metadata/src/test/resources/annotations/Org.Olingo.Test.V1.xml index 08be8d638..7d0986648 100644 --- a/jpa/odata-jpa-metadata/src/test/resources/annotations/Org.Olingo.Test.V1.xml +++ b/jpa/odata-jpa-metadata/src/test/resources/annotations/Org.Olingo.Test.V1.xml @@ -24,7 +24,15 @@ - + + + + + + + + +