Repository: olingo-odata4 Updated Branches: refs/heads/olingo786 41210245d -> 15164da8f
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d00e3881/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java index 87cb4b4..356b90e 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java @@ -26,11 +26,11 @@ import java.util.Map; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import org.apache.olingo.commons.api.data.Valuable; import org.apache.olingo.commons.api.edm.EdmAction; import org.apache.olingo.commons.api.edm.EdmActionImport; import org.apache.olingo.commons.api.edm.EdmAnnotatable; import org.apache.olingo.commons.api.edm.EdmAnnotation; +import org.apache.olingo.commons.api.edm.EdmAnnotations; import org.apache.olingo.commons.api.edm.EdmBindingTarget; import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmEntityContainer; @@ -40,6 +40,7 @@ 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.EdmKeyPropertyRef; +import org.apache.olingo.commons.api.edm.EdmMember; import org.apache.olingo.commons.api.edm.EdmNavigationProperty; import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding; import org.apache.olingo.commons.api.edm.EdmOperation; @@ -53,8 +54,23 @@ import org.apache.olingo.commons.api.edm.EdmStructuredType; import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.api.edm.EdmTypeDefinition; import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.annotation.EdmApply; +import org.apache.olingo.commons.api.edm.annotation.EdmCast; 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.EdmIf; +import org.apache.olingo.commons.api.edm.annotation.EdmIsOf; +import org.apache.olingo.commons.api.edm.annotation.EdmLabeledElement; +import org.apache.olingo.commons.api.edm.annotation.EdmLabeledElementReference; +import org.apache.olingo.commons.api.edm.annotation.EdmLogicalOrComparisonExpression; +import org.apache.olingo.commons.api.edm.annotation.EdmNavigationPropertyPath; +import org.apache.olingo.commons.api.edm.annotation.EdmNot; +import org.apache.olingo.commons.api.edm.annotation.EdmPath; +import org.apache.olingo.commons.api.edm.annotation.EdmPropertyPath; +import org.apache.olingo.commons.api.edm.annotation.EdmPropertyValue; +import org.apache.olingo.commons.api.edm.annotation.EdmRecord; +import org.apache.olingo.commons.api.edm.annotation.EdmUrlRef; import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.edmx.EdmxReference; @@ -119,6 +135,8 @@ public class MetadataDocumentXmlSerializer { private static final String DATA_SERVICES = "DataServices"; private static final String ABSTRACT = "Abstract"; + private static final String XML_ANNOTATIONS = "Annotations"; + private static final String EDMX = "Edmx"; private static final String PREFIX_EDMX = "edmx"; private static final String NS_EDMX = "http://docs.oasis-open.org/odata/ns/edmx"; @@ -128,6 +146,7 @@ public class MetadataDocumentXmlSerializer { private static final String XML_CONTAINS_TARGET = "ContainsTarget"; private static final String XML_TERM_ATT = "Term"; private static final String XML_QUALIFIER_ATT = "Qualifier"; + private static final String XML_PROPERTY_Value = "PropertyValue"; private final ServiceMetadata serviceMetadata; private final Map<String, String> namespaceToAlias = new HashMap<String, String>(); @@ -140,8 +159,6 @@ public class MetadataDocumentXmlSerializer { this.serviceMetadata = serviceMetadata; } - // TODO: Annotations in metadata document - public void writeMetadataDocument(final XMLStreamWriter writer) throws XMLStreamException { writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0"); writer.setPrefix(PREFIX_EDMX, NS_EDMX); @@ -195,13 +212,227 @@ public class MetadataDocumentXmlSerializer { // EntityContainer appendEntityContainer(writer, schema.getEntityContainer()); + // AnnotationGroups + appendAnnotationGroups(writer, schema.getAnnotationGroups()); + + appendAnnotations(writer, schema); + + writer.writeEndElement(); + } + + private void appendAnnotationGroups(XMLStreamWriter writer, List<EdmAnnotations> annotationGroups) + throws XMLStreamException { + for (EdmAnnotations annotationGroup : annotationGroups) { + appendAnnotationGroup(writer, annotationGroup); + } + } + + private void appendAnnotationGroup(XMLStreamWriter writer, EdmAnnotations annotationGroup) + throws XMLStreamException { + writer.writeStartElement(XML_ANNOTATIONS); + writer.writeAttribute(XML_TARGET, annotationGroup.getTargetPath()); + if (annotationGroup.getQualifier() != null) { + writer.writeAttribute(XML_QUALIFIER_ATT, annotationGroup.getQualifier()); + } + appendAnnotations(writer, annotationGroup); + writer.writeEndElement(); + } + + private void appendAnnotations(XMLStreamWriter writer, EdmAnnotatable annotatable) throws XMLStreamException { + List<EdmAnnotation> annotations = annotatable.getAnnotations(); + if (annotations != null && !annotations.isEmpty()) { + for (EdmAnnotation annotation : annotations) { + writer.writeStartElement(XML_ANNOTATION); + if (annotation.getTerm() != null) { + writer.writeAttribute(XML_TERM_ATT, annotation.getTerm().getFullQualifiedName() + .getFullQualifiedNameAsString()); + } + if (annotation.getQualifier() != null) { + writer.writeAttribute(XML_QUALIFIER_ATT, annotation.getQualifier()); + } + appendExpression(writer, annotation.getExpression()); + appendAnnotations(writer, annotation); + writer.writeEndElement(); + } + } + } + + private void appendExpression(XMLStreamWriter writer, EdmExpression expression) throws XMLStreamException { + if (expression == null) { + return; + } + if (expression.isConstant()) { + appendConstantExpression(writer, expression.asConstant()); + } else if (expression.isDynamic()) { + appendDynamicExpression(writer, expression.asDynamic()); + } else { + throw new IllegalArgumentException("Unkown expressiontype in metadata"); + } + } + + private void appendDynamicExpression(XMLStreamWriter writer, EdmDynamicExpression dynExp) throws XMLStreamException { + writer.writeStartElement(dynExp.getExpressionName()); + switch (dynExp.getExpressionType()) { + // Logical + case And: + appendLogicalOrComparisonExpression(writer, dynExp.asAnd()); + break; + case Or: + appendLogicalOrComparisonExpression(writer, dynExp.asOr()); + break; + case Not: + appendNotExpression(writer, dynExp.asNot()); + break; + // Comparison + case Eq: + appendLogicalOrComparisonExpression(writer, dynExp.asEq()); + break; + case Ne: + appendLogicalOrComparisonExpression(writer, dynExp.asNe()); + break; + case Gt: + appendLogicalOrComparisonExpression(writer, dynExp.asGt()); + break; + case Ge: + appendLogicalOrComparisonExpression(writer, dynExp.asGe()); + break; + case Lt: + appendLogicalOrComparisonExpression(writer, dynExp.asLt()); + break; + case Le: + appendLogicalOrComparisonExpression(writer, dynExp.asLe()); + break; + case AnnotationPath: + writer.writeCharacters(dynExp.asAnnotationPath().getValue()); + break; + case Apply: + EdmApply asApply = dynExp.asApply(); + writer.writeAttribute(XML_FUNCTION, asApply.getFunction()); + for (EdmExpression parameter : asApply.getParameters()) { + appendExpression(writer, parameter); + } + appendAnnotations(writer, asApply); + break; + case Cast: + EdmCast asCast = dynExp.asCast(); + writer.writeAttribute(XML_TYPE, asCast.getType().getFullQualifiedName().getFullQualifiedNameAsString()); + + if (asCast.getMaxLength() != null) { + writer.writeAttribute(XML_MAX_LENGTH, "" + asCast.getMaxLength()); + } + + if (asCast.getPrecision() != null) { + writer.writeAttribute(XML_PRECISION, "" + asCast.getPrecision()); + } + + if (asCast.getScale() != null) { + writer.writeAttribute(XML_SCALE, "" + asCast.getScale()); + } + appendExpression(writer, asCast.getValue()); + appendAnnotations(writer, asCast); + break; + case Collection: + for (EdmExpression item : dynExp.asCollection().getItems()) { + appendExpression(writer, item); + } + break; + case If: + EdmIf asIf = dynExp.asIf(); + appendExpression(writer, asIf.getGuard()); + appendExpression(writer, asIf.getThen()); + appendExpression(writer, asIf.getElse()); + appendAnnotations(writer, asIf); + break; + case IsOf: + EdmIsOf asIsOf = dynExp.asIsOf(); + writer.writeAttribute(XML_TYPE, asIsOf.getType().getFullQualifiedName().getFullQualifiedNameAsString()); + + if (asIsOf.getMaxLength() != null) { + writer.writeAttribute(XML_MAX_LENGTH, "" + asIsOf.getMaxLength()); + } + + if (asIsOf.getPrecision() != null) { + writer.writeAttribute(XML_PRECISION, "" + asIsOf.getPrecision()); + } + + if (asIsOf.getScale() != null) { + writer.writeAttribute(XML_SCALE, "" + asIsOf.getScale()); + } + appendExpression(writer, asIsOf.getValue()); + appendAnnotations(writer, asIsOf); + break; + case LabeledElement: + EdmLabeledElement asLabeledElement = dynExp.asLabeledElement(); + writer.writeAttribute(XML_NAME, asLabeledElement.getName()); + appendExpression(writer, asLabeledElement.getValue()); + appendAnnotations(writer, asLabeledElement); + break; + case LabeledElementReference: + EdmLabeledElementReference asLabeledElementReference = dynExp.asLabeledElementReference(); + writer.writeCharacters(asLabeledElementReference.getValue()); + break; + case Null: + appendAnnotations(writer, dynExp.asNull()); + break; + case NavigationPropertyPath: + EdmNavigationPropertyPath asNavigationPropertyPath = dynExp.asNavigationPropertyPath(); + writer.writeCharacters(asNavigationPropertyPath.getValue()); + break; + case Path: + EdmPath asPath = dynExp.asPath(); + writer.writeCharacters(asPath.getValue()); + break; + case PropertyPath: + EdmPropertyPath asPropertyPath = dynExp.asPropertyPath(); + writer.writeCharacters(asPropertyPath.getValue()); + break; + case Record: + EdmRecord asRecord = dynExp.asRecord(); + writer.writeAttribute(XML_TYPE, asRecord.getType().getFullQualifiedName().getFullQualifiedNameAsString()); + for (EdmPropertyValue propValue : asRecord.getPropertyValues()) { + writer.writeStartElement(XML_PROPERTY_Value); + writer.writeAttribute(XML_PROPERTY, propValue.getProperty()); + appendExpression(writer, propValue.getValue()); + appendAnnotations(writer, propValue); + writer.writeEndElement(); + } + appendAnnotations(writer, asRecord); + break; + case UrlRef: + EdmUrlRef asUrlRef = dynExp.asUrlRef(); + appendExpression(writer, asUrlRef.getValue()); + appendAnnotations(writer, asUrlRef); + break; + default: + throw new IllegalArgumentException("Unkown ExpressionType for dynamic expression: " + dynExp.getExpressionType()); + } + + writer.writeEndElement(); + } + + private void appendNotExpression(XMLStreamWriter writer, EdmNot exp) throws XMLStreamException { + appendExpression(writer, exp.getLeftExpression()); + appendAnnotations(writer, exp); + } + + private void appendLogicalOrComparisonExpression(XMLStreamWriter writer, EdmLogicalOrComparisonExpression exp) + throws XMLStreamException { + appendExpression(writer, exp.getLeftExpression()); + appendExpression(writer, exp.getRightExpression()); + appendAnnotations(writer, exp); + } + + private void appendConstantExpression(XMLStreamWriter writer, EdmConstantExpression constExp) + throws XMLStreamException { + writer.writeStartElement(constExp.getExpressionName()); + writer.writeCharacters(constExp.getValueAsString()); writer.writeEndElement(); } private void appendTypeDefinitions(final XMLStreamWriter writer, final List<EdmTypeDefinition> typeDefinitions) throws XMLStreamException { for (EdmTypeDefinition definition : typeDefinitions) { - writer.writeEmptyElement(XML_TYPE_DEFINITION); + writer.writeStartElement(XML_TYPE_DEFINITION); writer.writeAttribute(XML_NAME, definition.getName()); writer.writeAttribute(XML_UNDERLYING_TYPE, getFullQualifiedName(definition.getUnderlyingType(), false)); @@ -217,6 +448,9 @@ public class MetadataDocumentXmlSerializer { if (definition.getScale() != null) { writer.writeAttribute(XML_SCALE, "" + definition.getScale()); } + + appendAnnotations(writer, definition); + writer.writeEndElement(); } } @@ -256,6 +490,9 @@ public class MetadataDocumentXmlSerializer { // Singletons appendSingletons(writer, container.getSingletons()); + // Annotations + appendAnnotations(writer, container); + writer.writeEndElement(); } } @@ -283,6 +520,7 @@ public class MetadataDocumentXmlSerializer { if (functionImport.isIncludeInServiceDocument()) { writer.writeAttribute(XML_INCLUDE_IN_SERVICE_DOCUMENT, "" + functionImport.isIncludeInServiceDocument()); } + appendAnnotations(writer, functionImport); writer.writeEndElement(); } } @@ -294,6 +532,7 @@ public class MetadataDocumentXmlSerializer { writer.writeAttribute(XML_NAME, actionImport.getName()); writer.writeAttribute(XML_ACTION, getAliasedFullQualifiedName(actionImport.getUnboundAction(), false)); writer.writeEndElement(); + appendAnnotations(writer, actionImport); } } @@ -305,6 +544,7 @@ public class MetadataDocumentXmlSerializer { writer.writeAttribute(XML_ENTITY_TYPE, getAliasedFullQualifiedName(singleton.getEntityType(), false)); appendNavigationPropertyBindings(writer, singleton); + appendAnnotations(writer, singleton); writer.writeEndElement(); } @@ -357,6 +597,8 @@ public class MetadataDocumentXmlSerializer { appendOperationReturnType(writer, function); + appendAnnotations(writer, function); + writer.writeEndElement(); } } @@ -382,7 +624,7 @@ public class MetadataDocumentXmlSerializer { throws XMLStreamException { for (String parameterName : operation.getParameterNames()) { EdmParameter parameter = operation.getParameter(parameterName); - writer.writeEmptyElement(XML_PARAMETER); + writer.writeStartElement(XML_PARAMETER); writer.writeAttribute(XML_NAME, parameterName); String typeFqnString; if (EdmTypeKind.PRIMITIVE.equals(parameter.getType().getKind())) { @@ -393,6 +635,9 @@ public class MetadataDocumentXmlSerializer { writer.writeAttribute(XML_TYPE, typeFqnString); appendParameterFacets(writer, parameter); + + appendAnnotations(writer, parameter); + writer.writeEndElement(); } } @@ -409,6 +654,8 @@ public class MetadataDocumentXmlSerializer { appendOperationReturnType(writer, action); + appendAnnotations(writer, action); + writer.writeEndElement(); } } @@ -463,6 +710,8 @@ public class MetadataDocumentXmlSerializer { appendNavigationProperties(writer, complexType); + appendAnnotations(writer, complexType); + writer.writeEndElement(); } } @@ -497,30 +746,6 @@ public class MetadataDocumentXmlSerializer { } } - private void appendAnnotations(XMLStreamWriter writer, EdmAnnotatable annotatable) throws XMLStreamException { - List<EdmAnnotation> annotations = annotatable.getAnnotations(); - for (EdmAnnotation annotation : annotations) { - writer.writeStartElement(XML_ANNOTATION); - String term = getAliasedFullQualifiedName(annotation.getTerm().getFullQualifiedName(), false); - writer.writeAttribute(XML_TERM_ATT, term); - String qualifier = annotation.getQualifier(); - if (qualifier != null) { - writer.writeAttribute(XML_QUALIFIER_ATT, qualifier); - } - EdmExpression expression = annotation.getExpression(); - if (expression != null) { - if (expression.isConstant()) { - EdmConstantExpression constExpression = expression.asConstant(); - Valuable value = constExpression.getValue(); - writer.writeAttribute(value.getType(), constExpression.getValueAsString()); - } else { - // TODO: mibo_150930: Handle dynamic expressions - } - } - writer.writeEndElement(); - } - } - private void appendNavigationProperties(final XMLStreamWriter writer, final EdmStructuredType type) throws XMLStreamException { List<String> navigationPropertyNames = new ArrayList<String>(type.getNavigationPropertyNames()); @@ -549,12 +774,16 @@ public class MetadataDocumentXmlSerializer { if (navigationProperty.getReferentialConstraints() != null) { for (EdmReferentialConstraint constraint : navigationProperty.getReferentialConstraints()) { - writer.writeEmptyElement("ReferentialConstraint"); + writer.writeStartElement("ReferentialConstraint"); writer.writeAttribute(XML_PROPERTY, constraint.getPropertyName()); writer.writeAttribute("ReferencedProperty", constraint.getReferencedPropertyName()); + appendAnnotations(writer, constraint); + writer.writeEndElement(); } } + appendAnnotations(writer, navigationProperty); + writer.writeEndElement(); } } @@ -566,7 +795,7 @@ public class MetadataDocumentXmlSerializer { } for (String propertyName : propertyNames) { EdmProperty property = type.getStructuralProperty(propertyName); - writer.writeEmptyElement(XML_PROPERTY); + writer.writeStartElement(XML_PROPERTY); writer.writeAttribute(XML_NAME, propertyName); String fqnString; if (property.isPrimitive()) { @@ -600,6 +829,9 @@ public class MetadataDocumentXmlSerializer { if (property.getScale() != null) { writer.writeAttribute(XML_SCALE, "" + property.getScale()); } + + appendAnnotations(writer, property); + writer.writeEndElement(); } } @@ -637,7 +869,9 @@ public class MetadataDocumentXmlSerializer { for (String memberName : enumType.getMemberNames()) { writer.writeEmptyElement(XML_MEMBER); writer.writeAttribute(XML_NAME, memberName); - writer.writeAttribute(XML_VALUE, enumType.getMember(memberName).getValue()); + EdmMember member = enumType.getMember(memberName); + writer.writeAttribute(XML_VALUE, member.getValue()); + appendAnnotations(writer, member); } writer.writeEndElement(); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d00e3881/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java index ea39b17..7af3780 100644 --- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializerTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.ArrayList; @@ -32,16 +33,16 @@ import java.util.Collections; import java.util.List; import org.apache.commons.io.IOUtils; -import org.apache.olingo.commons.api.ex.ODataException; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.EdmSchema; import org.apache.olingo.commons.api.edm.FullQualifiedName; -import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider; import org.apache.olingo.commons.api.edm.provider.CsdlAction; import org.apache.olingo.commons.api.edm.provider.CsdlActionImport; import org.apache.olingo.commons.api.edm.provider.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; @@ -58,6 +59,31 @@ import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef; import org.apache.olingo.commons.api.edm.provider.CsdlReturnType; import org.apache.olingo.commons.api.edm.provider.CsdlSchema; import org.apache.olingo.commons.api.edm.provider.CsdlSingleton; +import org.apache.olingo.commons.api.edm.provider.CsdlTerm; +import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlAnnotationPath; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlApply; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlCast; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlCollection; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlIf; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlIsOf; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPath; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPropertyValue; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression.ConstantExpressionType; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlExpression; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLabeledElement; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLabeledElementReference; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLogicalOrComparisonExpression; +//CHECKSTYLE:OFF +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlLogicalOrComparisonExpression.LogicalOrComparisonExpressionType; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlNavigationPropertyPath; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlNull; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlPropertyPath; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlRecord; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlUrlRef; +//CHECKSTYLE:ON +import org.apache.olingo.commons.api.ex.ODataException; import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.commons.core.edm.EdmComplexTypeImpl; import org.apache.olingo.server.api.OData; @@ -74,7 +100,7 @@ import org.junit.Test; public class MetadataDocumentXmlSerializerTest { private static ODataSerializer serializer; - + @BeforeClass public static void init() throws SerializerException { serializer = OData.newInstance().createSerializer(ContentType.APPLICATION_XML); @@ -113,7 +139,6 @@ public class MetadataDocumentXmlSerializerTest { IOUtils.toString(metadata)); } - /** Writes simplest (empty) Schema. */ @Test public void writeMetadataWithSimpleSchema() throws Exception { @@ -127,11 +152,11 @@ public class MetadataDocumentXmlSerializerTest { InputStream metadata = serializer.metadataDocument(serviceMetadata).getContent(); assertNotNull(metadata); assertEquals("<?xml version='1.0' encoding='UTF-8'?>" + - "<edmx:Edmx Version=\"4.0\" xmlns:edmx=\"http://docs.oasis-open.org/odata/ns/edmx\">" + - "<edmx:DataServices>" + - "<Schema xmlns=\"http://docs.oasis-open.org/odata/ns/edm\" Namespace=\"MyNamespace\"/>" + - "</edmx:DataServices>" + - "</edmx:Edmx>", + "<edmx:Edmx Version=\"4.0\" xmlns:edmx=\"http://docs.oasis-open.org/odata/ns/edmx\">" + + "<edmx:DataServices>" + + "<Schema xmlns=\"http://docs.oasis-open.org/odata/ns/edm\" Namespace=\"MyNamespace\"/>" + + "</edmx:DataServices>" + + "</edmx:Edmx>", IOUtils.toString(metadata)); } @@ -235,11 +260,7 @@ public class MetadataDocumentXmlSerializerTest { @Test public void aliasTest() throws Exception { - CsdlEdmProvider provider = new LocalProvider(); - ServiceMetadata serviceMetadata = new ServiceMetadataImpl(provider, Collections.<EdmxReference> emptyList(), null); - InputStream metadataStream = serializer.metadataDocument(serviceMetadata).getContent(); - String metadata = IOUtils.toString(metadataStream); - assertNotNull(metadata); + String metadata = localMetadata(); assertTrue(metadata.contains("<EnumType Name=\"ENString\" IsFlags=\"true\" UnderlyingType=\"Edm.Int16\">")); assertTrue(metadata.contains("<EntityType Name=\"ETAbstractBase\" BaseType=\"Alias.ETAbstract\">")); @@ -253,6 +274,81 @@ public class MetadataDocumentXmlSerializerTest { } @Test + public void annotationsTest() throws Exception { + String metadata = localMetadata(); + // All constant expressions + assertTrue(metadata.contains("<Annotations Target=\"Alias.ETAbstract\" Qualifier=\"Tablett\">")); + assertTrue(metadata.contains("</Annotations>")); + assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Binary>qrvM3e7_</Binary></Annotation>")); + assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Bool>true</Bool></Annotation>")); + assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Date>2012-02-29</Date></Annotation>")); + assertTrue(metadata + .contains("<Annotation Term=\"ns.term\"><DateTimeOffset>2012-02-29T01:02:03Z</DateTimeOffset></Annotation>")); + assertTrue(metadata + .contains("<Annotation Term=\"ns.term\"><Decimal>-12345678901234567234567890</Decimal></Annotation>")); + assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Duration>PT10S</Duration></Annotation>")); + assertTrue(metadata + .contains("<Annotation Term=\"ns.term\"><EnumMember>Enum/enumMember</EnumMember></Annotation>")); + assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Float>1.42</Float></Annotation>")); + assertTrue(metadata + .contains("<Annotation Term=\"ns.term\"><Guid>aabbccdd-aabb-ccdd-eeff-aabbccddeeff</Guid></Annotation>")); + assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><Int>42</Int></Annotation>")); + assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><String>ABCD</String></Annotation>")); + assertTrue(metadata.contains("<Annotation Term=\"ns.term\"><TimeOfDay>00:00:00.999</TimeOfDay></Annotation>")); + + // All dynamic expressions + // Logical expressions + assertTrue(metadata.contains("<And><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></And>")); + assertTrue(metadata.contains("<Or><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Or>")); + assertTrue(metadata.contains("<Not><Bool>true</Bool><Annotation Term=\"ns.term\"/></Not>")); + + // Comparison expressions + assertTrue(metadata.contains("<Eq><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Eq>")); + assertTrue(metadata.contains("<Ne><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Ne>")); + assertTrue(metadata.contains("<Gt><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Gt>")); + assertTrue(metadata.contains("<Ge><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Ge>")); + assertTrue(metadata.contains("<Lt><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Lt>")); + assertTrue(metadata.contains("<Le><Bool>true</Bool><Bool>false</Bool><Annotation Term=\"ns.term\"/></Le>")); + + // Other + assertTrue(metadata.contains("<AnnotationPath>AnnoPathValue</AnnotationPath>")); + assertTrue(metadata + .contains("<Apply Function=\"odata.concat\"><Bool>true</Bool><Annotation Term=\"ns.term\"/></Apply>")); + assertTrue(metadata + .contains("<Cast Type=\"Edm.String\" MaxLength=\"1\" Precision=\"2\" Scale=\"3\">" + + "<String>value</String><Annotation Term=\"ns.term\"/></Cast>")); + assertTrue(metadata.contains("<Collection><Bool>true</Bool>" + + "<Bool>false</Bool><String>String</String></Collection>")); + assertTrue(metadata + .contains("<If><Bool>true</Bool><String>Then</String>" + + "<String>Else</String><Annotation Term=\"ns.term\"/></If>")); + assertTrue(metadata + .contains("<IsOf Type=\"Edm.String\" MaxLength=\"1\" Precision=\"2\" Scale=\"3\">" + + "<String>value</String><Annotation Term=\"ns.term\"/></IsOf>")); + assertTrue(metadata + .contains("<LabeledElement Name=\"NameAtt\">" + + "<String>value</String><Annotation Term=\"ns.term\"/></LabeledElement>")); + assertTrue(metadata.contains("<LabeledElementReference>LabeledElementReferenceValue</LabeledElementReference>")); + assertTrue(metadata.contains("<NavigationPropertyPath>NavigationPropertyPathValue</NavigationPropertyPath>")); + assertTrue(metadata.contains("<Path>PathValue</Path>")); + assertTrue(metadata.contains("<PropertyPath>PropertyPathValue</PropertyPath>")); + assertTrue(metadata + .contains("<Record Type=\"namespace.ETAbstract\"><PropertyValue Property=\"PropName\"><String>value</String>" + + "<Annotation Term=\"ns.term\"/></PropertyValue><Annotation Term=\"ns.term\"/></Record>")); + assertTrue(metadata.contains("<UrlRef><String>URLRefValue</String><Annotation Term=\"ns.term\"/></UrlRef>")); + + } + + private String localMetadata() throws SerializerException, IOException { + CsdlEdmProvider provider = new LocalProvider(); + ServiceMetadata serviceMetadata = new ServiceMetadataImpl(provider, Collections.<EdmxReference> emptyList(), null); + InputStream metadataStream = serializer.metadataDocument(serviceMetadata).getContent(); + String metadata = IOUtils.toString(metadataStream); + assertNotNull(metadata); + return metadata; + } + + @Test public void writeAbstractComplexType() throws Exception { EdmSchema schema = mock(EdmSchema.class); when(schema.getNamespace()).thenReturn("MyNamespace"); @@ -286,7 +382,7 @@ public class MetadataDocumentXmlSerializerTest { + "</ComplexType>")); } - static class LocalProvider extends CsdlAbstractEdmProvider { + static class LocalProvider implements CsdlEdmProvider { private final static String nameSpace = "namespace"; private final FullQualifiedName nameETAbstract = new FullQualifiedName(nameSpace, "ETAbstract"); @@ -318,12 +414,15 @@ public class MetadataDocumentXmlSerializerTest { @Override public CsdlEnumType getEnumType(final FullQualifiedName enumTypeName) throws ODataException { - return new CsdlEnumType() - .setName("ENString") - .setFlags(true) - .setUnderlyingType(EdmPrimitiveTypeKind.Int16.getFullQualifiedName()) - .setMembers(Arrays.asList( - new CsdlEnumMember().setName("String1").setValue("1"))); + if ("ENString".equals(enumTypeName.getName())) { + return new CsdlEnumType() + .setName("ENString") + .setFlags(true) + .setUnderlyingType(EdmPrimitiveTypeKind.Int16.getFullQualifiedName()) + .setMembers(Arrays.asList( + new CsdlEnumMember().setName("String1").setValue("1"))); + } + return null; } @Override @@ -488,6 +587,11 @@ public class MetadataDocumentXmlSerializerTest { // EntityContainer schema.setEntityContainer(getEntityContainer()); + // Annotationgroups + List<CsdlAnnotations> annotationGroups = new ArrayList<CsdlAnnotations>(); + annotationGroups.add(getAnnotationsGroup(new FullQualifiedName("Alias.ETAbstract"), "Tablett")); + schema.setAnnotationsGroup(annotationGroups); + return schemas; } @@ -499,7 +603,7 @@ public class MetadataDocumentXmlSerializerTest { } return null; } - + @Override public CsdlEntityContainer getEntityContainer() throws ODataException { CsdlEntityContainer container = new CsdlEntityContainer(); @@ -527,5 +631,188 @@ public class MetadataDocumentXmlSerializerTest { return container; } + + @Override + public CsdlTypeDefinition getTypeDefinition(FullQualifiedName typeDefinitionName) throws ODataException { + return null; + } + + @Override + public CsdlTerm getTerm(FullQualifiedName termName) throws ODataException { + if (new FullQualifiedName("ns.term").equals(termName)) { + return new CsdlTerm().setType("Edm.String").setName("term"); + } + return null; + } + + @Override + public CsdlAnnotations getAnnotationsGroup(FullQualifiedName targetName, String qualifier) throws ODataException { + if (new FullQualifiedName("Alias.ETAbstract").equals(targetName) && "Tablett".equals(qualifier)) { + CsdlAnnotations annoGroup = new CsdlAnnotations(); + annoGroup.setTarget("Alias.ETAbstract"); + annoGroup.setQualifier("Tablett"); + + List<CsdlAnnotation> innerAnnotations = new ArrayList<CsdlAnnotation>(); + innerAnnotations.add(new CsdlAnnotation().setTerm("ns.term")); + + List<CsdlAnnotation> annotationsList = new ArrayList<CsdlAnnotation>(); + annoGroup.setAnnotations(annotationsList); + // Constant Annotations + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.Binary).setValue("qrvM3e7_"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.Bool, "true"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.Date, "2012-02-29"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.DateTimeOffset, "2012-02-29T01:02:03Z"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.Decimal, "-12345678901234567234567890"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.Duration, "PT10S"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.EnumMember, "Enum/enumMember"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.Float, "1.42"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression( + new CsdlConstantExpression(ConstantExpressionType.Guid, "aabbccdd-aabb-ccdd-eeff-aabbccddeeff"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.Int, "42"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.String, "ABCD"))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlConstantExpression(ConstantExpressionType.TimeOfDay, "00:00:00.999"))); + + // logical expressions + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.And) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")) + .setAnnotations(innerAnnotations))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Or) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")) + .setAnnotations(innerAnnotations))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Not) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setAnnotations(innerAnnotations))); + + // comparison + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Eq) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")) + .setAnnotations(innerAnnotations))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Ne) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")) + .setAnnotations(innerAnnotations))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Gt) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")) + .setAnnotations(innerAnnotations))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Ge) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")) + .setAnnotations(innerAnnotations))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Lt) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")) + .setAnnotations(innerAnnotations))); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLogicalOrComparisonExpression(LogicalOrComparisonExpressionType.Le) + .setLeft(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setRight(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")) + .setAnnotations(innerAnnotations))); + + // Other + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlAnnotationPath().setValue("AnnoPathValue"))); + + List<CsdlExpression> parameters = new ArrayList<CsdlExpression>(); + parameters.add(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlApply().setFunction("odata.concat") + .setParameters(parameters) + .setAnnotations(innerAnnotations))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlCast() + .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "value")) + .setMaxLength(1) + .setPrecision(2) + .setScale(3) + .setType("Edm.String") + .setAnnotations(innerAnnotations))); + + List<CsdlExpression> items = new ArrayList<CsdlExpression>(); + items.add(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")); + items.add(new CsdlConstantExpression(ConstantExpressionType.Bool, "false")); + items.add(new CsdlConstantExpression(ConstantExpressionType.String, "String")); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlCollection().setItems(items))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlIf() + .setGuard(new CsdlConstantExpression(ConstantExpressionType.Bool, "true")) + .setThen(new CsdlConstantExpression(ConstantExpressionType.String, "Then")) + .setElse(new CsdlConstantExpression(ConstantExpressionType.String, "Else")) + .setAnnotations(innerAnnotations))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlIsOf() + .setMaxLength(1) + .setPrecision(2) + .setScale(3) + .setType("Edm.String") + .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "value")) + .setAnnotations(innerAnnotations))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLabeledElement() + .setName("NameAtt") + .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "value")) + .setAnnotations(innerAnnotations))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlLabeledElementReference().setValue("LabeledElementReferenceValue"))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlNull().setAnnotations(innerAnnotations))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlNavigationPropertyPath().setValue("NavigationPropertyPathValue"))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlPath().setValue("PathValue"))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlPropertyPath().setValue("PropertyPathValue"))); + + CsdlPropertyValue prop = new CsdlPropertyValue() + .setProperty("PropName") + .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "value")) + .setAnnotations(innerAnnotations); + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlRecord().setType("Alias.ETAbstract") + .setPropertyValues(Arrays.asList(prop)) + .setAnnotations(innerAnnotations))); + + annotationsList.add(new CsdlAnnotation().setTerm("ns.term") + .setExpression(new CsdlUrlRef() + .setValue(new CsdlConstantExpression(ConstantExpressionType.String, "URLRefValue")) + .setAnnotations(innerAnnotations))); + + return annoGroup; + } + return null; + } } }
