From c41d10e8dcc09fb357ff146fe2e482104794420a Mon Sep 17 00:00:00 2001 From: ramya vasanth Date: Wed, 15 May 2019 11:29:01 +0530 Subject: [PATCH] [OLINGO-1062] Code improvements for support of annotations --- .../core/edm/ClientCsdlEdmProvider.java | 2 +- .../olingo/client/core/MetadataTest.java | 543 ++++++++++++-- .../apache/olingo/client/core/$metadata.xml | 209 +++++- .../olingo/client/core/Capabilities.xml | 559 +++++++++++++++ .../apache/olingo/client/core/Integration.xml | 77 ++ .../apache/olingo/client/core/annotations.xml | 40 +- .../olingo/commons/core/edm/AbstractEdm.java | 8 + .../core/edm/EdmEntityContainerImpl.java | 666 ++++++++++++------ .../commons/core/edm/EdmProviderImpl.java | 637 ++++++++++++----- .../commons/core/edm/EdmSchemaImpl.java | 7 + 10 files changed, 2270 insertions(+), 478 deletions(-) create mode 100644 lib/client-core/src/test/resources/org/apache/olingo/client/core/Capabilities.xml create mode 100644 lib/client-core/src/test/resources/org/apache/olingo/client/core/Integration.xml diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/ClientCsdlEdmProvider.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/ClientCsdlEdmProvider.java index 7ebb8c88b..f683a68e7 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/ClientCsdlEdmProvider.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/ClientCsdlEdmProvider.java @@ -202,7 +202,7 @@ public class ClientCsdlEdmProvider extends CsdlAbstractEdmProvider { public CsdlAnnotations getAnnotationsGroup(FullQualifiedName targetName, String qualifier) throws ODataException { CsdlSchema schema = xmlSchemas.get(targetName.getNamespace()); if (schema != null) { - return schema.getAnnotationGroup(targetName.getName(), qualifier); + return schema.getAnnotationGroup(targetName.getFullQualifiedNameAsString(), qualifier); } return null; } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java index 3fc21d9ca..76872c11a 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java @@ -42,6 +42,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmEnumType; import org.apache.olingo.commons.api.edm.EdmFunction; import org.apache.olingo.commons.api.edm.EdmFunctionImport; +import org.apache.olingo.commons.api.edm.EdmMember; import org.apache.olingo.commons.api.edm.EdmNavigationProperty; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.EdmProperty; @@ -50,6 +51,9 @@ import org.apache.olingo.commons.api.edm.EdmSingleton; import org.apache.olingo.commons.api.edm.EdmTerm; import org.apache.olingo.commons.api.edm.EdmTypeDefinition; import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.annotation.EdmCollection; +import org.apache.olingo.commons.api.edm.annotation.EdmConstantExpression; +import org.apache.olingo.commons.api.edm.annotation.EdmDynamicExpression; import org.apache.olingo.commons.api.edm.annotation.EdmExpression; import org.apache.olingo.commons.api.edm.annotation.EdmPropertyValue; import org.apache.olingo.commons.api.edm.annotation.EdmRecord; @@ -546,7 +550,7 @@ public class MetadataTest extends AbstractTest { new FullQualifiedName("SEPMRA_SO_MAN2", "SEPMRA_C_SalesOrderCustCntctVHType")); EdmAnnotation annotation = entity1.getAnnotations().get(0); assertNotNull(annotation); - assertEquals(5, entity1.getAnnotations().size()); + assertEquals(6, entity1.getAnnotations().size()); assertEquals("FieldGroup", annotation.getTerm().getName()); assertEquals("ContactPerson", annotation.getQualifier()); EdmExpression expression = annotation.getExpression(); @@ -563,7 +567,7 @@ public class MetadataTest extends AbstractTest { assertEquals("Label", propertyValues.get(1).getProperty()); assertEquals("Contact Person", propertyValues.get(1).getValue().asConstant().asPrimitive()); - assertEquals(1, entity1.getNavigationProperty("to_Customer").getAnnotations().size()); + assertEquals(2, entity1.getNavigationProperty("to_Customer").getAnnotations().size()); EdmNavigationProperty navProperty = entity1.getNavigationProperty("to_Customer"); assertEquals("ThingPerspective", navProperty. getAnnotations().get(0).getTerm().getName()); @@ -588,7 +592,7 @@ public class MetadataTest extends AbstractTest { assertNotNull(edm); EdmEntityContainer container = edm.getEntityContainer(); EdmActionImport actionImport = container.getActionImport("AIRTString"); - assertEquals(3, actionImport.getAnnotations().size()); + assertEquals(4, actionImport.getAnnotations().size()); assertEquals("Description", actionImport.getAnnotations().get(0).getTerm().getName()); assertEquals("HeaderInfo", actionImport.getAnnotations().get(2).getTerm().getName()); } @@ -599,15 +603,18 @@ public class MetadataTest extends AbstractTest { assertNotNull(edm); EdmEntityContainer container = edm.getEntityContainer(); EdmSingleton singleton = container.getSingleton("SINav"); - assertEquals(1, singleton.getAnnotations().size()); - assertEquals("HeaderInfo", singleton.getAnnotations().get(0).getTerm().getName()); - + assertEquals(2, singleton.getAnnotations().size()); + FullQualifiedName termName = new FullQualifiedName("UI", "HeaderInfo"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = singleton.getAnnotation(term, null); + assertNotNull(annotation); + EdmEntityType singletonET = singleton.getEntityType(); - EdmProperty singlComplexProp = (EdmProperty)singletonET.getProperty("ComplexProperty"); + EdmProperty singlComplexProp = (EdmProperty) singletonET.getProperty("ComplexProperty"); EdmComplexType singlCompType = (EdmComplexType) singlComplexProp.getTypeWithAnnotations(); - EdmNavigationProperty singlNavProp = (EdmNavigationProperty) singlCompType. - getNavigationProperty("NavPropertyDraftAdministrativeDataType"); - assertEquals(1, singlNavProp.getAnnotations().size()); + EdmNavigationProperty singlNavProp = (EdmNavigationProperty) singlCompType.getNavigationProperty( + "NavPropertyDraftAdministrativeDataType"); + assertEquals(2, singlNavProp.getAnnotations().size()); assertEquals("AdditionalInfo", singlNavProp.getAnnotations().get(0).getTerm().getName()); } @@ -616,15 +623,26 @@ public class MetadataTest extends AbstractTest { final Edm edm = fetchEdm(); assertNotNull(edm); List parameterNames = new ArrayList(); - EdmFunction function = edm.getBoundFunction(new FullQualifiedName("SEPMRA_SO_MAN2", "_FC_RTTimeOfDay_"), - new FullQualifiedName("Edm","TimeOfDay"), false, parameterNames); - assertEquals(1, function.getAnnotations().size()); + EdmFunction function = edm.getBoundFunction(new FullQualifiedName("SEPMRA_SO_MAN2", "_FC_RTTimeOfDay_"), + new FullQualifiedName("Edm", "TimeOfDay"), false, parameterNames); + assertEquals(2, function.getAnnotations().size()); assertEquals("HeaderInfo", function.getAnnotations().get(0).getTerm().getName()); + + FullQualifiedName termName = + new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = function.getAnnotation(term, null); + assertNotNull(annotation); // Annotations on Bound Function parameter - assertEquals(1, function.getParameter("ParameterTimeOfDay").getAnnotations().size()); + assertEquals(2, function.getParameter("ParameterTimeOfDay").getAnnotations().size()); assertEquals("HeaderInfo", function.getParameter("ParameterTimeOfDay") .getAnnotations().get(0).getTerm().getName()); + termName = + new FullQualifiedName("UI", "AdditionalInfo"); + term = edm.getTerm(termName); + annotation = function.getParameter("ParameterTimeOfDay").getAnnotation(term, null); + assertNotNull(annotation); } @Test @@ -633,8 +651,8 @@ public class MetadataTest extends AbstractTest { assertNotNull(edm); EdmSchema schema = edm.getSchema("sepmra_so_man2_anno_mdl.v1"); assertNotNull(schema); - assertEquals(112, schema.getAnnotationGroups().size()); - + assertEquals(117, schema.getAnnotationGroups().size()); + EdmAnnotations annotations = edm.getSchema("SEPMRA_SO_MAN2").getAnnotationGroups().get(22); assertEquals("SEPMRA_SO_MAN2.SEPMRA_C_SalesOrderCustCntctVHType", annotations.getTargetPath()); assertEquals(1, annotations.getAnnotations().size()); @@ -648,8 +666,8 @@ public class MetadataTest extends AbstractTest { final Edm edm = fetchEdm(); assertNotNull(edm); EdmEntityContainer container = edm.getEntityContainer(); - assertEquals(1, container.getAnnotations().size()); - assertEquals("HeaderInfo", container.getAnnotations().get(0).getTerm().getName()); + assertEquals(5, container.getAnnotations().size()); + assertEquals("HeaderInfo", container.getAnnotations().get(1).getTerm().getName()); } @Test @@ -658,17 +676,22 @@ public class MetadataTest extends AbstractTest { assertNotNull(edm); EdmComplexType complexType = edm.getComplexTypeWithAnnotations( new FullQualifiedName("SEPMRA_SO_MAN2", "CTPrim")); - assertEquals(1, complexType.getAnnotations().size()); + assertEquals(2, complexType.getAnnotations().size()); assertEquals("HeaderInfo", complexType.getAnnotations().get(0).getTerm().getName()); // Annotations on complex type property EdmProperty complexTypeProp = (EdmProperty) complexType.getProperty("PropertyInt16"); assertEquals(1, complexTypeProp.getAnnotations().size()); assertEquals("HeaderInfo", complexTypeProp.getAnnotations().get(0).getTerm().getName()); // Annotations on complex type navigation property - EdmNavigationProperty complexTypeNavProp = complexType. - getNavigationProperty("NavPropertyDraftAdministrativeDataType"); + EdmNavigationProperty complexTypeNavProp = complexType.getNavigationProperty( + "NavPropertyDraftAdministrativeDataType"); assertEquals(1, complexTypeNavProp.getAnnotations().size()); assertEquals("HeaderInfo", complexTypeNavProp.getAnnotations().get(0).getTerm().getName()); + + FullQualifiedName termName = new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = complexType.getAnnotation(term, null); + assertNotNull(annotation); } @Test @@ -676,23 +699,28 @@ public class MetadataTest extends AbstractTest { final Edm edm = fetchEdm(); assertNotNull(edm); EdmTypeDefinition typeDefn = edm.getTypeDefinition(new FullQualifiedName("SEPMRA_SO_MAN2", "TDString")); - assertEquals(1, typeDefn.getAnnotations().size()); - assertEquals("HeaderInfo", typeDefn.getAnnotations().get(0).getTerm().getName()); + assertEquals(3, typeDefn.getAnnotations().size()); + assertEquals("OriginalDataType", typeDefn.getAnnotations().get(0).getTerm().getName()); } @Test public void readAnnotationOnBoundActions() { final Edm edm = fetchEdm(); assertNotNull(edm); - EdmAction action = edm.getBoundAction(new FullQualifiedName("SEPMRA_SO_MAN2", "BA_RTCountryVHType"), - new FullQualifiedName("SEPMRA_SO_MAN2","I_DraftAdministrativeDataType"), false); + EdmAction action = edm.getBoundAction(new FullQualifiedName("SEPMRA_SO_MAN2", "BA_RTCountryVHType"), + new FullQualifiedName("SEPMRA_SO_MAN2", "I_DraftAdministrativeDataType"), false); assertEquals(1, action.getAnnotations().size()); assertEquals("HeaderInfo", action.getAnnotations().get(0).getTerm().getName()); - - //Annotations on Bound Action parameter - assertEquals(1, action.getParameter("ParameterCTPrim").getAnnotations().size()); + + // Annotations on Bound Action parameter + assertEquals(2, action.getParameter("ParameterCTPrim").getAnnotations().size()); assertEquals("HeaderInfo", action.getParameter("ParameterCTPrim") .getAnnotations().get(0).getTerm().getName()); + + FullQualifiedName termName = new FullQualifiedName("UI", "AdditionalInfo"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = action.getParameter("ParameterCTPrim").getAnnotation(term, null); + assertNotNull(annotation); } @Test @@ -703,58 +731,50 @@ public class MetadataTest extends AbstractTest { EdmEntitySet entitySet = container.getEntitySet("I_DraftAdministrativeData"); assertEquals(1, entitySet.getAnnotations().size()); assertEquals("HeaderInfo", entitySet.getAnnotations().get(0).getTerm().getName()); - - - + EdmEntityType entityType50 = edm.getEntityTypeWithAnnotations( new FullQualifiedName("SEPMRA_SO_MAN2", "I_DraftAdministrativeDataType")); - assertEquals(1, ((EdmProperty)entityType50.getProperty("DraftUUID")).getAnnotations().size()); - assertEquals("UI.HeaderInfo", ((EdmProperty)entityType50.getProperty("DraftUUID")). - getAnnotations().get(0).getTerm().getFullQualifiedName().getFullQualifiedNameAsString()); - - - + assertEquals(1, ((EdmProperty) entityType50.getProperty("DraftUUID")).getAnnotations().size()); + assertEquals("UI.HeaderInfo", ((EdmProperty) entityType50.getProperty("DraftUUID")).getAnnotations().get(0) + .getTerm().getFullQualifiedName().getFullQualifiedNameAsString()); + // Annotations on properties of entity type included in EntitySet EdmEntityType entityType3 = entitySet.getEntityTypeWithAnnotations(); - assertEquals(2, ((EdmProperty)entityType3.getProperty("DraftUUID")).getAnnotations().size()); - assertEquals("AdditionalInfo", ((EdmProperty)entityType3.getProperty("DraftUUID")) + assertEquals(3, ((EdmProperty) entityType3.getProperty("DraftUUID")).getAnnotations().size()); + assertEquals("AdditionalInfo", ((EdmProperty) entityType3.getProperty("DraftUUID")) .getAnnotations().get(0).getTerm().getName()); - assertEquals("HeaderInfo", ((EdmProperty)entityType3.getProperty("DraftUUID")) + assertEquals("HeaderInfo", ((EdmProperty) entityType3.getProperty("DraftUUID")) .getAnnotations().get(1).getTerm().getName()); - + // Annotations on navigation properties of entity type included in EntitySet EdmEntitySet entitySet1 = container.getEntitySet("SEPMRA_C_SalesOrderCustCntctVH"); EdmEntityType entityType5 = entitySet1.getEntityTypeWithAnnotations(); - assertEquals(2, ((EdmNavigationProperty)entityType5.getNavigationProperty("to_Customer")) + assertEquals(2, ((EdmNavigationProperty) entityType5.getNavigationProperty("to_Customer")) .getAnnotations().size()); - assertEquals("AdditionalInfo", ((EdmNavigationProperty)entityType5 + assertEquals("AdditionalInfo", ((EdmNavigationProperty) entityType5 .getNavigationProperty("to_Customer")) - .getAnnotations().get(0).getTerm().getName()); - assertEquals("HeaderInfo", ((EdmNavigationProperty)entityType5 + .getAnnotations().get(0).getTerm().getName()); + assertEquals("HeaderInfo", ((EdmNavigationProperty) entityType5 .getNavigationProperty("to_Customer")) - .getAnnotations().get(1).getTerm().getName()); - - - - EdmComplexType complexType = edm.getComplexTypeWithAnnotations( + .getAnnotations().get(1).getTerm().getName()); + + EdmComplexType complexType = edm.getComplexTypeWithAnnotations( new FullQualifiedName("SEPMRA_SO_MAN2", "CTPrim")); EdmProperty complexTypeProp = (EdmProperty) complexType.getProperty("PropertyInt16"); assertEquals(1, complexTypeProp.getAnnotations().size()); assertEquals("HeaderInfo", complexTypeProp.getAnnotations().get(0).getTerm().getName()); - - - + // Annotations on properties of complex properties of entity type included in EntitySet EdmProperty complexProp = (EdmProperty) entityType3.getProperty("ComplexProperty"); EdmComplexType compType = (EdmComplexType) complexProp.getTypeWithAnnotations(); EdmProperty prop = (EdmProperty) compType.getProperty("PropertyInt16"); - assertEquals(1, prop.getAnnotations().size()); + assertEquals(2, prop.getAnnotations().size()); assertEquals("AdditionalInfo", prop.getAnnotations().get(0).getTerm().getName()); - + // Annotations on navigation properties of complex properties of entity type included in EntitySet EdmNavigationProperty navProp = (EdmNavigationProperty) compType .getProperty("NavPropertyDraftAdministrativeDataType"); - assertEquals(1, navProp.getAnnotations().size()); + assertEquals(2, navProp.getAnnotations().size()); assertEquals("AdditionalInfo", navProp.getAnnotations().get(0).getTerm().getName()); } @@ -763,8 +783,417 @@ public class MetadataTest extends AbstractTest { streams.add(getClass().getResourceAsStream("annotations.xml")); streams.add(getClass().getResourceAsStream("VOC_Core.xml")); streams.add(getClass().getResourceAsStream("UI.xml")); + streams.add(getClass().getResourceAsStream("Capabilities.xml")); + streams.add(getClass().getResourceAsStream("Integration.xml")); final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("$metadata.xml"), streams); - return edm; + return edm; + } + + @Test + public void readAnnotationOnFunctionImport() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmEntityContainer container = edm.getEntityContainer(); + EdmFunctionImport functionImport = container.getFunctionImport("FIC_RTTimeOfDay_"); + assertEquals(3, functionImport.getAnnotations().size()); + + FullQualifiedName termName = new FullQualifiedName("UI", "Identification"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = functionImport.getAnnotation(term, null); + assertNotNull(annotation); + + } + + @Test + public void readAnnotationWithinMetadataFile() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + + //Get Annotations on entity types derived from edm + EdmEntityType entityType = edm.getEntityTypeWithAnnotations( + new FullQualifiedName("SEPMRA_SO_MAN2", "CDI_CDC_SOURCEResult")); + FullQualifiedName termName; + EdmTerm term; + EdmAnnotation annotation; + String valueAsString; + checkAnnotationsOnEntityType(edm, entityType); + + assertEquals(3, ((EdmProperty) entityType.getProperty("CHANGED")).getAnnotations().size()); + // Get the term defined on the entity property + termName = + new FullQualifiedName("Integration", "OriginalDataType"); + term = edm.getTerm(termName); + annotation = ((EdmProperty) entityType.getProperty("CHANGED")).getAnnotation(term, null); + assertNotNull(annotation); + valueAsString = annotation.getExpression().asConstant().getValueAsString(); + assertEquals("TIMESTAMP" , valueAsString); + + termName = + new FullQualifiedName("Integration", "SourceSystem"); + term = edm.getTerm(termName); + annotation = ((EdmProperty) entityType.getProperty("CHANGED")).getAnnotation(term, null); + assertNotNull(annotation); + valueAsString = annotation.getExpression().asConstant().getValueAsString(); + assertEquals("DB" , valueAsString); + + // Get annotations added on container + EdmEntityContainer container = edm.getEntityContainer(); + assertEquals(5, container.getAnnotations().size()); + // Get the term defined on the entity container + termName = + new FullQualifiedName("Integration", "SourceSystem"); + term = edm.getTerm(termName); + annotation = container.getAnnotation(term, null); + assertNotNull(annotation); + valueAsString = annotation.getExpression().asConstant().getValueAsString(); + assertEquals("DB", valueAsString); + + termName = + new FullQualifiedName("Integration", "Extractable"); + term = edm.getTerm(termName); + annotation = container.getAnnotation(term, null); + assertNotNull(annotation); + valueAsString = annotation.getExpression().asConstant().getValueAsString(); + assertTrue(Boolean.valueOf(valueAsString)); + + //Get the annotations defined on type definitions + final EdmTypeDefinition defn = edm.getTypeDefinition(new FullQualifiedName("SEPMRA_SO_MAN2", "TDString")); + assertNotNull(defn); + assertEquals(3, defn.getAnnotations().size()); + termName = + new FullQualifiedName("Integration", "Extractable"); + term = edm.getTerm(termName); + annotation = defn.getAnnotation(term, null); + assertNotNull(annotation); + valueAsString = annotation.getExpression().asConstant().getValueAsString(); + assertTrue(Boolean.valueOf(valueAsString)); + + termName = + new FullQualifiedName("UI", "HeaderInfo"); + term = edm.getTerm(termName); + annotation = defn.getAnnotation(term, null); + assertNotNull(annotation); + assertEquals("HeaderInfo", annotation.getTerm().getName()); + + // Get the annotations defined on entity set + container = edm.getEntityContainer(); + EdmEntitySet entitySet = container.getEntitySet("CDI_CDC_SOURCEResult"); + assertEquals(3, entitySet.getAnnotations().size()); + assertEquals("SourceSystem", entitySet.getAnnotations().get(0).getTerm().getName()); + assertEquals("Extractable", entitySet.getAnnotations().get(1).getTerm().getName()); + + termName = + new FullQualifiedName("UI", "Identification"); + term = edm.getTerm(termName); + annotation = entitySet.getAnnotation(term, null); + assertNotNull(annotation); + + EdmExpression expression = annotation.getExpression(); + EdmDynamicExpression asDynamic = expression.asDynamic(); + if ((asDynamic != null) && (asDynamic.isCollection())) { + EdmCollection collection = asDynamic.asCollection(); + EdmExpression exp = collection.getItems().get(0); + EdmRecord asRecord = exp.asDynamic().asRecord(); + if (asRecord != null) { + List propertyValues = asRecord.getPropertyValues(); + if (propertyValues != null) { + for (int i = 0; i < propertyValues.size(); i++) { + EdmPropertyValue edmPropertyValue = propertyValues.get(i); + String property = edmPropertyValue.getProperty(); + if (property.equals("Value")) { + EdmExpression value = edmPropertyValue.getValue(); + assertNotNull(value); + assertEquals("Path", value.getExpressionName()); + } + } + } + } + } + + // Get the annotations defined on entity type derived from entity set + entityType = entitySet.getEntityTypeWithAnnotations(); + checkAnnotationsOnEntityType(edm, entityType); + assertEquals(2, ((EdmProperty) entityType.getProperty("CHANGED")).getAnnotations().size()); + + termName = + new FullQualifiedName("Integration", "OriginalDataType"); + term = edm.getTerm(termName); + annotation = ((EdmProperty) entityType.getProperty("CHANGED")).getAnnotation(term, null); + assertNotNull(annotation); + valueAsString = annotation.getExpression().asConstant().getValueAsString(); + assertEquals("TIMESTAMP" , valueAsString); + + termName = + new FullQualifiedName("Integration", "Extractable"); + term = edm.getTerm(termName); + annotation = ((EdmProperty) entityType.getProperty("CHANGED")).getAnnotation(term, null); + assertNotNull(annotation); + valueAsString = annotation.getExpression().asConstant().getValueAsString(); + assertTrue(Boolean.valueOf(valueAsString)); + + assertEquals(3, entityType.getAnnotations().size()); + termName = + new FullQualifiedName("Capabilities", "ChangeTracking"); + term = edm.getTerm(termName); + annotation = entityType.getAnnotation(term, null); + assertNotNull(annotation); + + expression = annotation.getExpression(); + asDynamic = expression.asDynamic(); + if ((asDynamic != null) && (asDynamic.isRecord())) { + EdmRecord asRecord = asDynamic.asRecord(); + if (asRecord != null) { + List propertyValues = asRecord.getPropertyValues(); + if (propertyValues != null) { + for (int i = 0; i < propertyValues.size(); i++) { + EdmPropertyValue edmPropertyValue = propertyValues.get(i); + String property = edmPropertyValue.getProperty(); + if (property.equals("Supported")) { + EdmExpression value = edmPropertyValue.getValue(); + EdmConstantExpression asConstant2 = value.asConstant(); + String valueAsString1 = asConstant2.getValueAsString(); + assertTrue(Boolean.valueOf(valueAsString1)); + } + } + } + } + } + } + + /** + * @param edm + * @param entityType + */ + private void checkAnnotationsOnEntityType(final Edm edm, EdmEntityType entityType) { + FullQualifiedName termName = + new FullQualifiedName("Capabilities", "ChangeTracking"); + // Get the term defined on the entity type + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotationChangeTracking = entityType.getAnnotation(term, null); + assertNotNull(annotationChangeTracking); + if (annotationChangeTracking != null) { + EdmExpression expression = annotationChangeTracking.getExpression(); + EdmDynamicExpression asDynamic = expression.asDynamic(); + if ((asDynamic != null) && (asDynamic.isRecord())) { + EdmRecord asRecord = asDynamic.asRecord(); + if (asRecord != null) { + List propertyValues = asRecord.getPropertyValues(); + if (propertyValues != null) { + for (int i = 0; i < propertyValues.size(); i++) { + EdmPropertyValue edmPropertyValue = propertyValues.get(i); + String property = edmPropertyValue.getProperty(); + if (property.equals("Supported")) { + EdmExpression value = edmPropertyValue.getValue(); + EdmConstantExpression asConstant2 = value.asConstant(); + String valueAsString = asConstant2.getValueAsString(); + assertTrue(Boolean.valueOf(valueAsString)); + } + } + } + } + } + } + termName = + new FullQualifiedName("Integration", "Extractable"); + term = edm.getTerm(termName); + EdmAnnotation annotation = entityType.getAnnotation(term, null); + assertNotNull(annotation); + String valueAsString = annotation.getExpression().asConstant().getValueAsString(); + assertTrue(Boolean.valueOf(valueAsString)); + } + + @Test + public void readAnnotationWithAliasOnEntityTypesProperties() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmEntityType entityType = edm.getEntityTypeWithAnnotations(new FullQualifiedName("Test.CDI_CDC_SOURCEResult")); + List annotations = ((EdmProperty)entityType.getProperty("CHANGED")).getAnnotations(); + assertEquals(3, annotations.size()); + + FullQualifiedName termName = + new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = ((EdmProperty)entityType.getProperty("CHANGED")).getAnnotation(term, null); + assertNotNull(annotation); + + entityType = edm.getEntityTypeWithAnnotations( + new FullQualifiedName("Test.SEPMRA_C_SalesOrderCustCntctVHType")); + List annotationsOnNavProp = ((EdmNavigationProperty)entityType. + getNavigationProperty("to_Customer")).getAnnotations(); + assertEquals(2, annotationsOnNavProp.size()); + + termName = + new FullQualifiedName("UI", "HeaderInfo"); + term = edm.getTerm(termName); + annotation = ((EdmNavigationProperty)entityType.getNavigationProperty("to_Customer")). + getAnnotation(term, null); + assertNotNull(annotation); + } + + @Test + public void readAnnotationWithAliasOnEntitySetProperties() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmEntityContainer container = edm.getEntityContainer(); + EdmEntitySet entitySet = container.getEntitySet("I_DraftAdministrativeData"); + EdmEntityType entityType = entitySet.getEntityTypeWithAnnotations(); + List annotations = ((EdmProperty)entityType.getProperty("DraftUUID")).getAnnotations(); + assertEquals(3, annotations.size()); + + FullQualifiedName termName = + new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = ((EdmProperty)entityType.getProperty("DraftUUID")).getAnnotation(term, null); + assertNotNull(annotation); + + } + + @Test + public void readAnnotationFetchingAllSingletons() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmEntityContainer container = edm.getEntityContainer(); + List singletons = container.getSingletons(); + assertEquals(1, singletons.size()); + + FullQualifiedName termName = new FullQualifiedName("UI", "HeaderInfo"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = singletons.get(0).getAnnotation(term, null); + assertNotNull(annotation); + } + + @Test + public void readAnnotationFetchingAllActionImports() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmEntityContainer container = edm.getEntityContainer(); + List actionImports = container.getActionImports(); + assertEquals(1, actionImports.size()); + } + + @Test + public void readAnnotationFetchingAllFunctionImports() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmEntityContainer container = edm.getEntityContainer(); + List functionImports = container.getFunctionImports(); + assertEquals(1, functionImports.size()); + + FullQualifiedName termName = new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = functionImports.get(0).getAnnotation(term, null); + assertNotNull(annotation); + } + + @Test + public void readAnnotationFetchingAllEntitySets() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmEntityContainer container = edm.getEntityContainer(); + List entitySets = container.getEntitySets(); + assertEquals(4, entitySets.size()); + + FullQualifiedName termName = new FullQualifiedName("UI", "HeaderInfo"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = entitySets.get(0).getAnnotation(term, null); + assertNotNull(annotation); + } + + @Test + public void readAnnotationOnEnumTypes() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmEnumType enumType = edm.getEnumType(new FullQualifiedName("SEPMRA_SO_MAN2.ENString")); + EdmMember member = enumType.getMember("String1"); + assertEquals(1, member.getAnnotations().size()); + FullQualifiedName termName = new FullQualifiedName("Integration", "OriginalDataType"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = member.getAnnotation(term, null); + assertNotNull(annotation); + } + + @Test + public void readAnnotationOnFunction() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + List function = edm.getUnboundFunctions(new FullQualifiedName("SEPMRA_SO_MAN2", "UFCRTCollString")); + assertEquals(1, function.size()); + List annotations = function.get(0).getAnnotations(); + assertEquals(2, annotations.size()); + + FullQualifiedName termName = + new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = function.get(0).getAnnotation(term, null); + assertNotNull(annotation); + + } + + @Test + public void readAnnotationOnFunctionWithParameters() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + List paramNames = new ArrayList(); + paramNames.add("ParameterString"); + paramNames.add("ParameterInt16"); + EdmFunction function = edm.getUnboundFunction( + new FullQualifiedName("SEPMRA_SO_MAN2", "UFCRTStringTwoParam"), paramNames); + assertNotNull(function); + List annotations = function.getAnnotations(); + assertEquals(2, annotations.size()); + + FullQualifiedName termName = + new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = function.getAnnotation(term, null); + assertNotNull(annotation); + + termName = + new FullQualifiedName("UI", "AdditionalInfo"); + term = edm.getTerm(termName); + annotation = function.getParameter("ParameterString").getAnnotation(term, null); + assertNotNull(annotation); + + } + + @Test + public void readAnnotationOnAction() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + EdmAction action = edm.getUnboundAction(new FullQualifiedName("SEPMRA_SO_MAN2", "UARTString")); + List annotations = action.getAnnotations(); + assertEquals(2, annotations.size()); + + FullQualifiedName termName = + new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = action.getAnnotation(term, null); + assertNotNull(annotation); + + } + + @Test + public void readAnnotationGroup() { + final Edm edm = fetchEdm(); + assertNotNull(edm); + // Read annotations on annotation group within metadata file + EdmAnnotations annotations = edm.getAnnotationGroup( + new FullQualifiedName("SEPMRA_SO_MAN2", "CDI_CDC_SOURCEResult"), null); + assertNotNull(annotations); + FullQualifiedName termName = new FullQualifiedName("Integration", "Extractable"); + EdmTerm term = edm.getTerm(termName); + EdmAnnotation annotation = annotations.getAnnotation(term, null); + assertNotNull(annotation); + + //Read annotations on annotation group from external file + annotations = edm.getAnnotationGroup( + new FullQualifiedName( + "SEPMRA_SO_MAN2.SEPMRA_SO_MAN2_Entities/I_DraftAdministrativeData/ComplexProperty/PropertyInt16"), null); + assertNotNull(annotations); + termName = new FullQualifiedName("UI", "AdditionalInfo"); + term = edm.getTerm(termName); + annotation = annotations.getAnnotation(term, null); + assertNotNull(annotation); } } diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/$metadata.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/$metadata.xml index 4a29589d4..d7072de1d 100644 --- a/lib/client-core/src/test/resources/org/apache/olingo/client/core/$metadata.xml +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/$metadata.xml @@ -26,14 +26,28 @@ + + + + + + - + - + + + TIMESTAMP + + - + + + TIMESTAMP + + @@ -79,6 +93,36 @@ + + + + + + + TIMESTAMP + + + + + TIMESTAMP + + + + + INTEGER + + + + + VARCHAR + + + + + INTEGER + + + @@ -93,6 +137,9 @@ + + + @@ -102,13 +149,21 @@ + + + + + + + + - + Action Import returns a simple String @@ -116,11 +171,29 @@ true + + + + Overload with same unbound parameter name and different type Composable Importing:Edm.TimeOfDay (Edm.TimeOfDay) Returning:Edm.TimeOfDay + + + + false + + + + + DB + + + + DB + - + @@ -773,6 +846,132 @@ + + + + + + true + + + + + true + + + + + DB + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + true + + + + + true + + + + + + + + + + + + SEPMRA_SO_MAN2.SEPMRA_SO_MAN2_Entities/SEPMRA_C_SalesOrderTP + + + + + + true + + + + + true + + + + + + + + true + + + + + + + + + + + + + + + + + true + + + + + + + + true + + + + + + + + + + + + + + + + diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/Capabilities.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/Capabilities.xml new file mode 100644 index 000000000..d4376c964 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/Capabilities.xml @@ -0,0 +1,559 @@ + + + + + + + + + + + + + Terms describing capabilities of a service + + + + + + + + + + + + + + + + + + + +There are some capabilities which are strongly recommended for services to support even +though they are optional. Support for $top and $skip is a good example as +supporting these query options helps with performance of a service and are essential. Such +capabilities are assumed to be default capabilities of an OData service even in +the case that a capabilities annotation doesn’t exist. Capabilities annotations are +mainly expected to be used to explicitly specify that a service doesn’t support such +capabilities. Capabilities annotations can as well be used to declaratively +specify the support of such capabilities. + +On the other hand, there are some capabilities that a service may choose to support or +not support and in varying degrees. $filter and $orderby are such good examples. +This vocabulary aims to define terms to specify support or no support for such +capabilities. + +A service is assumed to support by default the following capabilities even though an +annotation doesn’t exist: +- Countability ($count) +- Client pageability ($top, $skip) +- Expandability ($expand) +- Indexability by key +- Batch support ($batch) +- Navigability of navigation properties + +A service is expected to support the following capabilities. If not supported, the +service is expected to call out the restrictions using annotations: +- Filterability ($filter) +- Sortability ($orderby) +- Queryability of top level entity sets +- Query functions + +A client cannot assume that a service supports certain capabilities. A client can try, but +it needs to be prepared to handle an error in case the following capabilities are not +supported: +- Insertability +- Updatability +- Deletability + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/Integration.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/Integration.xml new file mode 100644 index 000000000..55bb9d19d --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/Integration.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + Terms describing data extraction capabilities + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/annotations.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/annotations.xml index a89467da6..4670d85bc 100644 --- a/lib/client-core/src/test/resources/org/apache/olingo/client/core/annotations.xml +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/annotations.xml @@ -34,12 +34,18 @@ + + + - + + + + @@ -48,8 +54,6 @@ - - @@ -70,7 +74,7 @@ - + @@ -87,7 +91,7 @@ - + @@ -147,6 +151,9 @@ + + + @@ -1271,6 +1278,29 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdm.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdm.java index 06d053ed3..aa5a52eee 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdm.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdm.java @@ -37,6 +37,7 @@ import org.apache.olingo.commons.api.edm.EdmSchema; import org.apache.olingo.commons.api.edm.EdmTerm; import org.apache.olingo.commons.api.edm.EdmTypeDefinition; import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation; public abstract class AbstractEdm implements Edm { @@ -96,6 +97,9 @@ public abstract class AbstractEdm implements Edm { private final Map complexTypesDerivedFromES = Collections.synchronizedMap(new HashMap()); + private Map> annotationMap = + new HashMap>(); + @Override public List getSchemas() { if (schemaList == null) { @@ -547,4 +551,8 @@ public abstract class AbstractEdm implements Edm { protected boolean isPreviousES() { return isPreviousES; } + + protected Map> getAnnotationsMap() { + return annotationMap; + } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityContainerImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityContainerImpl.java index 9255cdabb..86733ee7a 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityContainerImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityContainerImpl.java @@ -24,7 +24,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.apache.olingo.commons.api.ex.ODataException; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmActionImport; import org.apache.olingo.commons.api.edm.EdmEntityContainer; @@ -34,8 +33,8 @@ import org.apache.olingo.commons.api.edm.EdmFunctionImport; import org.apache.olingo.commons.api.edm.EdmSingleton; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.provider.CsdlActionImport; +import org.apache.olingo.commons.api.edm.provider.CsdlAliasInfo; import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation; -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.CsdlEdmProvider; import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; @@ -44,8 +43,8 @@ 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.CsdlFunctionImport; import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty; +import org.apache.olingo.commons.api.edm.provider.CsdlOperationImport; import org.apache.olingo.commons.api.edm.provider.CsdlProperty; -import org.apache.olingo.commons.api.edm.provider.CsdlSchema; import org.apache.olingo.commons.api.edm.provider.CsdlSingleton; import org.apache.olingo.commons.api.ex.ODataException; @@ -75,6 +74,8 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit private final Map singletonWithAnnotationsCache = Collections.synchronizedMap( new LinkedHashMap()); private boolean isSingletonAnnotationsIncluded = false; + private final String SLASH = "/"; + private final String DOT = "."; public EdmEntityContainerImpl(final Edm edm, final CsdlEdmProvider provider, final CsdlEntityContainerInfo entityContainerInfo) { @@ -216,7 +217,7 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit try { final CsdlSingleton providerSingleton = provider.getSingleton(entityContainerName, singletonName); if (providerSingleton != null) { - addAnnotations(providerSingleton, entityContainerName); + addSingletonAnnotations(providerSingleton, entityContainerName); singleton = new EdmSingletonImpl(edm, this, providerSingleton); } } catch (ODataException e) { @@ -226,61 +227,130 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit return singleton; } - private void addAnnotations(CsdlSingleton singleton, FullQualifiedName entityContainerName) { - boolean isPropAnnotationsCleared = false; - boolean isNavPropAnnotationsCleared = false; + private void addSingletonAnnotations(CsdlSingleton singleton, FullQualifiedName entityContainerName) { CsdlEntityType entityType = fetchEntityTypeFromSingleton(singleton); if (entityType == null) { return; } - - List termSchemaDefinition = ((EdmProviderImpl)edm).getTermSchemaDefinitions(); - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + singleton.getName())) { - isSingletonAnnotationsIncluded = true; - addAnnotationsToSingleton(singleton, annotationGrp); - } else { - addAnnotationsToPropertiesDerivedFromSingleton(singleton, isPropAnnotationsCleared, - isNavPropAnnotationsCleared, entityType, annotationGrp); - isPropAnnotationsCleared = true; - isNavPropAnnotationsCleared = true; + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(entityContainerName + SLASH + singleton.getName()); + addAnnotationsOnSingleton(singleton, annotations); + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(aliasName + DOT + entityContainerName.getName() + SLASH + singleton.getName()); + addAnnotationsOnSingleton(singleton, annotationsOnAlias); + addAnnotationsToPropertiesDerivedFromSingleton(singleton, entityType, entityContainerName); + } + + /** + * Adds annotations on singleton + * @param singleton + * @param annotations + */ + private void addAnnotationsOnSingleton(CsdlSingleton singleton, List annotations) { + if (null != annotations && !annotations.isEmpty()) { + isSingletonAnnotationsIncluded = true; + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(singleton.getAnnotations(), annotation)) { + singleton.getAnnotations().add(annotation); } } } - } - + } + + /** + * Get alias name given the namespace from the alias info + * @param namespace + * @return + */ + private String getAliasInfo(String namespace) { + try { + if (null != provider.getAliasInfos()) { + for (CsdlAliasInfo aliasInfo : provider.getAliasInfos()) { + if (aliasInfo.getNamespace().equalsIgnoreCase(namespace)) { + return aliasInfo.getAlias(); + } + } + } + } catch (ODataException e) { + throw new EdmException(e); + } + return null; + } + /** adds annotations to entity type properties derived from singleton + * E.g of target paths + * MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyNavigationProperty * @param singleton * @param isPropAnnotationsCleared * @param isNavPropAnnotationsCleared * @param entityType + * @param entityContainerName * @param annotationGrp */ - private void addAnnotationsToPropertiesDerivedFromSingleton(CsdlSingleton singleton, boolean isPropAnnotationsCleared, - boolean isNavPropAnnotationsCleared, CsdlEntityType entityType, CsdlAnnotations annotationGrp) { - for (CsdlProperty propertyName : entityType.getProperties()) { - if (!isPropAnnotationsCleared) { - entityType.getProperty(propertyName.getName()).getAnnotations().clear(); - } - if (isPropertyComplex(propertyName)) { - CsdlComplexType complexType = getComplexTypeFromProperty(propertyName); - addAnnotationsToComplexTypeIncludedFromSingleton(singleton, - annotationGrp, propertyName, isNavPropAnnotationsCleared, complexType); + private void addAnnotationsToPropertiesDerivedFromSingleton(CsdlSingleton singleton, + CsdlEntityType entityType, FullQualifiedName entityContainerName) { + String entitySetName = null; + String schemaName = null; + String containerName = null; + try { + List entitySets = this.provider.getEntityContainer() != null ? + this.provider.getEntityContainer().getEntitySets() : new ArrayList(); + for (CsdlEntitySet entitySet : entitySets) { + entitySetName = entitySet.getName(); + String entityTypeName = entitySet.getTypeFQN().getFullQualifiedNameAsString(); + if ((null != entityTypeName && entityTypeName.equalsIgnoreCase( + entitySet.getTypeFQN().getNamespace() + DOT + entityType.getName()))) { + containerName = this.provider.getEntityContainer().getName(); + schemaName = entitySet.getTypeFQN().getNamespace(); + for (CsdlProperty property : entityType.getProperties()) { + if (isPropertyComplex(property)) { + CsdlComplexType complexType = getComplexTypeFromProperty(property); + addAnnotationsToComplexTypeIncludedFromSingleton(singleton, property, complexType); + } + removeAnnotationsAddedToPropertiesOfEntityType(entityType, property, entityContainerName); + removeAnnotationsAddedToPropertiesViaEntitySet(entityType, property, + schemaName, containerName, entitySetName); + } + } } + } catch (ODataException e) { + throw new EdmException(e); } } - - /** Adds annotation to singleton - * @param singleton - * @param annotationGrp + + /** + * If annotations are added to properties via Entity set then remove them + * @param entityType + * @param property + * @param schemaName + * @param containerName + * @param entitySetName */ - private void addAnnotationsToSingleton(CsdlSingleton singleton, CsdlAnnotations annotationGrp) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(singleton.getAnnotations(), annotation)) { - singleton.getAnnotations().add(annotation); + private void removeAnnotationsAddedToPropertiesViaEntitySet(CsdlEntityType entityType, CsdlProperty property, + String schemaName, String containerName, String entitySetName) { + List annotPropDerivedFromES = ((EdmProviderImpl)edm).getAnnotationsMap().get( + schemaName + DOT + + containerName + SLASH + entitySetName + SLASH + property.getName()); + removeAnnotationsOnPropertiesDerivedFromES(entityType, property, annotPropDerivedFromES); + String aliasName = getAliasInfo(schemaName); + List annotPropDerivedFromESOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap().get( + aliasName + DOT + + containerName + SLASH + entitySetName + SLASH + property.getName()); + removeAnnotationsOnPropertiesDerivedFromES(entityType, property, annotPropDerivedFromESOnAlias); + } + + /** + * Removes the annotations added on properties via Entity Set in case of singleton flow + * @param entityType + * @param property + * @param annotPropDerivedFromES + */ + private void removeAnnotationsOnPropertiesDerivedFromES(CsdlEntityType entityType, CsdlProperty property, + List annotPropDerivedFromES) { + if (null != annotPropDerivedFromES && !annotPropDerivedFromES.isEmpty()) { + for (CsdlAnnotation annotation : annotPropDerivedFromES) { + entityType.getProperty(property.getName()).getAnnotations().remove(annotation); } } } @@ -310,28 +380,82 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit * @param complexType */ private void addAnnotationsToComplexTypeIncludedFromSingleton(CsdlSingleton singleton, - CsdlAnnotations annotationGrp, CsdlProperty propertyName, - boolean isComplexNavPropAnnotationsCleared, CsdlComplexType complexType) { + CsdlProperty propertyName, CsdlComplexType complexType) { + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + for (CsdlProperty complexPropertyName : complexType.getProperties()) { + removeAnnotationAddedToPropertiesOfComplexType(complexType, complexPropertyName, entityContainerName); + + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap().get( + entityContainerName + SLASH + + singleton.getName() + SLASH + + propertyName.getName() + SLASH + complexPropertyName.getName()); + addAnnotationsOnComplexTypeProperties(complexType, complexPropertyName, annotations); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap().get( + aliasName + DOT + entityContainerName.getName() + SLASH + + singleton.getName() + SLASH + + propertyName.getName() + SLASH + complexPropertyName.getName()); + addAnnotationsOnComplexTypeProperties(complexType, complexPropertyName, annotationsOnAlias); + } for (CsdlNavigationProperty complexNavPropertyName : complexType.getNavigationProperties()) { - if (!isComplexNavPropAnnotationsCleared) { - complexType.getNavigationProperty(complexNavPropertyName.getName()).getAnnotations().clear(); - } - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + singleton.getName() + "/" + - propertyName.getName() + "/" + complexNavPropertyName.getName())) { - isSingletonAnnotationsIncluded = true; - addAnnotationsToComplexTypeNavProperties(annotationGrp, complexType, complexNavPropertyName); - } + checkAnnotationAddedToNavPropertiesOfComplexType(complexType, complexNavPropertyName, entityContainerName); + + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap().get(entityContainerName + + SLASH + singleton.getName() + SLASH + + propertyName.getName() + SLASH + complexNavPropertyName.getName()); + addAnnotationsOnComplexTypeNavProperties(complexType, complexNavPropertyName, annotations); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap().get( + aliasName + DOT + entityContainerName.getName() + + SLASH + singleton.getName() + SLASH + + propertyName.getName() + SLASH + complexNavPropertyName.getName()); + addAnnotationsOnComplexTypeNavProperties(complexType, complexNavPropertyName, annotationsOnAlias); } } + /** + * Adds annotations on complex type navigation properties + * @param complexType + * @param complexNavProperty + * @param annotations + */ + private void addAnnotationsOnComplexTypeNavProperties(CsdlComplexType complexType, + CsdlNavigationProperty complexNavProperty, List annotations) { + if (null != annotations && !annotations.isEmpty()) { + isAnnotationsIncluded = true; + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(complexType.getNavigationProperty( + complexNavProperty.getName()).getAnnotations(), annotation)) { + complexType.getNavigationProperty(complexNavProperty.getName()).getAnnotations().add(annotation); + } + } + } + } + + /** + * Adds annotations on complex type properties + * @param complexType + * @param complexProperty + * @param annotations + */ + private void addAnnotationsOnComplexTypeProperties(CsdlComplexType complexType, CsdlProperty complexProperty, + List annotations) { + if (null != annotations && !annotations.isEmpty()) { + isAnnotationsIncluded = true; + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(complexType.getProperty( + complexProperty.getName()).getAnnotations(), annotation)) { + complexType.getProperty(complexProperty.getName()).getAnnotations().add(annotation); + } + } + } + } + protected EdmEntitySet createEntitySet(final String entitySetName) { EdmEntitySet entitySet = null; try { final CsdlEntitySet providerEntitySet = provider.getEntitySet(entityContainerName, entitySetName); if (providerEntitySet != null) { - addAnnotations(providerEntitySet, entityContainerName); + addEntitySetAnnotations(providerEntitySet, entityContainerName); entitySet = new EdmEntitySetImpl(edm, this, providerEntitySet); } } catch (ODataException e) { @@ -341,42 +465,36 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit return entitySet; } - private void addAnnotations(CsdlEntitySet entitySet, FullQualifiedName entityContainerName) { - boolean isPropAnnotationsCleared = false; - boolean isNavPropAnnotationsCleared = false; + private void addEntitySetAnnotations(CsdlEntitySet entitySet, FullQualifiedName entityContainerName) { CsdlEntityType entityType = getCsdlEntityTypeFromEntitySet(entitySet); if (entityType == null) { return; } - List termSchemaDefinition = ((EdmProviderImpl)edm).getTermSchemaDefinitions(); - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + entitySet.getName())) { - isAnnotationsIncluded = true; - addAnnotationsToEntitySet(entitySet, annotationGrp); - } else { - addAnnotationsToEntityTypeIncludedFromES(entitySet, entityContainerName, - annotationGrp, isPropAnnotationsCleared, isNavPropAnnotationsCleared, entityType); - isPropAnnotationsCleared = true; - isNavPropAnnotationsCleared = true; - } - } - } + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(entityContainerName + SLASH + entitySet.getName()); + addAnnotationsOnEntitySet(entitySet, annotations); + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(aliasName + DOT + entityContainerName.getName() + SLASH + entitySet.getName()); + addAnnotationsOnEntitySet(entitySet, annotationsOnAlias); + addAnnotationsToPropertiesIncludedFromES(entitySet, entityContainerName, entityType); } /** + * Adds annotations on entity sets * @param entitySet - * @param annotationGrp + * @param annotations */ - private void addAnnotationsToEntitySet(CsdlEntitySet entitySet, CsdlAnnotations annotationGrp) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(entitySet.getAnnotations(), annotation)) { - entitySet.getAnnotations().add(annotation); - } - } + private void addAnnotationsOnEntitySet(CsdlEntitySet entitySet, List annotations) { + if (null != annotations && !annotations.isEmpty()) { + isAnnotationsIncluded = true; + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(entitySet.getAnnotations(), annotation)) { + entitySet.getAnnotations().add(annotation); + } + } + } } /** @@ -395,75 +513,172 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit } /** Adds annotations to Entity type Properties derived from entity set + * E.g of target paths + * MySchema.MyEntityContainer/MyEntitySet/MyProperty + * MySchema.MyEntityContainer/MyEntitySet/MyNavigationProperty + * MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyProperty + * MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyNavigationProperty * @param entitySet * @param entityContainerName - * @param annotationGrp * @param entityType - * @param isNavPropAnnotationsCleared - * @param isPropAnnotationsCleared * @return */ - private void addAnnotationsToEntityTypeIncludedFromES(CsdlEntitySet entitySet, - FullQualifiedName entityContainerName, CsdlAnnotations annotationGrp, - boolean isPropAnnotationsCleared, boolean isNavPropAnnotationsCleared, CsdlEntityType entityType) { - for (CsdlProperty propertyName : entityType.getProperties()) { - if (!isPropAnnotationsCleared) { - entityType.getProperty(propertyName.getName()).getAnnotations().clear(); - } - if (isPropertyComplex(propertyName)) { - CsdlComplexType complexType = getComplexTypeFromProperty(propertyName); - addAnnotationsToComplexTypeIncludedFromES(entitySet, entityContainerName, - annotationGrp, propertyName, isPropAnnotationsCleared, isNavPropAnnotationsCleared, complexType); - } else { - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + entitySet.getName() + "/" + - propertyName.getName())) { - isAnnotationsIncluded = true; - addAnnotationsToEntityTypeProperties(annotationGrp, entityType, propertyName); + private void addAnnotationsToPropertiesIncludedFromES(CsdlEntitySet entitySet, + FullQualifiedName entityContainerName, CsdlEntityType entityType) { + for (CsdlProperty property : entityType.getProperties()) { + removeAnnotationsAddedToPropertiesOfEntityType(entityType, property, entityContainerName); + if (isPropertyComplex(property)) { + CsdlComplexType complexType = getComplexTypeFromProperty(property); + addAnnotationsToComplexTypeIncludedFromES(entitySet, entityContainerName, + property, complexType); + } else { + addAnnotationsToETProperties(entitySet, entityContainerName, entityType, property); + } + } + for (CsdlNavigationProperty navProperty : entityType.getNavigationProperties()) { + removeAnnotationAddedToNavProperties(entityType, navProperty, entityContainerName); + addAnnotationsToETNavProperties(entitySet, entityContainerName, entityType, navProperty); + } + } + + /** + * @param entitySet + * @param entityContainerName + * @param entityType + * @param property + */ + private void addAnnotationsToETProperties(CsdlEntitySet entitySet, FullQualifiedName entityContainerName, + CsdlEntityType entityType, CsdlProperty property) { + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap().get( + entityContainerName + SLASH + entitySet.getName() + SLASH + + property.getName()); + addAnnotationsOnETProperties(entityType, property, annotations); + + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap().get( + aliasName + DOT + entityContainerName.getName() + SLASH + entitySet.getName() + SLASH + + property.getName()); + addAnnotationsOnETProperties(entityType, property, annotationsOnAlias); + } + + /** + * Adds annotations to Entity type Properties derived from entity set + * @param entityType + * @param property + * @param annotations + */ + private void addAnnotationsOnETProperties(CsdlEntityType entityType, CsdlProperty property, + List annotations) { + if (null != annotations && !annotations.isEmpty()) { + isAnnotationsIncluded = true; + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(entityType.getProperty( + property.getName()).getAnnotations(), annotation)) { + entityType.getProperty(property.getName()).getAnnotations().add(annotation); + } + } + } + } + + /** + * Adds annotations to Entity type Navigation Properties derived from entity set + * @param entitySet + * @param entityContainerName + * @param entityType + * @param navProperty + */ + private void addAnnotationsToETNavProperties(CsdlEntitySet entitySet, FullQualifiedName entityContainerName, + CsdlEntityType entityType, CsdlNavigationProperty navProperty) { + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap().get( + entityContainerName + SLASH + entitySet.getName() + SLASH + + navProperty.getName()); + addAnnotationsOnETNavProperties(entityType, navProperty, annotations); + + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap().get( + aliasName + DOT + entityContainerName.getName() + SLASH + entitySet.getName() + SLASH + + navProperty.getName()); + addAnnotationsOnETNavProperties(entityType, navProperty, annotationsOnAlias); + } + + /** + * @param entityType + * @param navProperty + * @param annotations + */ + private void addAnnotationsOnETNavProperties(CsdlEntityType entityType, CsdlNavigationProperty navProperty, + List annotations) { + if (null != annotations && !annotations.isEmpty()) { + isAnnotationsIncluded = true; + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(entityType.getNavigationProperty( + navProperty.getName()).getAnnotations(), annotation)) { + entityType.getNavigationProperty(navProperty.getName()).getAnnotations().add(annotation); } } } - for (CsdlNavigationProperty navPropertyName : entityType.getNavigationProperties()) { - if (!isNavPropAnnotationsCleared) { - entityType.getNavigationProperty(navPropertyName.getName()).getAnnotations().clear(); - } - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + entitySet.getName() + "/" + - navPropertyName.getName())) { - isAnnotationsIncluded = true; - addAnnotationsToEntityTypeNavProperties(annotationGrp, entityType, navPropertyName); - } - } } - /** Adds annotations to Entity type Navigation Properties derived from entity set - * @param annotationGrp - * @param entityType - * @param navPropertyName + /** + * If annotations are added to properties via entity type path, then remove it + * @param type + * @param property + * @param entityContainerName */ - private void addAnnotationsToEntityTypeNavProperties(CsdlAnnotations annotationGrp, CsdlEntityType entityType, - CsdlNavigationProperty navPropertyName) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(entityType.getNavigationProperty( - navPropertyName.getName()).getAnnotations(), annotation)) { - entityType.getNavigationProperty(navPropertyName.getName()).getAnnotations().add(annotation); - } - } + private void removeAnnotationsAddedToPropertiesOfEntityType(CsdlEntityType type, CsdlProperty property, + FullQualifiedName entityContainerName) { + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(entityContainerName.getNamespace() + + DOT + type.getName() + SLASH + property.getName()); + removeAnnotationsOnETProperties(property, annotations); + + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(aliasName + DOT + entityContainerName.getName() + + DOT + type.getName() + SLASH + property.getName()); + removeAnnotationsOnETProperties(property, annotationsOnAlias); } - /** Adds annotations to Entity type Properties derived from entity set - * @param annotationGrp - * @param entityType - * @param propertyName + /** + * Removes the annotations added on Entity type + * properties when there is a target path on entity type + * @param property + * @param annotations */ - private void addAnnotationsToEntityTypeProperties(CsdlAnnotations annotationGrp, CsdlEntityType entityType, - CsdlProperty propertyName) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(entityType.getProperty( - propertyName.getName()).getAnnotations(), annotation)) { - entityType.getProperty(propertyName.getName()).getAnnotations().add(annotation); - } - } + private void removeAnnotationsOnETProperties(CsdlProperty property, List annotations) { + if (null != annotations && !annotations.isEmpty()) { + for (CsdlAnnotation annotation : annotations) { + property.getAnnotations().remove(annotation); + } + } + } + + private void removeAnnotationAddedToNavProperties(CsdlEntityType entityType, + CsdlNavigationProperty navProperty, FullQualifiedName entityContainerName) { + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap().get( + entityContainerName.getNamespace() + + DOT + entityType.getName() + SLASH + navProperty.getName()); + removeAnnotationsOnNavProperties(navProperty, annotations); + + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap().get( + aliasName + DOT + entityContainerName.getName() + + DOT + entityType.getName() + SLASH + navProperty.getName()); + removeAnnotationsOnNavProperties(navProperty, annotationsOnAlias); + } + + /** + * Removes the annotations added on Entity type + * navigation properties when there is a target path on entity type + * @param property + * @param annotations + */ + private void removeAnnotationsOnNavProperties(CsdlNavigationProperty property, List annotations) { + if (null != annotations && !annotations.isEmpty()) { + for (CsdlAnnotation annotation : annotations) { + property.getAnnotations().remove(annotation); + } + } } /** @@ -483,69 +698,69 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit /** * @param entitySet * @param entityContainerName - * @param annotationGrp - * @param propertyName + * @param complexProperty * @param complexType - * @param isComplexNavPropAnnotationsCleared2 - * @param isComplexPropAnnotationsCleared2 * @return */ private void addAnnotationsToComplexTypeIncludedFromES(CsdlEntitySet entitySet, - FullQualifiedName entityContainerName, CsdlAnnotations annotationGrp, - CsdlProperty propertyName, boolean isComplexPropAnnotationsCleared, - boolean isComplexNavPropAnnotationsCleared, CsdlComplexType complexType) { - for (CsdlProperty complexPropertyName : complexType.getProperties()) { - if (!isComplexPropAnnotationsCleared) { - complexType.getProperty(complexPropertyName.getName()).getAnnotations().clear(); - } - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + entitySet.getName() + "/" + - propertyName.getName() + "/" + complexPropertyName.getName())) { - isAnnotationsIncluded = true; - addAnnotationsToComplexTypeProperties(annotationGrp, complexType, complexPropertyName); - } - } - for (CsdlNavigationProperty complexNavPropertyName : complexType.getNavigationProperties()) { - if (!isComplexNavPropAnnotationsCleared) { - complexType.getNavigationProperty(complexNavPropertyName.getName()).getAnnotations().clear(); - } - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + entitySet.getName() + "/" + - propertyName.getName() + "/" + complexNavPropertyName.getName())) { - isAnnotationsIncluded = true; - addAnnotationsToComplexTypeNavProperties(annotationGrp, complexType, complexNavPropertyName); - } - } + FullQualifiedName entityContainerName, CsdlProperty complexProperty, + CsdlComplexType complexType) { + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + for (CsdlProperty complexPropertyName : complexType.getProperties()) { + removeAnnotationAddedToPropertiesOfComplexType(complexType, complexPropertyName, entityContainerName); + + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap().get(entityContainerName + SLASH + + entitySet.getName() + SLASH + + complexProperty.getName() + SLASH + complexPropertyName.getName()); + addAnnotationsOnComplexTypeProperties(complexType, complexPropertyName, annotations); + + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap().get( + aliasName + DOT + entityContainerName.getName() + SLASH + + entitySet.getName() + SLASH + + complexProperty.getName() + SLASH + complexPropertyName.getName()); + addAnnotationsOnComplexTypeProperties(complexType, complexPropertyName, annotationsOnAlias); + } + for (CsdlNavigationProperty complexNavProperty : complexType.getNavigationProperties()) { + checkAnnotationAddedToNavPropertiesOfComplexType(complexType, complexNavProperty, entityContainerName); + + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap().get( + entityContainerName + SLASH + entitySet.getName() + SLASH + + complexProperty.getName() + SLASH + complexNavProperty.getName()); + addAnnotationsOnComplexTypeNavProperties(complexType, complexNavProperty, annotations); + + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap().get( + aliasName + DOT + entityContainerName.getName() + SLASH + entitySet.getName() + SLASH + + complexProperty.getName() + SLASH + complexNavProperty.getName()); + addAnnotationsOnComplexTypeNavProperties(complexType, complexNavProperty, annotationsOnAlias); + } } - /** - * @param annotationGrp - * @param complexType - * @param complexNavPropertyName - */ - private void addAnnotationsToComplexTypeNavProperties(CsdlAnnotations annotationGrp, CsdlComplexType complexType, - CsdlNavigationProperty complexNavPropertyName) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(complexType.getNavigationProperty( - complexNavPropertyName.getName()).getAnnotations(), annotation)) { - complexType.getNavigationProperty(complexNavPropertyName.getName()).getAnnotations().add(annotation); - } - } + private void checkAnnotationAddedToNavPropertiesOfComplexType(CsdlComplexType complexType, + CsdlNavigationProperty complexNavProperty, FullQualifiedName entityContainerName) { + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(entityContainerName.getNamespace() + + DOT + complexType.getName() + SLASH + complexNavProperty.getName()); + removeAnnotationsOnNavProperties(complexNavProperty, annotations); + + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(aliasName + + DOT + complexType.getName() + SLASH + complexNavProperty.getName()); + removeAnnotationsOnNavProperties(complexNavProperty, annotationsOnAlias); } - /** - * @param annotationGrp - * @param complexType - * @param complexPropertyName - */ - private void addAnnotationsToComplexTypeProperties(CsdlAnnotations annotationGrp, CsdlComplexType complexType, - CsdlProperty complexPropertyName) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(complexType.getProperty( - complexPropertyName.getName()).getAnnotations(), annotation)) { - complexType.getProperty(complexPropertyName.getName()).getAnnotations().add(annotation); - } - } + private void removeAnnotationAddedToPropertiesOfComplexType(CsdlComplexType complexType, + CsdlProperty complexPropertyName, FullQualifiedName entityContainerName) { + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(entityContainerName.getNamespace() + + DOT + complexType.getName() + SLASH + complexPropertyName.getName()); + removeAnnotationsOnETProperties(complexPropertyName, annotations); + + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(aliasName + DOT + entityContainerName.getName() + + DOT + complexType.getName() + SLASH + complexPropertyName.getName()); + removeAnnotationsOnETProperties(complexPropertyName, annotationsOnAlias); } private boolean isPropertyComplex(CsdlProperty propertyName) { @@ -562,7 +777,7 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit try { final CsdlActionImport providerImport = provider.getActionImport(entityContainerName, actionImportName); if (providerImport != null) { - addAnnotations(providerImport, entityContainerName); + addOperationImportAnnotations(providerImport, entityContainerName); actionImport = new EdmActionImportImpl(edm, this, providerImport); } } catch (ODataException e) { @@ -572,31 +787,40 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit return actionImport; } - private void addAnnotations(CsdlActionImport actionImport, FullQualifiedName entityContainerName) { - List termSchemaDefinition = ((EdmProviderImpl)edm).getTermSchemaDefinitions(); - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + actionImport.getName())) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(actionImport.getAnnotations(), annotation)) { - actionImport.getAnnotations().add(annotation); - } - } - break; + private void addOperationImportAnnotations(CsdlOperationImport operationImport, + FullQualifiedName entityContainerName) { + List annotations = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(entityContainerName + SLASH + operationImport.getName()); + addAnnotationsOnOperationImport(operationImport, annotations); + + String aliasName = getAliasInfo(entityContainerName.getNamespace()); + List annotationsOnAlias = ((EdmProviderImpl)edm).getAnnotationsMap(). + get(aliasName + DOT + entityContainerName.getName() + SLASH + operationImport.getName()); + addAnnotationsOnOperationImport(operationImport, annotationsOnAlias); + } + + /** + * Adds annotations on action import + * @param operationImport + * @param annotations + */ + private void addAnnotationsOnOperationImport(CsdlOperationImport operationImport, List annotations) { + if (null != annotations && !annotations.isEmpty()) { + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(operationImport.getAnnotations(), annotation)) { + operationImport.getAnnotations().add(annotation); } } } - } - + } + protected EdmFunctionImport createFunctionImport(final String functionImportName) { EdmFunctionImport functionImport = null; try { final CsdlFunctionImport providerImport = provider.getFunctionImport(entityContainerName, functionImportName); if (providerImport != null) { - addAnnotations(providerImport, entityContainerName); + addOperationImportAnnotations(providerImport, entityContainerName); functionImport = new EdmFunctionImportImpl(edm, this, providerImport); } } catch (ODataException e) { @@ -605,25 +829,7 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit return functionImport; } - - private void addAnnotations(CsdlFunctionImport functionImport, FullQualifiedName entityContainerName) { - List termSchemaDefinition = ((EdmProviderImpl)edm).getTermSchemaDefinitions(); - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget(). - equalsIgnoreCase(entityContainerName + "/" + functionImport.getName())) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(functionImport.getAnnotations(), annotation)) { - functionImport.getAnnotations().add(annotation); - } - } - break; - } - } - } - } - + protected void loadAllEntitySets() { loadContainer(); final List providerEntitySets = container.getEntitySets(); @@ -631,7 +837,7 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit if (providerEntitySets != null) { for (CsdlEntitySet entitySet : providerEntitySets) { - addAnnotations(entitySet, entityContainerName); + addEntitySetAnnotations(entitySet, entityContainerName); final EdmEntitySetImpl impl = new EdmEntitySetImpl(edm, this, entitySet); if (isAnnotationsIncluded) { entitySetWithAnnotationsCache.put(impl.getName(), impl); @@ -652,7 +858,7 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit if (providerFunctionImports != null) { for (CsdlFunctionImport functionImport : providerFunctionImports) { - addAnnotations(functionImport, entityContainerName); + addOperationImportAnnotations(functionImport, entityContainerName); EdmFunctionImportImpl impl = new EdmFunctionImportImpl(edm, this, functionImport); functionImportCache.put(impl.getName(), impl); functionImportsLocal.add(impl); @@ -668,7 +874,7 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit if (providerSingletons != null) { for (CsdlSingleton singleton : providerSingletons) { - addAnnotations(singleton, entityContainerName); + addSingletonAnnotations(singleton, entityContainerName); final EdmSingletonImpl impl = new EdmSingletonImpl(edm, this, singleton); singletonCache.put(singleton.getName(), impl); singletonsLocal.add(impl); @@ -684,7 +890,7 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit if (providerActionImports != null) { for (CsdlActionImport actionImport : providerActionImports) { - addAnnotations(actionImport, entityContainerName); + addOperationImportAnnotations(actionImport, entityContainerName); final EdmActionImportImpl impl = new EdmActionImportImpl(edm, this, actionImport); actionImportCache.put(actionImport.getName(), impl); actionImportsLocal.add(impl); @@ -701,7 +907,7 @@ public class EdmEntityContainerImpl extends AbstractEdmNamed implements EdmEntit if (containerLocal == null) { containerLocal = new CsdlEntityContainer().setName(getName()); } - ((EdmProviderImpl)edm).addAnnotations(containerLocal, entityContainerName); + ((EdmProviderImpl)edm).addEntityContainerAnnotations(containerLocal, entityContainerName); container = containerLocal; } catch (ODataException e) { throw new EdmException(e); diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java index e4ad8407b..c8b1c71a3 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java @@ -45,10 +45,12 @@ import org.apache.olingo.commons.api.edm.provider.CsdlComplexType; import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; 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.CsdlNavigationProperty; +import org.apache.olingo.commons.api.edm.provider.CsdlOperation; import org.apache.olingo.commons.api.edm.provider.CsdlParameter; import org.apache.olingo.commons.api.edm.provider.CsdlProperty; import org.apache.olingo.commons.api.edm.provider.CsdlSchema; @@ -66,6 +68,9 @@ public class EdmProviderImpl extends AbstractEdm { Collections.synchronizedMap(new HashMap>()); private List termSchemaDefinition = new ArrayList(); + private final String SLASH = "/"; + private final String DOT = "."; + public EdmProviderImpl(final CsdlEdmProvider provider) { this.provider = provider; } @@ -73,6 +78,7 @@ public class EdmProviderImpl extends AbstractEdm { public EdmProviderImpl(final CsdlEdmProvider provider, final List termSchemaDefinition) { this.provider = provider; this.termSchemaDefinition = termSchemaDefinition; + populateAnnotationMap(); } @Override @@ -80,7 +86,7 @@ public class EdmProviderImpl extends AbstractEdm { try { CsdlEntityContainerInfo entityContainerInfo = provider.getEntityContainerInfo(containerName); if (entityContainerInfo != null) { - addAnnotations(provider.getEntityContainer(), entityContainerInfo.getContainerName()); + addEntityContainerAnnotations(provider.getEntityContainer(), entityContainerInfo.getContainerName()); return new EdmEntityContainerImpl(this, provider, entityContainerInfo.getContainerName(), provider.getEntityContainer()); } @@ -90,18 +96,25 @@ public class EdmProviderImpl extends AbstractEdm { } } - public void addAnnotations(CsdlEntityContainer csdlEntityContainer, FullQualifiedName containerName) { - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget().equalsIgnoreCase(containerName.getFullQualifiedNameAsString())) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(csdlEntityContainer.getAnnotations(), annotation)) { - csdlEntityContainer.getAnnotations().addAll(annotationGrp.getAnnotations()); - } - } - break; - } + public void addEntityContainerAnnotations(CsdlEntityContainer csdlEntityContainer, FullQualifiedName containerName) { + String aliasName = getAliasInfo(containerName.getNamespace()); + List annotations = getAnnotationsMap().get(containerName.getFullQualifiedNameAsString()); + List annotationsOnAlias = getAnnotationsMap().get(aliasName + DOT + containerName.getName()); + addAnnotationsOnEntityContainer(csdlEntityContainer, annotations); + addAnnotationsOnEntityContainer(csdlEntityContainer, annotationsOnAlias); + } + + /** + * @param csdlEntityContainer + * @param annotations + */ + private void addAnnotationsOnEntityContainer(CsdlEntityContainer csdlEntityContainer, + List annotations) { + if (null != annotations) { + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(csdlEntityContainer.getAnnotations(), annotation)) { + csdlEntityContainer.getAnnotations().add(annotation); + } } } } @@ -111,7 +124,7 @@ public class EdmProviderImpl extends AbstractEdm { try { CsdlEnumType enumType = provider.getEnumType(enumName); if (enumType != null) { - addAnnotations(enumType, enumName); + addEnumTypeAnnotations(enumType, enumName); return new EdmEnumTypeImpl(this, enumName, enumType); } return null; @@ -120,18 +133,24 @@ public class EdmProviderImpl extends AbstractEdm { } } - public void addAnnotations(CsdlEnumType enumType, FullQualifiedName enumName) { - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget().equalsIgnoreCase(enumName.getFullQualifiedNameAsString())) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(enumType.getAnnotations(), annotation)) { - enumType.getAnnotations().addAll(annotationGrp.getAnnotations()); - } - } - break; - } + public void addEnumTypeAnnotations(CsdlEnumType enumType, FullQualifiedName enumName) { + String aliasName = getAliasInfo(enumName.getNamespace()); + List annotations = getAnnotationsMap().get(enumName.getFullQualifiedNameAsString()); + List annotationsOnAlias = getAnnotationsMap().get(aliasName + DOT + enumName.getName()); + addAnnotationsOnEnumTypes(enumType, annotations); + addAnnotationsOnEnumTypes(enumType, annotationsOnAlias); + } + + /** + * @param enumType + * @param annotations + */ + private void addAnnotationsOnEnumTypes(CsdlEnumType enumType, List annotations) { + if (null != annotations) { + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(enumType.getAnnotations(), annotation)) { + enumType.getAnnotations().add(annotation); + } } } } @@ -141,7 +160,7 @@ public class EdmProviderImpl extends AbstractEdm { try { CsdlTypeDefinition typeDefinition = provider.getTypeDefinition(typeDefinitionName); if (typeDefinition != null) { - addAnnotations(typeDefinition, typeDefinitionName); + addTypeDefnAnnotations(typeDefinition, typeDefinitionName); return new EdmTypeDefinitionImpl(this, typeDefinitionName, typeDefinition); } return null; @@ -150,18 +169,24 @@ public class EdmProviderImpl extends AbstractEdm { } } - public void addAnnotations(CsdlTypeDefinition typeDefinition, FullQualifiedName typeDefinitionName) { - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget().equalsIgnoreCase(typeDefinitionName.getFullQualifiedNameAsString())) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(typeDefinition.getAnnotations(), annotation)) { - typeDefinition.getAnnotations().addAll(annotationGrp.getAnnotations()); - } - } - break; - } + public void addTypeDefnAnnotations(CsdlTypeDefinition typeDefinition, FullQualifiedName typeDefinitionName) { + String aliasName = getAliasInfo(typeDefinitionName.getNamespace()); + List annotations = getAnnotationsMap().get(typeDefinitionName.getFullQualifiedNameAsString()); + List annotationsOnAlias = getAnnotationsMap().get(aliasName + DOT + typeDefinitionName.getName()); + addAnnotationsOnTypeDefinitions(typeDefinition, annotations); + addAnnotationsOnTypeDefinitions(typeDefinition, annotationsOnAlias); + } + + /** + * @param typeDefinition + * @param annotations + */ + private void addAnnotationsOnTypeDefinitions(CsdlTypeDefinition typeDefinition, List annotations) { + if (null != annotations) { + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(typeDefinition.getAnnotations(), annotation)) { + typeDefinition.getAnnotations().add(annotation); + } } } } @@ -171,8 +196,14 @@ public class EdmProviderImpl extends AbstractEdm { try { CsdlEntityType entityType = provider.getEntityType(entityTypeName); if (entityType != null) { + List annotations = getAnnotationsMap().get(entityTypeName.getFullQualifiedNameAsString()); + String aliasName = getAliasInfo(entityTypeName.getNamespace()); + List annotationsOnAlias = getAnnotationsMap().get(aliasName + DOT + entityTypeName.getName()); + addAnnotationsOnStructuralType(entityType, annotations); + addAnnotationsOnStructuralType(entityType, annotationsOnAlias); + if (!isEntityDerivedFromES()) { - addAnnotations(entityType, entityTypeName); + addStructuralTypeAnnotations(entityType, entityTypeName, this.provider.getEntityContainer()); } return new EdmEntityTypeImpl(this, entityTypeName, entityType); } @@ -183,108 +214,370 @@ public class EdmProviderImpl extends AbstractEdm { } /** - * Add the annotations defined in an external file to the property/ - * navigation property and the entity - * @param structuralType - * @param typeName + * Add annoations to entity types and complex types + * @param entityType + * @param annotations */ - public void addAnnotations(CsdlStructuralType structuralType, FullQualifiedName typeName) { - boolean isPropAnnotationsCleared = false; - boolean isNavPropAnnotationsCleared = false; - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget().equalsIgnoreCase(typeName.getFullQualifiedNameAsString())) { - addAnnotationsToStructuralTypes(structuralType, annotationGrp); - } else { - checkAnnotationsOnStructuralProperties(structuralType, typeName, isPropAnnotationsCleared, annotationGrp); - checkAnnotationsOnStructuralNavProperties(structuralType, typeName, isNavPropAnnotationsCleared, - annotationGrp); - isPropAnnotationsCleared = true; - isNavPropAnnotationsCleared = true; + private void addAnnotationsOnStructuralType(CsdlStructuralType structuralType, List annotations) { + if (null != annotations && !annotations.isEmpty()) { + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(structuralType.getAnnotations(), annotation)) { + structuralType.getAnnotations().add(annotation); } } } } + /** + * Populates a map of String (annotation target) and List of CsdlAnnotations + * Reads both term definition schema (external schema) and + * provider schema (actual metadata file) + */ + private void populateAnnotationMap() { + for (CsdlSchema schema : termSchemaDefinition) { + fetchAnnotationsInMetadataAndExternalFile(schema); + } + try { + if (null != provider.getSchemas()) { + for (CsdlSchema schema : provider.getSchemas()) { + fetchAnnotationsInMetadataAndExternalFile(schema); + } + } + } catch (ODataException e) { + throw new EdmException(e); + } + } + + /** + * @param schema + */ + private void fetchAnnotationsInMetadataAndExternalFile(CsdlSchema schema) { + List annotationGrps = schema.getAnnotationGroups(); + for (CsdlAnnotations annotationGrp : annotationGrps) { + if (!getAnnotationsMap().containsKey(annotationGrp.getTarget())) { + getAnnotationsMap().put(annotationGrp.getTarget(), annotationGrp.getAnnotations()); + } else { + List annotations = getAnnotationsMap().get(annotationGrp.getTarget()); + List newAnnotations = new ArrayList(); + for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { + if (!compareAnnotations(annotations, annotation)) { + newAnnotations.add(annotation); + } + } + if (!newAnnotations.isEmpty()) { + getAnnotationsMap().get(annotationGrp.getTarget()).addAll(newAnnotations); + } + } + } + } + + /** + * Add the annotations defined in an external file to the property/ + * navigation property and the entity + * @param structuralType + * @param typeName + * @param csdlEntityContainer + */ + public void addStructuralTypeAnnotations(CsdlStructuralType structuralType, FullQualifiedName typeName, + CsdlEntityContainer csdlEntityContainer) { + updateAnnotationsOnStructuralProperties(structuralType, typeName, csdlEntityContainer); + updateAnnotationsOnStructuralNavProperties(structuralType, typeName, csdlEntityContainer); + } + + /** + * Get alias name given the namespace from the alias info + * @param namespace + * @return + */ + private String getAliasInfo(String namespace) { + try { + if (null != provider.getAliasInfos()) { + for (CsdlAliasInfo aliasInfo : provider.getAliasInfos()) { + if (aliasInfo.getNamespace().equalsIgnoreCase(namespace)) { + return aliasInfo.getAlias(); + } + } + } + } catch (ODataException e) { + throw new EdmException(e); + } + return null; + } /** Check if annotations are added on navigation properties of a structural type * @param structuralType * @param typeName + * @param csdlEntityContainer * @param isNavPropAnnotationsCleared * @param annotationGrp */ - private void checkAnnotationsOnStructuralNavProperties(CsdlStructuralType structuralType, FullQualifiedName typeName, - boolean isNavPropAnnotationsCleared, CsdlAnnotations annotationGrp) { + private void updateAnnotationsOnStructuralNavProperties(CsdlStructuralType structuralType, + FullQualifiedName typeName, CsdlEntityContainer csdlEntityContainer) { List navProperties = structuralType.getNavigationProperties(); - for (CsdlNavigationProperty navProperty : navProperties) { - if (!isNavPropAnnotationsCleared) { - structuralType.getNavigationProperty(navProperty.getName()).getAnnotations().clear(); + String containerName = null; + String schemaName = null; + String entitySetName = null; + List entitySets = csdlEntityContainer != null ? + csdlEntityContainer.getEntitySets() : new ArrayList(); + if (structuralType instanceof CsdlComplexType) { + removeAnnotationsAddedToCTNavPropFromES(structuralType, typeName, csdlEntityContainer, navProperties, entitySets); + } else { + for (CsdlEntitySet entitySet : entitySets) { + entitySetName = entitySet.getName(); + String entityTypeName = entitySet.getTypeFQN().getFullQualifiedNameAsString(); + if (null != entityTypeName && entityTypeName.equalsIgnoreCase(typeName.getFullQualifiedNameAsString())) { + containerName = csdlEntityContainer.getName(); + schemaName = typeName.getNamespace(); + break; + } } - if (annotationGrp.getTarget().equalsIgnoreCase(typeName + "/" + navProperty.getName())) { - addAnnotationsToStructuralTypeNavProperties(structuralType, annotationGrp, navProperty); + for (CsdlNavigationProperty navProperty : navProperties) { + List annotPropDerivedFromES = getAnnotationsMap().get(schemaName + DOT + + containerName + SLASH + entitySetName + SLASH + navProperty.getName()); + removeAnnotationsOnNavPropDerivedFromEntitySet(structuralType, navProperty, annotPropDerivedFromES); + String aliasName = getAliasInfo(schemaName); + List annotPropDerivedFromESOnAlias = getAnnotationsMap().get(aliasName + DOT + + containerName + SLASH + entitySetName + SLASH + navProperty.getName()); + removeAnnotationsOnNavPropDerivedFromEntitySet(structuralType, navProperty, annotPropDerivedFromESOnAlias); + + List navPropAnnotations = getAnnotationsMap().get( + typeName + SLASH + navProperty.getName()); + addAnnotationsOnNavProperties(structuralType, navProperty, navPropAnnotations); + aliasName = getAliasInfo(typeName.getNamespace()); + List navPropAnnotationsOnAlias = getAnnotationsMap().get( + aliasName + DOT + typeName.getName() + SLASH + navProperty.getName()); + addAnnotationsOnNavProperties(structuralType, navProperty, navPropAnnotationsOnAlias); } } } + /** + * Adds annotations to navigation properties of entity and complex types + * @param structuralType + * @param navProperty + * @param navPropAnnotations + */ + private void addAnnotationsOnNavProperties(CsdlStructuralType structuralType, CsdlNavigationProperty navProperty, + List navPropAnnotations) { + if (null != navPropAnnotations && !navPropAnnotations.isEmpty()) { + for (CsdlAnnotation annotation : navPropAnnotations) { + if (!compareAnnotations(structuralType.getNavigationProperty( + navProperty.getName()).getAnnotations(), annotation)) { + structuralType.getNavigationProperty(navProperty.getName()).getAnnotations(). + add(annotation); + } + } + } + } + + /** + * Removes the annotations added to properties of structural types + * if annotation was added before via EntitySet path + * @param structuralType + * @param navProperty + * @param annotPropDerivedFromES + */ + private void removeAnnotationsOnNavPropDerivedFromEntitySet(CsdlStructuralType structuralType, + CsdlNavigationProperty navProperty, List annotPropDerivedFromES) { + if (null != annotPropDerivedFromES && !annotPropDerivedFromES.isEmpty()) { + for (CsdlAnnotation annotation : annotPropDerivedFromES) { + List propAnnot = structuralType.getNavigationProperty( + navProperty.getName()).getAnnotations(); + if (propAnnot.contains(annotation)) { + propAnnot.remove(annotation); + } + } + } + } + + /** + * Remove the annotations added to navigation properties + * of a complex type loaded via entity set path + * @param structuralType + * @param typeName + * @param csdlEntityContainer + * @param navProperties + * @param entitySets + */ + private void removeAnnotationsAddedToCTNavPropFromES(CsdlStructuralType structuralType, FullQualifiedName typeName, + CsdlEntityContainer csdlEntityContainer, List navProperties, + List entitySets) { + String containerName; + String schemaName; + String complexPropName; + for (CsdlEntitySet entitySet : entitySets) { + try { + CsdlEntityType entType = provider.getEntityType(entitySet.getTypeFQN()); + List entTypeProperties = null != entType ? + entType.getProperties() : new ArrayList(); + for (CsdlProperty entTypeProperty : entTypeProperties) { + if (null != entTypeProperty.getType() && + entTypeProperty.getType().equalsIgnoreCase(typeName.getFullQualifiedNameAsString())) { + complexPropName = entTypeProperty.getName(); + containerName = csdlEntityContainer.getName(); + schemaName = typeName.getNamespace(); + for (CsdlNavigationProperty navProperty : navProperties) { + List annotPropDerivedFromES = getAnnotationsMap().get(schemaName + DOT + + containerName + SLASH + entitySet.getName() + SLASH + + complexPropName + SLASH + navProperty.getName()); + removeAnnotationsOnNavPropDerivedFromEntitySet(structuralType, navProperty, annotPropDerivedFromES); + String aliasName = getAliasInfo(schemaName); + List annotPropDerivedFromESOnAlias = getAnnotationsMap().get(aliasName + DOT + + containerName + SLASH + entitySet.getName() + SLASH + + complexPropName + SLASH + navProperty.getName()); + removeAnnotationsOnNavPropDerivedFromEntitySet(structuralType, + navProperty, annotPropDerivedFromESOnAlias); + + List propAnnotations = getAnnotationsMap(). + get(typeName.getFullQualifiedNameAsString() + SLASH + navProperty.getName()); + addAnnotationsOnNavProperties(structuralType, navProperty, propAnnotations); + aliasName = getAliasInfo(typeName.getNamespace()); + List propAnnotationsOnAlias = getAnnotationsMap(). + get(aliasName + DOT + typeName.getName() + SLASH + navProperty.getName()); + addAnnotationsOnNavProperties(structuralType, navProperty, propAnnotationsOnAlias); + } + } + } + } catch (ODataException e) { + throw new EdmException(e); + } + } + for (CsdlNavigationProperty navProperty : structuralType.getNavigationProperties()) { + List propAnnotations = getAnnotationsMap(). + get(typeName.getFullQualifiedNameAsString() + SLASH + navProperty.getName()); + addAnnotationsOnNavProperties(structuralType, navProperty, propAnnotations); + String aliasName = getAliasInfo(typeName.getNamespace()); + List propAnnotationsOnAlias = getAnnotationsMap(). + get(aliasName + DOT + typeName.getName() + SLASH + navProperty.getName()); + addAnnotationsOnNavProperties(structuralType, navProperty, propAnnotationsOnAlias); + } + } + /** Check if annotations are added on properties of a structural type * @param structuralType * @param typeName - * @param isPropAnnotationsCleared - * @param annotationGrp + * @param csdlEntityContainer */ - private void checkAnnotationsOnStructuralProperties(CsdlStructuralType structuralType, FullQualifiedName typeName, - boolean isPropAnnotationsCleared, CsdlAnnotations annotationGrp) { + private void updateAnnotationsOnStructuralProperties(CsdlStructuralType structuralType, FullQualifiedName typeName, + CsdlEntityContainer csdlEntityContainer) { List properties = structuralType.getProperties(); - for (CsdlProperty property : properties) { - if (!isPropAnnotationsCleared) { - structuralType.getProperty(property.getName()).getAnnotations().clear(); + String containerName = null; + String schemaName = null; + String entitySetName = null; + List entitySets = null != csdlEntityContainer ? + csdlEntityContainer.getEntitySets() : new ArrayList(); + if (structuralType instanceof CsdlComplexType) { + removeAnnotationsAddedToCTTypePropFromES(structuralType, typeName, csdlEntityContainer, properties, entitySets); + } else { + for (CsdlEntitySet entitySet : entitySets) { + entitySetName = entitySet.getName(); + String entityTypeName = entitySet.getTypeFQN().getFullQualifiedNameAsString(); + if (null != entityTypeName && entityTypeName.equalsIgnoreCase(typeName.getFullQualifiedNameAsString())) { + containerName = csdlEntityContainer.getName(); + schemaName = typeName.getNamespace(); + break; + } } - if (annotationGrp.getTarget().equalsIgnoreCase( - typeName.getFullQualifiedNameAsString() + "/" + property.getName())) { - addAnnotationsToStructuralTypeProperties(structuralType, annotationGrp, property); + for (CsdlProperty property : properties) { + List annotPropDerivedFromES = getAnnotationsMap().get(schemaName + DOT + + containerName + SLASH + entitySetName + SLASH + property.getName()); + removeAnnotationsOnPropDerivedFromEntitySet(structuralType, property, annotPropDerivedFromES); + String aliasName = getAliasInfo(schemaName); + List annotPropDerivedFromESOnAlias = getAnnotationsMap().get(aliasName + DOT + + containerName + SLASH + entitySetName + SLASH + property.getName()); + removeAnnotationsOnPropDerivedFromEntitySet(structuralType, property, annotPropDerivedFromESOnAlias); + List propAnnotations = getAnnotationsMap(). + get(typeName.getFullQualifiedNameAsString() + SLASH + property.getName()); + addAnnotationsOnPropertiesOfStructuralType(structuralType, property, propAnnotations); + aliasName = getAliasInfo(typeName.getNamespace()); + List propAnnotationsOnAlias = getAnnotationsMap(). + get(aliasName + DOT + typeName.getName() + SLASH + property.getName()); + addAnnotationsOnPropertiesOfStructuralType(structuralType, property, propAnnotationsOnAlias); } } } /** + * Adds annotations to properties of entity type and complex type * @param structuralType - * @param annotationGrp - * @param navProperty - */ - private void addAnnotationsToStructuralTypeNavProperties(CsdlStructuralType structuralType, - CsdlAnnotations annotationGrp, CsdlNavigationProperty navProperty) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(structuralType.getNavigationProperty( - navProperty.getName()).getAnnotations(), annotation)) { - structuralType.getNavigationProperty(navProperty.getName()).getAnnotations(). - add(annotation); - } - } - } - - /** - * @param structuralType - * @param annotationGrp * @param property + * @param propAnnotations */ - private void addAnnotationsToStructuralTypeProperties(CsdlStructuralType structuralType, - CsdlAnnotations annotationGrp, CsdlProperty property) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(structuralType.getProperty( - property.getName()).getAnnotations(), annotation)) { - structuralType.getProperty(property.getName()).getAnnotations().add(annotation); + private void addAnnotationsOnPropertiesOfStructuralType(CsdlStructuralType structuralType, CsdlProperty property, + List propAnnotations) { + if (null != propAnnotations && !propAnnotations.isEmpty()) { + for (CsdlAnnotation annotation : propAnnotations) { + if (!compareAnnotations(structuralType.getProperty( + property.getName()).getAnnotations(), annotation)) { + structuralType.getProperty(property.getName()).getAnnotations().add(annotation); + } + } + } + } + + /** + * Removes the annotations added to properties of entity type when added via entity set + * @param structuralType + * @param property + * @param annotPropDerivedFromESOnAlias + */ + private void removeAnnotationsOnPropDerivedFromEntitySet(CsdlStructuralType structuralType, CsdlProperty property, + List annotPropDerivedFromES) { + if (null != annotPropDerivedFromES && !annotPropDerivedFromES.isEmpty()) { + for (CsdlAnnotation annotation : annotPropDerivedFromES) { + List propAnnot = structuralType.getProperty( + property.getName()).getAnnotations(); + if (propAnnot.contains(annotation)) { + propAnnot.remove(annotation); + } } } } /** + * Removes the annotation added on complex type property via Entity Set * @param structuralType - * @param annotationGrp + * @param typeName + * @param csdlEntityContainer + * @param properties + * @param entitySets */ - private void addAnnotationsToStructuralTypes(CsdlStructuralType structuralType, CsdlAnnotations annotationGrp) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(structuralType.getAnnotations(), annotation)) { - structuralType.getAnnotations().addAll(annotationGrp.getAnnotations()); + private void removeAnnotationsAddedToCTTypePropFromES(CsdlStructuralType structuralType, FullQualifiedName typeName, + CsdlEntityContainer csdlEntityContainer, List properties, List entitySets) { + String containerName; + String schemaName; + String complexPropName; + for (CsdlEntitySet entitySet : entitySets) { + try { + CsdlEntityType entType = provider.getEntityType(entitySet.getTypeFQN()); + List entTypeProperties = null != entType ? + entType.getProperties() : new ArrayList(); + for (CsdlProperty entTypeProperty : entTypeProperties) { + if (null != entTypeProperty.getType() && + entTypeProperty.getType().endsWith(DOT + structuralType.getName())) { + complexPropName = entTypeProperty.getName(); + containerName = csdlEntityContainer.getName(); + schemaName = typeName.getNamespace(); + for (CsdlProperty property : properties) { + List annotPropDerivedFromES = getAnnotationsMap().get(schemaName + DOT + + containerName + SLASH + entitySet.getName() + SLASH + complexPropName + SLASH + property.getName()); + removeAnnotationsOnPropDerivedFromEntitySet(structuralType, property, annotPropDerivedFromES); + String aliasName = getAliasInfo(schemaName); + List annotPropDerivedFromESOnAlias = getAnnotationsMap().get(aliasName + DOT + + containerName + SLASH + entitySet.getName() + SLASH + complexPropName + SLASH + property.getName()); + removeAnnotationsOnPropDerivedFromEntitySet(structuralType, property, annotPropDerivedFromESOnAlias); + + List propAnnotations = getAnnotationsMap(). + get(typeName.getFullQualifiedNameAsString() + SLASH + property.getName()); + addAnnotationsOnPropertiesOfStructuralType(structuralType, property, propAnnotations); + aliasName = getAliasInfo(typeName.getNamespace()); + List propAnnotationsOnAlias = getAnnotationsMap(). + get(typeName.getName() + SLASH + property.getName()); + addAnnotationsOnPropertiesOfStructuralType(structuralType, property, propAnnotationsOnAlias); + } + } + } + } catch (ODataException e) { + throw new EdmException(e); } } } @@ -294,8 +587,18 @@ public class EdmProviderImpl extends AbstractEdm { try { final CsdlComplexType complexType = provider.getComplexType(complexTypeName); if (complexType != null) { + List annotations = getAnnotationsMap().get(complexTypeName.getFullQualifiedNameAsString()); + if (null != annotations && !annotations.isEmpty()) { + addAnnotationsOnStructuralType(complexType, annotations); + } + String aliasName = getAliasInfo(complexTypeName.getNamespace()); + List annotationsOnAlias = getAnnotationsMap().get(aliasName + DOT + complexTypeName.getName()); + if (null != annotationsOnAlias && !annotationsOnAlias.isEmpty()) { + addAnnotationsOnStructuralType(complexType, annotationsOnAlias); + } + if (!isComplexDerivedFromES()) { - addAnnotations(complexType, complexTypeName); + addStructuralTypeAnnotations(complexType, complexTypeName, provider.getEntityContainer()); } return new EdmComplexTypeImpl(this, complexTypeName, complexType); } @@ -329,7 +632,7 @@ public class EdmProviderImpl extends AbstractEdm { isComplexPreviousTypeCompatibleToBindingParam(bindingParameterTypeName, parameter, isBindingParameterCollection)) && isBindingParameterCollection.booleanValue() == parameter.isCollection()) { - addAnnotations(action, actionName); + addOperationsAnnotations(action, actionName); return new EdmActionImpl(this, actionName, action); } @@ -341,48 +644,57 @@ public class EdmProviderImpl extends AbstractEdm { } } - public void addAnnotations(CsdlAction action, FullQualifiedName actionName) { - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget().equalsIgnoreCase( - actionName.getFullQualifiedNameAsString())) { - addAnnotationsToActions(action, annotationGrp); - } else { - addAnnotationsToParamsOfActions(action, actionName, annotationGrp); - } - } + public void addOperationsAnnotations(CsdlOperation operation, FullQualifiedName actionName) { + String aliasName = getAliasInfo(actionName.getNamespace()); + List annotations = getAnnotationsMap().get(actionName.getFullQualifiedNameAsString()); + List annotationsOnAlias = getAnnotationsMap().get(aliasName + DOT + actionName.getName()); + if (null != annotations) { + addAnnotationsToOperations(operation, annotations); } + if (null != annotationsOnAlias) { + addAnnotationsToOperations(operation, annotationsOnAlias); + } + addAnnotationsToParamsOfOperations(operation, actionName); } - /** Adds annotations to actions - * @param action + /** Adds annotations to action parameters + * @param operation * @param actionName - * @param annotationGrp + * @param annotations */ - private void addAnnotationsToParamsOfActions(CsdlAction action, FullQualifiedName actionName, - CsdlAnnotations annotationGrp) { - final List parameters = action.getParameters(); + private void addAnnotationsToParamsOfOperations(CsdlOperation operation, FullQualifiedName actionName) { + final List parameters = operation.getParameters(); for (CsdlParameter parameter : parameters) { - if (annotationGrp.getTarget().equalsIgnoreCase( - actionName.getFullQualifiedNameAsString() + "/" + parameter.getName())) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(action.getParameter(parameter.getName()).getAnnotations(), annotation)) { - action.getParameter(parameter.getName()).getAnnotations().add(annotation); + List annotsToParams = getAnnotationsMap().get( + actionName.getFullQualifiedNameAsString() + SLASH + parameter.getName()); + if (null != annotsToParams && !annotsToParams.isEmpty()) { + for (CsdlAnnotation annotation : annotsToParams) { + if (!compareAnnotations(operation.getParameter(parameter.getName()).getAnnotations(), annotation)) { + operation.getParameter(parameter.getName()).getAnnotations().add(annotation); + } + } + } + String aliasName = getAliasInfo(actionName.getNamespace()); + List annotsToParamsOnAlias = getAnnotationsMap().get( + aliasName + DOT + actionName.getName() + SLASH + parameter.getName()); + if (null != annotsToParamsOnAlias && !annotsToParamsOnAlias.isEmpty()) { + for (CsdlAnnotation annotation : annotsToParamsOnAlias) { + if (!compareAnnotations(operation.getParameter(parameter.getName()).getAnnotations(), annotation)) { + operation.getParameter(parameter.getName()).getAnnotations().add(annotation); } } } } } - /** Adds annotations to parameters of action - * @param action - * @param annotationGrp + /** Adds annotations to action + * @param operation + * @param annotationsOnAlias */ - private void addAnnotationsToActions(CsdlAction action, CsdlAnnotations annotationGrp) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(action.getAnnotations(), annotation)) { - action.getAnnotations().add(annotation); + private void addAnnotationsToOperations(CsdlOperation operation, List annotations) { + for (CsdlAnnotation annotation : annotations) { + if (!compareAnnotations(operation.getAnnotations(), annotation)) { + operation.getAnnotations().add(annotation); } } } @@ -464,7 +776,7 @@ public class EdmProviderImpl extends AbstractEdm { providerParameterNames.add(providerParameters.get(i).getName()); } if (parameterNamesCopy.containsAll(providerParameterNames)) { - addAnnotations(function, functionName); + addOperationsAnnotations(function, functionName); return new EdmFunctionImpl(this, functionName, function); } } @@ -476,51 +788,6 @@ public class EdmProviderImpl extends AbstractEdm { } } - public void addAnnotations(CsdlFunction function, FullQualifiedName functionName) { - for (CsdlSchema schema : termSchemaDefinition) { - List annotationGrps = schema.getAnnotationGroups(); - for (CsdlAnnotations annotationGrp : annotationGrps) { - if (annotationGrp.getTarget().equalsIgnoreCase( - functionName.getFullQualifiedNameAsString())) { - addAnnotationsToFunctions(function, annotationGrp); - } else { - addAnnotationsToParamsOFunctions(function, functionName, annotationGrp); - } - } - } - } - - /** Adds annotations of function parameters - * @param function - * @param functionName - * @param annotationGrp - */ - private void addAnnotationsToParamsOFunctions(CsdlFunction function, FullQualifiedName functionName, - CsdlAnnotations annotationGrp) { - final List parameters = function.getParameters(); - for (CsdlParameter parameter : parameters) { - if (annotationGrp.getTarget().equalsIgnoreCase( - functionName.getFullQualifiedNameAsString() + "/" + parameter.getName())) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(function.getParameter(parameter.getName()).getAnnotations(), annotation)) { - function.getParameter(parameter.getName()).getAnnotations().add(annotation); - } - } - } - } - } - - /**Add annotations to functions - * @param function - * @param annotationGrp - */ - private void addAnnotationsToFunctions(CsdlFunction function, CsdlAnnotations annotationGrp) { - for (CsdlAnnotation annotation : annotationGrp.getAnnotations()) { - if (!compareAnnotations(function.getAnnotations(), annotation)) { - function.getAnnotations().add(annotation); - } - } - } @Override protected Map createAliasToNamespaceInfo() { @@ -553,6 +820,7 @@ public class EdmProviderImpl extends AbstractEdm { // Search for first unbound action for (CsdlAction action : actions) { if (!action.isBound()) { + addOperationsAnnotations(action, actionName); return new EdmActionImpl(this, actionName, action); } } @@ -577,6 +845,7 @@ public class EdmProviderImpl extends AbstractEdm { if (functions != null) { for (CsdlFunction function : functions) { if (!function.isBound()) { + addOperationsAnnotations(function, functionName); result.add(new EdmFunctionImpl(this, functionName, function)); } } @@ -616,6 +885,8 @@ public class EdmProviderImpl extends AbstractEdm { } if (parameterNamesCopy.containsAll(functionParameterNames)) { + addOperationsAnnotations(function, functionName); + addAnnotationsToParamsOfOperations(function, functionName); return new EdmFunctionImpl(this, functionName, function); } } @@ -677,6 +948,12 @@ public class EdmProviderImpl extends AbstractEdm { protected EdmAnnotations createAnnotationGroup(final FullQualifiedName targetName, String qualifier) { try { CsdlAnnotations providerGroup = provider.getAnnotationsGroup(targetName, qualifier); + if (null == providerGroup) { + for(CsdlSchema schema : termSchemaDefinition) { + providerGroup = schema.getAnnotationGroup(targetName.getFullQualifiedNameAsString(), qualifier); + break; + } + } if (providerGroup != null) { return new EdmAnnotationsImpl(this, providerGroup); } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmSchemaImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmSchemaImpl.java index a88faeeb9..20489a521 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmSchemaImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmSchemaImpl.java @@ -152,6 +152,7 @@ public class EdmSchemaImpl extends AbstractEdmAnnotatable implements EdmSchema { protected EdmEntityContainer createEntityContainer() { if (schema.getEntityContainer() != null) { FullQualifiedName containerFQN = new FullQualifiedName(namespace, schema.getEntityContainer().getName()); + edm.addEntityContainerAnnotations(schema.getEntityContainer(), containerFQN); EdmEntityContainer impl = new EdmEntityContainerImpl(edm, provider, containerFQN, schema.getEntityContainer()); edm.cacheEntityContainer(containerFQN, impl); edm.cacheEntityContainer(null, impl); @@ -166,6 +167,7 @@ public class EdmSchemaImpl extends AbstractEdmAnnotatable implements EdmSchema { if (providerTypeDefinitions != null) { for (CsdlTypeDefinition def : providerTypeDefinitions) { FullQualifiedName typeDefName = new FullQualifiedName(namespace, def.getName()); + edm.addTypeDefnAnnotations(def, typeDefName); EdmTypeDefinitionImpl typeDefImpl = new EdmTypeDefinitionImpl(edm, typeDefName, def); typeDefns.add(typeDefImpl); edm.cacheTypeDefinition(typeDefName, typeDefImpl); @@ -180,6 +182,7 @@ public class EdmSchemaImpl extends AbstractEdmAnnotatable implements EdmSchema { if (providerEnumTypes != null) { for (CsdlEnumType enumType : providerEnumTypes) { FullQualifiedName enumName = new FullQualifiedName(namespace, enumType.getName()); + edm.addEnumTypeAnnotations(enumType, enumName); EdmEnumType enumTypeImpl = new EdmEnumTypeImpl(edm, enumName, enumType); enumTyps.add(enumTypeImpl); edm.cacheEnumType(enumName, enumTypeImpl); @@ -194,6 +197,7 @@ public class EdmSchemaImpl extends AbstractEdmAnnotatable implements EdmSchema { if (providerEntityTypes != null) { for (CsdlEntityType entityType : providerEntityTypes) { FullQualifiedName entityTypeName = new FullQualifiedName(namespace, entityType.getName()); + edm.addStructuralTypeAnnotations(entityType, entityTypeName, schema.getEntityContainer()); EdmEntityTypeImpl entityTypeImpl = new EdmEntityTypeImpl(edm, entityTypeName, entityType); edmEntityTypes.add(entityTypeImpl); edm.cacheEntityType(entityTypeName, entityTypeImpl); @@ -208,6 +212,7 @@ public class EdmSchemaImpl extends AbstractEdmAnnotatable implements EdmSchema { if (providerComplexTypes != null) { for (CsdlComplexType complexType : providerComplexTypes) { FullQualifiedName comlexTypeName = new FullQualifiedName(namespace, complexType.getName()); + edm.addStructuralTypeAnnotations(complexType, comlexTypeName, schema.getEntityContainer()); EdmComplexTypeImpl complexTypeImpl = new EdmComplexTypeImpl(edm, comlexTypeName, complexType); edmComplexTypes.add(complexTypeImpl); edm.cacheComplexType(comlexTypeName, complexTypeImpl); @@ -222,6 +227,7 @@ public class EdmSchemaImpl extends AbstractEdmAnnotatable implements EdmSchema { if (providerActions != null) { for (CsdlAction action : providerActions) { FullQualifiedName actionName = new FullQualifiedName(namespace, action.getName()); + edm.addOperationsAnnotations(action, actionName); EdmActionImpl edmActionImpl = new EdmActionImpl(edm, actionName, action); edmActions.add(edmActionImpl); edm.cacheAction(actionName, edmActionImpl); @@ -236,6 +242,7 @@ public class EdmSchemaImpl extends AbstractEdmAnnotatable implements EdmSchema { if (providerFunctions != null) { for (CsdlFunction function : providerFunctions) { FullQualifiedName functionName = new FullQualifiedName(namespace, function.getName()); + edm.addOperationsAnnotations(function, functionName); EdmFunctionImpl functionImpl = new EdmFunctionImpl(edm, functionName, function); edmFunctions.add(functionImpl); edm.cacheFunction(functionName, functionImpl);