correct context URL for server property responses Change-Id: Ie262212ab1ec1a0b9067770ff3b13eb14f216e53
Signed-off-by: Michael Bolz <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/3e117381 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/3e117381 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/3e117381 Branch: refs/heads/OLINGO-450_FunctionActionExecution Commit: 3e117381257e3ee0aa66ae94f025f7e3eb9f084c Parents: 357e8b6 Author: Klaus Straubinger <[email protected]> Authored: Fri Oct 31 14:11:28 2014 +0100 Committer: Michael Bolz <[email protected]> Committed: Fri Oct 31 14:19:47 2014 +0100 ---------------------------------------------------------------------- .../olingo/commons/api/data/ContextURL.java | 30 +----- .../server/api/serializer/ODataSerializer.java | 9 ++ .../core/serializer/ODataXmlSerializerImpl.java | 17 ++- .../serializer/json/ODataJsonSerializer.java | 49 ++++----- .../core/serializer/utils/ContextURLHelper.java | 23 +++++ .../serializer/utils/ContextURLBuilderTest.java | 23 ++--- .../tecsvc/processor/TechnicalProcessor.java | 73 ++++++++----- .../json/ODataJsonSerializerTest.java | 103 +++++++------------ .../serializer/utils/ContextURLHelperTest.java | 33 ++++++ 9 files changed, 202 insertions(+), 158 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java ---------------------------------------------------------------------- diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java index dcc45f5..af5cc4d 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java @@ -19,7 +19,6 @@ package org.apache.olingo.commons.api.data; import java.net.URI; -import java.util.Map; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; @@ -143,38 +142,17 @@ public class ContextURL { return this; } - public Builder keySegment(String value) { - if (value != null) { - contextURL.keyPath = value; - } + public Builder keyPath(final String value) { + contextURL.keyPath = value; return this; } - - public Builder keySegment(Map<String, String> values) { - if (values != null && !values.isEmpty()) { - - if (values.size() == 1) { - return keySegment(values.values().iterator().next()); - } - - StringBuilder sb = new StringBuilder(); - for (String key: values.keySet()) { - if (sb.length() > 0) { - sb.append(","); - } - sb.append(key).append("=").append(values.get(key)); - } - contextURL.keyPath = sb.toString(); - } - return this; - } public Builder entitySetOrSingletonOrType(final String entitySetOrSingletonOrType) { contextURL.entitySetOrSingletonOrType = entitySetOrSingletonOrType; return this; } - - public Builder propertyType(final EdmType type) { + + public Builder type(final EdmType type) { contextURL.entitySetOrSingletonOrType = type.getFullQualifiedName().toString(); return this; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java index 1331247..2072798 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java @@ -19,6 +19,7 @@ package org.apache.olingo.server.api.serializer; import java.io.InputStream; +import java.util.List; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntitySet; @@ -28,6 +29,7 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.server.api.ODataServerError; import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.SelectOption; @@ -93,4 +95,11 @@ public interface ODataSerializer { */ String buildContextURLSelectList(EdmEntitySet edmEntitySet, ExpandOption expand, SelectOption select) throws SerializerException; + + /** + * Builds the key-predicate part of a {@link org.apache.olingo.commons.api.data.ContextURL ContextURL}. + * @param keys the keys as a list of {@link UriParameter} instances + * @return a String with the key predicate + */ + String buildContextURLKeyPredicate(List<UriParameter> keys) throws SerializerException; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java index 8956a6d..5138669 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java @@ -19,6 +19,7 @@ package org.apache.olingo.server.core.serializer; import java.io.InputStream; +import java.util.List; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; @@ -35,6 +36,7 @@ import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.ODataSerializerOptions; +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.SelectOption; import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer; @@ -105,15 +107,20 @@ public class ODataXmlSerializerImpl implements ODataSerializer { } @Override + public InputStream entityProperty(EdmProperty edmProperty, Property property, + ODataSerializerOptions options) throws SerializerException{ + throw new SerializerException("error serialization not implemented for XML format", + SerializerException.MessageKeys.NOT_IMPLEMENTED); + } + + @Override public String buildContextURLSelectList(final EdmEntitySet edmEntitySet, final ExpandOption expand, final SelectOption select) throws SerializerException { return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select); } @Override - public InputStream entityProperty(EdmProperty edmProperty, Property property, - ODataSerializerOptions options) throws SerializerException{ - throw new SerializerException("error serialization not implemented for XML format", - SerializerException.MessageKeys.NOT_IMPLEMENTED); - } + public String buildContextURLKeyPredicate(final List<UriParameter> keys) throws SerializerException { + return ContextURLHelper.buildKeyPredicate(keys); + } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java index 324c5aa..d549ff0 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java @@ -46,6 +46,7 @@ import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.ODataSerializerOptions; +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.queryoption.ExpandItem; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.SelectOption; @@ -176,17 +177,16 @@ public class ODataJsonSerializer implements ODataSerializer { return buffer.getInputStream(); } - private ContextURL checkContextURL(final ODataSerializerOptions options) - throws SerializerException { - ContextURL contextURL = options == null ? null : options.getContextURL(); - if (format != ODataFormat.JSON_NO_METADATA && contextURL == null) { - throw new SerializerException("ContextURL null!", - SerializerException.MessageKeys.NO_CONTEXT_URL); - } + private ContextURL checkContextURL(final ODataSerializerOptions options) throws SerializerException { if (format == ODataFormat.JSON_NO_METADATA) { - contextURL = null; + return null; + } else { + final ContextURL contextURL = options == null ? null : options.getContextURL(); + if (contextURL == null) { + throw new SerializerException("ContextURL null!", SerializerException.MessageKeys.NO_CONTEXT_URL); + } + return contextURL; } - return contextURL; } protected void writeEntitySet(final EdmEntityType entityType, final EntitySet entitySet, @@ -421,28 +421,18 @@ public class ODataJsonSerializer implements ODataSerializer { } @Override - public String buildContextURLSelectList(final EdmEntitySet edmEntitySet, - final ExpandOption expand, final SelectOption select) throws SerializerException { - return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select); - } - - @Override - public InputStream entityProperty(EdmProperty edmProperty, - Property property, ODataSerializerOptions options) - throws SerializerException { + public InputStream entityProperty(final EdmProperty edmProperty, final Property property, + final ODataSerializerOptions options) throws SerializerException { final ContextURL contextURL = checkContextURL(options); CircleStreamBuffer buffer = new CircleStreamBuffer(); try { JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream()); json.writeStartObject(); - if (format != ODataFormat.JSON_NO_METADATA) { - if (contextURL != null) { - json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString()); - } + if (contextURL != null) { + json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString()); } if (property.isPrimitive() && property.isNull()) { - throw new SerializerException("Property value can not be null", - SerializerException.MessageKeys.NULL_INPUT); + throw new SerializerException("Property value can not be null.", SerializerException.MessageKeys.NULL_INPUT); } else if (property.isComplex() && !property.isNull()) { writePropertyValues(edmProperty, property.asComplex(), null, json); } else if (property.isLinkedComplex() && !property.isNull()) { @@ -459,4 +449,15 @@ public class ODataJsonSerializer implements ODataSerializer { } return buffer.getInputStream(); } + + @Override + public String buildContextURLSelectList(final EdmEntitySet edmEntitySet, + final ExpandOption expand, final SelectOption select) throws SerializerException { + return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select); + } + + @Override + public String buildContextURLKeyPredicate(final List<UriParameter> keys) throws SerializerException { + return ContextURLHelper.buildKeyPredicate(keys); + } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java index 099055e..80c13de 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java @@ -28,6 +28,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.core.Encoder; import org.apache.olingo.server.api.serializer.SerializerException; +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.queryoption.ExpandItem; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.SelectItem; @@ -142,4 +143,26 @@ public final class ContextURLHelper { } return result; } + + /** + * Builds a key predicate for the ContextURL. + * @param keys the keys as a list of {@link UriParameter} instances + * @return a String with the key predicate + */ + public static String buildKeyPredicate(List<UriParameter> keys) throws SerializerException { + if (keys == null || keys.isEmpty()) { + return null; + } else if (keys.size() == 1) { + return Encoder.encode(keys.get(0).getText()); + } else { + StringBuilder result = new StringBuilder(); + for (final UriParameter key : keys) { + if (result.length() > 0) { + result.append(','); + } + result.append(Encoder.encode(key.getName())).append('=').append(Encoder.encode(key.getText())); + } + return result.toString(); + } + } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java index 4ce699f..8a7c9c6 100644 --- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java @@ -25,7 +25,6 @@ import static org.mockito.Mockito.when; import java.net.URI; import java.util.ArrayList; import java.util.List; -import java.util.TreeMap; import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.ContextURL.Suffix; @@ -104,47 +103,45 @@ public class ContextURLBuilderTest { assertEquals("http://host/service/$metadata#Customers/Model.VipCustomer/$entity", ContextURLBuilder.create(contextURL).toASCIIString()); } - + @Test - public void buildPropertyValue() { + public void buildProperty() { EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class); Mockito.when(entitySet.getName()).thenReturn("Customers"); ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/")) .entitySet(entitySet) - .keySegment(String.valueOf(1)) + .keyPath("1") .navOrPropertyPath("Name") .build(); assertEquals("http://host/service/$metadata#Customers(1)/Name", ContextURLBuilder.create(contextURL).toASCIIString()); - TreeMap<String, String> keys = new TreeMap<String, String>(); - keys.put("one", String.valueOf(1)); - keys.put("two", "'two'"); + contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/")) .entitySet(entitySet) - .keySegment(keys) + .keyPath("one=1,two='two'") .navOrPropertyPath("Name") .build(); assertEquals("http://host/service/$metadata#Customers(one=1,two='two')/Name", ContextURLBuilder.create(contextURL).toASCIIString()); } - + @Test public void buildPrimitiveType() { EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class); Mockito.when(entitySet.getName()).thenReturn("Customers"); ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/")) - .propertyType(EdmString.getInstance()) + .type(EdmString.getInstance()) .build(); assertEquals("http://host/service/$metadata#Edm.String", ContextURLBuilder.create(contextURL).toASCIIString()); contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/")) - .propertyType(EdmString.getInstance()).asCollection() + .type(EdmString.getInstance()).asCollection() .build(); assertEquals("http://host/service/$metadata#Collection(Edm.String)", ContextURLBuilder.create(contextURL).toString()); } - + @Test public void buildComplexType() throws Exception { EdmProvider provider = mock(EdmProvider.class); @@ -165,7 +162,7 @@ public class ContextURLBuilderTest { EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class); Mockito.when(entitySet.getName()).thenReturn("Customers"); ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/")) - .propertyType(baseType) + .type(baseType) .build(); assertEquals("http://host/service/$metadata#namespace.BaseTypeName", ContextURLBuilder.create(contextURL).toASCIIString()); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java index 383b889..d88a02f 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java @@ -20,16 +20,16 @@ package org.apache.olingo.server.tecsvc.processor; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; -import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Map; import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.ContextURL.Suffix; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntitySet; import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; @@ -98,7 +98,7 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, response.setContent(serializer.entitySet(edmEntitySet, entitySet, ODataSerializerOptions.with() .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : - getContextUrl(serializer, edmEntitySet, false, expand, select, null)) + getContextUrl(serializer, edmEntitySet, false, expand, select, null, null)) .count(uriInfo.getCountOption()) .expand(expand).select(select) .build())); @@ -124,7 +124,7 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, response.setContent(serializer.entity(edmEntitySet, entity, ODataSerializerOptions.with() .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : - getContextUrl(serializer, edmEntitySet, true, expand, select, null)) + getContextUrl(serializer, edmEntitySet, true, expand, select, null, null)) .count(uriInfo.getCountOption()) .expand(expand).select(select) .build())); @@ -209,40 +209,47 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, private ContextURL getContextUrl(final ODataSerializer serializer, final EdmEntitySet entitySet, final boolean isSingleEntity, - final ExpandOption expand, final SelectOption select, final String propertyPath) - throws SerializerException { + final ExpandOption expand, final SelectOption select, + final List<UriParameter> keys, final String propertyPath) throws SerializerException { return ContextURL.with().entitySet(entitySet) .selectList(serializer.buildContextURLSelectList(entitySet, expand, select)) .suffix(isSingleEntity && propertyPath == null ? Suffix.ENTITY : null) + .keyPath(serializer.buildContextURLKeyPredicate(keys)) .navOrPropertyPath(propertyPath) .build(); } - private Map<String, String> mapKeys(List<UriParameter> parameters) - throws ODataApplicationException { - Map<String, String> keys = new LinkedHashMap<String, String>(); - for (UriParameter param: parameters) { - keys.put(param.getName(), param.getText()); - } - return keys; - } - @Override public void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType contentType) throws ODataApplicationException, SerializerException { validateOptions(uriInfo.asUriInfoResource()); final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); - final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0); + final List<UriResource> resourceParts = uriInfo.getUriResourceParts(); + final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0); final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet); if (entity == null) { throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); } else { - final UriResourceProperty uriProperty = (UriResourceProperty) uriInfo - .getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 1); - final EdmProperty edmProperty = uriProperty.getProperty(); - final Property property = entity.getProperty(edmProperty.getName()); + final List<String> path = getPropertyPath(resourceParts); + EdmProperty edmProperty = edmEntitySet.getEntityType().getStructuralProperty(path.get(0)); + Property property = entity.getProperty(path.get(0)); + for (final String name : path.subList(1, path.size())) { + if (property != null && (property.isLinkedComplex() || property.isComplex())) { + edmProperty = ((EdmComplexType) edmProperty.getType()).getStructuralProperty(name); + final List<Property> complex = property.isLinkedComplex() ? + property.asLinkedComplex().getValue() : + property.asComplex(); + property = null; + for (final Property innerProperty : complex) { + if (innerProperty.getName().equals(name)) { + property = innerProperty; + break; + } + } + } + } if (property == null) { throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); } else { @@ -252,11 +259,10 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, final ODataFormat format = ODataFormat.fromContentType(contentType); ODataSerializer serializer = odata.createSerializer(format); response.setContent(serializer.entityProperty(edmProperty, property, - ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null : - ContextURL.with().entitySet(edmEntitySet) - .keySegment(mapKeys(resourceEntitySet.getKeyPredicates())) - .navOrPropertyPath(edmProperty.getName()) - .build()).build())); + ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null : + getContextUrl(serializer, edmEntitySet, true, null, null, + resourceEntitySet.getKeyPredicates(), buildPropertyPath(path))) + .build())); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString()); } @@ -264,6 +270,23 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, } } + private List<String> getPropertyPath(final List<UriResource> path) { + List<String> result = new LinkedList<String>(); + int index = path.size(); + while (path.get(--index) instanceof UriResourceProperty) { + result.add(0, ((UriResourceProperty) path.get(index)).getProperty().getName()); + } + return result; + } + + private String buildPropertyPath(final List<String> path) { + StringBuilder result = new StringBuilder(); + for (final String segment : path) { + result.append(result.length() == 0 ? "" : '/').append(segment); + } + return result.toString(); + } + @Override public void readPropertyValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType contentType) throws ODataApplicationException, SerializerException { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java index 562787d..fc65245 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java @@ -28,9 +28,9 @@ import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.ContextURL.Suffix; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntitySet; +import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.data.ValueType; import org.apache.olingo.commons.api.edm.Edm; -import org.apache.olingo.commons.api.edm.EdmElement; import org.apache.olingo.commons.api.edm.EdmEntityContainer; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmProperty; @@ -40,8 +40,8 @@ import org.apache.olingo.commons.core.data.PropertyImpl; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.serializer.ODataSerializer; -import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.ODataSerializerOptions; +import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.uri.queryoption.CountOption; import org.apache.olingo.server.api.uri.queryoption.ExpandItem; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; @@ -52,7 +52,6 @@ import org.apache.olingo.server.tecsvc.data.DataProvider; import org.apache.olingo.server.tecsvc.provider.EdmTechProvider; import org.hamcrest.CoreMatchers; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import org.mockito.Mockito; @@ -575,96 +574,70 @@ public class ODataJsonSerializerTest { } @Test - public void individualPrimitiveProperty() throws Exception { + public void primitiveProperty() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); - final EntitySet entitySet = data.readAll(edmEntitySet); - - EdmElement edmElement = edmEntitySet.getEntityType().getProperty("PropertyString"); - Entity entity = entitySet.getEntities().get(0); - - InputStream result = serializer - .entityProperty((EdmProperty) edmElement, entity.getProperty("PropertyString"), + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + final String resultString = IOUtils.toString(serializer + .entityProperty(edmProperty, property, ODataSerializerOptions.with() - .contextURL(ContextURL.with().entitySetOrSingletonOrType("Edm.String") + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName()) .build()) - .build()); - final String resultString = IOUtils.toString(result); + .build())); Assert.assertEquals("{" - + "\"@odata.context\":\"$metadata#Edm.String\"," + + "\"@odata.context\":\"$metadata#ESAllPrim(32767)/PropertyString\"," + "\"value\":\"First Resource - positive values\"}", resultString); } @Test(expected = SerializerException.class) - public void individualPrimitivePropertyNull() throws Exception { - PropertyImpl property = new PropertyImpl("Edm.String", "PropertyString", ValueType.PRIMITIVE, null); + public void primitivePropertyNull() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); - EdmElement edmElement = edmEntitySet.getEntityType().getProperty("PropertyString"); - serializer.entityProperty((EdmProperty) edmElement, property, - ODataSerializerOptions.with() - .contextURL(ContextURL.with().entitySetOrSingletonOrType("Edm.String") - .build()) - .build()); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString"); + final Property property = new PropertyImpl("Edm.String", edmProperty.getName(), ValueType.PRIMITIVE, null); + serializer.entityProperty(edmProperty, property, + ODataSerializerOptions.with() + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("4242").navOrPropertyPath(edmProperty.getName()) + .build()) + .build()); } @Test - public void individualPrimitivePropertyArray() throws Exception { + public void primitiveCollectionProperty() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim"); - final EntitySet entitySet = data.readAll(edmEntitySet); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyString"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); - EdmElement edmElement = edmEntitySet.getEntityType().getProperty("CollPropertyString"); - Entity entity = entitySet.getEntities().get(0); - - InputStream result = serializer - .entityProperty((EdmProperty) edmElement, entity.getProperty("CollPropertyString"), + final String resultString = IOUtils.toString(serializer + .entityProperty(edmProperty, property, ODataSerializerOptions.with() - .contextURL(ContextURL.with().entitySetOrSingletonOrType("Collection(Edm.String)") + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("1").navOrPropertyPath(edmProperty.getName()) .build()) - .build()); - final String resultString = IOUtils.toString(result); + .build())); Assert.assertEquals("{" - + "\"@odata.context\":\"$metadata#Collection%28Edm.String%29\"," + + "\"@odata.context\":\"$metadata#ESCollAllPrim(1)/CollPropertyString\"," + "\"value\":[\"[email protected]\",\"[email protected]\",\"[email protected]\"]}", resultString); } @Test - @Ignore("Serialization of value of primitive property is not done by json serializer") - public void individualPrimitivePropertyValue() throws Exception { - final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); - final EntitySet entitySet = data.readAll(edmEntitySet); - - EdmElement edmElement = edmEntitySet.getEntityType().getProperty("PropertyString"); - Entity entity = entitySet.getEntities().get(0); - - InputStream result = serializer - .entityProperty((EdmProperty) edmElement, entity.getProperty("PropertyString"), - ODataSerializerOptions.with() - .contextURL(ContextURL.with().entitySetOrSingletonOrType("ESAllPrim(0)") - .navOrPropertyPath("PropertyString") - .build()) - .build()); - final String resultString = IOUtils.toString(result); - Assert.assertEquals("\"First Resource - positive values\"", resultString); - } - - @Test - public void individualComplexProperty() throws Exception { + public void complexProperty() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp"); - final EntitySet entitySet = data.readAll(edmEntitySet); - - EdmElement edmElement = edmEntitySet.getEntityType().getProperty("PropertyComp"); - Entity entity = entitySet.getEntities().get(0); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyComp"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty("PropertyComp"); - InputStream result = serializer - .entityProperty((EdmProperty) edmElement, entity.getProperty("PropertyComp"), + final String resultString = IOUtils.toString(serializer + .entityProperty(edmProperty, property, ODataSerializerOptions.with() - .contextURL(ContextURL.with().entitySetOrSingletonOrType("ESMixPrimCollComp.PropertyComp") + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName()) .build()) - .build()); - final String resultString = IOUtils.toString(result); + .build())); Assert.assertEquals("{" - + "\"@odata.context\":\"$metadata#ESMixPrimCollComp.PropertyComp\"," + + "\"@odata.context\":\"$metadata#ESMixPrimCollComp(32767)/PropertyComp\"," + "\"PropertyInt16\":111,\"PropertyString\":\"TEST A\"}", resultString); } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3e117381/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java index a880c60..5397856 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java @@ -27,9 +27,11 @@ import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmEntityContainer; import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.edmx.EdmxReference; +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.queryoption.ExpandItem; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.SelectItem; @@ -179,4 +181,35 @@ public class ContextURLHelperTest { assertEquals("$metadata#ESTwoPrim(NavPropertyETAllPrimOne(NavPropertyETTwoPrimOne(*)))", ContextURLBuilder.create(contextURL).toASCIIString()); } + + @Test + public void buildSingleKey() throws Exception { + final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim"); + final EdmProperty edmProperty = entitySet.getEntityType().getStructuralProperty("PropertyInt16"); + UriParameter key = Mockito.mock(UriParameter.class); + Mockito.when(key.getName()).thenReturn(edmProperty.getName()); + Mockito.when(key.getText()).thenReturn("42"); + final ContextURL contextURL = ContextURL.with().entitySet(entitySet) + .keyPath(ContextURLHelper.buildKeyPredicate(Arrays.asList(key))) + .navOrPropertyPath(edmProperty.getName()).build(); + assertEquals("$metadata#ESTwoPrim(42)/PropertyInt16", + ContextURLBuilder.create(contextURL).toASCIIString()); + } + + @Test + public void buildCompoundKey() throws Exception { + final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoKeyNav"); + final EdmProperty edmProperty = entitySet.getEntityType().getStructuralProperty("PropertyInt16"); + UriParameter key1 = Mockito.mock(UriParameter.class); + Mockito.when(key1.getName()).thenReturn(edmProperty.getName()); + Mockito.when(key1.getText()).thenReturn("1"); + UriParameter key2 = Mockito.mock(UriParameter.class); + Mockito.when(key2.getName()).thenReturn("PropertyString"); + Mockito.when(key2.getText()).thenReturn("'2'"); + final ContextURL contextURL = ContextURL.with().entitySet(entitySet) + .keyPath(ContextURLHelper.buildKeyPredicate(Arrays.asList(key1, key2))) + .navOrPropertyPath(edmProperty.getName()).build(); + assertEquals("$metadata#ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyInt16", + ContextURLBuilder.create(contextURL).toASCIIString()); + } }
