[OLINGO-422] More support for expand and select in ContextURL

This commit is contained in:
mibo 2014-09-17 06:27:19 +02:00
parent 461cdbbe23
commit a1d9f747b8
10 changed files with 452 additions and 122 deletions

View File

@ -25,6 +25,8 @@ import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
public interface ODataSerializer {
@ -47,4 +49,15 @@ public interface ODataSerializer {
* @throws ODataSerializerException
*/
InputStream error(ODataServerError error) throws ODataSerializerException;
/**
* Builds the select-list part of a {@link org.apache.olingo.commons.api.data.ContextURL ContextURL}.
* @param edmEntitySet the Entity Set
* @param expand the $expand option
* @param select the $select option
* @return a String with the select list
* @throws ODataSerializerException
*/
String buildContextURLSelectList(EdmEntitySet edmEntitySet, ExpandOption expand, SelectOption select)
throws ODataSerializerException;
}

View File

@ -32,7 +32,10 @@ import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializerException;
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
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;
import org.apache.olingo.server.core.serializer.utils.ContextURLHelper;
import org.apache.olingo.server.core.serializer.xml.MetadataDocumentXmlSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -98,4 +101,9 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
ODataSerializerException.MessageKeys.NOT_IMPLEMENTED);
}
@Override
public String buildContextURLSelectList(final EdmEntitySet edmEntitySet,
final ExpandOption expand, final SelectOption select) throws ODataSerializerException {
return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select);
}
}

View File

@ -20,7 +20,6 @@ package org.apache.olingo.server.core.serializer.json;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -51,6 +50,7 @@ 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;
import org.apache.olingo.server.core.serializer.utils.ContextURLBuilder;
import org.apache.olingo.server.core.serializer.utils.ContextURLHelper;
import org.apache.olingo.server.core.serializer.utils.ExpandSelectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -382,9 +382,9 @@ public class ODataJsonSerializer implements ODataSerializer {
json.writeStartObject();
for (final String propertyName : type.getPropertyNames()) {
final Property property = findProperty(propertyName, properties);
if (selectedPaths == null || isSelected(selectedPaths, propertyName)) {
if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) {
writeProperty((EdmProperty) type.getProperty(propertyName), property,
selectedPaths == null ? null : getReducedSelectedPaths(selectedPaths, propertyName),
selectedPaths == null ? null : ExpandSelectHelper.getReducedSelectedPaths(selectedPaths, propertyName),
json);
}
}
@ -400,27 +400,9 @@ public class ODataJsonSerializer implements ODataSerializer {
return null;
}
private static boolean isSelected(final Set<List<String>> selectedPaths, final String propertyName) {
for (final List<String> path : selectedPaths) {
if (propertyName.equals(path.get(0))) {
return true;
}
}
return false;
}
private static Set<List<String>> getReducedSelectedPaths(final Set<List<String>> selectedPaths,
final String propertyName) {
Set<List<String>> reducedPaths = new HashSet<List<String>>();
for (final List<String> path : selectedPaths) {
if (path.size() > 1) {
if (propertyName.equals(path.get(0))) {
reducedPaths.add(path.subList(1, path.size()));
}
} else {
return null;
}
}
return reducedPaths.isEmpty() ? null : reducedPaths;
@Override
public String buildContextURLSelectList(final EdmEntitySet edmEntitySet,
final ExpandOption expand, final SelectOption select) throws ODataSerializerException {
return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select);
}
}

View File

