This commit is contained in:
Archana Rai 2017-06-22 16:31:02 +05:30
commit 7dedb25c3a
7 changed files with 245 additions and 20 deletions

View File

@ -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\""));
}
}

View File

@ -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 =

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}
}