[OLINGO-786] First minor adaption to MetadataSerializer

This commit is contained in:
Michael Bolz 2015-09-30 15:28:00 +02:00
parent a88800c47a
commit 3ec5a161ef
17 changed files with 265 additions and 56 deletions

View File

@ -25,6 +25,7 @@ import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.olingo.commons.api.edm.provider.annotation.AbstractCsdlAnnotationExpression;
import org.apache.olingo.commons.api.edm.provider.annotation.AnnotationPath;
import org.apache.olingo.commons.api.edm.provider.annotation.Apply;
import org.apache.olingo.commons.api.edm.provider.annotation.Cast;
@ -50,7 +51,7 @@ import java.io.IOException;
@JsonDeserialize(using = AbstractClientCsdlDynamicAnnotationExpression.DynamicAnnotationExpressionDeserializer.class)
abstract class AbstractClientCsdlDynamicAnnotationExpression
extends AbstractClientCsdlAnnotationExpression implements DynamicAnnotationExpression {
extends AbstractCsdlAnnotationExpression implements DynamicAnnotationExpression {
private static final long serialVersionUID = 1093411847477874348L;
@ -257,8 +258,8 @@ abstract class AbstractClientCsdlDynamicAnnotationExpression
}
}
private AbstractClientCsdlAnnotationExpression parseConstOrEnumExpression(final JsonParser jp) throws IOException {
AbstractClientCsdlAnnotationExpression result;
private AbstractCsdlAnnotationExpression parseConstOrEnumExpression(final JsonParser jp) throws IOException {
AbstractCsdlAnnotationExpression result;
if (isAnnotationConstExprConstruct(jp)) {
result = parseAnnotationConstExprConstruct(jp);
} else {

View File

@ -18,35 +18,10 @@
*/
package org.apache.olingo.client.core.edm.xml;
import org.apache.olingo.commons.api.edm.provider.annotation.ConstantAnnotationExpression;
import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantAnnotationExpression;
class ClientCsdlConstantAnnotationExpression
extends AbstractClientCsdlAnnotationExpression implements ConstantAnnotationExpression {
extends CsdlConstantAnnotationExpression {
private static final long serialVersionUID = 5618680702707972904L;
private Type type;
private String value;
@Override
public Type getType() {
return type;
}
@Override
public void setType(final Type type) {
this.type = type;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(final String value) {
this.value = value;
}
}

View File

@ -173,7 +173,7 @@ public class MetadataTest extends AbstractTest {
final EdmAnnotation annotation = annotationGroup.getAnnotations().get(0);
assertNotNull(annotation);
assertTrue(annotation.getExpression().isConstant());
assertEquals("Edm.String", annotation.getExpression().asConstant().getValue().getType());
assertEquals("String", annotation.getExpression().asConstant().getValue().getType());
assertEquals(10, schema.getAnnotationGroups().get(3).getAnnotations().size());
}
@ -331,10 +331,10 @@ public class MetadataTest extends AbstractTest {
assertNotNull(group);
final EdmAnnotation time1 = group.getAnnotations().get(0);
assertEquals("Edm.TimeOfDay", time1.getExpression().asConstant().getValue().getType());
assertEquals("TimeOfDay", time1.getExpression().asConstant().getValue().getType());
final EdmAnnotation time2 = group.getAnnotations().get(1);
assertEquals("Edm.TimeOfDay", time2.getExpression().asConstant().getValue().getType());
assertEquals("TimeOfDay", time2.getExpression().asConstant().getValue().getType());
}
/**

View File

@ -50,8 +50,9 @@ public class CsdlAnnotation extends CsdlAbstractEdmItem implements CsdlAnnotatab
* Sets the annotated expression
* @param annotationExpression annotated expression
*/
public void setExpression(final AnnotationExpression annotationExpression) {
public CsdlAnnotation setExpression(final AnnotationExpression annotationExpression) {
this.annotationExpression = annotationExpression;
return this;
}
/**

View File

@ -130,4 +130,8 @@ public abstract class CsdlBindingTarget extends CsdlAbstractEdmItem implements C
return annotations;
}
public CsdlBindingTarget setAnnotations(final List<CsdlAnnotation> annotations) {
this.annotations.addAll(annotations);
return this;
}
}

View File

@ -45,6 +45,13 @@ public class CsdlEntitySet extends CsdlBindingTarget {
return this;
}
@Override
public CsdlEntitySet setAnnotations(final List<CsdlAnnotation> annotations) {
super.setAnnotations(annotations);
return this;
}
@Override
public CsdlEntitySet setType(final String type) {
this.type = new FullQualifiedName(type);

View File

@ -16,14 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.client.core.edm.xml;
package org.apache.olingo.commons.api.edm.provider.annotation;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmItem;
import org.apache.olingo.commons.api.edm.provider.annotation.AnnotationExpression;
import org.apache.olingo.commons.api.edm.provider.annotation.ConstantAnnotationExpression;
import org.apache.olingo.commons.api.edm.provider.annotation.DynamicAnnotationExpression;
abstract class AbstractClientCsdlAnnotationExpression extends CsdlAbstractEdmItem implements AnnotationExpression {
public abstract class AbstractCsdlAnnotationExpression extends CsdlAbstractEdmItem implements AnnotationExpression {
private static final long serialVersionUID = -4238652997159205377L;

View File

@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.commons.api.edm.provider.annotation;
public class CsdlConstantAnnotationExpression
extends AbstractCsdlAnnotationExpression implements ConstantAnnotationExpression {
private static final long serialVersionUID = 5618680702707972904L;
private Type type;
private String value;
public CsdlConstantAnnotationExpression() {
}
public CsdlConstantAnnotationExpression(Type type, String value) {
this.type = type;
this.value = value;
}
@Override
public Type getType() {
return type;
}
@Override
public void setType(final Type type) {
this.type = type;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(final String value) {
this.value = value;
}
}

View File

@ -301,7 +301,7 @@ public abstract class AbstractEdm implements Edm {
TargetQualifierMapKey key = new TargetQualifierMapKey(fqn, qualifier);
EdmAnnotations _annotations = annotationGroups.get(key);
if (_annotations == null) {
_annotations = createAnnotationGroup(targetName);
_annotations = createAnnotationGroup(fqn);
if (_annotations != null) {
annotationGroups.put(key, _annotations);
}

View File

@ -45,8 +45,7 @@ public abstract class AbstractEdmAnnotatable implements EdmAnnotatable {
EdmAnnotation result = null;
for (EdmAnnotation annotation : getAnnotations()) {
if (term.getFullQualifiedName().equals(annotation.getTerm().getFullQualifiedName())) {
if (qualifier == annotation.getQualifier()
|| (qualifier != null && qualifier.equals(annotation.getQualifier()))) {
if (qualifierEqual(qualifier, annotation.getQualifier())) {
result = annotation;
break;
}
@ -55,6 +54,11 @@ public abstract class AbstractEdmAnnotatable implements EdmAnnotatable {
return result;
}
private boolean qualifierEqual(String qualifier, String annotationQualifier) {
return (qualifier == null && annotationQualifier == null)
|| (qualifier != null && qualifier.equals(annotationQualifier));
}
@Override
public List<EdmAnnotation> getAnnotations() {
if (annotations == null) {

View File

@ -100,8 +100,7 @@ public class EdmConstantAnnotationExpressionImpl implements EdmConstantAnnotatio
final Object valueOfString = type.valueOfString(constExprConstruct.getValue(),
null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null,
type.getDefaultType());
value = new Property(kind.getFullQualifiedName().getFullQualifiedNameAsString(),
null, ValueType.PRIMITIVE, valueOfString);
value = new Property(kind.getFullQualifiedName().getName(), null, ValueType.PRIMITIVE, valueOfString);
} catch (EdmPrimitiveTypeException e) {
throw new IllegalArgumentException(e);
}

View File

@ -26,8 +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.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
@ -50,6 +53,8 @@ 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.EdmAnnotationExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmConstantAnnotationExpression;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edmx.EdmxReference;
@ -102,6 +107,7 @@ public class MetadataDocumentXmlSerializer {
private static final String XML_ALIAS = "Alias";
private static final String XML_NAMESPACE = "Namespace";
private static final String XML_TYPE_DEFINITION = "TypeDefinition";
private static final String XML_ANNOTATION = "Annotation";
private static final String REFERENCE = "Reference";
private static final String INCLUDE = "Include";
private static final String INCLUDE_ANNOTATIONS = "IncludeAnnotations";
@ -120,6 +126,8 @@ public class MetadataDocumentXmlSerializer {
private static final String NS_EDM = "http://docs.oasis-open.org/odata/ns/edm";
private static final String XML_ENTITY_SET_PATH = "EntitySetPath";
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 final ServiceMetadata serviceMetadata;
private final Map<String, String> namespaceToAlias = new HashMap<String, String>();
@ -324,6 +332,7 @@ public class MetadataDocumentXmlSerializer {
}
appendNavigationPropertyBindings(writer, entitySet);
appendAnnotations(writer, entitySet);
writer.writeEndElement();
}
}
@ -482,10 +491,37 @@ public class MetadataDocumentXmlSerializer {
appendNavigationProperties(writer, entityType);
appendAnnotations(writer, entityType);
writer.writeEndElement();
}
}
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);
}
EdmAnnotationExpression expression = annotation.getExpression();
if(expression != null) {
if(expression.isConstant()) {
EdmConstantAnnotationExpression 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());
@ -616,6 +652,10 @@ public class MetadataDocumentXmlSerializer {
private String getAliasedFullQualifiedName(final EdmType type, final boolean isCollection) {
FullQualifiedName fqn = type.getFullQualifiedName();
return getAliasedFullQualifiedName(fqn, isCollection);
}
private String getAliasedFullQualifiedName(final FullQualifiedName fqn, final boolean isCollection) {
final String name;
if (namespaceToAlias.get(fqn.getNamespace()) != null) {
name = namespaceToAlias.get(fqn.getNamespace()) + "." + fqn.getName();
@ -640,6 +680,7 @@ public class MetadataDocumentXmlSerializer {
writer.writeStartElement(PREFIX_EDMX, INCLUDE, NS_EDMX);
writer.writeAttribute(XML_NAMESPACE, include.getNamespace());
if (include.getAlias() != null) {
namespaceToAlias.put(include.getNamespace(), include.getAlias());
// Reference Aliases are ignored for now since they are not V2 compatible
writer.writeAttribute(XML_ALIAS, include.getAlias());
}

View File

@ -113,6 +113,28 @@ public class MetadataDocumentXmlSerializerTest {
IOUtils.toString(metadata));
}
/** Writes simplest (empty) Schema. */
@Test
public void writeMetadataWithSimpleSchema() throws Exception {
EdmSchema schema = mock(EdmSchema.class);
when(schema.getNamespace()).thenReturn("MyNamespace");
Edm edm = mock(Edm.class);
when(edm.getSchemas()).thenReturn(Arrays.asList(schema));
ServiceMetadata serviceMetadata = mock(ServiceMetadata.class);
when(serviceMetadata.getEdm()).thenReturn(edm);
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>",
IOUtils.toString(metadata));
}
@Test
public void writeEdmxWithLocalTestEdm() throws Exception {
List<EdmxReference> edmxReferences = new ArrayList<EdmxReference>();

View File

@ -22,6 +22,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
import org.apache.olingo.commons.api.edm.provider.annotation.ConstantAnnotationExpression;
import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantAnnotationExpression;
import org.apache.olingo.commons.api.ex.ODataException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
@ -160,14 +163,23 @@ public class ContainerProvider {
return new CsdlEntitySet()
.setName("ESAllPrim")
.setType(EntityTypeProvider.nameETAllPrim)
.setNavigationPropertyBindings(Arrays.asList(
new CsdlNavigationPropertyBinding()
.setPath("NavPropertyETTwoPrimOne")
.setTarget("ESTwoPrim"),
new CsdlNavigationPropertyBinding()
.setPath("NavPropertyETTwoPrimMany")
.setTarget("ESTwoPrim")
));
.setNavigationPropertyBindings(Arrays
.asList(new CsdlNavigationPropertyBinding().setPath("NavPropertyETTwoPrimOne").setTarget("ESTwoPrim"),
new CsdlNavigationPropertyBinding().setPath("NavPropertyETTwoPrimMany").setTarget("ESTwoPrim")))
.setAnnotations(Arrays.asList(new CsdlAnnotation().setTerm("Core.Description").setExpression(
new CsdlConstantAnnotationExpression(ConstantAnnotationExpression.Type.String,
"Contains entities with all primitive types")),
new CsdlAnnotation().setTerm("Core.LongDescription").setQualifier("EnabledForEntitySet").setExpression(
new CsdlConstantAnnotationExpression(ConstantAnnotationExpression.Type.String,
"System Query Options: $filter, $count, $orderby, $skip, $top, $expand, $select, $format; "
+ "Operations: Create, Create with Deep Insert, Create with Bind Operation, Read")),
new CsdlAnnotation().setTerm("Core.LongDescription").setQualifier("EnabledForEntity").setExpression(
new CsdlConstantAnnotationExpression(ConstantAnnotationExpression.Type.String,
"System Query Options: $expand, $select, $format; Operations: "
+ "Read, Update, Update with Bind Operation, Delete")),
new CsdlAnnotation().setTerm("Core.LongDescription").setQualifier("EnabledNavigationProperties")
.setExpression(new CsdlConstantAnnotationExpression(ConstantAnnotationExpression.Type.String,
"NavPropertyETTwoPrimOne, NavPropertyETTwoPrimMany"))));
} else if (name.equals("ESCollAllPrim")) {
return new CsdlEntitySet()

View File

@ -18,6 +18,7 @@
*/
package org.apache.olingo.server.tecsvc.provider;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -43,6 +44,7 @@ import org.apache.olingo.commons.api.ex.ODataException;
public class EdmTechProvider extends CsdlAbstractEdmProvider {
public static final String nameSpace = "olingo.odata.test1";
public static final String CORE_VOCABULARY_NAMESPACE = "Org.OData.Core.V1";
private final SchemaProvider schemaProvider;
private final EntityTypeProvider entityTypeProvider;
@ -52,6 +54,7 @@ public class EdmTechProvider extends CsdlAbstractEdmProvider {
private final ActionProvider actionProvider;
private final FunctionProvider functionProvider;
private final TypeDefinitionProvider typeDefinitionProvider;
private final TermProvider termProvider;
public EdmTechProvider() {
containerProvider = new ContainerProvider(this);
@ -62,12 +65,14 @@ public class EdmTechProvider extends CsdlAbstractEdmProvider {
functionProvider = new FunctionProvider();
typeDefinitionProvider = new TypeDefinitionProvider();
schemaProvider = new SchemaProvider(this);
termProvider = new TermProvider();
}
@Override
public List<CsdlAliasInfo> getAliasInfos() throws ODataException {
return Collections.singletonList(
new CsdlAliasInfo().setAlias("Namespace1_Alias").setNamespace(nameSpace));
return Arrays.asList(
new CsdlAliasInfo().setAlias("Namespace1_Alias").setNamespace(nameSpace),
new CsdlAliasInfo().setAlias("Core").setNamespace(CORE_VOCABULARY_NAMESPACE));
}
@Override
@ -102,7 +107,7 @@ public class EdmTechProvider extends CsdlAbstractEdmProvider {
@Override
public CsdlTerm getTerm(final FullQualifiedName termName) throws ODataException {
return null;
return termProvider.getTerm(termName);
}
@Override

View File

@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.tecsvc.provider;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
import org.apache.olingo.commons.api.edm.provider.annotation.ConstantAnnotationExpression;
import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantAnnotationExpression;
import java.util.Arrays;
/**
*/
public class TermProvider {
// <Term Name="Description" Type="Edm.String">
// <Annotation Term="Core.Description" String="A brief description of a model element" />
// <Annotation Term="Core.IsLanguageDependent" />
// </Term>
//
// <Term Name="LongDescription" Type="Edm.String">
// <Annotation Term="Core.Description" String="A lengthy description of a model element" />
// <Annotation Term="Core.IsLanguageDependent" />
// </Term>
private static FullQualifiedName TERM_DESCRIPTION = new FullQualifiedName("Org.OData.Core.V1", "Description");
private static FullQualifiedName TERM_LONG_DESCRIPTION =
new FullQualifiedName("Org.OData.Core.V1", "LongDescription");
public CsdlTerm getTerm(FullQualifiedName termName) {
if(TERM_DESCRIPTION.equals(termName)) {
return new CsdlTerm().setName("Description").setType("Edm.String")
.setAnnotations(Arrays.asList(new CsdlAnnotation().setTerm("Core.Description").setExpression(
new CsdlConstantAnnotationExpression(ConstantAnnotationExpression.Type.String,
"A brief description of a model element")),
new CsdlAnnotation().setTerm("Core.IsLanguageDependent")));
} else if(TERM_LONG_DESCRIPTION.equals(termName)) {
return new CsdlTerm().setName("LongDescription").setType("Edm.String")
.setAnnotations(Arrays.asList(new CsdlAnnotation().setTerm("Core.Description").setExpression(
new CsdlConstantAnnotationExpression(ConstantAnnotationExpression.Type.String,
"A lengthy description of a model element")),
new CsdlAnnotation().setTerm("Core.IsLanguageDependent")));
}
return null;
}
}

View File

@ -49,10 +49,8 @@ public class MetadataDocumentTest {
final String metadata = IOUtils.toString(
odata.createSerializer(ContentType.APPLICATION_XML).metadataDocument(serviceMetadata).getContent());
assertNotNull(metadata);
assertThat(metadata,
containsString("<edmx:Reference Uri=\"" + CORE_VOCABULARY + "\">"
+ "<edmx:Include Namespace=\"Org.OData.Core.V1\" Alias=\"Core\"/>"
+ "</edmx:Reference>"));
assertThat(metadata, containsString("<edmx:Reference Uri=\"" + CORE_VOCABULARY + "\">"
+ "<edmx:Include Namespace=\"Org.OData.Core.V1\" Alias=\"Core\"/>" + "</edmx:Reference>"));
assertThat(metadata,
containsString("<edmx:Edmx Version=\"4.0\" xmlns:edmx=\"http://docs.oasis-open.org/odata/ns/edmx\">"));
@ -76,6 +74,24 @@ public class MetadataDocumentTest {
+ "<Property Name=\"AdditionalPropertyString_5\" Type=\"Edm.String\"/>"
+ "</EntityType>"));
// assertThat(metadata, containsString("<EntitySet Name=\"ESAllPrim\" EntityType=\"Namespace1_Alias.ETAllPrim\">"
// + "<NavigationPropertyBinding Path=\"NavPropertyETTwoPrimOne\" Target=\"ESTwoPrim\"/>"
// + "<NavigationPropertyBinding Path=\"NavPropertyETTwoPrimMany\" Target=\"ESTwoPrim\"/>"
// + "</EntitySet>"));
assertThat(metadata, containsString("<EntitySet Name=\"ESAllPrim\" EntityType=\"Namespace1_Alias.ETAllPrim\">"
+ "<NavigationPropertyBinding Path=\"NavPropertyETTwoPrimOne\" Target=\"ESTwoPrim\"/>"
+ "<NavigationPropertyBinding Path=\"NavPropertyETTwoPrimMany\" Target=\"ESTwoPrim\"/>"
+ "<Annotation Term=\"Core.Description\" String=\"Contains entities with all primitive types\"/>"
+ "<Annotation Term=\"Core.LongDescription\" Qualifier=\"EnabledForEntitySet\" String=\"System Query Options:"
+ " $filter, $count, $orderby, $skip, $top, $expand, $select, $format; Operations: Create, Create with Deep "
+ "Insert, Create with Bind Operation, Read\"/>"
+ "<Annotation Term=\"Core.LongDescription\" Qualifier=\"EnabledForEntity\" String=\"System Query Options: "
+ "$expand, $select, $format; Operations: Read, Update, Update with Bind Operation, Delete\"/>"
+ "<Annotation Term=\"Core.LongDescription\" Qualifier=\"EnabledNavigationProperties\" "
+ "String=\"NavPropertyETTwoPrimOne, NavPropertyETTwoPrimMany\"/>"
+ "</EntitySet>"));
assertThat(metadata,
containsString("<ComplexType Name=\"CTPrim\">"
+ "<Property Name=\"PropertyInt16\" Type=\"Edm.Int16\"/></ComplexType>"));