diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java index 63a0d0ed9..6d1b51ba2 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java @@ -29,9 +29,12 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; +import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; @@ -83,9 +86,12 @@ import org.apache.olingo.commons.api.edm.EdmActionImport; import org.apache.olingo.commons.api.edm.EdmAnnotation; 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.EdmPrimitiveTypeException; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.EdmTerm; import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.annotation.EdmExpression; import org.apache.olingo.commons.api.ex.ODataError; import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.commons.api.http.HttpHeader; @@ -115,6 +121,8 @@ public class BasicITCase extends AbstractParamTecSvcITCase { private static final String PROPERTY_COMP_NAV = "CollPropertyCompNav"; private static final String COL_PROPERTY_COMP = "CollPropertyComp"; private static final String PROPERTY_COMP_TWO_PRIM = "PropertyCompTwoPrim"; + + private static final String SERVICE_ROOT_URL = "http://localhost:9080/odata-server-tecsvc/"; @Test public void readServiceDocument() { @@ -1603,4 +1611,57 @@ public class BasicITCase extends AbstractParamTecSvcITCase { getEntities().get(1).getTypeName().toString()); assertEquals("olingo.odata.test1.ETAllPrim", entity.getTypeName().toString()); } + + @Test + public void readViaXmlMetadataAnnotation() throws URISyntaxException, IOException { + InputStream input = Thread.currentThread().getContextClassLoader(). + getResourceAsStream("edmxWithCoreAnnotation.xml"); + final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).toMetadata(input); + String vocabUrl = metadata.getReferences().get(0).getUri().toString(); + vocabUrl = vocabUrl.substring(vocabUrl.indexOf("../") + 3); + vocabUrl = SERVICE_ROOT_URL + vocabUrl; + URI uri = new URI(vocabUrl); + input.close(); + ODataRawRequest request = getClient().getRetrieveRequestFactory().getRawRequest(uri); + assertNotNull(request); + setCookieHeader(request); + + ODataRawResponse response = request.execute(); + saveCookieHeader(response); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); + + List streams = new ArrayList(); + streams.add(response.getRawResponse()); + Edm edm = getClient().getReader().readMetadata(Thread.currentThread().getContextClassLoader(). + getResourceAsStream("edmxWithCoreAnnotation.xml"), streams); + assertNotNull(edm); + final EdmEntityType person = edm.getEntityType( + new FullQualifiedName("Microsoft.Exchange.Services.OData.Model", "Person")); + assertNotNull(person); + EdmProperty concurrency = (EdmProperty) person.getProperty("Concurrency"); + List annotations = concurrency.getAnnotations(); + for (EdmAnnotation annotation : annotations) { + annotation.getExpression(); + EdmTerm term = annotation.getTerm(); + assertNotNull(term); + assertEquals("Computed", term.getName()); + assertEquals("Org.OData.Core.V1.Computed", + term.getFullQualifiedName().getFullQualifiedNameAsString()); + assertEquals(1, term.getAnnotations().size()); + } + EdmProperty userName = (EdmProperty) person.getProperty("UserName"); + List userNameAnnotations = userName.getAnnotations(); + for (EdmAnnotation annotation : userNameAnnotations) { + EdmTerm term = annotation.getTerm(); + assertNotNull(term); + assertEquals("Permissions", term.getName()); + assertEquals("Org.OData.Core.V1.Permissions", + term.getFullQualifiedName().getFullQualifiedNameAsString()); + EdmExpression expression = annotation.getExpression(); + assertNotNull(expression); + assertTrue(expression.isConstant()); + assertEquals("Org.OData.Core.V1.Permission/Read", expression.asConstant().getValueAsString()); + assertEquals("EnumMember", expression.getExpressionName()); + } + } } diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicHttpITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicHttpITCase.java index 55a04f528..7e4b9b090 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicHttpITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicHttpITCase.java @@ -181,5 +181,30 @@ public class BasicHttpITCase extends AbstractBaseTestITCase { protected ODataClient getClient() { return null; } + + @Test + public void testInvalidTopUrl() throws Exception { + URL url = new URL(SERVICE_URI + "?$top"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.connect(); + + assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode()); + assertTrue(IOUtils.toString(connection.getErrorStream()). + contains("The system query option '$top' has the not-allowed value ''.")); + } + + @Test + public void testInvalidSkipUrl() throws Exception { + URL url = new URL(SERVICE_URI + "?$skip="); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.connect(); + + assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode()); + assertTrue(IOUtils.toString(connection.getErrorStream()). + contains("The system query option '$skip' has the not-allowed value ''.")); + } } diff --git a/fit/src/test/resources/edmxWithCoreAnnotation.xml b/fit/src/test/resources/edmxWithCoreAnnotation.xml new file mode 100644 index 000000000..e10fcf8d6 --- /dev/null +++ b/fit/src/test/resources/edmxWithCoreAnnotation.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + Org.OData.Core.V1.Permission/Read + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ClientODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ClientODataDeserializer.java index ba1868376..47935b13f 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ClientODataDeserializer.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ClientODataDeserializer.java @@ -19,15 +19,19 @@ package org.apache.olingo.client.api.serialization; import java.io.InputStream; +import java.util.List; import org.apache.olingo.client.api.data.ResWrap; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.edm.xml.XMLMetadata; import org.apache.olingo.commons.api.data.Delta; +import org.apache.olingo.commons.api.edm.provider.CsdlSchema; public interface ClientODataDeserializer extends ODataDeserializer { XMLMetadata toMetadata(InputStream input); + + List fetchTermDefinitionSchema(List input); /** * Gets the ServiceDocument object represented by the given InputStream. diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataReader.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataReader.java index a374adbc0..43f46e5d4 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataReader.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataReader.java @@ -19,6 +19,7 @@ package org.apache.olingo.client.api.serialization; import java.io.InputStream; +import java.util.List; import java.util.Map; import org.apache.olingo.client.api.data.ResWrap; @@ -47,6 +48,15 @@ public interface ODataReader { * @return metadata representation. */ Edm readMetadata(InputStream input); + + /** + * Parses a stream into metadata representation. + * Also parses a term definition stream into Term representation. + * @param input + * @param termDefinitions + * @return + */ + Edm readMetadata(InputStream input, List termDefinitions); /** * Parses a stream into metadata representation, including referenced metadata documents. @@ -56,6 +66,8 @@ public interface ODataReader { * @return metadata representation. */ Edm readMetadata(Map xmlSchemas); + + Edm readMetadata(Map xmlSchemas, List termDefinitionSchema); /** * Parses an OData service document. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ClientODataDeserializerImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ClientODataDeserializerImpl.java index ec361ab81..ca3d88a83 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ClientODataDeserializerImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ClientODataDeserializerImpl.java @@ -20,6 +20,8 @@ package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; import javax.xml.stream.XMLStreamException; @@ -38,6 +40,7 @@ import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import org.apache.olingo.commons.api.edm.provider.CsdlSchema; import org.apache.olingo.commons.api.ex.ODataError; import org.apache.olingo.commons.api.format.ContentType; @@ -117,6 +120,20 @@ public class ClientODataDeserializerImpl implements ClientODataDeserializer { throw new IllegalArgumentException("Could not parse as Edmx document", e); } } + + @Override + public List fetchTermDefinitionSchema(final List input) { + List schemas = new ArrayList(); + try { + for (InputStream stream : input) { + ClientCsdlEdmx edmx = getXmlMapper().readValue(stream, ClientCsdlEdmx.class); + schemas.addAll(edmx.getDataServices().getSchemas()); + } + return schemas; + } catch (Exception e) { + throw new IllegalArgumentException("Could not parse as Term definition", e); + } + } @Override public ResWrap toServiceDocument(final InputStream input) throws ODataDeserializerException { diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java index 6b8c956ce..c72ce6ab2 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java @@ -20,6 +20,7 @@ package org.apache.olingo.client.core.serialization; import java.io.InputStream; import java.net.URI; +import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; @@ -66,12 +67,24 @@ public class ODataReaderImpl implements ODataReader { return readMetadata(client.getDeserializer(ContentType.APPLICATION_XML).toMetadata(input).getSchemaByNsOrAlias()); } + @Override + public Edm readMetadata(final InputStream input, List termDefinition) { + return readMetadata(client.getDeserializer(ContentType.APPLICATION_XML).toMetadata(input).getSchemaByNsOrAlias(), + client.getDeserializer(ContentType.APPLICATION_XML).fetchTermDefinitionSchema(termDefinition)); + } + @Override public Edm readMetadata(final Map xmlSchemas) { ClientCsdlEdmProvider prov = new ClientCsdlEdmProvider(xmlSchemas); return new EdmProviderImpl(prov); } + @Override + public Edm readMetadata(final Map xmlSchemas, List termDefinitionSchema) { + ClientCsdlEdmProvider prov = new ClientCsdlEdmProvider(xmlSchemas); + return new EdmProviderImpl(prov, termDefinitionSchema); + } + @Override public ClientServiceDocument readServiceDocument(final InputStream input, final ContentType contentType) throws ODataDeserializerException { diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java index c150e6482..181335b80 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.InputStream; +import java.util.ArrayList; import java.util.List; import org.apache.olingo.client.api.edm.xml.XMLMetadata; @@ -40,9 +41,12 @@ import org.apache.olingo.commons.api.edm.EdmEnumType; import org.apache.olingo.commons.api.edm.EdmFunction; import org.apache.olingo.commons.api.edm.EdmFunctionImport; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.EdmSchema; +import org.apache.olingo.commons.api.edm.EdmTerm; import org.apache.olingo.commons.api.edm.EdmTypeDefinition; import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.annotation.EdmExpression; import org.apache.olingo.commons.api.edm.annotation.EdmUrlRef; import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation; @@ -414,4 +418,41 @@ public class MetadataTest extends AbstractTest { assertNotNull(deleteRestrictions); assertEquals("Capabilities.DeleteRestrictionsType", deleteRestrictions.getType()); } + + @Test + public void readPropertyAnnotations() { + List streams = new ArrayList(); + streams.add(getClass().getResourceAsStream("VOC_Core.xml")); + final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("edmxWithCoreAnnotation.xml"), + streams); + assertNotNull(edm); + + final EdmEntityType person = edm.getEntityType( + new FullQualifiedName("Microsoft.Exchange.Services.OData.Model", "Person")); + assertNotNull(person); + EdmProperty concurrency = (EdmProperty) person.getProperty("Concurrency"); + List annotations = concurrency.getAnnotations(); + for (EdmAnnotation annotation : annotations) { + EdmTerm term = annotation.getTerm(); + assertNotNull(term); + assertEquals("Computed", term.getName()); + assertEquals("Org.OData.Core.V1.Computed", + term.getFullQualifiedName().getFullQualifiedNameAsString()); + assertEquals(1, term.getAnnotations().size()); + } + EdmProperty userName = (EdmProperty) person.getProperty("UserName"); + List userNameAnnotations = userName.getAnnotations(); + for (EdmAnnotation annotation : userNameAnnotations) { + EdmTerm term = annotation.getTerm(); + assertNotNull(term); + assertEquals("Permissions", term.getName()); + assertEquals("Org.OData.Core.V1.Permissions", + term.getFullQualifiedName().getFullQualifiedNameAsString()); + EdmExpression expression = annotation.getExpression(); + assertNotNull(expression); + assertTrue(expression.isConstant()); + assertEquals("Org.OData.Core.V1.Permission/Read", expression.asConstant().getValueAsString()); + assertEquals("EnumMember", expression.getExpressionName()); + } + } } diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/VOC_Core.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/VOC_Core.xml new file mode 100644 index 000000000..4e30cadbf --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/VOC_Core.xml @@ -0,0 +1,125 @@ + + + + + + + Core terms needed to write vocabularies + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/edmxWithCoreAnnotation.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/edmxWithCoreAnnotation.xml new file mode 100644 index 000000000..8dfa97436 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/edmxWithCoreAnnotation.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + Org.OData.Core.V1.Permission/Read + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java index 53c69f4e6..362bae71c 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java @@ -59,10 +59,16 @@ public class EdmProviderImpl extends AbstractEdm { Collections.synchronizedMap(new HashMap>()); private final Map> functionsMap = Collections.synchronizedMap(new HashMap>()); + private List termSchemaDefinition = null; public EdmProviderImpl(final CsdlEdmProvider provider) { this.provider = provider; } + + public EdmProviderImpl(final CsdlEdmProvider provider, final List termSchemaDefinition) { + this.provider = provider; + this.termSchemaDefinition = termSchemaDefinition; + } @Override public EdmEntityContainer createEntityContainer(final FullQualifiedName containerName) { @@ -334,6 +340,17 @@ public class EdmProviderImpl extends AbstractEdm { CsdlTerm providerTerm = provider.getTerm(termName); if (providerTerm != null) { return new EdmTermImpl(this, termName.getNamespace(), providerTerm); + } else if (termSchemaDefinition != null && termSchemaDefinition.size() > 0) { + for (CsdlSchema schema : termSchemaDefinition) { + if (schema.getNamespace().equalsIgnoreCase(termName.getNamespace())) { + List terms = schema.getTerms(); + for (CsdlTerm term : terms) { + if (term.getName().equals(termName.getName())) { + return new EdmTermImpl(this, termName.getNamespace(), term); + } + } + } + } } return null; } catch (ODataException e) { diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java index d1a9cf24f..6d8ed1b84 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java @@ -211,7 +211,10 @@ public class ODataHandlerImpl implements ODataHandler { if(endIndex == -1) { endIndex = query.length(); } - final String format = query.substring(index + formatOption.length(), endIndex); + String format = ""; + if (index + formatOption.length() < endIndex) { + format = query.substring(index + formatOption.length(), endIndex); + } return new FormatOptionImpl().setFormat(format); } return uriInfo.getFormatOption(); diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java index 0ce8c7558..edbb36951 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java @@ -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,17 @@ 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(); } } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java index f97b7eb7c..a7aff9552 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java @@ -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(); + if (resourceParts.get(resourceParts.size() - trailing - 1) + instanceof UriResourceComplexProperty && + ((UriResourceComplexProperty)resourceParts.get(resourceParts.size() - trailing - 1)). + getComplexTypeFilter() != null) { + EdmType type1 = ((UriResourceComplexProperty)resourceParts.get(resourceParts.size() - trailing - 1)). + getComplexTypeFilter(); + property.setType(type1.getFullQualifiedName().getFullQualifiedNameAsString()); + } final EdmType type = edmProperty == null ? - ((UriResourceFunction) resourceParts.get(0)).getType() : - edmProperty.getType(); + ((UriResourceFunction) resourceParts.get(0)).getType() : + edmProperty.getType(); + final EdmReturnType returnType = resourceParts.get(0) instanceof UriResourceFunction ? ((UriResourceFunction) resourceParts.get(0)).getFunction().getReturnType() : null; 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 fc6991f37..9220db9e6 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 @@ -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; @@ -75,11 +76,36 @@ public abstract class TechnicalProcessor implements Processor { EdmEntitySet entitySet = null; final List resourcePaths = uriInfo.getUriResourceParts(); EdmSingleton singleton = null; - // First must be an entity, an entity collection, a function import, or an action import. - blockTypeFilters(resourcePaths.get(0)); + //blockTypeFilters(resourcePaths.get(0)); if (resourcePaths.get(0) instanceof UriResourceEntitySet) { - entitySet = ((UriResourceEntitySet) resourcePaths.get(0)).getEntitySet(); + entitySet = getEntitySetBasedOnTypeCast(((UriResourceEntitySet)resourcePaths.get(0))); + //entitySet = ((UriResourceEntitySet) resourcePaths.get(0)).getEntitySet(); + } else if (resourcePaths.get(0) instanceof UriResourceFunction) { + entitySet = ((UriResourceFunction) resourcePaths.get(0)).getFunctionImport().getReturnedEntitySet(); + } else if (resourcePaths.get(0) instanceof UriResourceAction) { + entitySet = ((UriResourceAction) resourcePaths.get(0)).getActionImport().getReturnedEntitySet(); + }else if (resourcePaths.get(0) instanceof UriResourceSingleton ) { + singleton =((UriResourceSingleton) resourcePaths.get(0)).getSingleton(); + } else { + throw new ODataApplicationException("Invalid resource type.", + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + + entitySet = (EdmEntitySet) getEntitySetForNavigation(entitySet, singleton, resourcePaths); + + return entitySet; + } + + protected EdmEntitySet getEdmEntitySetTypeCast(final UriInfoResource uriInfo) throws ODataApplicationException { + EdmEntitySet entitySet = null; + final List resourcePaths = uriInfo.getUriResourceParts(); + EdmSingleton singleton = null; + // 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 = getEntitySetBasedOnTypeCast(((UriResourceEntitySet)resourcePaths.get(0))); + //entitySet = ((UriResourceEntitySet) resourcePaths.get(0)).getEntitySet(); } else if (resourcePaths.get(0) instanceof UriResourceFunction) { entitySet = ((UriResourceFunction) resourcePaths.get(0)).getFunctionImport().getReturnedEntitySet(); } else if (resourcePaths.get(0) instanceof UriResourceAction) { @@ -100,24 +126,24 @@ public abstract class TechnicalProcessor implements Processor { List resourcePaths) throws ODataApplicationException { int navigationCount = 0; while ((entitySet != null || singleton!=null) - && ++navigationCount < resourcePaths.size() + && ++navigationCount < resourcePaths.size() && resourcePaths.get(navigationCount) instanceof UriResourceNavigation) { - final UriResourceNavigation uriResourceNavigation = - (UriResourceNavigation) resourcePaths.get(navigationCount); - blockTypeFilters(uriResourceNavigation); - if (uriResourceNavigation.getProperty().containsTarget()) { - throw new ODataApplicationException("Containment navigation is not supported.", - HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); - } - EdmBindingTarget target = null ; - if(entitySet!=null){ - target = entitySet.getRelatedBindingTarget(uriResourceNavigation.getProperty().getName()); - }else if(singleton != null){ - target = singleton.getRelatedBindingTarget(uriResourceNavigation.getProperty().getName()); - } - if (target instanceof EdmEntitySet) { - entitySet = (EdmEntitySet) target; - } + final UriResourceNavigation uriResourceNavigation = + (UriResourceNavigation) resourcePaths.get(navigationCount); + blockTypeFilters(uriResourceNavigation); + if (uriResourceNavigation.getProperty().containsTarget()) { + throw new ODataApplicationException("Containment navigation is not supported.", + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + EdmBindingTarget target = null ; + if(entitySet!=null){ + target = entitySet.getRelatedBindingTarget(uriResourceNavigation.getProperty().getName()); + }else if(singleton != null){ + target = singleton.getRelatedBindingTarget(uriResourceNavigation.getProperty().getName()); + } + if (target instanceof EdmEntitySet) { + entitySet = (EdmEntitySet) target; + } } return entitySet; } @@ -139,11 +165,10 @@ public abstract class TechnicalProcessor implements Processor { protected Entity readEntity(final UriInfoResource uriInfo, final boolean ignoreLastNavigation) throws ODataApplicationException { final List resourcePaths = uriInfo.getUriResourceParts(); - 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(((UriResourceEntitySet)resourcePaths.get(0))); + entity = dataProvider.read(entitySet, ((UriResourceEntitySet)resourcePaths.get(0)).getKeyPredicates()); }else if (resourcePaths.get(0) instanceof UriResourceSingleton) { final UriResourceSingleton uriResource = (UriResourceSingleton) resourcePaths.get(0); entity = dataProvider.read( uriResource.getSingleton()); @@ -205,6 +230,27 @@ 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 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 resourcePaths = uriInfo.getUriResourceParts(); if (resourcePaths.size() > 1 && resourcePaths.get(1) instanceof UriResourceNavigation) { @@ -217,7 +263,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); } } }