http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java new file mode 100644 index 0000000..484bbfa --- /dev/null +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java @@ -0,0 +1,376 @@ +/* + * 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.client.core.serialization; + +import java.io.IOException; +import java.io.Writer; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.serialization.ODataSerializer; +import org.apache.olingo.client.api.serialization.ODataSerializerException; +import org.apache.olingo.commons.api.Constants; +import org.apache.olingo.commons.api.data.Annotatable; +import org.apache.olingo.commons.api.data.Annotation; +import org.apache.olingo.commons.api.data.ComplexValue; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.data.Link; +import org.apache.olingo.commons.api.data.Linked; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ResWrap; +import org.apache.olingo.commons.api.data.Valuable; +import org.apache.olingo.commons.api.data.ValueType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.geo.Geospatial; +import org.apache.olingo.commons.api.format.ODataFormat; +import org.apache.olingo.commons.core.edm.EdmTypeInfo; +import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; + +public class JsonSerializer implements ODataSerializer { + + private static final EdmPrimitiveTypeKind[] NUMBER_TYPES = { + EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte, + EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double, + EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int64, + EdmPrimitiveTypeKind.Decimal + }; + + private final JsonGeoValueSerializer geoSerializer = new JsonGeoValueSerializer(); + + protected boolean serverMode; + + protected ODataFormat format; + + public JsonSerializer(final boolean serverMode) { + this(serverMode, ODataFormat.JSON_FULL_METADATA); + } + + public JsonSerializer(final boolean serverMode, final ODataFormat format) { + this.serverMode = serverMode; + this.format = format; + } + + @Override + public <T> void write(final Writer writer, final T obj) throws ODataSerializerException { + try { + final JsonGenerator json = new JsonFactory().createGenerator(writer); + if (obj instanceof EntityCollection) { + new JsonEntitySetSerializer(serverMode).doSerialize((EntityCollection) obj, json); + } else if (obj instanceof Entity) { + new JsonEntitySerializer(serverMode, format).doSerialize((Entity) obj, json); + } else if (obj instanceof Property) { + new JsonPropertySerializer(serverMode).doSerialize((Property) obj, json); + } else if (obj instanceof Link) { + link((Link) obj, json); + } + json.flush(); + } catch (final IOException e) { + throw new ODataSerializerException(e); + } catch (final EdmPrimitiveTypeException e) { + throw new ODataSerializerException(e); + } + } + + private void reference(final ResWrap<URI> container, final JsonGenerator json) throws IOException { + json.writeStartObject(); + + json.writeStringField(Constants.JSON_CONTEXT, container.getContextURL().toASCIIString()); + json.writeStringField(Constants.JSON_ID, container.getPayload().toASCIIString()); + + json.writeEndObject(); + } + + @SuppressWarnings("unchecked") + @Override + public <T> void write(final Writer writer, final ResWrap<T> container) throws ODataSerializerException { + final T obj = container == null ? null : container.getPayload(); + try { + final JsonGenerator json = new JsonFactory().createGenerator(writer); + if (obj instanceof EntityCollection) { + new JsonEntitySetSerializer(serverMode).doContainerSerialize((ResWrap<EntityCollection>) container, json); + } else if (obj instanceof Entity) { + new JsonEntitySerializer(serverMode).doContainerSerialize((ResWrap<Entity>) container, json); + } else if (obj instanceof Property) { + new JsonPropertySerializer(serverMode).doContainerSerialize((ResWrap<Property>) container, json); + } else if (obj instanceof Link) { + link((Link) obj, json); + } else if (obj instanceof URI) { + reference((ResWrap<URI>) container, json); + } + json.flush(); + } catch (final IOException e) { + throw new ODataSerializerException(e); + } catch (final EdmPrimitiveTypeException e) { + throw new ODataSerializerException(e); + } + } + + protected void link(final Link link, final JsonGenerator jgen) throws IOException { + jgen.writeStartObject(); + jgen.writeStringField(Constants.JSON_URL, link.getHref()); + jgen.writeEndObject(); + } + + protected void links(final Linked linked, final JsonGenerator jgen) + throws IOException, EdmPrimitiveTypeException { + + if (serverMode) { + serverLinks(linked, jgen); + } else { + clientLinks(linked, jgen); + } + } + + protected void clientLinks(final Linked linked, final JsonGenerator jgen) + throws IOException, EdmPrimitiveTypeException { + + final Map<String, List<String>> entitySetLinks = new HashMap<String, List<String>>(); + for (Link link : linked.getNavigationLinks()) { + for (Annotation annotation : link.getAnnotations()) { + valuable(jgen, annotation, link.getTitle() + "@" + annotation.getTerm()); + } + + if (isEntitySetNavigation(link)) { + final List<String> uris; + if (entitySetLinks.containsKey(link.getTitle())) { + uris = entitySetLinks.get(link.getTitle()); + } else { + uris = new ArrayList<String>(); + entitySetLinks.put(link.getTitle(), uris); + } + if (StringUtils.isNotBlank(link.getHref())) { + uris.add(link.getHref()); + } + } else { + if (StringUtils.isNotBlank(link.getHref())) { + jgen.writeStringField(link.getTitle() + Constants.JSON_BIND_LINK_SUFFIX, link.getHref()); + } + } + + if (link.getInlineEntity() != null) { + jgen.writeFieldName(link.getTitle()); + new JsonEntitySerializer(serverMode).doSerialize(link.getInlineEntity(), jgen); + } else if (link.getInlineEntitySet() != null) { + jgen.writeArrayFieldStart(link.getTitle()); + final JsonEntitySerializer entitySerializer = new JsonEntitySerializer(serverMode); + for (Entity subEntry : link.getInlineEntitySet().getEntities()) { + entitySerializer.doSerialize(subEntry, jgen); + } + jgen.writeEndArray(); + } + } + for (Map.Entry<String, List<String>> entitySetLink : entitySetLinks.entrySet()) { + if (!entitySetLink.getValue().isEmpty()) { + jgen.writeArrayFieldStart(entitySetLink.getKey() + Constants.JSON_BIND_LINK_SUFFIX); + for (String uri : entitySetLink.getValue()) { + jgen.writeString(uri); + } + jgen.writeEndArray(); + } + } + } + + private boolean isEntitySetNavigation(final Link link) { + return Constants.ENTITY_SET_NAVIGATION_LINK_TYPE.equals(link.getType()); + } + + protected void serverLinks(final Linked linked, final JsonGenerator jgen) + throws IOException, EdmPrimitiveTypeException { + if (linked instanceof Entity) { + for (Link link : ((Entity) linked).getMediaEditLinks()) { + if (StringUtils.isNotBlank(link.getHref())) { + jgen.writeStringField( + link.getTitle() + StringUtils.prependIfMissing(Constants.JSON_MEDIA_EDIT_LINK, "@"), + link.getHref()); + } + } + } + + for (Link link : linked.getAssociationLinks()) { + if (StringUtils.isNotBlank(link.getHref())) { + jgen.writeStringField( + link.getTitle() + Constants.JSON_ASSOCIATION_LINK, + link.getHref()); + } + } + + for (Link link : linked.getNavigationLinks()) { + for (Annotation annotation : link.getAnnotations()) { + valuable(jgen, annotation, link.getTitle() + "@" + annotation.getTerm()); + } + + if (StringUtils.isNotBlank(link.getHref())) { + jgen.writeStringField( + link.getTitle() + Constants.JSON_NAVIGATION_LINK, + link.getHref()); + } + + if (link.getInlineEntity() != null) { + jgen.writeFieldName(link.getTitle()); + new JsonEntitySerializer(serverMode).doSerialize(link.getInlineEntity(), jgen); + } else if (link.getInlineEntitySet() != null) { + jgen.writeArrayFieldStart(link.getTitle()); + JsonEntitySerializer entitySerializer = new JsonEntitySerializer(serverMode); + for (Entity subEntry : link.getInlineEntitySet().getEntities()) { + entitySerializer.doSerialize(subEntry, jgen); + } + jgen.writeEndArray(); + } + } + } + + private void collection(final JsonGenerator jgen, final EdmTypeInfo typeInfo, + final ValueType valueType, final List<?> value) + throws IOException, EdmPrimitiveTypeException { + + jgen.writeStartArray(); + + for (Object item : value) { + final EdmTypeInfo itemTypeInfo = typeInfo == null + ? null + : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build(); + switch (valueType) { + case COLLECTION_PRIMITIVE: + primitiveValue(jgen, itemTypeInfo, item); + break; + + case COLLECTION_GEOSPATIAL: + jgen.writeStartObject(); + geoSerializer.serialize(jgen, (Geospatial) item); + jgen.writeEndObject(); + break; + + case COLLECTION_ENUM: + jgen.writeString(item.toString()); + break; + + case COLLECTION_COMPLEX: + final ComplexValue complexItem2 = (ComplexValue) item; + complexValue(jgen, itemTypeInfo, complexItem2.getValue(), complexItem2); + break; + + default: + } + } + + jgen.writeEndArray(); + } + + protected void primitiveValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo, final Object value) + throws IOException, EdmPrimitiveTypeException { + + final EdmPrimitiveTypeKind kind = typeInfo == null ? null : typeInfo.getPrimitiveTypeKind(); + final boolean isNumber = kind == null ? value instanceof Number : ArrayUtils.contains(NUMBER_TYPES, kind); + final boolean isBoolean = kind == null ? value instanceof Boolean : kind == EdmPrimitiveTypeKind.Boolean; + + if (value == null) { + jgen.writeNull(); + } else if (isBoolean) { + jgen.writeBoolean((Boolean) value); + } else { + final String serialized = kind == null + ? value.toString() + // TODO: add facets + : EdmPrimitiveTypeFactory.getInstance(kind). + valueToString(value, null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null); + if (isNumber) { + jgen.writeNumber(serialized); + } else { + jgen.writeString(serialized); + } + } + } + + private void complexValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo, + final List<Property> value, final Linked linked) + throws IOException, EdmPrimitiveTypeException { + jgen.writeStartObject(); + + if (typeInfo != null && format != ODataFormat.JSON_NO_METADATA) { + jgen.writeStringField(Constants.JSON_TYPE, typeInfo.external()); + } + + for (Property property : value) { + valuable(jgen, property, property.getName()); + } + if (linked != null) { + links(linked, jgen); + } + + jgen.writeEndObject(); + } + + private void value(final JsonGenerator jgen, final String type, final Valuable value) + throws IOException, EdmPrimitiveTypeException { + final EdmTypeInfo typeInfo = type == null ? null : new EdmTypeInfo.Builder().setTypeExpression(type).build(); + + if (value.isNull()) { + jgen.writeNull(); + } else if (value.isCollection()) { + collection(jgen, typeInfo, value.getValueType(), value.asCollection()); + } else if (value.isPrimitive()) { + primitiveValue(jgen, typeInfo, value.asPrimitive()); + } else if (value.isEnum()) { + jgen.writeString(value.asEnum().toString()); + } else if (value.isGeospatial()) { + jgen.writeStartObject(); + geoSerializer.serialize(jgen, value.asGeospatial()); + jgen.writeEndObject(); + } else if (value.isComplex()) { + complexValue(jgen, typeInfo, value.asComplex().getValue(), value.asComplex()); + } + } + + protected void valuable(final JsonGenerator jgen, final Valuable valuable, final String name) + throws IOException, EdmPrimitiveTypeException { + + if (!Constants.VALUE.equals(name) && !(valuable instanceof Annotation) + && !(valuable.isComplex() && !valuable.isCollection())) { + + String type = valuable.getType(); + if ((!valuable.isCollection() && + StringUtils.isBlank(type) && + valuable.isPrimitive()) || valuable.isNull()) { + type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString(); + } + if (StringUtils.isNotBlank(type) && format != ODataFormat.JSON_NO_METADATA) { + jgen.writeFieldName( + name + StringUtils.prependIfMissing(Constants.JSON_TYPE, "@")); + jgen.writeString(new EdmTypeInfo.Builder().setTypeExpression(type).build().external()); + } + } + + for (Annotation annotation : ((Annotatable) valuable).getAnnotations()) { + valuable(jgen, annotation, name + "@" + annotation.getTerm()); + } + + jgen.writeFieldName(name); + value(jgen, valuable.getType(), valuable); + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java index adecc20..e953cae 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java @@ -31,6 +31,7 @@ import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.data.ServiceDocumentItem; import org.apache.olingo.client.api.serialization.ODataBinder; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.Annotatable; @@ -87,14 +88,12 @@ import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.geo.Geospatial; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; import org.apache.olingo.client.core.domain.ClientAnnotationImpl; import org.apache.olingo.client.core.domain.ClientDeletedEntityImpl; import org.apache.olingo.client.core.domain.ClientDeltaLinkImpl; import org.apache.olingo.client.core.domain.ClientPropertyImpl; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.commons.core.edm.EdmTypeInfo; -import org.apache.olingo.commons.core.serialization.ContextURLParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java index 6c97cdb..6153cdb 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java @@ -27,6 +27,7 @@ import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.domain.ClientEntitySetIterator; import org.apache.olingo.client.api.edm.xml.XMLMetadata; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.client.api.serialization.ODataReader; import org.apache.olingo.client.core.edm.ClientCsdlEdmProvider; import org.apache.olingo.commons.api.data.Entity; @@ -43,7 +44,6 @@ import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.provider.CsdlSchema; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.core.edm.EdmProviderImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java index c891f1e..584c420 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java @@ -29,6 +29,7 @@ import java.util.Collections; import org.apache.commons.io.IOUtils; import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.api.serialization.ODataWriter; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.ResWrap; @@ -36,7 +37,6 @@ import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientLink; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; public class ODataWriterImpl implements ODataWriter { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/AtomDeserializerTest.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/AtomDeserializerTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/AtomDeserializerTest.java new file mode 100644 index 0000000..0b793f8 --- /dev/null +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/AtomDeserializerTest.java @@ -0,0 +1,329 @@ +/* + * 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.client.core.serialization; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import org.apache.olingo.client.core.serialization.AtomDeserializer; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.data.ResWrap; +import org.junit.Test; + +public class AtomDeserializerTest { + + @Test + public void emptyInlineEntityOlingo540() throws Exception { + final String content = "" + + "<entry xmlns=\"http://www.w3.org/2005/Atom\" " + + "xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\" " + + "xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\" " + + "xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" " + + "xml:base=\"http://services.odata.org/V3/OData/OData.svc/\">\r\n" + + " <id>http://services.odata.org/V3/OData/OData.svc/Products(3)</id>\r\n" + + " <category term=\"ODataDemo.Product\" " + + "scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />\r\n" + + " \r\n" + + " <link rel=\"edit\" title=\"Product\" href=\"Products\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Categories\" " + + "type=\"application/atom+xml;type=feed\" title=\"Categories\" href=\"Products(3)/Categories\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Supplier\" " + + "type=\"application/atom+xml;type=entry\" title=\"Supplier\" href=\"Products(3)/Supplier\">\r\n" + + " <metadata:inline>\r\n" + + " </metadata:inline>\r\n" + + " </link>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/ProductDetail\"" + + " type=\"application/atom+xml;type=entry\" title=\"ProductDetail\" " + + "href=\"Products(3)/ProductDetail\" />\r\n" + + " <title type=\"text\">Havina Cola</title>\r\n" + + " <summary type=\"text\">The Original Key Lime Cola</summary>\r\n" + + " <updated>2015-01-26T08:57:02Z</updated>\r\n" + + " <author>\r\n" + + " <name />\r\n" + + " </author>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Categories\" " + + "type=\"application/xml\" title=\"Categories\" href=\"Products(3)/$links/Categories\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Supplier\" " + + "type=\"application/xml\" title=\"Supplier\" href=\"Products(3)/$links/Supplier\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/ProductDetail\"" + + " type=\"application/xml\" title=\"ProductDetail\" href=\"Products(3)/$links/ProductDetail\" />\r\n" + + " <content type=\"application/xml\">\r\n" + + " <metadata:properties>\r\n" + + " <data:ID metadata:type=\"Edm.Int32\">3</data:ID>\r\n" + + " <data:ReleaseDate metadata:type=\"Edm.DateTime\">2005-10-01T00:00:00</data:ReleaseDate>\r\n" + + " <data:DiscontinuedDate metadata:type=\"Edm.DateTime\">2006-10-01T00:00:00</data:DiscontinuedDate>\r\n" + + " <data:Rating metadata:type=\"Edm.Int16\">3</data:Rating>\r\n" + + " <data:Price metadata:type=\"Edm.Double\">19.9</data:Price>\r\n" + + " </metadata:properties>\r\n" + + " </content>\r\n" + + " </entry>"; + + final AtomDeserializer deserializer = new AtomDeserializer(); + final InputStream in = new ByteArrayInputStream(content.getBytes("UTF-8")); + final ResWrap<Entity> entity = deserializer.toEntity(in); + + assertNotNull(entity); + assertNull(entity.getPayload().getNavigationLink("Supplier").getInlineEntitySet()); + } + + @Test + public void filledInlineEntity() throws Exception { + final String content = "" + + "<entry xmlns=\"http://www.w3.org/2005/Atom\" " + + "xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\" " + + "xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\" " + + "xmlns:georss=\"http://www.georss.org/georss\" " + + "xmlns:gml=\"http://www.opengis.net/gml\" " + + "xml:base=\"http://services.odata.org/V4/OData/OData.svc/\">\r\n" + + " <id>http://services.odata.org/V4/OData/OData.svc/Products(3)</id>\r\n" + + " <category term=\"#ODataDemo.Product\" " + + "scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />\r\n" + + " \r\n" + + " <link rel=\"edit\" title=\"Product\" href=\"Products\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Categories\" " + + "type=\"application/atom+xml;type=feed\" title=\"Categories\" href=\"Products(3)/Categories\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Supplier\" " + + "type=\"application/atom+xml;type=entry\" title=\"Supplier\" href=\"Products(3)/Supplier\">\r\n" + + " <metadata:inline>\r\n" + + " <entry>\r\n" + + " <id>http://services.odata.org/V4/OData/OData.svc/Suppliers(0)</id>\r\n" + + " <category term=\"ODataDemo.Supplier\" " + + "scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />\r\n" + + " <link rel=\"edit\" title=\"Supplier\" href=\"Suppliers(0)\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Products\" " + + "type=\"application/atom+xml;type=feed\" title=\"Products\" href=\"Suppliers(0)/Products\" />\r\n" + + " <title type=\"text\">Exotic Liquids</title>\r\n" + + " <updated>2015-01-26T08:57:02Z</updated>\r\n" + + " <author>\r\n" + + " <name />\r\n" + + " </author>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Products\" " + + "type=\"application/xml\" title=\"Products\" href=\"Suppliers(0)/$links/Products\" />\r\n" + + " <content type=\"application/xml\">\r\n" + + " <metadata:properties>\r\n" + + " <data:ID metadata:type=\"Edm.Int32\">0</data:ID>\r\n" + + " <data:Name>Exotic Liquids</data:Name>\r\n" + + " <data:Address metadata:type=\"ODataDemo.Address\">\r\n" + + " <data:Street>NE 228th</data:Street>\r\n" + + " <data:City>Sammamish</data:City>\r\n" + + " <data:State>WA</data:State>\r\n" + + " <data:ZipCode>98074</data:ZipCode>\r\n" + + " <data:Country>USA</data:Country>\r\n" + + " </data:Address>\r\n" + + " <data:Location metadata:type=\"Edm.GeographyPoint\">\r\n" + + " <gml:Point gml:srsName=\"http://www.opengis.net/def/crs/EPSG/0/4326\">\r\n" + + " <gml:pos>47.6316604614258 -122.03547668457</gml:pos>\r\n" + + " </gml:Point>\r\n" + + " </data:Location>\r\n" + + " <data:Concurrency metadata:type=\"Edm.Int32\">0</data:Concurrency>\r\n" + + " </metadata:properties>\r\n" + + " </content>\r\n" + + " </entry>" + + " </metadata:inline>\r\n" + + " </link>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/ProductDetail\" " + + "type=\"application/atom+xml;type=entry\" " + + "title=\"ProductDetail\" href=\"Products(3)/ProductDetail\" />\r\n" + + " <title type=\"text\">Havina Cola</title>\r\n" + + " <summary type=\"text\">The Original Key Lime Cola</summary>\r\n" + + " <updated>2015-01-26T08:57:02Z</updated>\r\n" + + " <author>\r\n" + + " <name />\r\n" + + " </author>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Categories\" " + + "type=\"application/xml\" title=\"Categories\" href=\"Products(3)/$links/Categories\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Supplier\" " + + "type=\"application/xml\" title=\"Supplier\" href=\"Products(3)/$links/Supplier\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/ProductDetail\" " + + "type=\"application/xml\" title=\"ProductDetail\" href=\"Products(3)/$links/ProductDetail\" />\r\n" + + " <content type=\"application/xml\">\r\n" + + " <metadata:properties>\r\n" + + " <data:ID metadata:type=\"Edm.Int32\">3</data:ID>\r\n" + + " <data:ReleaseDate metadata:type=\"Edm.DateTime\">2005-10-01T00:00:00</data:ReleaseDate>\r\n" + + " <data:DiscontinuedDate metadata:type=\"Edm.DateTime\">2006-10-01T00:00:00</data:DiscontinuedDate>\r\n" + + " <data:Rating metadata:type=\"Edm.Int16\">3</data:Rating>\r\n" + + " <data:Price metadata:type=\"Edm.Double\">19.9</data:Price>\r\n" + + " </metadata:properties>\r\n" + + " </content>\r\n" + + " </entry>"; + final AtomDeserializer deserializer = new AtomDeserializer(); + final InputStream in = new ByteArrayInputStream(content.getBytes("UTF-8")); + final ResWrap<Entity> entity = deserializer.toEntity(in); + + assertNotNull(entity); + final Entity inlineEntity = entity.getPayload().getNavigationLink("Supplier").getInlineEntity(); + assertNotNull(inlineEntity); + + assertEquals(new Integer(0), inlineEntity.getProperty("ID").getValue()); + assertEquals("Exotic Liquids", inlineEntity.getProperty("Name").getValue()); + } + + @Test + public void emptyInlineEntityCollection() throws Exception { + final String content = "" + + "<entry xmlns=\"http://www.w3.org/2005/Atom\" " + + "xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\" " + + "xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\" " + + "xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" " + + "xml:base=\"http://services.odata.org/V3/OData/OData.svc/\">\r\n" + + " <id>http://services.odata.org/V3/OData/OData.svc/Products(3)</id>\r\n" + + " <category term=\"ODataDemo.Product\" " + + "scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />\r\n" + + " \r\n" + + " <link rel=\"edit\" title=\"Product\" href=\"Products(3)\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Categories\" " + + "type=\"application/atom+xml;type=feed\" title=\"Categories\" href=\"Products(3)/Categories\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Supplier\" " + + "type=\"application/atom+xml;type=feed\" title=\"Supplier\" href=\"Products(3)/Supplier\">\r\n" + + " <metadata:inline>\r\n" + + " <feed>\r\n" + + " </feed>\r\n" + + " </metadata:inline>\r\n" + + " </link>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/ProductDetail\" " + + "type=\"application/atom+xml;type=entry\" " + + "title=\"ProductDetail\" href=\"Products(3)/ProductDetail\" />\r\n" + + " <title type=\"text\">Havina Cola</title>\r\n" + + " <summary type=\"text\">The Original Key Lime Cola</summary>\r\n" + + " <updated>2015-01-26T08:57:02Z</updated>\r\n" + + " <author>\r\n" + + " <name />\r\n" + + " </author>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Categories\" " + + "type=\"application/xml\" title=\"Categories\" href=\"Products(3)/$links/Categories\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Supplier\" " + + "type=\"application/xml\" title=\"Supplier\" href=\"Products(3)/$links/Supplier\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/ProductDetail\" " + + "type=\"application/xml\" title=\"ProductDetail\" href=\"Products(3)/$links/ProductDetail\" />\r\n" + + " <content type=\"application/xml\">\r\n" + + " <metadata:properties>\r\n" + + " <data:ID metadata:type=\"Edm.Int32\">3</data:ID>\r\n" + + " <data:ReleaseDate metadata:type=\"Edm.DateTime\">2005-10-01T00:00:00</data:ReleaseDate>\r\n" + + " <data:DiscontinuedDate metadata:type=\"Edm.DateTime\">2006-10-01T00:00:00</data:DiscontinuedDate>\r\n" + + " <data:Rating metadata:type=\"Edm.Int16\">3</data:Rating>\r\n" + + " <data:Price metadata:type=\"Edm.Double\">19.9</data:Price>\r\n" + + " </metadata:properties>\r\n" + + " </content>\r\n" + + " </entry>"; + final AtomDeserializer deserializer = new AtomDeserializer(); + final InputStream in = new ByteArrayInputStream(content.getBytes("UTF-8")); + final ResWrap<Entity> entity = deserializer.toEntity(in); + + assertNotNull(entity); + final EntityCollection inlineEntitySet = entity.getPayload().getNavigationLink("Supplier").getInlineEntitySet(); + assertNotNull(inlineEntitySet); + assertEquals(0, inlineEntitySet.getEntities().size()); + } + + @Test + public void filledInlineEntityCollection() throws Exception { + final String content = "" + + "<entry xmlns=\"http://www.w3.org/2005/Atom\" " + + "xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\" " + + "xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\" " + + "xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" " + + "xml:base=\"http://services.odata.org/V3/OData/OData.svc/\">\r\n" + + " <id>http://services.odata.org/V3/OData/OData.svc/Products(3)</id>\r\n" + + " <category term=\"ODataDemo.Product\" " + + "scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />\r\n" + + " \r\n" + + " <link rel=\"edit\" title=\"Product\" href=\"Products(3)\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Categories\" " + + "type=\"application/atom+xml;type=feed\" title=\"Categories\" href=\"Products(3)/Categories\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Supplier\" " + + "type=\"application/atom+xml;type=feed\" title=\"Supplier\" href=\"Products(3)/Supplier\">\r\n" + + " <metadata:inline>\r\n" + + " <feed>\r\n" + + " <entry>\r\n" + + " <id>http://services.odata.org/V3/OData/OData.svc/Suppliers(0)</id>\r\n" + + " <category term=\"ODataDemo.Supplier\" " + + "scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />\r\n" + + " <link rel=\"edit\" title=\"Supplier\" href=\"Suppliers(0)\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/Products\" " + + "type=\"application/atom+xml;type=feed\" title=\"Products\" href=\"Suppliers(0)/Products\" />\r\n" + + " <title type=\"text\">Exotic Liquids</title>\r\n" + + " <updated>2015-01-26T08:57:02Z</updated>\r\n" + + " <author>\r\n" + + " <name />\r\n" + + " </author>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Products\" " + + "type=\"application/xml\" title=\"Products\" href=\"Suppliers(0)/$links/Products\" />\r\n" + + " <content type=\"application/xml\">\r\n" + + " <metadata:properties>\r\n" + + " <data:ID metadata:type=\"Edm.Int32\">0</data:ID>\r\n" + + " <data:Name>Exotic Liquids</data:Name>\r\n" + + " <data:Address metadata:type=\"ODataDemo.Address\">\r\n" + + " <data:Street>NE 228th</data:Street>\r\n" + + " <data:City>Sammamish</data:City>\r\n" + + " <data:State>WA</data:State>\r\n" + + " <data:ZipCode>98074</data:ZipCode>\r\n" + + " <data:Country>USA</data:Country>\r\n" + + " </data:Address>\r\n" + + " <data:Location metadata:type=\"Edm.GeographyPoint\">\r\n" + + " <gml:Point gml:srsName=\"http://www.opengis.net/def/crs/EPSG/0/4326\">\r\n" + + " <gml:pos>47.6316604614258 -122.03547668457</gml:pos>\r\n" + + " </gml:Point>\r\n" + + " </data:Location>\r\n" + + " <data:Concurrency metadata:type=\"Edm.Int32\">0</data:Concurrency>\r\n" + + " </metadata:properties>\r\n" + + " </content>\r\n" + + " </entry>\r\n" + + " </feed>\r\n" + + " </metadata:inline>\r\n" + + " </link>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/related/ProductDetail\" " + + "type=\"application/atom+xml;type=entry\" " + + "title=\"ProductDetail\" href=\"Products(3)/ProductDetail\" />\r\n" + + " <title type=\"text\">Havina Cola</title>\r\n" + + " <summary type=\"text\">The Original Key Lime Cola</summary>\r\n" + + " <updated>2015-01-26T08:57:02Z</updated>\r\n" + + " <author>\r\n" + + " <name />\r\n" + + " </author>\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Categories\" " + + "type=\"application/xml\" title=\"Categories\" href=\"Products(3)/$links/Categories\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/Supplier\" " + + "type=\"application/xml\" title=\"Supplier\" href=\"Products(3)/$links/Supplier\" />\r\n" + + " <link rel=\"http://docs.oasis-open.org/odata/ns/relatedlinks/ProductDetail\" " + + "type=\"application/xml\" title=\"ProductDetail\" href=\"Products(3)/$links/ProductDetail\" />\r\n" + + " <content type=\"application/xml\">\r\n" + + " <metadata:properties>\r\n" + + " <data:ID metadata:type=\"Edm.Int32\">3</data:ID>\r\n" + + " <data:ReleaseDate metadata:type=\"Edm.DateTime\">2005-10-01T00:00:00</data:ReleaseDate>\r\n" + + " <data:DiscontinuedDate metadata:type=\"Edm.DateTime\">2006-10-01T00:00:00</data:DiscontinuedDate>\r\n" + + " <data:Rating metadata:type=\"Edm.Int16\">3</data:Rating>\r\n" + + " <data:Price metadata:type=\"Edm.Double\">19.9</data:Price>\r\n" + + " </metadata:properties>\r\n" + + " </content>\r\n" + + " </entry>"; + final AtomDeserializer deserializer = new AtomDeserializer(); + final InputStream in = new ByteArrayInputStream(content.getBytes("UTF-8")); + final ResWrap<Entity> entity = deserializer.toEntity(in); + + assertNotNull(entity); + final EntityCollection inlineEntitySet = entity.getPayload().getNavigationLink("Supplier").getInlineEntitySet(); + assertNotNull(inlineEntitySet); + assertEquals(1, inlineEntitySet.getEntities().size()); + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/ContextURLParserTest.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/ContextURLParserTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/ContextURLParserTest.java new file mode 100644 index 0000000..009b100 --- /dev/null +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/ContextURLParserTest.java @@ -0,0 +1,256 @@ +/* + * 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.client.core.serialization; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.net.URI; + +import org.apache.olingo.client.core.serialization.ContextURLParser; +import org.apache.olingo.commons.api.data.ContextURL; +import org.junit.Test; + +public class ContextURLParserTest { + + @Test + public void collectionOfEntities() { + ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers")); + + assertEquals(URI.create("http://host/service/"), contextURL.getServiceRoot()); + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + + contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Orders(4711)/Items")); + + assertEquals("Orders", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertEquals("Items", contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + + contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Me/Folders('Inbox')/Messages")); + + assertEquals("Me/Folders", contextURL.getEntitySetOrSingletonOrType()); + assertEquals("Messages", contextURL.getNavOrPropertyPath()); + } + + @Test + public void entity() { + ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$entity")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertTrue(contextURL.isEntity()); + + contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Orders(4711)/Items/$entity")); + + assertEquals("Orders/Items", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertTrue(contextURL.isEntity()); + + contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Users('user')/Messages('message')/Attachments/$entity")); + + assertEquals("Users/Messages/Attachments", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertTrue(contextURL.isEntity()); + + // v3 + contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Products/@Element")); + + assertEquals("Products", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertTrue(contextURL.isEntity()); + } + + @Test + public void singleton() { + ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Contoso")); + + assertEquals("Contoso", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } + + @Test + public void collectionOfDerivedEntities() { + final ContextURL contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Customers/Model.VipCustomer")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertEquals("Model.VipCustomer", contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } + + @Test + public void derivedEntity() { + final ContextURL contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Customers/Model.VipCustomer/$entity")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertEquals("Model.VipCustomer", contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertTrue(contextURL.isEntity()); + } + + @Test + public void collectionOfProjectedEntities() { + final ContextURL contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Customers(Address,Orders)")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertEquals("Address,Orders", contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } + + @Test + public void projectedEntity() { + ContextURL contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Customers(Name,Rating)/$entity")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertEquals("Name,Rating", contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertTrue(contextURL.isEntity()); + + contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Customers(Name,Address/Country)")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertEquals("Name,Address/Country", contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } + + @Test + public void collectionOfProjectedExpandedEntities() { + final ContextURL contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Employees/" + + "Sales.Manager(DirectReports,DirectReports+(FirstName,LastName))")); + + assertEquals("Employees", contextURL.getEntitySetOrSingletonOrType()); + assertEquals("Sales.Manager", contextURL.getDerivedEntity()); + assertEquals("DirectReports,DirectReports+(FirstName,LastName)", contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } + + @Test + public void propertyValue() { + final ContextURL contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Customers(1)/Addresses")); + + assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertEquals("Addresses", contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } + + @Test + public void CollectionOfComplexOrPrimitiveTypes() { + final ContextURL contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Collection(Edm.String)")); + + assertEquals("Collection(Edm.String)", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } + + @Test + public void complexOrPrimitiveType() { + ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Edm.String")); + + assertEquals("Edm.String", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + + contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#ODataDemo.Address")); + + assertEquals("ODataDemo.Address", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } + + @Test + public void reference() { + ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$ref")); + assertTrue(contextURL.isReference()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + assertFalse(contextURL.isDelta()); + } + + @Test + public void delta() { + ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$delta")); + assertTrue(contextURL.isDelta()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + + contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$deletedLink")); + assertTrue(contextURL.isDeltaDeletedLink()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + + contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$link")); + assertTrue(contextURL.isDeltaLink()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + + contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$deletedEntity")); + assertTrue(contextURL.isDeltaDeletedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); + assertFalse(contextURL.isEntity()); + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java index 5395472..d3746e1 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java @@ -24,8 +24,8 @@ import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientEntitySet; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.junit.Test; import java.io.IOException; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java index 057c0de..93b43df 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java @@ -19,10 +19,10 @@ package org.apache.olingo.client.core.v4; import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.client.core.AbstractTest; import org.apache.olingo.commons.api.ODataError; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.junit.Test; import static org.junit.Assert.assertEquals; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java index 46e0d22..b0423e7 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java @@ -24,9 +24,9 @@ import org.apache.olingo.client.api.domain.ClientCollectionValue; import org.apache.olingo.client.api.domain.ClientComplexValue; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.client.api.domain.ClientValue; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; import org.junit.Test; import java.io.InputStream; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java index 1a2de09..b0a769f 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java @@ -23,8 +23,8 @@ import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.core.AbstractTest; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientServiceDocument; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.junit.Test; import java.net.URI; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializer.java ---------------------------------------------------------------------- diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializer.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializer.java deleted file mode 100755 index d288cf9..0000000 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializer.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.serialization; - -import java.io.InputStream; - -import org.apache.olingo.commons.api.ODataError; -import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.data.EntityCollection; -import org.apache.olingo.commons.api.data.Property; -import org.apache.olingo.commons.api.data.ResWrap; - -/** - * Interface for de-serialization. - */ -public interface ODataDeserializer { - - /** - * Gets an entity set object from the given InputStream. - * - * @param input stream to be de-serialized. - * @return {@link EntityCollection} instance. - */ - ResWrap<EntityCollection> toEntitySet(InputStream input) throws ODataDeserializerException; - - /** - * Gets an entity object from the given InputStream. - * - * @param input stream to be de-serialized. - * @return {@link Entity} instance. - */ - ResWrap<Entity> toEntity(InputStream input) throws ODataDeserializerException; - - /** - * Gets a property object from the given InputStream. - * - * @param input stream to be de-serialized. - * @return Property instance. - */ - ResWrap<Property> toProperty(InputStream input) throws ODataDeserializerException; - - /** - * Gets the ODataError object represented by the given InputStream. - * - * @param input stream to be parsed and de-serialized. - * @return parsed ODataError object represented by the given InputStream - */ - ODataError toError(InputStream input) throws ODataDeserializerException; -} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializerException.java ---------------------------------------------------------------------- diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializerException.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializerException.java deleted file mode 100755 index e5d7df6..0000000 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializerException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.serialization; - -import org.apache.olingo.commons.api.ODataException; - -public class ODataDeserializerException extends ODataException { - - private static final long serialVersionUID = -3236099963180859670L; - - public ODataDeserializerException(final String msg) { - super(msg); - } - - public ODataDeserializerException(final Throwable cause) { - super(cause); - } - - public ODataDeserializerException(final String msg, final Throwable cause) { - super(msg, cause); - } -} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializer.java ---------------------------------------------------------------------- diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializer.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializer.java deleted file mode 100644 index 0c0f795..0000000 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.serialization; - -import java.io.Writer; - -import org.apache.olingo.commons.api.data.ResWrap; - -/** - * Interface for serialization. - */ -public interface ODataSerializer { - - public <T> void write(final Writer writer, final T obj) throws ODataSerializerException; - - public <T> void write(final Writer writer, final ResWrap<T> container) throws ODataSerializerException; -} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializerException.java ---------------------------------------------------------------------- diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializerException.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializerException.java deleted file mode 100755 index 797c40a..0000000 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializerException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.serialization; - -import org.apache.olingo.commons.api.ODataException; - -public class ODataSerializerException extends ODataException { - - private static final long serialVersionUID = -3236099963180859670L; - - public ODataSerializerException(final String msg) { - super(msg); - } - - public ODataSerializerException(final Throwable cause) { - super(cause); - } - - public ODataSerializerException(final String msg, final Throwable cause) { - super(msg, cause); - } -} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/20351253/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AbstractAtomDealer.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AbstractAtomDealer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AbstractAtomDealer.java deleted file mode 100644 index d73daca..0000000 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AbstractAtomDealer.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.core.serialization; - -import javax.xml.XMLConstants; -import javax.xml.namespace.QName; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; - -import org.apache.commons.lang3.StringUtils; -import org.apache.olingo.commons.api.Constants; - -abstract class AbstractAtomDealer { - - protected static final String TYPE_TEXT = "text"; - - protected final String namespaceMetadata; - protected final String namespaceData; - - protected final QName etagQName; - protected final QName metadataEtagQName; - protected final QName inlineQName; - protected final QName actionQName; - protected final QName propertiesQName; - protected final QName typeQName; - protected final QName nullQName; - protected final QName elementQName; - protected final QName countQName; - protected final QName uriQName; - protected final QName nextQName; - protected final QName annotationQName; - protected final QName contextQName; - protected final QName entryRefQName; - protected final QName propertyValueQName; - protected final QName deletedEntryQName; - protected final QName reasonQName; - protected final QName linkQName; - protected final QName deletedLinkQName; - protected final QName errorCodeQName; - protected final QName errorMessageQName; - protected final QName errorTargetQName; - - public AbstractAtomDealer() { - namespaceMetadata = Constants.NS_METADATA; - namespaceData = Constants.NS_DATASERVICES; - - etagQName = new QName(namespaceMetadata, Constants.ATOM_ATTR_ETAG); - metadataEtagQName = new QName(namespaceMetadata, Constants.ATOM_ATTR_METADATAETAG); - inlineQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_INLINE); - actionQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_ACTION); - propertiesQName = new QName(namespaceMetadata, Constants.PROPERTIES); - typeQName = new QName(namespaceMetadata, Constants.ATTR_TYPE); - nullQName = new QName(namespaceMetadata, Constants.ATTR_NULL); - elementQName = new QName(namespaceMetadata, Constants.ELEM_ELEMENT); - countQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_COUNT); - uriQName = new QName(namespaceData, Constants.ELEM_URI); - nextQName = new QName(namespaceData, Constants.NEXT_LINK_REL); - annotationQName = new QName(namespaceMetadata, Constants.ANNOTATION); - contextQName = new QName(namespaceMetadata, Constants.CONTEXT); - entryRefQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_ENTRY_REF); - propertyValueQName = new QName(namespaceMetadata, Constants.VALUE); - - deletedEntryQName = new QName(Constants.NS_ATOM_TOMBSTONE, Constants.ATOM_ELEM_DELETED_ENTRY); - reasonQName = new QName(namespaceMetadata, Constants.ELEM_REASON); - linkQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_LINK); - deletedLinkQName = new QName(namespaceMetadata, Constants.ELEM_DELETED_LINK); - - errorCodeQName = new QName(namespaceMetadata, Constants.ERROR_CODE); - errorMessageQName = new QName(namespaceMetadata, Constants.ERROR_MESSAGE); - errorTargetQName = new QName(namespaceMetadata, Constants.ERROR_TARGET); - } - - protected void namespaces(final XMLStreamWriter writer) throws XMLStreamException { - writer.writeNamespace(StringUtils.EMPTY, Constants.NS_ATOM); - writer.writeNamespace(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI); - writer.writeNamespace(Constants.PREFIX_METADATA, Constants.NS_METADATA); - writer.writeNamespace(Constants.PREFIX_DATASERVICES, Constants.NS_DATASERVICES); - writer.writeNamespace(Constants.PREFIX_GML, Constants.NS_GML); - writer.writeNamespace(Constants.PREFIX_GEORSS, Constants.NS_GEORSS); - } -}
