mirror of
https://github.com/apache/olingo-odata4.git
synced 2025-02-06 01:59:12 +00:00
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/olingo-odata4.git
This commit is contained in:
commit
7dedb25c3a
@ -206,4 +206,86 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
|
||||
assertTrue(IOUtils.toString(connection.getErrorStream()).
|
||||
contains("The system query option '$skip' has the not-allowed value ''."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseTypeDerivedTypeCasting1() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESTwoPrim(111)/olingo.odata.test1.ETBase");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getInputStream());
|
||||
|
||||
assertTrue(content.contains("\"PropertyInt16\":111"));
|
||||
assertTrue(content.contains("\"PropertyString\":\"TEST A\""));
|
||||
assertTrue(content.contains("\"AdditionalPropertyString_5\":\"TEST A 0815\""));
|
||||
assertTrue(content.contains("\"@odata.type\":\"#olingo.odata.test1.ETBase\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseTypeDerivedTypeCasting2() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESTwoPrim(111)/olingo.odata.test1.ETBase/AdditionalPropertyString_5");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getInputStream());
|
||||
assertTrue(content.contains("\"TEST A 0815\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseTypeDerivedTypeCasting3() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESTwoPrim(32766)/olingo.odata.test1.ETTwoPrim");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getInputStream());
|
||||
|
||||
assertTrue(content.contains("\"PropertyInt16\":32766"));
|
||||
assertTrue(content.contains("\"PropertyString\":\"Test String1\""));
|
||||
assertTrue(content.contains("\"@odata.type\":\"#olingo.odata.test1.ETTwoPrim\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseTypeDerivedTypeCastingException() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESBase(111)/olingo.odata.test1.ETTwoPrim");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
|
||||
assertTrue(content.contains("The type filter 'olingo.odata.test1.ETTwoPrim' is incompatible."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseTypeDerivedComplexTypeCasting1() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESMixPrimCollComp(32767)/PropertyComp/olingo.odata.test1.CTBase");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getInputStream());
|
||||
|
||||
assertTrue(content.contains("\"PropertyInt16\":111"));
|
||||
assertTrue(content.contains("\"PropertyString\":\"TEST A\""));
|
||||
assertTrue(content.contains("\"AdditionalPropString\":null"));
|
||||
assertTrue(content.contains("\"@odata.type\":\"#olingo.odata.test1.CTBase\""));
|
||||
}
|
||||
}
|
||||
|
@ -702,9 +702,23 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
|
||||
throws IOException, SerializerException{
|
||||
json.writeStartObject();
|
||||
String derivedName = property.getType();
|
||||
final EdmComplexType resolvedType = resolveComplexType(metadata, type, derivedName);
|
||||
EdmComplexType resolvedType = null;
|
||||
if (!type.getFullQualifiedName().getFullQualifiedNameAsString().
|
||||
equals(derivedName)) {
|
||||
if (type.getBaseType() != null &&
|
||||
type.getBaseType().getFullQualifiedName().getFullQualifiedNameAsString().
|
||||
equals(derivedName)) {
|
||||
resolvedType = resolveComplexType(metadata, type.getBaseType(),
|
||||
type.getFullQualifiedName().getFullQualifiedNameAsString());
|
||||
} else {
|
||||
resolvedType = resolveComplexType(metadata, type, derivedName);
|
||||
}
|
||||
} else {
|
||||
resolvedType = resolveComplexType(metadata, type, derivedName);
|
||||
}
|
||||
if (!isODataMetadataNone && !resolvedType.equals(type) || isODataMetadataFull) {
|
||||
json.writeStringField(Constants.JSON_TYPE, "#" + property.getType());
|
||||
json.writeStringField(Constants.JSON_TYPE, "#" +
|
||||
resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
|
||||
}
|
||||
writeComplexValue(metadata, resolvedType, property.asComplex().getValue(), selectedPaths,
|
||||
json);
|
||||
@ -1000,9 +1014,23 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
|
||||
json.writeStartObject();
|
||||
writeContextURL(contextURL, json);
|
||||
writeMetadataETag(metadata, json);
|
||||
final EdmComplexType resolvedType = resolveComplexType(metadata, type, property.getType());
|
||||
EdmComplexType resolvedType = null;
|
||||
if (!type.getFullQualifiedName().getFullQualifiedNameAsString().
|
||||
equals(property.getType())) {
|
||||
if (type.getBaseType() != null &&
|
||||
type.getBaseType().getFullQualifiedName().getFullQualifiedNameAsString().
|
||||
equals(property.getType())) {
|
||||
resolvedType = resolveComplexType(metadata, type.getBaseType(),
|
||||
type.getFullQualifiedName().getFullQualifiedNameAsString());
|
||||
} else {
|
||||
resolvedType = resolveComplexType(metadata, type, property.getType());
|
||||
}
|
||||
} else {
|
||||
resolvedType = resolveComplexType(metadata, type, property.getType());
|
||||
}
|
||||
if (!isODataMetadataNone && !resolvedType.equals(type) || isODataMetadataFull) {
|
||||
json.writeStringField(Constants.JSON_TYPE, "#" + property.getType());
|
||||
json.writeStringField(Constants.JSON_TYPE, "#" +
|
||||
resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
|
||||
}
|
||||
writeOperations(property.getOperations(), json);
|
||||
final List<Property> values =
|
||||
|
@ -1041,7 +1041,20 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
|
||||
OutputStream outputStream = null;
|
||||
SerializerException cachedException = null;
|
||||
try {
|
||||
EdmComplexType resolvedType = resolveComplexType(metadata, type, property.getType());
|
||||
EdmComplexType resolvedType = null;
|
||||
if (!type.getFullQualifiedName().getFullQualifiedNameAsString().
|
||||
equals(property.getType())) {
|
||||
if (type.getBaseType() != null &&
|
||||
type.getBaseType().getFullQualifiedName().getFullQualifiedNameAsString().
|
||||
equals(property.getType())) {
|
||||
resolvedType = resolveComplexType(metadata, type.getBaseType(),
|
||||
type.getFullQualifiedName().getFullQualifiedNameAsString());
|
||||
} else {
|
||||
resolvedType = resolveComplexType(metadata, type, property.getType());
|
||||
}
|
||||
} else {
|
||||
resolvedType = resolveComplexType(metadata, type, property.getType());
|
||||
}
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
outputStream = buffer.getOutputStream();
|
||||
XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
|
||||
|
@ -33,6 +33,7 @@ import org.apache.olingo.server.api.uri.UriInfoKind;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceAction;
|
||||
import org.apache.olingo.server.api.uri.UriResourceCount;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.api.uri.UriResourceRef;
|
||||
@ -255,11 +256,16 @@ public class Parser {
|
||||
if (lastSegment instanceof UriResourcePartTyped) {
|
||||
final UriResourcePartTyped typed = (UriResourcePartTyped) lastSegment;
|
||||
contextType = ParserHelper.getTypeInformation(typed);
|
||||
if (contextUriInfo.getIdOption() != null && contextType != null) {
|
||||
if (contextType instanceof EdmEntityType) {
|
||||
contextUriInfo.setEntityTypeCast((EdmEntityType) contextType);
|
||||
}
|
||||
}
|
||||
if (contextType != null) {
|
||||
if ((lastSegment instanceof UriResourceEntitySet &&
|
||||
(((UriResourceEntitySet) lastSegment).getTypeFilterOnCollection() != null
|
||||
|| ((UriResourceEntitySet) lastSegment).getTypeFilterOnEntry() != null))
|
||||
|| contextUriInfo.getIdOption() != null) {
|
||||
if (contextType instanceof EdmEntityType) {
|
||||
contextUriInfo.setEntityTypeCast((EdmEntityType) contextType);
|
||||
}
|
||||
}
|
||||
}
|
||||
contextIsCollection = typed.isCollection();
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ import org.apache.olingo.server.api.uri.UriHelper;
|
||||
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.UriResourceComplexProperty;
|
||||
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
@ -246,9 +247,18 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
||||
} else {
|
||||
final EdmProperty edmProperty = path.isEmpty() ? null :
|
||||
((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1)).getProperty();
|
||||
final EdmType type = edmProperty == null ?
|
||||
((UriResourceFunction) resourceParts.get(0)).getType() :
|
||||
edmProperty.getType();
|
||||
EdmType type = null;
|
||||
if (resourceParts.get(resourceParts.size() - trailing - 1)
|
||||
instanceof UriResourceComplexProperty &&
|
||||
((UriResourceComplexProperty)resourceParts.get(resourceParts.size() - trailing - 1)).
|
||||
getComplexTypeFilter() != null) {
|
||||
type = ((UriResourceComplexProperty)resourceParts.get(resourceParts.size() - trailing - 1)).
|
||||
getComplexTypeFilter();
|
||||
} else {
|
||||
type = edmProperty == null ?
|
||||
((UriResourceFunction) resourceParts.get(0)).getType() :
|
||||
edmProperty.getType();
|
||||
}
|
||||
final EdmReturnType returnType = resourceParts.get(0) instanceof UriResourceFunction ?
|
||||
((UriResourceFunction) resourceParts.get(0)).getFunction().getReturnType() : null;
|
||||
|
||||
|
@ -25,6 +25,7 @@ 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.edm.EdmBindingTarget;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmFunction;
|
||||
@ -79,7 +80,7 @@ public abstract class TechnicalProcessor implements Processor {
|
||||
// First must be an entity, an entity collection, a function import, or an action import.
|
||||
blockTypeFilters(resourcePaths.get(0));
|
||||
if (resourcePaths.get(0) instanceof UriResourceEntitySet) {
|
||||
entitySet = ((UriResourceEntitySet) resourcePaths.get(0)).getEntitySet();
|
||||
entitySet = getEntitySetBasedOnTypeCast(((UriResourceEntitySet)resourcePaths.get(0)));
|
||||
} else if (resourcePaths.get(0) instanceof UriResourceFunction) {
|
||||
entitySet = ((UriResourceFunction) resourcePaths.get(0)).getFunctionImport().getReturnedEntitySet();
|
||||
} else if (resourcePaths.get(0) instanceof UriResourceAction) {
|
||||
@ -143,7 +144,8 @@ public abstract class TechnicalProcessor implements Processor {
|
||||
Entity entity = null;
|
||||
if (resourcePaths.get(0) instanceof UriResourceEntitySet) {
|
||||
final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
|
||||
entity = dataProvider.read(uriResource.getEntitySet(), uriResource.getKeyPredicates());
|
||||
EdmEntitySet entitySet = getEntitySetBasedOnTypeCast(uriResource);
|
||||
entity = dataProvider.read(entitySet, uriResource.getKeyPredicates());
|
||||
}else if (resourcePaths.get(0) instanceof UriResourceSingleton) {
|
||||
final UriResourceSingleton uriResource = (UriResourceSingleton) resourcePaths.get(0);
|
||||
entity = dataProvider.read( uriResource.getSingleton());
|
||||
@ -205,6 +207,28 @@ public abstract class TechnicalProcessor implements Processor {
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected EdmEntitySet getEntitySetBasedOnTypeCast(UriResourceEntitySet uriResource) {
|
||||
EdmEntitySet entitySet = null;
|
||||
EdmEntityContainer container = this.serviceMetadata.getEdm().getEntityContainer();
|
||||
if (uriResource.getTypeFilterOnEntry() != null ||
|
||||
uriResource.getTypeFilterOnCollection() != null) {
|
||||
List<EdmEntitySet> entitySets = container.getEntitySets();
|
||||
for (EdmEntitySet entitySet1 : entitySets) {
|
||||
EdmEntityType entityType = entitySet1.getEntityType();
|
||||
if ((uriResource.getTypeFilterOnEntry() != null &&
|
||||
entityType.getName().equalsIgnoreCase(uriResource.getTypeFilterOnEntry().getName())) ||
|
||||
(uriResource.getTypeFilterOnCollection() != null &&
|
||||
entityType.getName().equalsIgnoreCase(uriResource.getTypeFilterOnCollection().getName()))) {
|
||||
entitySet = entitySet1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
entitySet = uriResource.getEntitySet();
|
||||
}
|
||||
return entitySet;
|
||||
}
|
||||
|
||||
protected EntityCollection readEntityCollection(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
if (resourcePaths.size() > 1 && resourcePaths.get(1) instanceof UriResourceNavigation) {
|
||||
@ -217,7 +241,8 @@ public abstract class TechnicalProcessor implements Processor {
|
||||
return dataProvider.readFunctionEntityCollection(uriResource.getFunction(), uriResource.getParameters(),
|
||||
uriInfo);
|
||||
} else {
|
||||
return dataProvider.readAll(((UriResourceEntitySet) resourcePaths.get(0)).getEntitySet());
|
||||
EdmEntitySet entitySet = getEntitySetBasedOnTypeCast(((UriResourceEntitySet)resourcePaths.get(0)));
|
||||
return dataProvider.readAll(entitySet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -235,10 +260,7 @@ public abstract class TechnicalProcessor implements Processor {
|
||||
}
|
||||
|
||||
private void blockTypeFilters(final UriResource uriResource) throws ODataApplicationException {
|
||||
if (uriResource instanceof UriResourceEntitySet
|
||||
&& (((UriResourceEntitySet) uriResource).getTypeFilterOnCollection() != null
|
||||
|| ((UriResourceEntitySet) uriResource).getTypeFilterOnEntry() != null)
|
||||
|| uriResource instanceof UriResourceFunction
|
||||
if (uriResource instanceof UriResourceFunction
|
||||
&& (((UriResourceFunction) uriResource).getTypeFilterOnCollection() != null
|
||||
|| ((UriResourceFunction) uriResource).getTypeFilterOnEntry() != null)
|
||||
|| uriResource instanceof UriResourceNavigation
|
||||
|
@ -49,6 +49,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.edm.geo.Point;
|
||||
import org.apache.olingo.commons.api.edm.geo.Polygon;
|
||||
import org.apache.olingo.commons.api.edm.geo.SRID;
|
||||
@ -2321,4 +2322,67 @@ public class ODataJsonSerializerTest {
|
||||
"}";
|
||||
Assert.assertEquals(expected, resultString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deriveComplexProperty() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
|
||||
EdmComplexType derivedComplexType = mockComplexType();
|
||||
final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyComp");
|
||||
final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty("PropertyComp");
|
||||
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.complex(metadata, derivedComplexType, property,
|
||||
ComplexSerializerOptions.with()
|
||||
.contextURL(ContextURL.with()
|
||||
.entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName()
|
||||
+ "/olingo.odata.test1.CTBase")
|
||||
.build())
|
||||
.build()).getContent());
|
||||
Assert.assertEquals("{\"@odata.context\":\"$metadata#ESMixPrimCollComp(32767)/"
|
||||
+ "PropertyComp/olingo.odata.test1.CTBase\","
|
||||
+ "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
|
||||
+ "\"@odata.type\":\"#olingo.odata.test1.CTBase\","
|
||||
+ "\"AdditionalPropertyString\":null,"
|
||||
+ "\"PropertyInt16\":111,"
|
||||
+ "\"PropertyString\":\"TEST A\"}",
|
||||
resultString);
|
||||
}
|
||||
|
||||
private EdmComplexType mockComplexType() {
|
||||
EdmProperty property1 = Mockito.mock(EdmProperty.class);
|
||||
final String name1 = "AdditionalPropertyString";
|
||||
Mockito.when(property1.getName()).thenReturn(name1);
|
||||
Mockito.when(property1.isNullable()).thenReturn(true);
|
||||
Mockito.when(property1.getType()).thenReturn(odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String));
|
||||
Mockito.when(property1.isPrimitive()).thenReturn(true);
|
||||
|
||||
EdmProperty property2 = Mockito.mock(EdmProperty.class);
|
||||
final String name2 = "PropertyInt16";
|
||||
Mockito.when(property2.getName()).thenReturn(name2);
|
||||
Mockito.when(property2.isNullable()).thenReturn(false);
|
||||
Mockito.when(property2.getType()).thenReturn(odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int16));
|
||||
Mockito.when(property2.isPrimitive()).thenReturn(true);
|
||||
|
||||
EdmProperty property3 = Mockito.mock(EdmProperty.class);
|
||||
final String name3 = "PropertyString";
|
||||
Mockito.when(property3.getName()).thenReturn(name3);
|
||||
Mockito.when(property3.isNullable()).thenReturn(false);
|
||||
Mockito.when(property3.getMaxLength()).thenReturn(50);
|
||||
Mockito.when(property3.getType()).thenReturn(odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String));
|
||||
Mockito.when(property3.isPrimitive()).thenReturn(true);
|
||||
|
||||
EdmComplexType complexType = Mockito.mock(EdmComplexType.class);
|
||||
Mockito.when(complexType.getPropertyNames()).thenReturn(Arrays.asList(name1, name2, name3));
|
||||
Mockito.when(complexType.getStructuralProperty(name1)).thenReturn(property1);
|
||||
Mockito.when(complexType.getStructuralProperty(name2)).thenReturn(property2);
|
||||
Mockito.when(complexType.getStructuralProperty(name3)).thenReturn(property3);
|
||||
EdmComplexType baseComplexType = metadata.getEdm().getComplexType(
|
||||
new FullQualifiedName("olingo.odata.test1.CTTwoPrim"));
|
||||
Mockito.when(complexType.getBaseType()).thenReturn(baseComplexType);
|
||||
Mockito.when(complexType.getFullQualifiedName()).thenReturn(
|
||||
new FullQualifiedName("olingo.odata.test1.CTBase"));
|
||||
Mockito.when(complexType.getName()).thenReturn("CTBase");
|
||||
Mockito.when(complexType.getNamespace()).thenReturn("olingo.odata.test1");
|
||||
return complexType;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user