@ -19,7 +19,6 @@
package org.apache.olingo.server.core.serializer.utils;
import java.net.URI;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.core.Encoder;
@ -41,6 +40,9 @@ public final class ContextURLBuilder {
}
result.append('/').append(Encoder.encode(contextURL.getDerivedEntity()));
}
if (contextURL.getSelectList() != null) {
result.append('(').append(contextURL.getSelectList()).append(')');
}
if (contextURL.isReference()) {
if (contextURL.getEntitySetOrSingletonOrType() != null) {
throw new IllegalArgumentException("ContextURL: $ref with Entity Set");

View File

@ -0,0 +1,144 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.core.serializer.utils;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.apache.olingo.commons.api.edm.EdmComplexType;
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.ODataSerializerException;
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;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
public final class ContextURLHelper {
/** Builds a list of selected Properties for the ContextURL,
* taking care to preserve the order as defined in the EDM;
* returns NULL if no selection has taken place.
* @param entityType the Entity Type
* @param expand the Expand option (from the URL's $expand query option)
* @param select the Select option (from the URL's $select query option)
* @return a select-list String
* @throws ODataSerializerException if an unsupported feature is used
*/
public static String buildSelectList(final EdmEntityType entityType,
final ExpandOption expand, final SelectOption select) throws ODataSerializerException {
StringBuilder result = new StringBuilder();
boolean isSelected = select != null && select.getSelectItems() != null && !select.getSelectItems().isEmpty();
if(isSelected) {
handleSelect(entityType, select, result);
}
if (ExpandSelectHelper.hasExpand(expand) && !ExpandSelectHelper.isExpandAll(expand)) {
handleExpand(entityType, expand, result);
}
return result.length() == 0 ? null : result.toString();
}
private static void handleSelect(EdmEntityType entityType, SelectOption select, StringBuilder result) {
if (ExpandSelectHelper.isAll(select)) {
result.append('*');
} else {
final List<SelectItem> selectItems = select.getSelectItems();
final Set<String> selectedPropertyNames = ExpandSelectHelper.getSelectedPropertyNames(selectItems);
for (final String propertyName : entityType.getPropertyNames()) {
if (selectedPropertyNames.contains(propertyName)) {
if (result.length() > 0) {
result.append(',');
}
final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
final Set<List<String>> selectedPaths = ExpandSelectHelper.getSelectedPaths(selectItems, propertyName);
if (selectedPaths == null) {
result.append(Encoder.encode(propertyName));
} else {
final List<List<String>> complexSelectedPaths = getComplexSelectedPaths(edmProperty, selectedPaths);
boolean first = true;
for (final List<String> path : complexSelectedPaths) {
if (first) {
first = false;
} else {
result.append(',');
}
boolean innerFirst = true;
for (final String name : path) {
if (innerFirst) {
innerFirst = false;
} else {
result.append('/');
}
result.append(Encoder.encode(name));
}
}
}
}
}
}
}
private static void handleExpand(EdmEntityType entityType, ExpandOption expand, StringBuilder result)
throws ODataSerializerException {
final Set<String> expandedPropertyNames = ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems());
for (final String propertyName : entityType.getNavigationPropertyNames()) {
if (expandedPropertyNames.contains(propertyName)) {
final ExpandItem expandItem = ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName);
if (ExpandSelectHelper.hasExpand(expandItem.getExpandOption())
&& !ExpandSelectHelper.isExpandAll(expandItem.getExpandOption())
|| ExpandSelectHelper.hasSelect(expandItem.getSelectOption())) {
final String innerSelectList = buildSelectList(entityType.getNavigationProperty(propertyName).getType(),
expandItem.getExpandOption(), expandItem.getSelectOption());
if (result.length() > 0) {
result.append(',');
}
result.append(Encoder.encode(propertyName)).append('(').append(innerSelectList).append(')');
}
}
}
}
private static List<List<String>> getComplexSelectedPaths(final EdmProperty edmProperty,
final Set<List<String>> selectedPaths) {
List<List<String>> result = new ArrayList<List<String>>();
if (selectedPaths == null) {
List<String> path = new LinkedList<String>();
path.add(edmProperty.getName());
result.add(path);
} else {
final EdmComplexType type = (EdmComplexType) edmProperty.getType();
for (final String complexPropertyName : type.getPropertyNames()) {
if (ExpandSelectHelper.isSelected(selectedPaths, complexPropertyName)) {
List<List<String>> complexSelectedPaths = getComplexSelectedPaths(
(EdmProperty) type.getProperty(complexPropertyName),
ExpandSelectHelper.getReducedSelectedPaths(selectedPaths, complexPropertyName));
for (final List<String> path : complexSelectedPaths) {
path.add(0, edmProperty.getName());
result.add(path);
}
}
}
}
return result;
}
}

