diff --git a/README.md b/README.md index 11758c393..32c478cd7 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build Status](https://travis-ci.org/SAP/olingo-jpa-processor-v4.svg?branch=develop)](https://travis-ci.org/github/SAP/olingo-jpa-processor-v4) [![Coverage Status](https://coveralls.io/repos/github/SAP/olingo-jpa-processor-v4/badge.svg?branch=develop)](https://coveralls.io/github/SAP/olingo-jpa-processor-v4?branch=develop) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE.txt) +[![REUSE status](https://api.reuse.software/badge/github.com/SAP/olingo-jpa-processor-v4)](https://api.reuse.software/info/github.com/SAP/olingo-jpa-processor-v4) ![GitHub last commit (develop)](https://img.shields.io/github/last-commit/SAP/OLINGO-JPA-PROCESSOR-V4/develop.svg) [![GitHub pre-release](https://img.shields.io/github/release-pre/sap/olingo-jpa-processor-v4.svg?color=orange&label=pre-release)](https://github.com/SAP/olingo-jpa-processor-v4/releases/) [![REUSE status](https://api.reuse.software/badge/github.com/SAP/olingo-jpa-processor-v4)](https://api.reuse.software/info/github.com/SAP/olingo-jpa-processor-v4) @@ -30,7 +31,7 @@ clone the repository, import the projects and declare a dependency to either the com.sap.olingo odata-jpa-metadata - 0.3.8-SNAPSHOT + 0.3.10-SNAPSHOT ``` @@ -40,7 +41,7 @@ Or to the complete processor: com.sap.olingo odata-jpa-processor - 0.3.8-SNAPSHOT + 0.3.10-SNAPSHOT ``` @@ -84,5 +85,6 @@ Detailed information including third-party components and their licensing/copyri |0.3.6|- Enable more flexible transaction handling
- Part solution for issue [#83](https://github.com/SAP/olingo-jpa-processor-v4/issues/83)
- Increase support of Spring by performing request mapping in case a mapping path is provided via the service context|No| |0.3.7| - Update Olingo dependency to 4.7.0|No| |0.3.8| - Update Olingo dependency to 4.7.1
- Support of `java.time` data types. Prerequisite is the usage of JPA 2.2.
- Support of Absolute Context URL. See issue [#103](https://github.com/SAP/olingo-jpa-processor-v4/issues/103)
- Temporal data types do not longer require a Precision [#98](https://github.com/SAP/olingo-jpa-processor-v4/issues/98)
Support of MappedSuperclass|No| -|0.3.9| - Solutions for issue [#112](https://github.com/SAP/olingo-jpa-processor-v4/issues/112)
Solutions for issue [#114](https://github.com/SAP/olingo-jpa-processor-v4/issues/114)|No| +|0.3.9| - Solutions for issue [#112](https://github.com/SAP/olingo-jpa-processor-v4/issues/112)
- Solutions for issue [#114](https://github.com/SAP/olingo-jpa-processor-v4/issues/114)|No| +|0.3.9| - Solutions for issue [#136](https://github.com/SAP/olingo-jpa-processor-v4/issues/136) |No| diff --git a/jpa-archetype/jpa-archetype-spring/pom.xml b/jpa-archetype/jpa-archetype-spring/pom.xml index 61d99dbdb..0a78febf8 100644 --- a/jpa-archetype/jpa-archetype-spring/pom.xml +++ b/jpa-archetype/jpa-archetype-spring/pom.xml @@ -3,9 +3,9 @@ 4.0.0 - com.sap.olingo - odata-jpa-archetype - 0.3.8 + com.sap.olingo + odata-jpa-archetype + 0.3.10 odata-jpa-archetype-spring Archetype - odata-jpa-archetype-spring diff --git a/jpa-archetype/jpa-archetype-spring/src/main/resources/archetype-resources/pom.xml b/jpa-archetype/jpa-archetype-spring/src/main/resources/archetype-resources/pom.xml index 6a53e085b..1e3ec2c9e 100644 --- a/jpa-archetype/jpa-archetype-spring/src/main/resources/archetype-resources/pom.xml +++ b/jpa-archetype/jpa-archetype-spring/src/main/resources/archetype-resources/pom.xml @@ -11,12 +11,12 @@ org.springframework.boot spring-boot-starter-parent - 2.1.0.RELEASE + 2.5.5 - 0.3.8-SNAPSHOT + 0.3.10-SNAPSHOT 1.8 @@ -102,13 +102,13 @@ org.junit.jupiter junit-jupiter - 5.4.2 + 5.8.1 test org.junit.platform junit-platform-launcher - 1.4.2 + 1.8.1 test diff --git a/jpa-archetype/jpa-archetype-spring/src/main/resources/archetype-resources/src/main/java/config/EclipseLinkJpaConfiguration.java b/jpa-archetype/jpa-archetype-spring/src/main/resources/archetype-resources/src/main/java/config/EclipseLinkJpaConfiguration.java index c7dcf39f4..82923cc67 100644 --- a/jpa-archetype/jpa-archetype-spring/src/main/resources/archetype-resources/src/main/java/config/EclipseLinkJpaConfiguration.java +++ b/jpa-archetype/jpa-archetype-spring/src/main/resources/archetype-resources/src/main/java/config/EclipseLinkJpaConfiguration.java @@ -20,7 +20,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -35,9 +34,8 @@ public class EclipseLinkJpaConfiguration extends JpaBaseConfiguration { private String punit; protected EclipseLinkJpaConfiguration(DataSource dataSource, JpaProperties properties, - ObjectProvider jtaTransactionManager, - ObjectProvider transactionManagerCustomizers) { - super(dataSource, properties, jtaTransactionManager, transactionManagerCustomizers); + ObjectProvider jtaTransactionManager) { + super(dataSource, properties, jtaTransactionManager); } @Override diff --git a/jpa-archetype/pom.xml b/jpa-archetype/pom.xml index 52149a066..fe697027d 100644 --- a/jpa-archetype/pom.xml +++ b/jpa-archetype/pom.xml @@ -5,14 +5,14 @@ 4.0.0 com.sap.olingo odata-jpa-archetype - 0.3.9 + 0.3.10 pom https://github.com/SAP/olingo-jpa-processor-v4 UTF-8 1.8 - 0.3.8-SNAPSHOT + 0.3.10-SNAPSHOT diff --git a/jpa/odata-jpa-annotation/pom.xml b/jpa/odata-jpa-annotation/pom.xml index 7410ea78c..7af649a7e 100644 --- a/jpa/odata-jpa-annotation/pom.xml +++ b/jpa/odata-jpa-annotation/pom.xml @@ -6,7 +6,7 @@ com.sap.olingo odata-jpa - 0.3.9-SNAPSHOT + 0.3.10-SNAPSHOT odata-jpa-annotation odata-jpa-annotation diff --git a/jpa/odata-jpa-coverage/pom.xml b/jpa/odata-jpa-coverage/pom.xml index a6ddcac7c..54a3a2f11 100644 --- a/jpa/odata-jpa-coverage/pom.xml +++ b/jpa/odata-jpa-coverage/pom.xml @@ -5,7 +5,7 @@ com.sap.olingo odata-jpa - 0.3.9-SNAPSHOT + 0.3.10-SNAPSHOT odata-jpa-coverage diff --git a/jpa/odata-jpa-metadata/pom.xml b/jpa/odata-jpa-metadata/pom.xml index cdc3bd8cd..5669f4154 100644 --- a/jpa/odata-jpa-metadata/pom.xml +++ b/jpa/odata-jpa-metadata/pom.xml @@ -7,7 +7,7 @@ com.sap.olingo odata-jpa - 0.3.9-SNAPSHOT + 0.3.10-SNAPSHOT @@ -63,6 +63,11 @@ jackson-dataformat-yaml ${jackson.version} + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + net.oneandone.reflections8 reflections8 @@ -77,7 +82,7 @@ com.google.code.findbugs jsr305 3.0.2 - + diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/api/JPAEdmProvider.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/api/JPAEdmProvider.java index a95a85951..1443d8116 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/api/JPAEdmProvider.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/api/JPAEdmProvider.java @@ -58,8 +58,7 @@ public JPAEdmProvider(final Metamodel jpaMetamodel, final JPAEdmMetadataPostProc final String[] packageName, final JPAEdmNameBuilder nameBuilder) throws ODataException { super(); this.nameBuilder = nameBuilder; - this.serviceDocument = new JPAServiceDocumentFactory(nameBuilder.getNamespace(), jpaMetamodel, postProcessor, - packageName).getServiceDocument(); + this.serviceDocument = new JPAServiceDocumentFactory(nameBuilder, jpaMetamodel, postProcessor, packageName).getServiceDocument(); } @Override 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/api/JPAServiceDocument.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/api/JPAServiceDocument.java index 3a7204714..318398e46 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/api/JPAServiceDocument.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/api/JPAServiceDocument.java @@ -53,5 +53,7 @@ public interface JPAServiceDocument extends CustomETagSupport { JPAEnumerationAttribute getEnumType(final EdmEnumType type); JPAEnumerationAttribute getEnumType(final String fqnAsString); + + JPAEdmNameBuilder getNameBuilder(); } \ No newline at end of file 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/java/com/sap/olingo/jpa/metadata/core/edm/mapper/extention/IntermediateEntitySetAccess.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/extention/IntermediateEntitySetAccess.java index 774b2782b..7391cf69a 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/extention/IntermediateEntitySetAccess.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/extention/IntermediateEntitySetAccess.java @@ -4,6 +4,7 @@ import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEdmNameBuilder; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAElement; public interface IntermediateEntitySetAccess extends JPAElement { @@ -15,8 +16,8 @@ public interface IntermediateEntitySetAccess extends JPAElement { public void addAnnotations(final List annotations); /** - * Enables a rename external, OData, name of an entity set. - * @param externalName + * @deprecated (0.3.10, Overriding the external name not working correctly. Create an {@link JPAEdmNameBuilder} instead ) */ + @Deprecated void setExternalName(String externalName); } diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/extention/IntermediateModelItemAccess.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/extention/IntermediateModelItemAccess.java index 62d4019ee..ec3d547c1 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/extention/IntermediateModelItemAccess.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/extention/IntermediateModelItemAccess.java @@ -1,5 +1,6 @@ package com.sap.olingo.jpa.metadata.core.edm.mapper.extention; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEdmNameBuilder; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAElement; /** @@ -14,9 +15,9 @@ public interface IntermediateModelItemAccess extends JPAElement { boolean ignore(); /** - * Enables to overwrite the External, OData, name of a model item. - * @param externalName + * @deprecated (0.3.10, Overriding the external name not working correctly. Create an {@link JPAEdmNameBuilder} instead ) */ + @Deprecated void setExternalName(String externalName); /** diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/IntermediateServiceDocument.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/IntermediateServiceDocument.java index 44f337280..526b533a2 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/IntermediateServiceDocument.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/IntermediateServiceDocument.java @@ -274,6 +274,11 @@ public boolean hasMediaETag(final EdmBindingTarget entitySetOrSingleton) { return false; } + @Override + public JPAEdmNameBuilder getNameBuilder() { + return nameBuilder; + } + private void buildIntermediateSchemas() throws ODataJPAModelException { final IntermediateSchema schema = new IntermediateSchema(nameBuilder, jpaMetamodel, reflections); diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/JPAServiceDocumentFactory.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/JPAServiceDocumentFactory.java index a38f75e68..42f7f5785 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/JPAServiceDocumentFactory.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/JPAServiceDocumentFactory.java @@ -3,26 +3,32 @@ import javax.persistence.metamodel.Metamodel; import com.sap.olingo.jpa.metadata.api.JPAEdmMetadataPostProcessor; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEdmNameBuilder; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; public final class JPAServiceDocumentFactory { - private final String namespace; + private final JPAEdmNameBuilder nameBuilder; private final Metamodel jpaMetamodel; private final JPAEdmMetadataPostProcessor postProcessor; private final String[] packageName; - public JPAServiceDocumentFactory(final String namespace, final Metamodel jpaMetamodel, + public JPAServiceDocumentFactory(final JPAEdmNameBuilder nameBuilder, final Metamodel jpaMetamodel, final JPAEdmMetadataPostProcessor postProcessor, final String[] packageName) { super(); - this.namespace = namespace; + this.nameBuilder = nameBuilder; this.jpaMetamodel = jpaMetamodel; this.postProcessor = postProcessor; this.packageName = packageName; } + /** + * Late creation of the service document. A service document contains at least one schema and a container. + * @return + * @throws ODataJPAModelException + */ public JPAServiceDocument getServiceDocument() throws ODataJPAModelException { - return new IntermediateServiceDocument(namespace, jpaMetamodel, postProcessor, packageName); + return new IntermediateServiceDocument(nameBuilder, jpaMetamodel, postProcessor, packageName); } } 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/api/TestJPAEdmProvider.java b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/api/TestJPAEdmProvider.java new file mode 100644 index 000000000..4dbd3a303 --- /dev/null +++ b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/api/TestJPAEdmProvider.java @@ -0,0 +1,319 @@ +package com.sap.olingo.jpa.metadata.api; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.CsdlAction; +import org.apache.olingo.commons.api.edm.provider.CsdlActionImport; +import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations; +import org.apache.olingo.commons.api.edm.provider.CsdlComplexType; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo; +import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; +import org.apache.olingo.commons.api.edm.provider.CsdlEnumType; +import org.apache.olingo.commons.api.edm.provider.CsdlFunction; +import org.apache.olingo.commons.api.edm.provider.CsdlFunctionImport; +import org.apache.olingo.commons.api.edm.provider.CsdlSchema; +import org.apache.olingo.commons.api.edm.provider.CsdlTerm; +import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition; +import org.apache.olingo.commons.api.ex.ODataException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEdmNameBuilder; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; +import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; +import com.sap.olingo.jpa.metadata.core.edm.mapper.extention.IntermediateEntityTypeAccess; +import com.sap.olingo.jpa.metadata.core.edm.mapper.extention.IntermediateNavigationPropertyAccess; +import com.sap.olingo.jpa.metadata.core.edm.mapper.extention.IntermediatePropertyAccess; +import com.sap.olingo.jpa.metadata.core.edm.mapper.extention.IntermediateReferenceList; +import com.sap.olingo.jpa.metadata.core.edm.mapper.extention.IntermediateReferenceList.IntermediateReferenceAccess; +import com.sap.olingo.jpa.metadata.core.edm.mapper.impl.CustomJPANameBuilder; +import com.sap.olingo.jpa.metadata.core.edm.mapper.impl.JPADefaultEdmNameBuilder; +import com.sap.olingo.jpa.processor.core.testmodel.DataSourceHelper; + +class TestJPAEdmProvider { + private static final String PUNIT_NAME = "com.sap.olingo.jpa"; + private static final String[] enumPackages = { "com.sap.olingo.jpa.processor.core.testmodel" }; + private static EntityManagerFactory emf; + private static DataSource ds; + private JPAEdmProvider cut; + private JPAEdmMetadataPostProcessor pp; + + @BeforeAll + public static void setupClass() throws ODataJPAModelException { + ds = DataSourceHelper.createDataSource(DataSourceHelper.DB_H2); + emf = JPAEntityManagerFactory.getEntityManagerFactory(PUNIT_NAME, ds); + } + + @BeforeEach + void setup() throws ODataException { + cut = new JPAEdmProvider(PUNIT_NAME, emf, null, enumPackages); + } + + @Test + void checkReturnsDefaultNamerBuilderIfNotProvided() throws ODataException { + assertTrue(cut.getEdmNameBuilder() instanceof JPADefaultEdmNameBuilder); + } + + @Test + void checkReturnsReferencesFromServiceDocument() throws ODataException { + assertEquals(cut.getServiceDocument().getReferences(), cut.getReferences()); + } + + @Test + void checkThrowsExceptionOnMissingNamespace() throws ODataException { + assertThrows(NullPointerException.class, () -> new JPAEdmProvider(null, emf, null, enumPackages)); + } + + @Test + void checkThrowsExceptionOnMissingEmf() throws ODataException { + final EntityManagerFactory nullFactory = null; + assertThrows(NullPointerException.class, () -> new JPAEdmProvider("Willi", nullFactory, null, enumPackages)); + } + + @Test + void checkGetSchemas() throws ODataException { + final JPAEdmNameBuilder nameBuilder = new CustomJPANameBuilder(); + cut = new JPAEdmProvider(emf.getMetamodel(), null, null, nameBuilder); + final JPAServiceDocument act = cut.getServiceDocument(); + assertNotNull(act); + assertEquals(nameBuilder, act.getNameBuilder()); + } + + @Test + void checkGetSchemasReturnsOneSchema() throws ODataException { + final List act = cut.getSchemas(); + assertEquals(1, act.size()); + assertNotNull(act.get(0)); + assertEquals(PUNIT_NAME, act.get(0).getNamespace()); + } + + @Test + void checkGetEnumReturnsNullOnUnknown() throws ODataException { + final CsdlEnumType act = cut.getEnumType(new FullQualifiedName("Hello", "World")); + assertNull(act); + } + + @Test + void checkGetEnumReturnsKnownEnum() throws ODataException { + final CsdlEnumType act = cut.getEnumType(new FullQualifiedName(PUNIT_NAME, "AccessRights")); + assertNotNull(act); + assertTrue(act.isFlags()); + } + + @Test + void checkGetComplexTypeReturnsNullOnUnknown() throws ODataException { + final CsdlComplexType act = cut.getComplexType(new FullQualifiedName("Hello", "World")); + assertNull(act); + } + + @Test + void checkGetComplexTypeReturnsKnownEnum() throws ODataException { + final CsdlComplexType act = cut.getComplexType(new FullQualifiedName(PUNIT_NAME, "PostalAddressData")); + assertNotNull(act); + assertFalse(act.isAbstract()); + } + + @Test + void checkGeEntityContainerReturnsContainer() throws ODataException { + final CsdlEntityContainer act = cut.getEntityContainer(); + assertNotNull(act); + assertEquals(cut.getServiceDocument().getNameBuilder().buildContainerName(), act.getName()); + } + + @Test + void checkGetEntityContainerInfoReturnsNullOnUnknown() throws ODataException { + final CsdlEntityContainerInfo act = cut.getEntityContainerInfo(new FullQualifiedName("Hello", "World")); + assertNull(act); + } + + @Test + void checkEntityContainerInfoReturnsKnownContainer() throws ODataException { + final String name = cut.getServiceDocument().getNameBuilder().buildContainerName(); + final FullQualifiedName fqn = new FullQualifiedName(PUNIT_NAME, name); + final CsdlEntityContainerInfo act = cut.getEntityContainerInfo(new FullQualifiedName(PUNIT_NAME, name)); + assertNotNull(act); + assertEquals(fqn, act.getContainerName()); + } + + @Test + void checkEntityContainerInfoReturnsContainerIfNull() throws ODataException { + final FullQualifiedName fqn = buildContainerFQN(); + final CsdlEntityContainerInfo act = cut.getEntityContainerInfo(null); + assertNotNull(act); + assertEquals(fqn, act.getContainerName()); + } + + @Test + void checkGetEntitySetReturnsNullOnUnknownSet() throws ODataException { + final FullQualifiedName fqn = buildContainerFQN(); + final CsdlEntitySet act = cut.getEntitySet(fqn, "Hello"); + assertNull(act); + } + + @Test + void checkGetEntitySetReturnsNullOnUnknownNamespace() throws ODataException { + final FullQualifiedName fqn = new FullQualifiedName(PUNIT_NAME, "Hello"); + final CsdlEntitySet act = cut.getEntitySet(fqn, "World"); + assertNull(act); + } + + @Test + void checkGetEntitySetReturnsKnownSet() throws ODataException { + final FullQualifiedName fqn = buildContainerFQN(); + final CsdlEntitySet act = cut.getEntitySet(fqn, "Persons"); + assertNotNull(act); + assertEquals("Persons", act.getName()); + } + + @Test + void checkGetEntityTypeReturnsNullOnUnknown() throws ODataException { + final CsdlEntityType act = cut.getEntityType(new FullQualifiedName("Hello", "World")); + assertNull(act); + } + + @Test + void checkGetEntityTypeReturnsKnownEnum() throws ODataException { + final CsdlEntityType act = cut.getEntityType(new FullQualifiedName(PUNIT_NAME, "BusinessPartner")); + assertNotNull(act); + assertTrue(act.isAbstract()); + } + + @Test + void checkGetFunctionImportReturnsNullOnUnknownContainer() throws ODataException { + final CsdlFunctionImport act = cut.getFunctionImport(new FullQualifiedName("Hello", "World"), "Hello"); + assertNull(act); + } + + @Test + void checkGetFunctionImportReturnsNullOnUnknownFunction() throws ODataException { + final FullQualifiedName fqn = buildContainerFQN(); + final CsdlFunctionImport act = cut.getFunctionImport(fqn, "Hello"); + assertNull(act); + } + + @Test + void checkGetFunctionImportReturnsKnownImport() throws ODataException { + final FullQualifiedName fqn = buildContainerFQN(); + final CsdlFunctionImport act = cut.getFunctionImport(fqn, "Siblings"); + assertNotNull(act); + } + + @Test + void checkGetFunctionsReturnsNullOnUnknownschema() throws ODataException { + final List act = cut.getFunctions(new FullQualifiedName("Hallo", "Welt")); + assertNull(act); + } + + @Test + void checkGetFunctionsReturnsKnownFunction() throws ODataException { + final List act = cut.getFunctions(new FullQualifiedName(PUNIT_NAME, "PopulationDensity")); + assertNotNull(act); + assertEquals(1, act.size()); + assertEquals(2, act.get(0).getParameters().size()); + } + + @Test + void checkGetAnnotationsGroupReturnsNull() throws ODataException { + final CsdlAnnotations act = cut.getAnnotationsGroup(new FullQualifiedName(PUNIT_NAME, "Hello"), "World"); + assertNull(act); + } + + @Test + void checkGetTermReturnsNullOnUnknown() throws ODataException { + final CsdlTerm act = cut.getTerm(new FullQualifiedName("Hello", "World")); + assertNull(act); + } + + @Test + void checkGetTermReturnsKnownTerm() throws ODataException { + pp = new PostProcessor(); + cut = new JPAEdmProvider(PUNIT_NAME, emf, pp, enumPackages); + final CsdlTerm act = cut.getTerm(new FullQualifiedName("Org.OData.Measures.V1", "ISOCurrency")); + assertNotNull(act); + } + + @Test + void checkTypeDefinitionReturnsNullOnUnknown() throws ODataException { + final CsdlTypeDefinition act = cut.getTypeDefinition(new FullQualifiedName("Hello", "World")); + assertNull(act); + } + + @Test + void checkGetActionsReturnsNullOnUnknown() throws ODataException { + final List act = cut.getActions(new FullQualifiedName("Hello", "World")); + assertNull(act); + } + + @Test + void checkGetActionsReturnsKnownAction() throws ODataException { + final String[] operationPackages = { "com.sap.olingo.jpa.metadata.core.edm.mapper.testaction", + "com.sap.olingo.jpa.processor.core.testmodel" }; + cut = new JPAEdmProvider(PUNIT_NAME, emf, null, operationPackages); + final List act = cut.getActions(new FullQualifiedName(PUNIT_NAME, "BoundNoImport")); + assertNotNull(act); + assertEquals(1, act.size()); + } + + @Test + void checkGetActionImportReturnsNullOnUnknownContainer() throws ODataException { + final CsdlActionImport act = cut.getActionImport(new FullQualifiedName("Hello", "World"), "Dummy"); + assertNull(act); + } + + @Test + void checkGetActionImportReturnsNullOnUnknownAction() throws ODataException { + final FullQualifiedName fqn = buildContainerFQN(); + final CsdlActionImport act = cut.getActionImport(fqn, "Dummy"); + assertNull(act); + } + + @Test + void checkGetActionImportReturnsKnownAction() throws ODataException { + final FullQualifiedName fqn = buildContainerFQN(); + final String[] operationPackages = { "com.sap.olingo.jpa.metadata.core.edm.mapper.testaction", + "com.sap.olingo.jpa.processor.core.testmodel" }; + cut = new JPAEdmProvider(PUNIT_NAME, emf, null, operationPackages); + final CsdlActionImport act = cut.getActionImport(fqn, "WithImport"); + assertNotNull(act); + } + + private FullQualifiedName buildContainerFQN() { + final String name = cut.getServiceDocument().getNameBuilder().buildContainerName(); + final FullQualifiedName fqn = new FullQualifiedName(PUNIT_NAME, name); + return fqn; + } + + private class PostProcessor extends JPAEdmMetadataPostProcessor { + @Override + public void processNavigationProperty(final IntermediateNavigationPropertyAccess property, + final String jpaManagedTypeClassName) {} + + @Override + public void processProperty(final IntermediatePropertyAccess property, final String jpaManagedTypeClassName) {} + + @Override + public void processEntityType(final IntermediateEntityTypeAccess entity) {} + + @Override + public void provideReferences(final IntermediateReferenceList references) throws ODataJPAModelException { + final String uri = "http://docs.oasisopen.org/odata/odata/v4.0/os/vocabularies/Org.OData.Measures.V1.xml"; + final IntermediateReferenceAccess reference = references.addReference(uri, + "annotations/Org.OData.Measures.V1.xml"); + reference.addInclude("Org.OData.Core.V1", "Core"); + } + } +} 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/java/com/sap/olingo/jpa/metadata/core/edm/mapper/testaction/Actions.java b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/testaction/Actions.java index 18f6de316..b30269e7b 100644 --- a/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/testaction/Actions.java +++ b/jpa/odata-jpa-metadata/src/test/java/com/sap/olingo/jpa/metadata/core/edm/mapper/testaction/Actions.java @@ -20,4 +20,11 @@ public void boundNoImport( @EdmParameter(name = "A", precision = 34, scale = 10) BigDecimal a) { // Do nothing } + + @EdmAction(name = "WithImport", isBound = false) + public void withImport( + @EdmParameter(name = "Person") Person person, + @EdmParameter(name = "A", precision = 34, scale = 10) BigDecimal a) { + // Do nothing + } } 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 @@ - + + + + + + + + + diff --git a/jpa/odata-jpa-processor/pom.xml b/jpa/odata-jpa-processor/pom.xml index 6ec4010be..260179d60 100644 --- a/jpa/odata-jpa-processor/pom.xml +++ b/jpa/odata-jpa-processor/pom.xml @@ -7,7 +7,7 @@ com.sap.olingo odata-jpa - 0.3.9-SNAPSHOT + 0.3.10-SNAPSHOT odata-jpa-processor diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPALiteralOperator.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPALiteralOperator.java index b7db47297..f4d997930 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPALiteralOperator.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPALiteralOperator.java @@ -1,8 +1,5 @@ package com.sap.olingo.jpa.processor.core.filter; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.http.HttpStatusCode; @@ -23,10 +20,9 @@ public class JPALiteralOperator implements JPAPrimitiveTypeOperator { public JPALiteralOperator(final OData odata, final Literal literal) { this(odata, literal, literal.getText()); - } - private JPALiteralOperator(OData odata, Literal literal, String literalText) { + private JPALiteralOperator(final OData odata, final Literal literal, final String literalText) { this.literal = literal; this.odata = odata; this.literalText = literalText; @@ -34,19 +30,19 @@ private JPALiteralOperator(OData odata, Literal literal, String literalText) { /* * (non-Javadoc) - * + * * @see com.sap.olingo.jpa.processor.core.filter.JPAPrimitiveTypeOperator#get() */ @Override public Object get() throws ODataApplicationException { final EdmPrimitiveType edmType = ((EdmPrimitiveType) literal.getType()); - try { - final Class defaultType = edmType.getDefaultType(); - final Constructor c = defaultType.getConstructor(String.class); - return c.newInstance(edmType.fromUriLiteral(literalText)); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException - | EdmPrimitiveTypeException | InstantiationException | NoSuchMethodException | SecurityException e) { + try { + final Object value = edmType.valueOfString(literalText, true, null, null, null, true, edmType.getDefaultType()); + if (value instanceof String) + return ((String) value).replace("'", ""); + return value; + } catch (final EdmPrimitiveTypeException e) { throw new ODataJPAFilterException(e, HttpStatusCode.INTERNAL_SERVER_ERROR); } } @@ -58,11 +54,11 @@ public Object get(final JPAAttribute attribute) throws ODataApplicationException return ExpressionUtil.convertValueOnAttribute(odata, attribute, literalText); } - public Object get(JPAOperationResultParameter returnType) throws ODataApplicationException { + public Object get(final JPAOperationResultParameter returnType) throws ODataApplicationException { return ExpressionUtil.convertValueOnFacet(odata, returnType, literalText); } - public Object get(JPAParameter jpaParameter) throws ODataApplicationException { + public Object get(final JPAParameter jpaParameter) throws ODataApplicationException { return ExpressionUtil.convertValueOnFacet(odata, jpaParameter, literalText); } @@ -72,8 +68,8 @@ public boolean isNull() { return literal.getText().equals("null"); } - JPALiteralOperator clone(String prefix, String postfix) { - return new JPALiteralOperator(odata, literal, "'" + prefix + literal.getText().replaceAll("'", "") + postfix + "'"); + JPALiteralOperator clone(final String prefix, final String postfix) { + return new JPALiteralOperator(odata, literal, "'" + prefix + literal.getText().replace("'", "") + postfix + "'"); } Literal getLiteral() { diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPALiteralOperator.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPALiteralOperator.java new file mode 100644 index 000000000..b81f3b3d9 --- /dev/null +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPALiteralOperator.java @@ -0,0 +1,89 @@ +package com.sap.olingo.jpa.processor.core.filter; + +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 static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Set; +import java.util.stream.Stream; + +import org.apache.olingo.commons.core.edm.primitivetype.SingletonPrimitiveType; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +import org.apache.olingo.server.api.uri.queryoption.expression.Literal; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; +import org.reflections8.Reflections; +import org.reflections8.scanners.SubTypesScanner; +import org.reflections8.util.ConfigurationBuilder; + +class TestJPALiteralOperator { + private static OData odata = OData.newInstance(); + + @TestFactory + Stream testNonGeometryPrimitiveTypeAreConverted() { + final ConfigurationBuilder configBuilder = new ConfigurationBuilder(); + configBuilder.setScanners(new SubTypesScanner(false)); + configBuilder.forPackages(SingletonPrimitiveType.class.getPackage().getName()); + + final Reflections refection = new Reflections(configBuilder); + final Set> edmPrimitiveTypes = refection.getSubTypesOf( + SingletonPrimitiveType.class); + + return edmPrimitiveTypes + .stream() + .filter(t -> t.getSuperclass() == SingletonPrimitiveType.class) + .map(TestJPALiteralOperator::createEdmPrimitiveType) + .filter(i -> i != null) + .map(TestJPALiteralOperator::createLiteralOperator) + .map(operator -> dynamicTest(operator.getLiteral().getType().getName(), () -> assertTypeConversion(operator))); + } + + private void assertTypeConversion(final JPALiteralOperator operator) throws ODataApplicationException { + final Object act = operator.get(); + assertNotNull(act); + assertFalse(act.toString().contains("'")); + } + + private static SingletonPrimitiveType createEdmPrimitiveType( + final Class typeClass) { + try { + final Method m = typeClass.getMethod("getInstance"); + return (SingletonPrimitiveType) m.invoke(null); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException + | SecurityException e) { + return null; + } + } + + private static JPALiteralOperator createLiteralOperator(final SingletonPrimitiveType typeInstance) { + final Literal l = mock(Literal.class); + when(l.getType()).thenReturn(typeInstance); + when(l.getText()).thenReturn(determineLiteral(typeInstance)); + + return new JPALiteralOperator(odata, l); + } + + private static String determineLiteral(final SingletonPrimitiveType typeInstance) { + switch (typeInstance.getName()) { + case "Guid": + return "819a3e3b-837e-4ecb-a600-654ef7b5aace"; + case "Date": + return "2021-10-01"; + case "Boolean": + return "true"; + case "TimeOfDay": + return "10:00:12.10"; + case "DateTimeOffset": + return "2021-10-01T10:00:12Z"; + case "Duration": + return "P2DT12H30M5S"; + default: + return "123"; + } + } +} \ No newline at end of file diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPAVisitor.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPAVisitor.java index ae93f3817..5a8cf266b 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPAVisitor.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPAVisitor.java @@ -1,6 +1,6 @@ package com.sap.olingo.jpa.processor.core.filter; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -26,7 +26,7 @@ import com.sap.olingo.jpa.processor.core.database.JPAODataDatabaseOperations; import com.sap.olingo.jpa.processor.core.query.JPAAbstractQuery; -public class TestJPAVisitor { +class TestJPAVisitor { private JPAFilterComplierAccess compiler; private JPAAbstractQuery query; @@ -49,34 +49,30 @@ public void setUp() { cut = new JPAVisitor(compiler); } -//return new JPAFunctionOperator(jpaFunction, odataParams, this.jpaComplier.getParent().getRoot(), jpaComplier.getConverter().cb); - @Test - public void createFunctionOperation() throws ExpressionVisitException, ODataApplicationException { + void createFunctionOperation() throws ExpressionVisitException, ODataApplicationException { // final UriResource resource = member.getResourcePath().getUriResourceParts().get(0); - Member member = mock(Member.class); - UriInfoResource info = mock(UriInfoResource.class); - UriResourceFunction uriFunction = mock(UriResourceFunction.class); + final Member member = mock(Member.class); + final UriInfoResource info = mock(UriInfoResource.class); + final UriResourceFunction uriFunction = mock(UriResourceFunction.class); - List resources = new ArrayList<>(); + final List resources = new ArrayList<>(); resources.add(uriFunction); when(member.getResourcePath()).thenReturn(info); when(info.getUriResourceParts()).thenReturn(resources); // final JPAFunction jpaFunction = this.jpaComplier.getSd().getFunction(((UriResourceFunction) resource).getFunction()); - JPAServiceDocument sd = mock(JPAServiceDocument.class); - JPADataBaseFunction jpaFunction = mock(JPADataBaseFunction.class); - EdmFunction edmFunction = mock(EdmFunction.class); + final JPAServiceDocument sd = mock(JPAServiceDocument.class); + final JPADataBaseFunction jpaFunction = mock(JPADataBaseFunction.class); + final EdmFunction edmFunction = mock(EdmFunction.class); when(uriFunction.getFunction()).thenReturn(edmFunction); when(compiler.getSd()).thenReturn(sd); when(sd.getFunction(edmFunction)).thenReturn(jpaFunction); when(uriFunction.getParameters()).thenReturn(new ArrayList()); - if (!(cut.visitMember(member) instanceof JPAFunctionOperator)) { - fail(); - } + assertTrue(cut.visitMember(member) instanceof JPAFunctionOperator); } -} +} \ No newline at end of file diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/util/EdmNavigationPropertyDouble.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/util/EdmNavigationPropertyDouble.java index 8ef7884dc..42ee15626 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/util/EdmNavigationPropertyDouble.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/util/EdmNavigationPropertyDouble.java @@ -7,6 +7,7 @@ import org.apache.olingo.commons.api.edm.EdmAnnotation; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmNavigationProperty; +import org.apache.olingo.commons.api.edm.EdmOnDelete; import org.apache.olingo.commons.api.edm.EdmReferentialConstraint; import org.apache.olingo.commons.api.edm.EdmTerm; @@ -77,4 +78,10 @@ public List getReferentialConstraints() { return null; } + @Override + public EdmOnDelete getOnDelete() { + fail(); + return null; + } + } diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/util/EdmPropertyDouble.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/util/EdmPropertyDouble.java index ea205c54f..4dd67f2c3 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/util/EdmPropertyDouble.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/util/EdmPropertyDouble.java @@ -115,4 +115,10 @@ public EdmType getTypeWithAnnotations() { return null; } + @Override + public String getScaleAsString() { + fail(); + return null; + } + } diff --git a/jpa/odata-jpa-spring-support/pom.xml b/jpa/odata-jpa-spring-support/pom.xml index a16366df5..56d5e4440 100644 --- a/jpa/odata-jpa-spring-support/pom.xml +++ b/jpa/odata-jpa-spring-support/pom.xml @@ -6,7 +6,7 @@ com.sap.olingo odata-jpa - 0.3.9-SNAPSHOT + 0.3.10-SNAPSHOT odata-jpa-spring-support diff --git a/jpa/odata-jpa-test/pom.xml b/jpa/odata-jpa-test/pom.xml index 6fa53004d..9d2664a96 100644 --- a/jpa/odata-jpa-test/pom.xml +++ b/jpa/odata-jpa-test/pom.xml @@ -7,7 +7,7 @@ com.sap.olingo odata-jpa - 0.3.9-SNAPSHOT + 0.3.10-SNAPSHOT odata-jpa-test @@ -16,18 +16,18 @@ https://github.com/SAP/olingo-jpa-processor-v4 UTF-8 - 5.4.4.Final + 5.4.4.Final org.junit.jupiter junit-jupiter - 5.4.2 + 5.8.1 org.junit.platform junit-platform-launcher - 1.4.2 + 1.8.1 org.mockito @@ -72,7 +72,7 @@ org.apache.derby derby - 10.12.1.1 + 10.14.2.0 diff --git a/jpa/pom.xml b/jpa/pom.xml index 6ccb72a48..8adb2c379 100644 --- a/jpa/pom.xml +++ b/jpa/pom.xml @@ -5,7 +5,7 @@ com.sap.olingo odata-jpa - 0.3.9-SNAPSHOT + 0.3.10-SNAPSHOT pom odata-jpa @@ -15,8 +15,8 @@ UTF-8 1.8 3.8.0 - 4.7.1 - 2.9.8 + 4.8.0 + 2.12.5 1.7.1 4.3.0 @@ -39,66 +39,6 @@ - - vulas - - - vulas - - - - 3.1.9 - http://localhost:8033/backend/ - 8DCFB02D5B94AD17C76ED1A5F48DEAED - ${project.groupId} - ${project.artifactId} - ${project.version} - - - - - com.sap.research.security.vulas - plugin-maven - ${vulas.version} - - - ${vulas.shared.backend.serviceUrl} - ${vulas.core.space.token} - - ${vulas.core.appContext.group} - ${vulas.core.appContext.artifact} - ${vulas.core.appContext.version} - - ${project.build.directory}/vulas/tmp - ${project.build.directory}/vulas/upload - ${project.build.directory}/classes,${project.basedir}/src/main/java,${project.basedir}/src/main/python - - - ${project.build.directory} - ${project.build.directory}/vulas/target - ${project.build.directory}/vulas/include - ${project.build.directory}/vulas/lib - false - com.sap.psr.vulas.monitor.trace.SingleTraceInstrumentor - false - false - 10 - - - NO_FLOW_TO_CASTS_NO_METHOD_INVOKE - 60 - - - - ${project.build.directory}/vulas/report - - - - - -