[OLINGO-1062]Cannot consume Term defined in external Vocabulary

This commit is contained in:
ramya vasanth 2017-06-21 10:59:27 +05:30
parent aea44a33a0
commit ce4bc57a84
15 changed files with 509 additions and 30 deletions

View File

@ -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;
@ -116,6 +122,8 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
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() {
ODataServiceDocumentRequest request = getClient().getRetrieveRequestFactory()
@ -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<InputStream> streams = new ArrayList<InputStream>();
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<EdmAnnotation> 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<EdmAnnotation> 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());
}
}
}

View File

@ -182,4 +182,29 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
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 ''."));
}
}

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:Reference Uri="../v4.0/cs02/vocabularies/Org.OData.Core.V1.xml"/>
<edmx:DataServices m:DataServiceVersion="4.0" m:MaxDataServiceVersion="4.0" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata">
<Schema Namespace="Microsoft.Exchange.Services.OData.Model" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Person" OpenType="true">
<Key>
<PropertyRef Name="UserName"/>
</Key>
<Property Name="UserName" Type="Edm.String" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Permissions">
<EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
</Annotation>
</Property>
<Property Name="FirstName" Type="Edm.String" Nullable="false"/>
<Property Name="LastName" Type="Edm.String" Nullable="false"/>
<Property Name="Emails" Type="Collection(Edm.String)"/>
<Property Name="AddressInfo" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Location)"/>
<Property Name="Gender" Type="Microsoft.OData.SampleService.Models.TripPin.PersonGender"/>
<Property Name="Concurrency" Type="Edm.Int64" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Property>
</EntityType>
<EntityContainer Name="EntityContainer" m:IsDefaultEntityContainer="true">
<EntitySet Name="People" EntityType="Microsoft.Exchange.Services.OData.Model.Person"/>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>

View File