View File

@ -34,16 +34,20 @@ import org.apache.olingo.server.api.uri.queryoption.SelectOption;
public abstract class ExpandSelectHelper {
public static boolean hasSelect(final SelectOption select) {
return select != null && select.getSelectItems() != null && !select.getSelectItems().isEmpty();
}
public static boolean isAll(final SelectOption select) {
if (select == null || select.getSelectItems() == null || select.getSelectItems().isEmpty()) {
return true;
} else {
if (hasSelect(select)) {
for (final SelectItem item : select.getSelectItems()) {
if (item.isStar()) {
return true;
}
}
return false;
} else {
return true;
}
}
@ -81,6 +85,31 @@ public abstract class ExpandSelectHelper {
return selectedPaths.isEmpty() ? null : selectedPaths;
}
public static boolean isSelected(final Set<List<String>> selectedPaths, final String propertyName) {
for (final List<String> path : selectedPaths) {
if (propertyName.equals(path.get(0))) {
return true;
}
}
return false;
}
public static Set<List<String>> getReducedSelectedPaths(final Set<List<String>> selectedPaths,
final String propertyName) {
Set<List<String>> reducedPaths = new HashSet<List<String>>();
for (final List<String> path : selectedPaths) {
if (propertyName.equals(path.get(0))) {
if (path.size() > 1) {
reducedPaths.add(path.subList(1, path.size()));
} else {
return null;
}
}
}
return reducedPaths.isEmpty() ? null : reducedPaths;
}
public static boolean hasExpand(final ExpandOption expand) {
return expand != null && expand.getExpandItems() != null && !expand.getExpandItems().isEmpty();
}

View File

@ -21,7 +21,6 @@ package org.apache.olingo.server.core.serializer.utils;
import static org.junit.Assert.assertEquals;
import java.net.URI;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
@ -34,14 +33,14 @@ public class ContextURLBuilderTest {
@Test
public void buildServiceDocument() {
ContextURL contextURL = ContextURL.with()
final ContextURL contextURL = ContextURL.with()
.serviceRoot(URI.create("http://host/service/")).build();
assertEquals("http://host/service/$metadata", ContextURLBuilder.create(contextURL).toASCIIString());
}
@Test
public void buildRelative() {
ContextURL contextURL = ContextURL.with().build();
final ContextURL contextURL = ContextURL.with().build();
assertEquals("$metadata", ContextURLBuilder.create(contextURL).toASCIIString());
}
@ -49,7 +48,7 @@ public class ContextURLBuilderTest {
public void buildEntitySet() {
EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
Mockito.when(entitySet.getName()).thenReturn("Customers");
ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/"))
final ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/"))
.entitySet(entitySet)
.build();
assertEquals("http://host/service/$metadata#Customers", ContextURLBuilder.create(contextURL).toASCIIString());
@ -61,7 +60,7 @@ public class ContextURLBuilderTest {
Mockito.when(entitySet.getName()).thenReturn("Customers");
EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
Mockito.when(derivedType.getFullQualifiedName()).thenReturn(new FullQualifiedName("Model", "VipCustomer"));
ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/"))
final ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/"))
.entitySet(entitySet)
.derived(derivedType)
.build();
@ -82,7 +81,7 @@ public class ContextURLBuilderTest {
Mockito.when(entitySet.getName()).thenReturn("Customers");
EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
Mockito.when(derivedType.getFullQualifiedName()).thenReturn(new FullQualifiedName("Model", "VipCustomer"));
ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/"))
final ContextURL contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/"))
.entitySet(entitySet)
.derived(derivedType)
.suffix(Suffix.ENTITY)
@ -98,7 +97,7 @@ public class ContextURLBuilderTest {
@Test
public void buildReference() {
ContextURL contextURL = ContextURL.with().suffix(Suffix.REFERENCE).build();
final ContextURL contextURL = ContextURL.with().suffix(Suffix.REFERENCE).build();
assertEquals("$metadata#$ref", ContextURLBuilder.create(contextURL).toASCIIString());
}
@ -116,7 +115,7 @@ public class ContextURLBuilderTest {
EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
Mockito.when(derivedType.getFullQualifiedName()).thenReturn(
new FullQualifiedName("Namensräumchen", "UnüblicherName"));
ContextURL contextURL = ContextURL.with().entitySet(entitySet).derived(derivedType).build();
final ContextURL contextURL = ContextURL.with().entitySet(entitySet).derived(derivedType).build();
assertEquals("$metadata#Entit%C3%A4ten/Namensr%C3%A4umchen.Un%C3%BCblicherName",
ContextURLBuilder.create(contextURL).toString());
}

View File

@ -36,11 +36,14 @@ import org.apache.olingo.server.api.ODataTranslatedException;
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializerException;
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.tecsvc.data.DataProvider;
import java.util.List;
@ -74,11 +77,13 @@ public class TechnicalProcessor implements EntityCollectionProcessor, EntityProc
response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
} else {
ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(requestedContentType));
final ExpandOption expand = uriInfo.getExpandOption();
final SelectOption select = uriInfo.getSelectOption();
response.setContent(serializer.entitySet(edmEntitySet, entitySet,
ODataSerializerOptions.with()
.contextURL(getContextUrl(edmEntitySet, false))
.contextURL(getContextUrl(serializer, edmEntitySet, false, expand, select))
.count(uriInfo.getCountOption())
.expand(uriInfo.getExpandOption()).select(uriInfo.getSelectOption())
.expand(expand).select(select)
.build()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
@ -106,12 +111,13 @@ public class TechnicalProcessor implements EntityCollectionProcessor, EntityProc
response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
} else {
ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(requestedContentType));
final ExpandOption expand = uriInfo.getExpandOption();
final SelectOption select = uriInfo.getSelectOption();
response.setContent(serializer.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(getContextUrl(edmEntitySet, true))
.contextURL(getContextUrl(serializer, edmEntitySet, true, expand, select))
.count(uriInfo.getCountOption())
.expand(uriInfo.getExpandOption())
.select(uriInfo.getSelectOption())
.expand(uriInfo.getExpandOption()).select(uriInfo.getSelectOption())
.build()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
@ -167,7 +173,11 @@ public class TechnicalProcessor implements EntityCollectionProcessor, EntityProc
return uriResource.getEntitySet();
}
private ContextURL getContextUrl(final EdmEntitySet entitySet, final boolean isSingleEntity) {
return ContextURL.with().entitySet(entitySet).suffix(isSingleEntity ? Suffix.ENTITY : null).build();
private ContextURL getContextUrl(final ODataSerializer serializer,
final EdmEntitySet entitySet, final boolean isSingleEntity,
final ExpandOption expand, final SelectOption select) throws ODataSerializerException {
return ContextURL.with().entitySet(entitySet)
.selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
.suffix(isSingleEntity ? Suffix.ENTITY : null).build();
}
}

View File

@ -350,18 +350,17 @@ public class ODataJsonSerializerTest {
final SelectItem selectItem1 = mockSelectItem(edmEntitySet, "PropertyDate");
final SelectItem selectItem2 = mockSelectItem(edmEntitySet, "PropertyBoolean");
final SelectOption select = mockSelectOption(Arrays.asList(selectItem1, selectItem2, selectItem2));
InputStream result =
new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(null)
// ContextURL.Builder.with().entitySet(edmEntitySet).selectList("PropertyBoolean,PropertyDate")
// .suffix(Suffix.ENTITY).build(),
.select(select)
.build());
InputStream result = serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet)
.selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
.suffix(Suffix.ENTITY).build())
.select(select)
.build());
final String resultString = IOUtils.toString(result);
final String expectedResult = "{"
// + "\"@odata.context\":\"$metadata#ESAllPrim(PropertyBoolean,PropertyDate)/$entity\","
+ "\"@odata.context\":\"$metadata#ESAllPrim(PropertyBoolean,PropertyDate)/$entity\","
+ "\"PropertyBoolean\":true,\"PropertyDate\":\"2012-12-03\"}";
Assert.assertEquals(expectedResult, resultString);
}
@ -391,18 +390,17 @@ public class ODataJsonSerializerTest {
final EntitySet entitySet = data.readAll(edmEntitySet);
final SelectOption select = mockSelectOption(Arrays.asList(
mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp", "PropertyString")));
InputStream result =
new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
.entitySet(edmEntitySet, entitySet,
ODataSerializerOptions.with()
.contextURL(null)
// ContextURL.Builder.with().entitySet(edmEntitySet)
// .selectList("PropertyComp/PropertyComp/PropertyString").build(),
.select(select)
.build());
InputStream result = serializer
.entitySet(edmEntitySet, entitySet,
ODataSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet)
.selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
.build())
.select(select)
.build());
final String resultString = IOUtils.toString(result);
Assert.assertEquals("{"
// + "\"@odata.context\":\"$metadata#ESCompComp(PropertyComp/PropertyComp/PropertyString)\","
+ "\"@odata.context\":\"$metadata#ESCompComp(PropertyComp/PropertyComp/PropertyString)\","
+ "\"value\":["
+ "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyString\":\"String 1\"}}},"
+ "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyString\":\"String 2\"}}}]}",
@ -416,18 +414,16 @@ public class ODataJsonSerializerTest {
final SelectOption select = mockSelectOption(Arrays.asList(
mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp", "PropertyString"),
mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp")));
InputStream result =
new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
.entitySet(edmEntitySet, entitySet,
ODataSerializerOptions.with()
.contextURL(null)
// ContextURL.Builder.with().entitySet(edmEntitySet)
// .selectList("PropertyComp/PropertyComp").build()
.select(select)
.build());
final String resultString = IOUtils.toString(result);
final String resultString = IOUtils.toString(serializer
.entitySet(edmEntitySet, entitySet,
ODataSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet)
.selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
.build())
.select(select)
.build()));
Assert.assertEquals("{"
// + "\"@odata.context\":\"$metadata#ESCompComp(PropertyComp/PropertyComp)\","
+ "\"@odata.context\":\"$metadata#ESCompComp(PropertyComp/PropertyComp)\","
+ "\"value\":["
+ "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyInt16\":123,\"PropertyString\":\"String 1\"}}},"
+ "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyInt16\":987,\"PropertyString\":\"String 2\"}}}]}",
@ -477,17 +473,16 @@ public class ODataJsonSerializerTest {
ExpandItem expandItem = mockExpandItem(edmEntitySet, "NavPropertyETAllPrimOne");
Mockito.when(expandItem.getSelectOption()).thenReturn(select);
final ExpandOption expand = mockExpandOption(Arrays.asList(expandItem));
InputStream result =
new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(null)
// ContextURL.Builder.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()
.expand(expand)
.build());
final String resultString = IOUtils.toString(result);
final String resultString = IOUtils.toString(serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet)
.selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
.suffix(Suffix.ENTITY).build())
.expand(expand)
.build()));
Assert.assertEquals("{"
// + "\"@odata.context\":\"$metadata#ESTwoPrim(NavPropertyETAllPrimOne(PropertyDate))/$entity\","
+ "\"@odata.context\":\"$metadata#ESTwoPrim(NavPropertyETAllPrimOne(PropertyDate))/$entity\","
+ "\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\","
+ "\"NavPropertyETAllPrimOne\":{\"PropertyDate\":\"2012-12-03\"}}",
resultString);
@ -502,18 +497,17 @@ public class ODataJsonSerializerTest {
Mockito.when(expandItemAll.isStar()).thenReturn(true);
final ExpandOption expand = mockExpandOption(Arrays.asList(expandItem, expandItem, expandItemAll));
final SelectOption select = mockSelectOption(Arrays.asList(mockSelectItem(edmEntitySet, "PropertySByte")));
InputStream result =
new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(null)
// ContextURL.Builder.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()
.expand(expand)
.select(select)
.build());
final String resultString = IOUtils.toString(result);
final String resultString = IOUtils.toString(serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet)
.selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
.suffix(Suffix.ENTITY).build())
.expand(expand)
.select(select)
.build()));
Assert.assertEquals("{"
// + "\"@odata.context\":\"$metadata#ESAllPrim(PropertySByte)/$entity\","
+ "\"@odata.context\":\"$metadata#ESAllPrim(PropertySByte)/$entity\","
+ "\"PropertySByte\":127,"
+ "\"NavPropertyETTwoPrimOne\":{\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\"},"
+ "\"NavPropertyETTwoPrimMany\":[{\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\"}]}",
@ -528,18 +522,17 @@ public class ODataJsonSerializerTest {
Mockito.when(expandItemAll.isStar()).thenReturn(true);
final ExpandOption expand = mockExpandOption(Arrays.asList(expandItemAll));
final SelectOption select = mockSelectOption(Arrays.asList(mockSelectItem(edmEntitySet, "PropertyTimeOfDay")));
InputStream result =
new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(null)
// ContextURL.Builder.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()
.expand(expand)
.select(select)
.build());
final String resultString = IOUtils.toString(result);
final String resultString = IOUtils.toString(serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet)
.selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
.suffix(Suffix.ENTITY).build())
.expand(expand)
.select(select)
.build()));
Assert.assertEquals("{"
// + "\"@odata.context\":\"$metadata#ESAllPrim(PropertyTimeOfDay)/$entity\","
+ "\"@odata.context\":\"$metadata#ESAllPrim(PropertyTimeOfDay)/$entity\","
+ "\"PropertyTimeOfDay\":\"23:49:14\","
+ "\"NavPropertyETTwoPrimOne\":null,\"NavPropertyETTwoPrimMany\":[]}",
resultString);
@ -559,17 +552,16 @@ public class ODataJsonSerializerTest {
mockSelectItem(innerEntitySet, "PropertyInt32")));
Mockito.when(expandItemFirst.getSelectOption()).thenReturn(select);
final ExpandOption expand = mockExpandOption(Arrays.asList(expandItemFirst));
InputStream result =
new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(null)
// ContextURL.Builder.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()
.expand(expand)
.build());
final String resultString = IOUtils.toString(result);
final String resultString = IOUtils.toString(serializer
.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet)
.selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
.suffix(Suffix.ENTITY).build())
.expand(expand)
.build()));
Assert.assertEquals("{"
// + "\"@odata.context\":\"$metadata#ESTwoPrim(NavPropertyETAllPrimMany(PropertyInt32))/$entity\","
+ "\"@odata.context\":\"$metadata#ESTwoPrim(NavPropertyETAllPrimMany(PropertyInt32))/$entity\","
+ "\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\","
+ "\"NavPropertyETAllPrimMany\":["
+ "{\"PropertyInt32\":-2147483648,\"NavPropertyETTwoPrimOne\":null,\"NavPropertyETTwoPrimMany\":[]},"
@ -581,7 +573,7 @@ public class ODataJsonSerializerTest {
resultString);
}
private UriInfoResource mockResource(final EdmEntitySet edmEntitySet, final String... names) {
private static UriInfoResource mockResource(final EdmEntitySet edmEntitySet, final String... names) {
EdmStructuredType type = edmEntitySet.getEntityType();
List<UriResource> elements = new ArrayList<UriResource>();
for (final String name : Arrays.asList(names)) {
@ -603,27 +595,27 @@ public class ODataJsonSerializerTest {
return resource;
}
private SelectItem mockSelectItem(final EdmEntitySet edmEntitySet, final String... names) {
public static SelectItem mockSelectItem(final EdmEntitySet edmEntitySet, final String... names) {
final UriInfoResource resource = mockResource(edmEntitySet, names);
SelectItem selectItem = Mockito.mock(SelectItem.class);
Mockito.when(selectItem.getResourcePath()).thenReturn(resource);
return selectItem;
}
private SelectOption mockSelectOption(final List<SelectItem> selectItems) {
public static SelectOption mockSelectOption(final List<SelectItem> selectItems) {
SelectOption select = Mockito.mock(SelectOption.class);
Mockito.when(select.getSelectItems()).thenReturn(selectItems);
return select;
}
private ExpandItem mockExpandItem(final EdmEntitySet edmEntitySet, final String... names) {
public static ExpandItem mockExpandItem(final EdmEntitySet edmEntitySet, final String... names) {
final UriInfoResource resource = mockResource(edmEntitySet, names);
ExpandItem expandItem = Mockito.mock(ExpandItem.class);
Mockito.when(expandItem.getResourcePath()).thenReturn(resource);
return expandItem;
}
private ExpandOption mockExpandOption(final List<ExpandItem> expandItems) {
public static ExpandOption mockExpandOption(final List<ExpandItem> expandItems) {
ExpandOption expand = Mockito.mock(ExpandOption.class);
Mockito.when(expand.getExpandItems()).thenReturn(expandItems);
return expand;

View File

@ -0,0 +1,151 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.core.serializer.utils;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
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.FullQualifiedName;
import org.apache.olingo.server.api.OData;
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;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.core.serializer.json.ODataJsonSerializerTest;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Test;
import org.mockito.Mockito;
public class ContextURLHelperTest {
private static final Edm edm = OData.newInstance().createEdm(new EdmTechProvider());
private static final EdmEntityContainer entityContainer = edm.getEntityContainer(
new FullQualifiedName("olingo.odata.test1", "Container"));
@Test
public void buildSelect() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESAllPrim");
final SelectItem selectItem1 = ODataJsonSerializerTest.mockSelectItem(entitySet, "PropertyString");
final SelectItem selectItem2 = ODataJsonSerializerTest.mockSelectItem(entitySet, "PropertyInt16");
final SelectOption select = ODataJsonSerializerTest.mockSelectOption(Arrays.asList(
selectItem1, selectItem2, selectItem2));
final ContextURL contextURL = ContextURL.with().entitySet(entitySet)
.selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), null, select)).build();
assertEquals("$metadata#ESAllPrim(PropertyInt16,PropertyString)",
ContextURLBuilder.create(contextURL).toASCIIString());
}
@Test
public void buildSelectAll() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESAllPrim");
final SelectItem selectItem1 = ODataJsonSerializerTest.mockSelectItem(entitySet, "PropertyGuid");
SelectItem selectItem2 = Mockito.mock(SelectItem.class);
Mockito.when(selectItem2.isStar()).thenReturn(true);
final SelectOption select = ODataJsonSerializerTest.mockSelectOption(Arrays.asList(selectItem1, selectItem2));
final ContextURL contextURL = ContextURL.with().entitySet(entitySet)
.selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), null, select)).build();
assertEquals("$metadata#ESAllPrim(*)", ContextURLBuilder.create(contextURL).toASCIIString());
}
@Test
public void buildSelectComplex() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESCompMixPrimCollComp");
final SelectOption select = ODataJsonSerializerTest.mockSelectOption(Arrays.asList(
ODataJsonSerializerTest.mockSelectItem(entitySet,
"PropertyMixedPrimCollComp", "PropertyComp", "PropertyString"),
ODataJsonSerializerTest.mockSelectItem(entitySet,
"PropertyMixedPrimCollComp", "PropertyComp", "PropertyInt16"),
ODataJsonSerializerTest.mockSelectItem(entitySet, "PropertyMixedPrimCollComp", "CollPropertyString"),
ODataJsonSerializerTest.mockSelectItem(entitySet, "PropertyMixedPrimCollComp", "CollPropertyComp"),
ODataJsonSerializerTest.mockSelectItem(entitySet, "PropertyInt16")));
final ContextURL contextURL = ContextURL.with().entitySet(entitySet)
.selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), null, select)).build();
assertEquals("$metadata#ESCompMixPrimCollComp("
+ "PropertyInt16,"
+ "PropertyMixedPrimCollComp/CollPropertyString,"
+ "PropertyMixedPrimCollComp/PropertyComp/PropertyInt16,"
+ "PropertyMixedPrimCollComp/PropertyComp/PropertyString,"
+ "PropertyMixedPrimCollComp/CollPropertyComp)",
ContextURLBuilder.create(contextURL).toASCIIString());
}
@Test
public void buildExpandAll() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
ExpandItem expandItem = Mockito.mock(ExpandItem.class);
Mockito.when(expandItem.isStar()).thenReturn(true);
final ExpandOption expand = ODataJsonSerializerTest.mockExpandOption(Arrays.asList(expandItem));
final ContextURL contextURL = ContextURL.with().entitySet(entitySet)
.selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), expand, null)).build();
assertEquals("$metadata#ESTwoPrim", ContextURLBuilder.create(contextURL).toASCIIString());
}
@Test
public void buildExpandNoSelect() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
final ExpandOption expand = ODataJsonSerializerTest.mockExpandOption(Arrays.asList(
ODataJsonSerializerTest.mockExpandItem(entitySet, "NavPropertyETAllPrimOne")));
final ContextURL contextURL = ContextURL.with().entitySet(entitySet)
.selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), expand, null)).build();
assertEquals("$metadata#ESTwoPrim", ContextURLBuilder.create(contextURL).toASCIIString());
}
@Test
public void buildExpandSelect() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
final ExpandItem expandItem1 = ODataJsonSerializerTest.mockExpandItem(entitySet, "NavPropertyETAllPrimOne");
final EdmEntitySet innerEntitySet = entityContainer.getEntitySet("ESAllPrim");
ExpandItem expandItem2 = ODataJsonSerializerTest.mockExpandItem(entitySet, "NavPropertyETAllPrimMany");
final SelectOption innerSelect = ODataJsonSerializerTest.mockSelectOption(Arrays.asList(
ODataJsonSerializerTest.mockSelectItem(innerEntitySet, "PropertyInt32")));
Mockito.when(expandItem2.getSelectOption()).thenReturn(innerSelect);
final ExpandOption expand = ODataJsonSerializerTest.mockExpandOption(Arrays.asList(
expandItem1, expandItem2));
final SelectItem selectItem = ODataJsonSerializerTest.mockSelectItem(entitySet, "PropertyString");
final SelectOption select = ODataJsonSerializerTest.mockSelectOption(Arrays.asList(selectItem));
final ContextURL contextURL = ContextURL.with().entitySet(entitySet)
.selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), expand, select)).build();
assertEquals("$metadata#ESTwoPrim(PropertyString,NavPropertyETAllPrimMany(PropertyInt32))",
ContextURLBuilder.create(contextURL).toASCIIString());
}
@Test
public void buildExpandSelectTwoLevels() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
final EdmEntitySet innerEntitySet = entityContainer.getEntitySet("ESAllPrim");
ExpandItem expandItemInner = ODataJsonSerializerTest.mockExpandItem(innerEntitySet, "NavPropertyETTwoPrimOne");
SelectItem innerSelectItem = Mockito.mock(SelectItem.class);
Mockito.when(innerSelectItem.isStar()).thenReturn(true);
final SelectOption innerSelect = ODataJsonSerializerTest.mockSelectOption(Arrays.asList(innerSelectItem));
Mockito.when(expandItemInner.getSelectOption()).thenReturn(innerSelect);
final ExpandOption innerExpand = ODataJsonSerializerTest.mockExpandOption(Arrays.asList(expandItemInner));
ExpandItem expandItem = ODataJsonSerializerTest.mockExpandItem(entitySet, "NavPropertyETAllPrimOne");
Mockito.when(expandItem.getExpandOption()).thenReturn(innerExpand);
final ExpandOption expand = ODataJsonSerializerTest.mockExpandOption(Arrays.asList(expandItem));
final ContextURL contextURL = ContextURL.with().entitySet(entitySet)
.selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), expand, null)).build();
assertEquals("$metadata#ESTwoPrim(NavPropertyETAllPrimOne(NavPropertyETTwoPrimOne(*)))",
ContextURLBuilder.create(contextURL).toASCIIString());
}
}