@ -19,16 +19,20 @@
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<CsdlSchema> fetchTermDefinitionSchema(List<InputStream> input);
/**
* Gets the ServiceDocument object represented by the given InputStream.
*

View File

@ -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;
@ -48,6 +49,15 @@ public interface ODataReader {
*/
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<InputStream> termDefinitions);
/**
* Parses a stream into metadata representation, including referenced metadata documents.
*
@ -57,6 +67,8 @@ public interface ODataReader {
*/
Edm readMetadata(Map<String, CsdlSchema> xmlSchemas);
Edm readMetadata(Map<String, CsdlSchema> xmlSchemas, List<CsdlSchema> termDefinitionSchema);
/**
* Parses an OData service document.
*

View File

@ -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;
@ -118,6 +121,20 @@ public class ClientODataDeserializerImpl implements ClientODataDeserializer {
}
}
@Override
public List<CsdlSchema> fetchTermDefinitionSchema(final List<InputStream> input) {
List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
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<ServiceDocument> toServiceDocument(final InputStream input) throws ODataDeserializerException {
return contentType.isCompatible(ContentType.APPLICATION_XML) ?

View File

@ -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<InputStream> termDefinition) {
return readMetadata(client.getDeserializer(ContentType.APPLICATION_XML).toMetadata(input).getSchemaByNsOrAlias(),
client.getDeserializer(ContentType.APPLICATION_XML).fetchTermDefinitionSchema(termDefinition));
}
@Override
public Edm readMetadata(final Map<String, CsdlSchema> xmlSchemas) {
ClientCsdlEdmProvider prov = new ClientCsdlEdmProvider(xmlSchemas);
return new EdmProviderImpl(prov);
}
@Override
public Edm readMetadata(final Map<String, CsdlSchema> xmlSchemas, List<CsdlSchema> termDefinitionSchema) {
ClientCsdlEdmProvider prov = new ClientCsdlEdmProvider(xmlSchemas);
return new EdmProviderImpl(prov, termDefinitionSchema);
}
@Override
public ClientServiceDocument readServiceDocument(final InputStream input, final ContentType contentType)
throws ODataDeserializerException {

View File

@ -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<InputStream> streams = new ArrayList<InputStream>();
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<EdmAnnotation> 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<EdmAnnotation> 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());
}
}
}

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Org.OData.Core.V1" Alias="Core">
<Annotation Term="Core.Description">
<String>Core terms needed to write vocabularies</String>
</Annotation>
<!--Documentation -->
<Term Name="Description" Type="Edm.String">
<Annotation Term="Core.Description" String="A brief description of a model element" />
<Annotation Term="Core.IsLanguageDependent" />
</Term>
<Term Name="LongDescription" Type="Edm.String">
<Annotation Term="Core.Description" String="A lengthy description of a model element" />
<Annotation Term="Core.IsLanguageDependent" />
</Term>
<!-- Localization -->
<Term Name="IsLanguageDependent" Type="Core.Tag" DefaultValue="true" AppliesTo="Property Term">
<Annotation Term="Core.Description" String="Properties and terms annotated with this term are language-dependent" />
<Annotation Term="Core.RequiresType" String="Edm.String" />
</Term>
<!-- Term Restrictions -->
<TypeDefinition Name="Tag" UnderlyingType="Edm.Boolean">
<Annotation Term="Core.Description" String="This is the type to use for all tagging terms" />
</TypeDefinition>
<Term Name="RequiresType" Type="Edm.String" AppliesTo="Term">
<Annotation Term="Core.Description"
String="Properties and terms annotated with this annotation MUST have a type that is identical to or derived from the given type name" />
</Term>
<!--Resource Paths -->
<Term Name="ResourcePath" Type="Edm.String" AppliesTo="EntitySet Singleton ActionImport FunctionImport">
<Annotation Term="Core.Description"
String="Resource path for entity container child, can be relative to xml:base and the request URL" />
<Annotation Term="Core.IsUrl" />
</Term>
<Term Name="DereferenceableIDs" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
<Annotation Term="Core.Description" String="Entity-ids are URLs that locate the identified entity" />
</Term>
<Term Name="ConventionalIDs" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
<Annotation Term="Core.Description" String="Entity-ids follow OData URL conventions" />
</Term>
<!-- Permissions -->
<Term Name="Permissions" Type="Core.Permission" AppliesTo="Property">
<Annotation Term="Core.Description" String="Permissions available for a property.The value of 2 is reserved for future use." />
</Term>
<EnumType Name="Permission" IsFlags="true">
<Member Name="None" Value="0" />
<Member Name="Read" Value="1" />
<Member Name="ReadWrite" Value="3" />
</EnumType>
<!-- Metadata Extensions -->
<Term Name="Immutable" Type="Core.Tag" DefaultValue="true" AppliesTo="Property">
<Annotation Term="Core.Description"
String="A value for this non-key property can be provided on insert and remains unchanged on update" />
</Term>
<Term Name="Computed" Type="Core.Tag" DefaultValue="true" AppliesTo="Property">
<Annotation Term="Core.Description" String="A value for this property is generated on both insert and update" />
</Term>
<Term Name="IsUrl" Type="Core.Tag" DefaultValue="true" AppliesTo="Property Term">
<Annotation Term="Core.Description" String="Properties and terms annotated with this term MUST contain a valid URL" />
<Annotation Term="Core.RequiresType" String="Edm.String" />
</Term>
<Term Name="AcceptableMediaTypes" Type="Collection(Edm.String)" AppliesTo="EntityType Property">
<Annotation Term="Core.Description"
String="Lists the MIME types acceptable for the annotated entity type marked with HasStream=&quot;true&quot; or the annotated stream property" />
<Annotation Term="Core.IsMediaType" />
</Term>
<Term Name="MediaType" Type="Edm.String" AppliesTo="Property">
<Annotation Term="Core.IsMediaType" />
<Annotation Term="Core.RequiresType" String="Edm.Binary" />
</Term>
<Term Name="IsMediaType" Type="Core.Tag" DefaultValue="true" AppliesTo="Property Term">
<Annotation Term="Core.Description" String="Properties and terms annotated with this term MUST contain a valid MIME type" />
<Annotation Term="Core.RequiresType" String="Edm.String" />
</Term>
<Term Name="OptimisticConcurrency" Type="Collection(Edm.PropertyPath)" AppliesTo="EntitySet">
<Annotation Term="Core.Description"
String="Data modification requires the use of Etags. A non-empty collection contains the set of properties that are used to compute the ETag" />
</Term>
</Schema>
</edmx:DataServices>
</edmx:Edmx>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices m:DataServiceVersion="4.0" m:MaxDataServiceVersion="4.0" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata">
<Schema Namespace="Microsoft.Exchange.Services.OData.Model" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Person" OpenType="true">
<Key>
<PropertyRef Name="UserName"/>
</Key>
<Property Name="UserName" Type="Edm.String" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Permissions">
<EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
</Annotation>
</Property>
<Property Name="FirstName" Type="Edm.String" Nullable="false"/>
<Property Name="LastName" Type="Edm.String" Nullable="false"/>
<Property Name="Emails" Type="Collection(Edm.String)"/>
<Property Name="AddressInfo" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Location)"/>
<Property Name="Gender" Type="Microsoft.OData.SampleService.Models.TripPin.PersonGender"/>
<Property Name="Concurrency" Type="Edm.Int64" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Property>
</EntityType>
<EntityContainer Name="EntityContainer" m:IsDefaultEntityContainer="true">
<EntitySet Name="People" EntityType="Microsoft.Exchange.Services.OData.Model.Person"/>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>

View File

@ -59,11 +59,17 @@ public class EdmProviderImpl extends AbstractEdm {
Collections.synchronizedMap(new HashMap<FullQualifiedName, List<CsdlAction>>());
private final Map<FullQualifiedName, List<CsdlFunction>> functionsMap =
Collections.synchronizedMap(new HashMap<FullQualifiedName, List<CsdlFunction>>());
private List<CsdlSchema> termSchemaDefinition = null;
public EdmProviderImpl(final CsdlEdmProvider provider) {
this.provider = provider;
}
public EdmProviderImpl(final CsdlEdmProvider provider, final List<CsdlSchema> termSchemaDefinition) {
this.provider = provider;
this.termSchemaDefinition = termSchemaDefinition;
}
@Override
public EdmEntityContainer createEntityContainer(final FullQualifiedName containerName) {
try {
@ -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<CsdlTerm> 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) {

View File

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

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

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

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;
@ -75,11 +76,36 @@ public abstract class TechnicalProcessor implements Processor {
EdmEntitySet entitySet = null;
final List<UriResource> 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<UriResource> 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) {
@ -102,22 +128,22 @@ public abstract class TechnicalProcessor implements Processor {
while ((entitySet != null || singleton!=null)
&& ++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<UriResource> 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<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 +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);
}
}
}