[OLINGO-175, OLINGO-205] provided (v4) context url and entity reference retrieving + it tests
This commit is contained in:
parent
f0edb50813
commit
428277c26d
|
@ -54,6 +54,7 @@ import javax.ws.rs.Produces;
|
|||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.fit.utils.Constants;
|
||||
|
@ -144,6 +145,40 @@ public abstract class AbstractServices {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve entity reference sample.
|
||||
*
|
||||
* @param accept Accept header.
|
||||
* @param path path.
|
||||
* @param format format query option.
|
||||
* @return entity reference or feed of entity reference.
|
||||
*/
|
||||
@GET
|
||||
@Path("/{path:.*}/$ref")
|
||||
public Response getEntityReference(
|
||||
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
|
||||
@PathParam("path") String path,
|
||||
@QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) {
|
||||
|
||||
try {
|
||||
final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
|
||||
|
||||
if (utils.getKey() == Accept.TEXT) {
|
||||
throw new UnsupportedMediaTypeException("Unsupported media type");
|
||||
}
|
||||
|
||||
final String filename = Base64.encodeBase64String(path.getBytes("UTF-8"));
|
||||
|
||||
return utils.getValue().createResponse(
|
||||
FSManager.instance(getVersion()).readFile(Constants.REF + File.separatorChar + filename, utils.getKey()),
|
||||
null,
|
||||
utils.getKey());
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error retrieving entity", e);
|
||||
return xml.createFaultResponse(accept, e);
|
||||
}
|
||||
}
|
||||
|
||||
@MERGE
|
||||
@Path("/{entitySetName}/{entityId}")
|
||||
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
|
||||
|
@ -386,7 +421,7 @@ public abstract class AbstractServices {
|
|||
} else if (StringUtils.isNotBlank(skiptoken)) {
|
||||
builder.append(SKIP_TOKEN).append(File.separatorChar).append(skiptoken);
|
||||
} else {
|
||||
builder.append(FEED);
|
||||
builder.append(Commons.getLinkInfo().get(getVersion()).isSingleton(name) ? ENTITY : FEED);
|
||||
}
|
||||
|
||||
InputStream feed = FSManager.instance(getVersion()).readFile(builder.toString(), acceptType);
|
||||
|
|
|
@ -1208,11 +1208,21 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
|
|||
writer.add(eventFactory.createStartDocument("UTF-8", "1.0"));
|
||||
writer.add(property.getStart());
|
||||
|
||||
if (property.getStart().getAttributeByName(new QName(ATOM_DATASERVICE_NS)) == null) {
|
||||
writer.add(eventFactory.createNamespace(ATOM_PROPERTY_PREFIX.substring(0, 1), DATASERVICES_NS));
|
||||
}
|
||||
if (property.getStart().getAttributeByName(new QName(ATOM_METADATA_NS)) == null) {
|
||||
writer.add(eventFactory.createNamespace(ATOM_METADATA_PREFIX.substring(0, 1), METADATA_NS));
|
||||
if (version == ODataVersion.v4) {
|
||||
|
||||
if (property.getStart().getAttributeByName(new QName(ATOM_DATASERVICE_NS)) == null) {
|
||||
writer.add(eventFactory.createNamespace(ATOM_PROPERTY_PREFIX.substring(0, 1), V4_DATASERVICES_NS));
|
||||
}
|
||||
if (property.getStart().getAttributeByName(new QName(ATOM_METADATA_NS)) == null) {
|
||||
writer.add(eventFactory.createNamespace(ATOM_METADATA_PREFIX.substring(0, 1), V4_METADATA_NS));
|
||||
}
|
||||
} else {
|
||||
if (property.getStart().getAttributeByName(new QName(ATOM_DATASERVICE_NS)) == null) {
|
||||
writer.add(eventFactory.createNamespace(ATOM_PROPERTY_PREFIX.substring(0, 1), V3_DATASERVICES_NS));
|
||||
}
|
||||
if (property.getStart().getAttributeByName(new QName(ATOM_METADATA_NS)) == null) {
|
||||
writer.add(eventFactory.createNamespace(ATOM_METADATA_PREFIX.substring(0, 1), V3_METADATA_NS));
|
||||
}
|
||||
}
|
||||
|
||||
writer.add(property.getContentReader());
|
||||
|
|
|
@ -41,6 +41,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -79,11 +80,14 @@ public abstract class Commons {
|
|||
}
|
||||
|
||||
public static String getEntityURI(final String entitySetName, final String entityKey) {
|
||||
return entitySetName + "(" + entityKey + ")";
|
||||
// expected singleton in case of null key
|
||||
return entitySetName + (StringUtils.isNotBlank(entityKey) ? "(" + entityKey + ")" : "");
|
||||
}
|
||||
|
||||
public static String getEntityBasePath(final String entitySetName, final String entityKey) {
|
||||
return entitySetName + File.separatorChar + getEntityKey(entityKey) + File.separatorChar;
|
||||
// expected singleton in case of null key
|
||||
return entitySetName + File.separatorChar
|
||||
+ (StringUtils.isNotBlank(entityKey) ? getEntityKey(entityKey) + File.separatorChar : "");
|
||||
}
|
||||
|
||||
public static String getLinksURI(
|
||||
|
@ -266,8 +270,18 @@ public abstract class Commons {
|
|||
public static Map.Entry<String, String> parseEntityURI(final String uri) {
|
||||
final String relPath = uri.substring(uri.lastIndexOf("/"));
|
||||
final int branchIndex = relPath.indexOf('(');
|
||||
final String es = relPath.substring(0, branchIndex);
|
||||
final String eid = relPath.substring(branchIndex + 1, relPath.indexOf(')'));
|
||||
|
||||
final String es;
|
||||
final String eid;
|
||||
|
||||
if (branchIndex > -1) {
|
||||
es = relPath.substring(0, branchIndex);
|
||||
eid = relPath.substring(branchIndex + 1, relPath.indexOf(')'));
|
||||
} else {
|
||||
es = relPath;
|
||||
eid = null;
|
||||
}
|
||||
|
||||
return new SimpleEntry<String, String>(es, eid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,9 +60,13 @@ public class Constants {
|
|||
|
||||
public final static String LINK = "link";
|
||||
|
||||
public final static String DATASERVICES_NS = "http://schemas.microsoft.com/ado/2007/08/dataservices";
|
||||
public final static String V3_DATASERVICES_NS = "http://schemas.microsoft.com/ado/2007/08/dataservices";
|
||||
|
||||
public final static String METADATA_NS = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
|
||||
public final static String V4_DATASERVICES_NS = "http://docs.oasis-open.org/odata/ns/dataservices";
|
||||
|
||||
public final static String V3_METADATA_NS = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
|
||||
|
||||
public final static String V4_METADATA_NS = "http://docs.oasis-open.org/odata/ns/metadata";
|
||||
|
||||
public final static String METADATA = "metadata";
|
||||
|
||||
|
@ -72,6 +76,8 @@ public class Constants {
|
|||
|
||||
public final static String ENTITY = "entity";
|
||||
|
||||
public final static String REF = "references";
|
||||
|
||||
public final static String MEDIA_CONTENT_FILENAME = "$value.bin";
|
||||
|
||||
public final static String SKIP_TOKEN = "skiptoken";
|
||||
|
|
|
@ -28,6 +28,14 @@ public class MetadataLinkInfo {
|
|||
|
||||
private Map<String, EntitySet> entitySets = new HashMap<String, EntitySet>();
|
||||
|
||||
public void setSingleton(final String entitySetName) {
|
||||
entitySets.get(entitySetName).setSingleton(true);
|
||||
}
|
||||
|
||||
public boolean isSingleton(final String entitySetName) {
|
||||
return entitySets.get(entitySetName).isSingleton();
|
||||
}
|
||||
|
||||
public Set<String> getEntitySets() {
|
||||
return entitySets.keySet();
|
||||
}
|
||||
|
@ -92,6 +100,8 @@ public class MetadataLinkInfo {
|
|||
|
||||
private Set<NavigationLink> links;
|
||||
|
||||
private boolean singleton;
|
||||
|
||||
public EntitySet(final String name) {
|
||||
this.name = name;
|
||||
links = new HashSet<NavigationLink>();
|
||||
|
@ -135,6 +145,18 @@ public class MetadataLinkInfo {
|
|||
this.links = links;
|
||||
}
|
||||
|
||||
public EntitySet(boolean singleton) {
|
||||
this.singleton = singleton;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public void setSingleton(boolean singleton) {
|
||||
this.singleton = singleton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + ": " + links;
|
||||
|
|
|
@ -138,5 +138,9 @@ public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtiliti
|
|||
if (size == 0) {
|
||||
metadataLinkInfo.addEntitySet(entitySetName);
|
||||
}
|
||||
|
||||
if (singletons.contains(entitySetName)) {
|
||||
metadataLinkInfo.setSingleton(entitySetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Company",
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Company",
|
||||
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company",
|
||||
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company",
|
||||
"CompanyID": 0,
|
||||
"CompanyCategory@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.CompanyCategory",
|
||||
"CompanyCategory": "IT",
|
||||
"Revenue@odata.type": "#Int64",
|
||||
"Revenue": 100000,
|
||||
"Name": "MS",
|
||||
"Address":
|
||||
{
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.CompanyAddress",
|
||||
"Street": "1 Microsoft Way",
|
||||
"City": "Redmond",
|
||||
"PostalCode": "98052",
|
||||
"CompanyName": "Microsoft"
|
||||
},
|
||||
"Employees@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Employees/$ref",
|
||||
"Employees@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Employees",
|
||||
"VipCustomer@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/VipCustomer/$ref",
|
||||
"VipCustomer@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/VipCustomer",
|
||||
"Departments@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Departments/$ref",
|
||||
"Departments@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Departments",
|
||||
"CoreDepartment@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/CoreDepartment/$ref",
|
||||
"CoreDepartment@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/CoreDepartment",
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue":
|
||||
{
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue",
|
||||
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue"
|
||||
},
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount":
|
||||
{
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount",
|
||||
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount"
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
||||
-->
|
||||
<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Company">
|
||||
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company</id>
|
||||
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Company" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
|
||||
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Employees" type="application/atom+xml;type=feed" title="Employees" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Employees" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/VipCustomer" type="application/atom+xml;type=entry" title="VipCustomer" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/VipCustomer" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Departments" type="application/atom+xml;type=feed" title="Departments" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/Departments" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/CoreDepartment" type="application/atom+xml;type=entry" title="CoreDepartment" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company/CoreDepartment" />
|
||||
<title />
|
||||
<updated>2014-03-24T17:09:31Z</updated>
|
||||
<author>
|
||||
<name />
|
||||
</author>
|
||||
<content type="application/xml">
|
||||
<m:properties>
|
||||
<d:CompanyID m:type="Int32">0</d:CompanyID>
|
||||
<d:CompanyCategory m:type="#Microsoft.Test.OData.Services.ODataWCFService.CompanyCategory">IT</d:CompanyCategory>
|
||||
<d:Revenue m:type="Int64">100000</d:Revenue>
|
||||
<d:Name>MS</d:Name>
|
||||
<d:Address m:type="#Microsoft.Test.OData.Services.ODataWCFService.CompanyAddress">
|
||||
<d:Street>1 Microsoft Way</d:Street>
|
||||
<d:City>Redmond</d:City>
|
||||
<d:PostalCode>98052</d:PostalCode>
|
||||
<d:CompanyName>Microsoft</d:CompanyName>
|
||||
</d:Address>
|
||||
</m:properties>
|
||||
</content>
|
||||
</entry>
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Customers/$entity",
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
|
||||
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)",
|
||||
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)",
|
||||
"PersonID": 1,
|
||||
"FirstName": "Bob",
|
||||
"LastName": "Cat",
|
||||
"MiddleName": null,
|
||||
"HomeAddress":
|
||||
{
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress",
|
||||
"Street": "1 Microsoft Way",
|
||||
"City": "London",
|
||||
"PostalCode": "98052",
|
||||
"FamilyName": "Cats"
|
||||
},
|
||||
"Home@odata.type": "#GeographyPoint",
|
||||
"Home":
|
||||
{
|
||||
"type": "Point",
|
||||
"coordinates":
|
||||
[
|
||||
23.1,
|
||||
32.1
|
||||
],
|
||||
"crs":
|
||||
{
|
||||
"type": "name",
|
||||
"properties":
|
||||
{
|
||||
"name": "EPSG:4326"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Numbers@odata.type": "#Collection(String)",
|
||||
"Numbers":
|
||||
[
|
||||
"111-111-1111"
|
||||
],
|
||||
"Emails@odata.type": "#Collection(String)",
|
||||
"Emails":
|
||||
[
|
||||
"abc@abc.com"
|
||||
],
|
||||
"City": "London",
|
||||
"Birthday@odata.type": "#DateTimeOffset",
|
||||
"Birthday": "1957-04-03T00:00:00Z",
|
||||
"TimeBetweenLastTwoOrders@odata.type": "#Duration",
|
||||
"TimeBetweenLastTwoOrders": "PT0.0000001S",
|
||||
"Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Parent/$ref",
|
||||
"Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Parent",
|
||||
"Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Orders/$ref",
|
||||
"Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Orders",
|
||||
"Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Company/$ref",
|
||||
"Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Company",
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
|
||||
{
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
|
||||
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
|
||||
},
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
|
||||
{
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
|
||||
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/"
|
||||
xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data"
|
||||
xmlns:m="http://docs.oasis-open.org/odata/ns/metadata"
|
||||
xmlns:georss="http://www.georss.org/georss"
|
||||
xmlns:gml="http://www.opengis.net/gml"
|
||||
m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Customers/$entity">
|
||||
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)</id>
|
||||
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
|
||||
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Parent" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Orders" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)/Company" />
|
||||
<title />
|
||||
<updated>2014-03-24T17:03:20Z</updated>
|
||||
<author>
|
||||
<name />
|
||||
</author>
|
||||
<content type="application/xml">
|
||||
<m:properties>
|
||||
<d:PersonID m:type="Int32">1</d:PersonID>
|
||||
<d:FirstName>Bob</d:FirstName>
|
||||
<d:LastName>Cat</d:LastName>
|
||||
<d:MiddleName m:null="true" />
|
||||
<d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress">
|
||||
<d:Street>1 Microsoft Way</d:Street>
|
||||
<d:City>London</d:City>
|
||||
<d:PostalCode>98052</d:PostalCode>
|
||||
<d:FamilyName>Cats</d:FamilyName>
|
||||
</d:HomeAddress>
|
||||
<d:Home m:type="GeographyPoint">
|
||||
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
|
||||
<gml:pos>32.1 23.1</gml:pos>
|
||||
</gml:Point>
|
||||
</d:Home>
|
||||
<d:Numbers m:type="#Collection(String)">
|
||||
<m:element>111-111-1111</m:element>
|
||||
</d:Numbers>
|
||||
<d:Emails m:type="#Collection(String)">
|
||||
<m:element>abc@abc.com</m:element>
|
||||
</d:Emails>
|
||||
<d:City>London</d:City>
|
||||
<d:Birthday m:type="DateTimeOffset">1957-04-03T00:00:00Z</d:Birthday>
|
||||
<d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000001S</d:TimeBetweenLastTwoOrders>
|
||||
</m:properties>
|
||||
</content>
|
||||
</entry>
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"odata.metadata": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Customer/$links/Info",
|
||||
"url": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company"
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<uri xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Company</uri>
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"odata.metadata": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/$metadata#Customer/$links/Orders",
|
||||
"value":
|
||||
[
|
||||
{
|
||||
"url": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/Orders(8)"
|
||||
}
|
||||
],
|
||||
"odata.nextLink": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/Customers(1)/$links/Orders?$skiptoken=2"
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<links xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">
|
||||
<uri>http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/Orders(8)</uri>
|
||||
<next>http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/Customers(1)/$links/Orders?$skiptoken=2</next>
|
||||
</links>
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Orders/$entity",
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Order",
|
||||
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)",
|
||||
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)",
|
||||
"@odata.etag": "W/\"123456789001\"",
|
||||
"OrderID": 8,
|
||||
"OrderDate@odata.type": "#DateTimeOffset",
|
||||
"OrderDate": "2011-03-04T16:03:57Z",
|
||||
"ShelfLife@odata.type": "#Duration",
|
||||
"ShelfLife": "PT0.0000001S",
|
||||
"OrderShelfLifes@odata.type": "#Collection(Duration)",
|
||||
"OrderShelfLifes":
|
||||
[
|
||||
"PT0.0000001S"
|
||||
],
|
||||
"LoggedInEmployee@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/LoggedInEmployee/$ref",
|
||||
"LoggedInEmployee@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/LoggedInEmployee",
|
||||
"CustomerForOrder@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/CustomerForOrder/$ref",
|
||||
"CustomerForOrder@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/CustomerForOrder",
|
||||
"OrderDetails@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/OrderDetails/$ref",
|
||||
"OrderDetails@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/OrderDetails"
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/"
|
||||
xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data"
|
||||
xmlns:m="http://docs.oasis-open.org/odata/ns/metadata"
|
||||
xmlns:georss="http://www.georss.org/georss"
|
||||
xmlns:gml="http://www.opengis.net/gml"
|
||||
m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Orders/$entity"
|
||||
m:etag="W/"123456789001"">
|
||||
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)</id>
|
||||
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Order" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
|
||||
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/LoggedInEmployee" type="application/atom+xml;type=entry" title="LoggedInEmployee" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/LoggedInEmployee" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/CustomerForOrder" type="application/atom+xml;type=entry" title="CustomerForOrder" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/CustomerForOrder" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/OrderDetails" type="application/atom+xml;type=feed" title="OrderDetails" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/OrderDetails" />
|
||||
<title />
|
||||
<updated>2014-03-24T17:36:01Z</updated>
|
||||
<author>
|
||||
<name />
|
||||
</author>
|
||||
<content type="application/xml">
|
||||
<m:properties>
|
||||
<d:OrderID m:type="Int32">8</d:OrderID>
|
||||
<d:OrderDate m:type="DateTimeOffset">2011-03-04T16:03:57Z</d:OrderDate>
|
||||
<d:ShelfLife m:type="Duration">PT0.0000001S</d:ShelfLife>
|
||||
<d:OrderShelfLifes m:type="#Collection(Duration)">
|
||||
<m:element>PT0.0000001S</m:element>
|
||||
</d:OrderShelfLifes>
|
||||
</m:properties>
|
||||
</content>
|
||||
</entry>
|
|
@ -0,0 +1 @@
|
|||
W/"123456789001"
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"odata.metadata": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/$metadata#Customer/$links/Info",
|
||||
"url": "http://localhost:${cargo.servlet.port}/StaticService/V30/Static.svc/CustomerInfo(11)"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"odata.metadata": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Orders/$links/CustomerForOrder",
|
||||
"url": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(1)"
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<uri xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(1)</uri>
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Orders",
|
||||
"value":
|
||||
[
|
||||
{
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Order",
|
||||
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)",
|
||||
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)",
|
||||
"OrderID": 7,
|
||||
"OrderDate@odata.type": "#DateTimeOffset",
|
||||
"OrderDate": "2011-05-29T14:21:12Z",
|
||||
"ShelfLife@odata.type": "#Duration",
|
||||
"ShelfLife": "PT0.0000001S",
|
||||
"OrderShelfLifes@odata.type": "#Collection(Duration)",
|
||||
"OrderShelfLifes":
|
||||
[
|
||||
"PT0.0000001S"
|
||||
],
|
||||
"LoggedInEmployee@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/LoggedInEmployee/$ref",
|
||||
"LoggedInEmployee@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/LoggedInEmployee",
|
||||
"CustomerForOrder@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/CustomerForOrder/$ref",
|
||||
"CustomerForOrder@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/CustomerForOrder",
|
||||
"OrderDetails@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/OrderDetails/$ref",
|
||||
"OrderDetails@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/OrderDetails"
|
||||
},
|
||||
{
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Order",
|
||||
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)",
|
||||
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)",
|
||||
"OrderID": 8,
|
||||
"OrderDate@odata.type": "#DateTimeOffset",
|
||||
"OrderDate": "2011-03-04T16:03:57Z",
|
||||
"ShelfLife@odata.type": "#Duration",
|
||||
"ShelfLife": "PT0.0000001S",
|
||||
"OrderShelfLifes@odata.type": "#Collection(Duration)",
|
||||
"OrderShelfLifes":
|
||||
[
|
||||
"PT0.0000001S"
|
||||
],
|
||||
"LoggedInEmployee@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/LoggedInEmployee/$ref",
|
||||
"LoggedInEmployee@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/LoggedInEmployee",
|
||||
"CustomerForOrder@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/CustomerForOrder/$ref",
|
||||
"CustomerForOrder@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/CustomerForOrder",
|
||||
"OrderDetails@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/OrderDetails/$ref",
|
||||
"OrderDetails@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/OrderDetails"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<feed xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#Orders">
|
||||
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders</id>
|
||||
<title />
|
||||
<updated>2014-03-24T17:17:25Z</updated>
|
||||
<entry>
|
||||
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)</id>
|
||||
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Order" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
|
||||
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/LoggedInEmployee" type="application/atom+xml;type=entry" title="LoggedInEmployee" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/LoggedInEmployee" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/CustomerForOrder" type="application/atom+xml;type=entry" title="CustomerForOrder" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/CustomerForOrder" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/OrderDetails" type="application/atom+xml;type=feed" title="OrderDetails" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(7)/OrderDetails" />
|
||||
<title />
|
||||
<updated>2014-03-24T17:17:25Z</updated>
|
||||
<author>
|
||||
<name />
|
||||
</author>
|
||||
<content type="application/xml">
|
||||
<m:properties>
|
||||
<d:OrderID m:type="Int32">7</d:OrderID>
|
||||
<d:OrderDate m:type="DateTimeOffset">2011-05-29T14:21:12Z</d:OrderDate>
|
||||
<d:ShelfLife m:type="Duration">PT0.0000001S</d:ShelfLife>
|
||||
<d:OrderShelfLifes m:type="#Collection(Duration)">
|
||||
<m:element>PT0.0000001S</m:element>
|
||||
</d:OrderShelfLifes>
|
||||
</m:properties>
|
||||
</content>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)</id>
|
||||
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Order" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
|
||||
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/LoggedInEmployee" type="application/atom+xml;type=entry" title="LoggedInEmployee" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/LoggedInEmployee" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/CustomerForOrder" type="application/atom+xml;type=entry" title="CustomerForOrder" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/CustomerForOrder" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/OrderDetails" type="application/atom+xml;type=feed" title="OrderDetails" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Orders(8)/OrderDetails" />
|
||||
<title />
|
||||
<updated>2014-03-24T17:17:25Z</updated>
|
||||
<author>
|
||||
<name />
|
||||
</author>
|
||||
<content type="application/xml">
|
||||
<m:properties>
|
||||
<d:OrderID m:type="Int32">8</d:OrderID>
|
||||
<d:OrderDate m:type="DateTimeOffset">2011-03-04T16:03:57Z</d:OrderDate>
|
||||
<d:ShelfLife m:type="Duration">PT0.0000001S</d:ShelfLife>
|
||||
<d:OrderShelfLifes m:type="#Collection(Duration)">
|
||||
<m:element>PT0.0000001S</m:element>
|
||||
</d:OrderShelfLifes>
|
||||
</m:properties>
|
||||
</content>
|
||||
</entry>
|
||||
</feed>
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#People/$entity",
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Person",
|
||||
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)",
|
||||
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)",
|
||||
"PersonID": 5,
|
||||
"FirstName": "Peter",
|
||||
"LastName": "Bee",
|
||||
"MiddleName": null,
|
||||
"HomeAddress": null,
|
||||
"Home@odata.type": "#GeographyPoint",
|
||||
"Home":
|
||||
{
|
||||
"type": "Point",
|
||||
"coordinates":
|
||||
[
|
||||
-261.8,
|
||||
-16
|
||||
],
|
||||
"crs":
|
||||
{
|
||||
"type": "name",
|
||||
"properties":
|
||||
{
|
||||
"name": "EPSG:4326"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Numbers@odata.type": "#Collection(String)",
|
||||
"Numbers":
|
||||
[
|
||||
"555-555-5555"
|
||||
],
|
||||
"Emails@odata.type": "#Collection(String)",
|
||||
"Emails":
|
||||
[
|
||||
"def@test.msn"
|
||||
],
|
||||
"Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent/$ref",
|
||||
"Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent",
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
|
||||
{
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
|
||||
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
|
||||
},
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
|
||||
{
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
|
||||
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#People/$entity">
|
||||
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)</id>
|
||||
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Person" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
|
||||
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent" />
|
||||
<title />
|
||||
<updated>2014-03-24T17:20:17Z</updated>
|
||||
<author>
|
||||
<name />
|
||||
</author>
|
||||
<content type="application/xml">
|
||||
<m:properties>
|
||||
<d:PersonID m:type="Int32">5</d:PersonID>
|
||||
<d:FirstName>Peter</d:FirstName>
|
||||
<d:LastName>Bee</d:LastName>
|
||||
<d:MiddleName m:null="true" />
|
||||
<d:HomeAddress m:null="true" />
|
||||
<d:Home m:type="GeographyPoint">
|
||||
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
|
||||
<gml:pos>-16 -261.8</gml:pos>
|
||||
</gml:Point>
|
||||
</d:Home>
|
||||
<d:Numbers m:type="#Collection(String)">
|
||||
<m:element>555-555-5555</m:element>
|
||||
</d:Numbers>
|
||||
<d:Emails m:type="#Collection(String)">
|
||||
<m:element>def@test.msn</m:element>
|
||||
</d:Emails>
|
||||
<d:IsRegistered m:type="Boolean">true</d:IsRegistered>
|
||||
<d:Height m:type="Decimal">179</d:Height>
|
||||
<d:PDC m:type="Binary">fi653p3+MklA/LdoBlhWgnMTUUEo8tEgtbMXnF0a3CUNL9BZxXpSRiD9ebTnmNR0zWPjJVIDx4tdmCnq55XrJh+RW9aI/b34wAogK3kcORw=</d:PDC>
|
||||
</m:properties>
|
||||
</content>
|
||||
</entry>
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#ProductDetails/$entity",
|
||||
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.ProductDetail",
|
||||
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)",
|
||||
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)",
|
||||
"ProductID": 6,
|
||||
"ProductDetailID": 1,
|
||||
"ProductName": "Candy",
|
||||
"Description": "sweet snack",
|
||||
"RelatedProduct@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)/RelatedProduct/$ref",
|
||||
"RelatedProduct@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)/RelatedProduct",
|
||||
"Reviews@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)/Reviews/$ref",
|
||||
"Reviews@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)/Reviews",
|
||||
"#Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct":
|
||||
{
|
||||
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct",
|
||||
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)/Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<entry xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#ProductDetails/$entity">
|
||||
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)</id>
|
||||
<category term="#Microsoft.Test.OData.Services.ODataWCFService.ProductDetail" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
|
||||
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/RelatedProduct" type="application/atom+xml;type=entry" title="RelatedProduct" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)/RelatedProduct" />
|
||||
<link rel="http://docs.oasis-open.org/odata/ns/related/Reviews" type="application/atom+xml;type=feed" title="Reviews" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/ProductDetails(ProductID=6,ProductDetailID=1)/Reviews" />
|
||||
<title />
|
||||
<updated>2014-03-24T17:23:51Z</updated>
|
||||
<author>
|
||||
<name />
|
||||
</author>
|
||||
<content type="application/xml">
|
||||
<m:properties>
|
||||
<d:ProductID m:type="Int32">6</d:ProductID>
|
||||
<d:ProductDetailID m:type="Int32">1</d:ProductDetailID>
|
||||
<d:ProductName>Candy</d:ProductName>
|
||||
<d:Description>sweet snack</d:Description>
|
||||
</m:properties>
|
||||
</content>
|
||||
</entry>
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"odata.error":
|
||||
{
|
||||
"code": "",
|
||||
"message":
|
||||
{
|
||||
"lang": "en-US",
|
||||
"value": "Bad request."
|
||||
},
|
||||
"innererror":
|
||||
{
|
||||
"message": "Bad request.",
|
||||
"type": "Microsoft.Data.OData.BadRequest",
|
||||
"stacktrace": " at Microsoft.Data.OData.MediaTypeUtils.GetContentTypeFromSettings...."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
|
||||
<m:code />
|
||||
<m:message xml:lang="en-US">Bad request.</m:message>
|
||||
<m:innererror>
|
||||
<m:message>Bad request.</m:message>
|
||||
<m:type>Microsoft.Data.OData.BadRequest</m:type>
|
||||
<m:stacktrace> at Microsoft.Data.OData.MediaTypeUtils.GetContentTypeFromSettings...</m:stacktrace>
|
||||
</m:innererror>
|
||||
</m:error>
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"odata.error":
|
||||
{
|
||||
"code": "",
|
||||
"message":
|
||||
{
|
||||
"lang": "en-US",
|
||||
"value": "Resource not found for the segment 'Customer'."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
|
||||
<m:code />
|
||||
<m:message xml:lang="en-US">Resource not found for the segment 'Customer'.</m:message>
|
||||
</m:error>
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#$ref",
|
||||
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)"
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<m:ref m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#$ref" id="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/Customers(PersonID=1)" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" />
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"odata.error":
|
||||
{
|
||||
"code": "",
|
||||
"message":
|
||||
{
|
||||
"lang": "en-US",
|
||||
"value": "Unsupported media type requested."
|
||||
},
|
||||
"innererror":
|
||||
{
|
||||
"message": "Unsupported media type requested.",
|
||||
"type": "Microsoft.Data.OData.ODataContentTypeException",
|
||||
"stacktrace": " at Microsoft.Data.OData.MediaTypeUtils.GetContentTypeFromSettings(ODataMessageWriterSettings settings, ODataPayloadKind payloadKind, MediaTypeResolver mediaTypeResolver, MediaType& mediaType, Encoding& encoding)\n at Microsoft.Data.OData.ODataMessageWriter.EnsureODataFormatAndContentType()\n at Microsoft.Data.OData.ODataMessageWriter.SetHeaders(ODataPayloadKind payloadKind)\n at Microsoft.Data.OData.ODataUtils.SetHeadersForPayload(ODataMessageWriter messageWriter, ODataPayloadKind payloadKind)\n at System.Data.Services.ResponseContentTypeNegotiator.DetermineResponseFormat(ODataPayloadKind payloadKind, String acceptableMediaTypes, String acceptableCharSets)"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
|
||||
<m:code />
|
||||
<m:message xml:lang="en-US">Unsupported media type requested.</m:message>
|
||||
<m:innererror>
|
||||
<m:message>A supported MIME type could not be found that matches the acceptable MIME types for the request. The supported type(s) 'application/atom+xml;type=feed, application/atom+xml, application/json;odata=minimalmetadata;streaming=true, application/json;odata=minimalmetadata;streaming=false, application/json;odata=minimalmetadata, application/json;odata=fullmetadata;streaming=true, application/json;odata=fullmetadata;streaming=false, application/json;odata=fullmetadata, application/json;odata=nometadata;streaming=true, application/json;odata=nometadata;streaming=false, application/json;odata=nometadata, application/json;streaming=true, application/json;streaming=false, application/json;odata=verbose, application/json' do not match any of the acceptable MIME types 'application/xml'.</m:message>
|
||||
<m:type>Microsoft.Data.OData.ODataContentTypeException</m:type>
|
||||
<m:stacktrace> at Microsoft.Data.OData.MediaTypeUtils.GetContentTypeFromSettings(ODataMessageWriterSettings settings, ODataPayloadKind payloadKind, MediaTypeResolver mediaTypeResolver, MediaType& mediaType, Encoding& encoding)
|
||||
at Microsoft.Data.OData.ODataMessageWriter.EnsureODataFormatAndContentType()
|
||||
at Microsoft.Data.OData.ODataMessageWriter.SetHeaders(ODataPayloadKind payloadKind)
|
||||
at Microsoft.Data.OData.ODataUtils.SetHeadersForPayload(ODataMessageWriter messageWriter, ODataPayloadKind payloadKind)
|
||||
at System.Data.Services.ResponseContentTypeNegotiator.DetermineResponseFormat(ODataPayloadKind payloadKind, String acceptableMediaTypes, String acceptableCharSets)</m:stacktrace>
|
||||
</m:innererror>
|
||||
</m:error>
|
|
@ -18,6 +18,11 @@
|
|||
*/
|
||||
package org.apache.olingo.client.api.communication.header;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
||||
/**
|
||||
* Major OData request/response header names.
|
||||
*/
|
||||
|
@ -26,7 +31,17 @@ public enum HeaderName {
|
|||
/**
|
||||
* The OData protocol uses the Accept request-header field, as specified in [RFC2616].
|
||||
*/
|
||||
accept("Accept"),
|
||||
accept("Accept", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
/**
|
||||
* As specified in [RFC2616], the client MAY specify the set of accepted character sets with the Accept-Charset
|
||||
* header.
|
||||
*/
|
||||
acceptCharset("Accept-Charset", Arrays.asList(ODataServiceVersion.V40)),
|
||||
/**
|
||||
* As specified in [RFC2616], the client MAY specify the set of accepted natural languages with the Accept-Language
|
||||
* header.
|
||||
*/
|
||||
acceptLanguage("Accept-Language", Arrays.asList(ODataServiceVersion.V40)),
|
||||
/**
|
||||
* The Content-Type header is used as specified in [RFC2616].
|
||||
* <br/>
|
||||
|
@ -44,76 +59,129 @@ public enum HeaderName {
|
|||
* <li>multipart/mixed</li>
|
||||
* </ul>
|
||||
*/
|
||||
contentType("Content-Type"),
|
||||
contentType("Content-Type", Arrays.asList(ODataServiceVersion.V30)),
|
||||
/**
|
||||
* This header is a custom HTTP header defined for protocol versioning purposes. This header MAY be present on any
|
||||
* request or response message.
|
||||
*/
|
||||
dataServiceVersion("DataServiceVersion"),
|
||||
dataServiceVersion("DataServiceVersion", Arrays.asList(ODataServiceVersion.V30)),
|
||||
/**
|
||||
* This header is a custom HTTP header defined for protocol versioning purposes. This header MAY be present on any
|
||||
* request or response message.
|
||||
*/
|
||||
odataVersion("OData-Version", Arrays.asList(ODataServiceVersion.V40)),
|
||||
/**
|
||||
* A response to a create operation that returns 204 No Content MUST include an OData-EntityId response header. The
|
||||
* value of the header is the entity-id of the entity that was acted on by the request. The syntax of the
|
||||
* OData-EntityId preference is specified in [OData-ABNF].
|
||||
*/
|
||||
odataEntityId("OData-EntityId", Arrays.asList(ODataServiceVersion.V40)),
|
||||
/**
|
||||
* An ETag (entity tag) is an HTTP response header returned by an HTTP/1.1 compliant web server used to determine
|
||||
* change in content of a resource at a given URL. The value of the header is an opaque string representing the state
|
||||
* of the resource at the time the response was generated.
|
||||
*/
|
||||
etag("ETag"),
|
||||
etag("ETag", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
/**
|
||||
* The If-Match request-header field is used with a method to make it conditional. As specified in [RFC2616], "the
|
||||
* purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction
|
||||
* overhead. It is also used, on updating requests, to prevent inadvertent modification of the wrong version of a
|
||||
* resource".
|
||||
*/
|
||||
ifMatch("If-Match"),
|
||||
ifMatch("If-Match", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
/**
|
||||
* The If-None-Match request header is used with a method to make it conditional. As specified in [RFC2616], "The
|
||||
* purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction
|
||||
* overhead. It is also used to prevent a method (for example, PUT) from inadvertently modifying an existing resource
|
||||
* when the client believes that the resource does not exist."
|
||||
*/
|
||||
ifNoneMatch("If-None-Match"),
|
||||
ifNoneMatch("If-None-Match", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
/**
|
||||
* Clients SHOULD specify an OData-MaxVersion request header.
|
||||
* <br />
|
||||
* If specified the service MUST generate a response with an OData-Version less than or equal to the specified
|
||||
* OData-MaxVersion.
|
||||
* <br />
|
||||
* If OData-MaxVersion is not specified, then the service SHOULD interpret the request as having an OData-MaxVersion
|
||||
* equal to the maximum version supported by the service.
|
||||
*/
|
||||
odataMaxVersion("OData-MaxVersion", Arrays.asList(ODataServiceVersion.V40)),
|
||||
/**
|
||||
* This header is a custom HTTP request only header defined for protocol versioning purposes. This header MAY be
|
||||
* present on any request message from client to server.
|
||||
*/
|
||||
maxDataServiceVersion("MaxDataServiceVersion"),
|
||||
maxDataServiceVersion("MaxDataServiceVersion", Arrays.asList(ODataServiceVersion.V30)),
|
||||
/**
|
||||
* This header is a custom HTTP request only header defined for protocol versioning purposes. This header MAY be
|
||||
* present on any request message from client to server.
|
||||
*/
|
||||
minDataServiceVersion("MinDataServiceVersion"),
|
||||
minDataServiceVersion("MinDataServiceVersion", Arrays.asList(ODataServiceVersion.V30)),
|
||||
/**
|
||||
* The OData-Isolation header specifies the isolation of the current request from external changes. The only supported
|
||||
* value for this header is snapshot.
|
||||
* <br />
|
||||
* If the service doesn’t support OData-Isolation:snapshot and this header was specified on the request, the service
|
||||
* MUST NOT process the request and MUST respond with 412 Precondition Failed.
|
||||
* <br />
|
||||
* Snapshot isolation guarantees that all data returned for a request, including multiple requests within a batch or
|
||||
* results retrieved across multiple pages, will be consistent as of a single point in time. Only data modifications
|
||||
* made within the request (for example, by a data modification request within the same batch) are visible. The effect
|
||||
* is as if the request generates a "snapshot" of the committed data as it existed at the start of the request.
|
||||
* <br />
|
||||
* The OData-Isolation header may be specified on a single or batch request. If it is specified on a batch then the
|
||||
* value is applied to all statements within the batch.
|
||||
* <br />
|
||||
* Next links returned within a snapshot return results within the same snapshot as the initial request; the client is
|
||||
* not required to repeat the header on each individual page request.
|
||||
* <br />
|
||||
* The OData-Isolation header has no effect on links other than the next link. Navigation links, read links, and edit
|
||||
* links return the current version of the data.
|
||||
* <br />
|
||||
* A service returns 410 Gone or 404 Not Found if a consumer tries to follow a next link referring to a snapshot that
|
||||
* is no longer available.
|
||||
* <br />
|
||||
* The syntax of the OData-Isolation header is specified in [OData-ABNF].
|
||||
* <br />
|
||||
* A service MAY specify the support for OData-Isolation:snapshot using an annotation with term
|
||||
* Capabilities.IsolationSupport, see [OData-VocCap].
|
||||
*/
|
||||
odataIsolation("OData-Isolation", Arrays.asList(ODataServiceVersion.V40)),
|
||||
/**
|
||||
* A Prefer header is included in a request to state the client’s preferred, but not required, server behavior (that
|
||||
* is, a hint to the server). The Prefer header MAY be included on any request type (within a standalone or batch
|
||||
* request), and a server MAY honor the header for HTTP POST, PUT, PATCH, and MERGE requests. A Prefer header with a
|
||||
* value of “return-content” MUST NOT be specified on a DELETE request, a batch request as a whole, or a PUT request
|
||||
* to update a named stream.
|
||||
*
|
||||
* @see ODataPreferenceNames.
|
||||
*/
|
||||
prefer("Prefer"),
|
||||
prefer("Prefer", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
/**
|
||||
* When a Prefer header value is successfully honored by the server, it MAY include a Preference-Applied response
|
||||
* header that states which preference values were honored by the server.
|
||||
*/
|
||||
preferenceApplied("Preference-Applied"),
|
||||
preferenceApplied("Preference-Applied", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
/**
|
||||
* The DataServiceId response header is returned by the server when the response payload for an HTTP PUT, POST, PATCH,
|
||||
* or MERGE request is empty. The value of the header is the identifier of the entity that was acted on by the PUT,
|
||||
* POST, PATCH, or MERGE request. The identifier, in this case, is the same identifier that would have been returned
|
||||
* in the response payload (for example, as the value of the atom:id element for Atom responses)
|
||||
*/
|
||||
dataServiceId("DataServiceId"),
|
||||
dataServiceId("DataServiceId", Arrays.asList(ODataServiceVersion.V30)),
|
||||
/**
|
||||
* Location header is used to specify the URL of an entity modified through a Data Modification request, or the
|
||||
* request URL to check on the status of an asynchronous operation as described in
|
||||
* <code>202 Accepted</code>.
|
||||
*/
|
||||
location("Location"),
|
||||
location("Location", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
/**
|
||||
* A service must include a
|
||||
* <code>Retry-After</code> header in a
|
||||
* <code>202 Accepted</code>.
|
||||
*/
|
||||
retryAfter("Retry-After"),
|
||||
dataServiceUrlConventions("DataServiceUrlConventions"),
|
||||
slug("Slug"),
|
||||
retryAfter("Retry-After", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
dataServiceUrlConventions("DataServiceUrlConventions", Arrays.asList(ODataServiceVersion.V30)),
|
||||
slug("Slug", Arrays.asList(ODataServiceVersion.V30)),
|
||||
/**
|
||||
* This header is a custom HTTP request header.
|
||||
* <br/>
|
||||
|
@ -132,12 +200,21 @@ public enum HeaderName {
|
|||
* <br/>
|
||||
* This header is only valid when on POST requests.
|
||||
*/
|
||||
xHttpMethod("X-HTTP-METHOD");
|
||||
xHttpMethod("X-HTTP-METHOD", Arrays.asList(ODataServiceVersion.V30));
|
||||
|
||||
private final String headerName;
|
||||
|
||||
private HeaderName(final String headerName) {
|
||||
private final List<ODataServiceVersion> supportedVersions;
|
||||
|
||||
private HeaderName(final String headerName, final List<ODataServiceVersion> supportedVersions) {
|
||||
this.headerName = headerName;
|
||||
this.supportedVersions = supportedVersions;
|
||||
}
|
||||
|
||||
final void isSupportedBy(final ODataServiceVersion serviceVersion) {
|
||||
if (!supportedVersions.contains(serviceVersion)) {
|
||||
throw new ODataRuntimeException("Unsupported header " + this.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,424 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.client.api.communication.header;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
||||
/**
|
||||
* Values of the Prefer header.
|
||||
*/
|
||||
public class ODataPreferences {
|
||||
|
||||
final ODataServiceVersion serviceVersion;
|
||||
|
||||
public ODataPreferences(final ODataServiceVersion serviceVersion) {
|
||||
this.serviceVersion = serviceVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>Prefer</code> header, return content.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
*/
|
||||
public String returnContent() {
|
||||
return PreferenceNames.returnContent.isSupportedBy(serviceVersion).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>Prefer</code> header, return no content.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
*/
|
||||
public String returnNoContent() {
|
||||
return PreferenceNames.returnNoContent.isSupportedBy(serviceVersion).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see HeaderName#dataServiceUrlConventions
|
||||
*/
|
||||
public String keyAsSegment() {
|
||||
return PreferenceNames.keyAsSegment.isSupportedBy(serviceVersion).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The odata.allow-entityreferences preference indicates that the service is allowed to return entity references in
|
||||
* place of entities that have previously been returned, with at least the properties requested, in the same response
|
||||
* (for example, when serializing the expanded results of many-to-many relationships). The service MUST NOT return
|
||||
* entity references in place of requested entities if odata.allow-entityreferences has not been specified in the
|
||||
* request, unless explicitly defined by other rules in this document. The syntax of the odata.allow-entityreferences
|
||||
* preference is specified in [OData-ABNF].
|
||||
* <br />
|
||||
* In the case the service applies the odata.allow-entityreferences preference it MUST include a Preference-Applied
|
||||
* response header containing the odata.allow-entityreferences preference to indicate that entity references MAY be
|
||||
* returned in place of entities that have previously been returned.
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String allowEntityReferences() {
|
||||
return PreferenceNames.allowEntityReferences.isSupportedBy(serviceVersion).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* For scenarios in which links returned by the service are used by the client to poll for additional information, the
|
||||
* client can specify the odata.callback preference to request that the service notify the client when data is
|
||||
* available.
|
||||
* <br />
|
||||
* The odata.callback preference can be specified:
|
||||
* <ul>
|
||||
* <li>when requesting asynchronous processing of a request with the respond-async preference, or</li>
|
||||
* <li>on a GET request to a delta link.</li>
|
||||
* </ul>
|
||||
* <br />
|
||||
* The odata.callback preference MUST include the parameter url whose value is the URL of a callback endpoint to be
|
||||
* invoked by the OData service when data is available. The syntax of the odata.callback preference is specified in
|
||||
* [OData-ABNF]. For HTTP based callbacks, the OData service executes an HTTP GET request against the specified URL.
|
||||
* <br />
|
||||
* Services that support odata.callback SHOULD support notifying the client through HTTP. Services can advertise
|
||||
* callback support using the Capabilities.CallbackSupport annotation term defined in [OData-VocCap].
|
||||
* <br />
|
||||
* If the service applies the odata.callback preference it MUST include the odata.callback preference in the
|
||||
* Preference-Applied response header.
|
||||
* <br />
|
||||
* When the odata.callback preference is applied to asynchronous requests, the OData service invokes the callback
|
||||
* endpoint once it has finished processing the request. The status monitor resource, returned in the Location header
|
||||
* of the previously returned 202 Accepted response, can then be used to retrieve the results of the asynchronously
|
||||
* executed request.
|
||||
* <br />
|
||||
* When the odata.callback preference is specified on a GET request to a delta link and there are no changes
|
||||
* available, the OData service returns a 202 Accepted response with a Location header specifying the delta link to be
|
||||
* used to check for future updates. The OData service then invokes the specified callback endpoint once new changes
|
||||
* become available.
|
||||
* <br />
|
||||
* Combining respond-async, odata.callback and odata.track-changes preferences on a GET request to a delta-link might
|
||||
* influence the response in a couple of ways.
|
||||
* <ul>
|
||||
* <li>If the service processes the request synchronously, and no updates are available, then the response is the same
|
||||
* as if the respond-async hadn’t been specified and results in a response as described above.</li>
|
||||
* <li>If the service processes the request asynchronously, then it responds with a 202 Accepted response specifying
|
||||
* the URL to the status monitor resource as it would have with any other asynchronous request. Once the service has
|
||||
* finished processing the asynchronous request to the delta link resource, if changes are available it invokes the
|
||||
* specified callback endpoint. If no changes are available, the service SHOULD wait to notify the client until
|
||||
* changes are available. Once notified, the client uses the status monitor resource from the Location header of the
|
||||
* previously returned 202 Accepted response to retrieve the results. In case no updates were available after
|
||||
* processing the initial request, the result will contain no updates and the client can use the delta-link contained
|
||||
* in the result to retrieve the updates that have since become available.</li>
|
||||
* </ul>
|
||||
* <br />
|
||||
* If the consumer specifies the same URL as callback endpoint in multiple requests, the service MAY collate them into
|
||||
* a single notification once additional data is available for any of the requests. However, the consumer MUST be
|
||||
* prepared to deal with receiving up to as many notifications as it requested.
|
||||
* <br /><br />
|
||||
* Example: using a HTTP callback endpoint to receive notification
|
||||
* <br /><br />
|
||||
* Prefer: odata.callback; url="http://myserver/notfication/token/12345"
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String callback(final String url) {
|
||||
return PreferenceNames.callback.isSupportedBy(serviceVersion).toString() + ";url=\"" + url + "\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* The odata.continue-on-error preference on a batch request is used to request that, upon encountering a request
|
||||
* within the batch that returns an error, the service return the error for that request and continue processing
|
||||
* additional requests within the batch. The syntax of the odata.continue-on-error preference is specified in
|
||||
* [OData-ABNF].
|
||||
* <br />
|
||||
* If not specified, upon encountering an error the service MUST return the error within the batch and stop processing
|
||||
* additional requests within the batch.
|
||||
* <br />
|
||||
* A service MAY specify the support for the odata.continue-on-error preference using an annotation with term
|
||||
* Capabilities.BatchContinueOnErrorSupported, see [OData-VocCap].
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String continueOnError() {
|
||||
return PreferenceNames.callback.isSupportedBy(serviceVersion).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The odata.include-annotations preference in a request for data or metadata is used to specify the set of
|
||||
* annotations the client requests to be included, where applicable, in the response.
|
||||
* <br/>
|
||||
* The value of the odata.include-annotations preference is a comma-separated list of namespaces or namespace
|
||||
* qualified term names to include or exclude, with "*" representing all. The full syntax of the
|
||||
* odata.include-annotations preference is defined in [OData-ABNF].
|
||||
* <br/>
|
||||
* The most specific identifier always takes precedence. If the same identifier value is requested to both be excluded
|
||||
* and included the behavior is undefined; the service MAY return or omit the specified vocabulary but MUST NOT raise
|
||||
* an exception.
|
||||
* <br/><br/>
|
||||
* Example 1: a Prefer header requesting all annotations within a metadata document to be returned
|
||||
* <br/><br/>
|
||||
* Prefer: odata.include-annotations="*"
|
||||
* <br/><br/>
|
||||
* Example 2: a Prefer header requesting that no annotations are returned
|
||||
* <br/><br/>
|
||||
* Prefer: odata.include-annotations="-*"
|
||||
* <br/><br/>
|
||||
* Example 3: a Prefer header requesting that all annotations defined under the "display" namespace (recursively) be
|
||||
* returned
|
||||
* <br/><br/>
|
||||
* Prefer: odata.include-annotations="display.*"
|
||||
* <br/><br/>
|
||||
* Example 4: a Prefer header requesting that the annotation with the term name subject within the display namespace
|
||||
* be returned if applied
|
||||
* <br/><br/>
|
||||
* Prefer: odata.include-annotations="display.subject"
|
||||
* <br/><br/>
|
||||
* The odata.include-annotations preference is only a hint to the service. The service MAY ignore the preference and
|
||||
* is free to decide whether or not to return annotations not specified in the odata.include-annotations preference.
|
||||
* <br/>
|
||||
* In the case that the client has specified the odata.include-annotations preference in the request, the service
|
||||
* SHOULD include a Preference-Applied response header containing the odata.include-annotations preference to specify
|
||||
* the annotations actually included, where applicable, in the response. This value may differ from the annotations
|
||||
* requested in the Prefer header of the request.
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String includeAnnotations(final String value) {
|
||||
return PreferenceNames.includeAnnotations.isSupportedBy(serviceVersion).toString() + "=" + value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The odata.maxpagesize preference is used to request that each collection within the response contain no more than
|
||||
* the number of items specified as the positive integer value of this preference. The syntax of the odata.maxpagesize
|
||||
* preference is specified in [OData-ABNF].
|
||||
* <br/><br/>
|
||||
* Example: a request for customers and their orders would result in a response containing one collection with
|
||||
* customer entities and for every customer a separate collection with order entities. The client could specify
|
||||
* <br/>
|
||||
* odata.maxpagesize=50
|
||||
* <br/>in order to request that each page of results contain a maximum of 50 customers, each with a maximum of 50
|
||||
* orders.
|
||||
* <br/><br/>
|
||||
* If a collection within the result contains more than the specified odata.maxpagesize, the collection SHOULD be a
|
||||
* partial set of the results with a next link to the next page of results. The client MAY specify a different value
|
||||
* for this preference with every request following a next link.
|
||||
* <br/>
|
||||
* In the example given above, the result page should include a next link for the customer collection, if there are
|
||||
* more than 50 customers, and additional next links for all returned orders collections with more than 50 entities.
|
||||
* <br/>
|
||||
* If the client has specified the odata.maxpagesize preference in the request, and the service limits the number of
|
||||
* items in collections within the response through server-driven paging, the service MAY include a Preference-Applied
|
||||
* response header containing the odata.maxpagesize preference and the maximum page size applied. This value may
|
||||
* differ from the value requested by the client.
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String maxPageSize(final int size) {
|
||||
return PreferenceNames.maxPageSize.isSupportedBy(serviceVersion).toString() + "=" + size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The odata.track-changes preference is used to request that the service return a delta link that can subsequently be
|
||||
* used to obtain changes (deltas) to this result. The syntax of the odata.track-changes preference is specified in
|
||||
* [OData-ABNF].
|
||||
* <br />
|
||||
* For paged results, the preference MUST be specified on the initial request. Services MUST ignore the
|
||||
* odata.track-changes preference if applied to the next link.
|
||||
* <br />
|
||||
* The delta link MUST NOT be returned prior to the final page of results.
|
||||
* <br />
|
||||
* The service includes a Preference-Applied response header in the first page of the response containing the
|
||||
* odata.track-changes preference to signal that changes are being tracked.
|
||||
* <br />
|
||||
* A service MAY specify the support for the odata.track-changes preference using an annotation with term
|
||||
* Capabilities.ChangeTrackingSupport, see [OData-VocCap].
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String trackChanges() {
|
||||
return PreferenceNames.trackChanges.isSupportedBy(serviceVersion).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The respond-async preference, as defined in [HTTP-Prefer], allows clients to request that the service process the
|
||||
* request asynchronously.
|
||||
* <br/>
|
||||
* If the client has specified respond-async in the request, the service MAY process the request asynchronously and
|
||||
* return a 202 Accepted response.
|
||||
* <br/>
|
||||
* The respond-async preference MAY be used for batch requests, but the service MUST ignore the respond-async
|
||||
* preference for individual requests within a batch request.
|
||||
* <br/>
|
||||
* In the case that the service applies the respond-async preference it MUST include a Preference-Applied response
|
||||
* header containing the respond-async preference.
|
||||
* <br/>
|
||||
* A service MAY specify the support for the respond-async preference using an annotation with term
|
||||
* Capabilities.AsynchronousRequestsSupported, see [OData-VocCap].
|
||||
* <br/><br/>
|
||||
* Example: a service receiving the following header might choose to respond
|
||||
* <ul>
|
||||
* <li>asynchronously if the synchronous processing of the request will take longer than 10 seconds</li>
|
||||
* <li>synchronously after 5 seconds</li>
|
||||
* <li>asynchronously (ignoring the wait preference)</li>
|
||||
* <li>synchronously after 15 seconds (ignoring respond-async preference and the wait preference)</li>
|
||||
* </ul>
|
||||
* <br/>
|
||||
* Prefer: respond-async, wait=10
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String respondAsync() {
|
||||
return PreferenceNames.respondAsync.isSupportedBy(serviceVersion).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The wait preference, as defined in [HTTP-Prefer], is used to establish an upper bound on the length of time, in
|
||||
* seconds, the client is prepared to wait for the service to process the request synchronously once it has been
|
||||
* received.
|
||||
* <br/>
|
||||
* If the respond-async preference is also specified, the client requests that the service respond asynchronously
|
||||
* after the specified length of time.
|
||||
* <br/>
|
||||
* If the respond-async preference has not been specified, the service MAY interpret the wait as a request to timeout
|
||||
* after the specified period of time.
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String wait(final int value) {
|
||||
return PreferenceNames.wait.isSupportedBy(serviceVersion).toString() + "=" + value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The return=representation and return=minimal preferences are defined in [HTTP-Prefer],
|
||||
* <br/>
|
||||
* In OData, return=representation or return=minimal is defined for use with a POST, PUT, or PATCH Data Modification
|
||||
* Request other than to a stream property, or to an Action Request. Specifying a preference of return=representation
|
||||
* or return=minimal in a GET or DELETE request, or any request to a stream property, SHOULD return a 4xx Client
|
||||
* Error.
|
||||
* <br/>
|
||||
* A preference of return=representation or return=minimal is allowed on an individual Data Modification Request or
|
||||
* Action Request within a batch, subject to the same restrictions, but SHOULD return a 4xx Client Error if specified
|
||||
* on the batch request itself.
|
||||
* <br/>
|
||||
* A preference of return=minimal requests that the service invoke the request but does not return content in the
|
||||
* response. The service MAY apply this preference by returning 204 No Content in which case it MAY include a
|
||||
* Preference-Applied response header containing the return=minimal preference.
|
||||
* <br/>
|
||||
* A preference of return=representation requests that the service invokes the request and returns the modified
|
||||
* entity. The service MAY apply this preference by returning the successfully modified resource in the body of the
|
||||
* response, formatted according to the rules specified for the requested format. In this case the service MAY include
|
||||
* a Preference-Applied response header containing the return=representation preference.
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String returnMinimal() {
|
||||
return PreferenceNames.odataReturn.isSupportedBy(serviceVersion).toString() + "=minimal";
|
||||
}
|
||||
|
||||
/**
|
||||
* The return=representation and return=minimal preferences are defined in [HTTP-Prefer],
|
||||
* <br/>
|
||||
* In OData, return=representation or return=minimal is defined for use with a POST, PUT, or PATCH Data Modification
|
||||
* Request other than to a stream property, or to an Action Request. Specifying a preference of return=representation
|
||||
* or return=minimal in a GET or DELETE request, or any request to a stream property, SHOULD return a 4xx Client
|
||||
* Error.
|
||||
* <br/>
|
||||
* A preference of return=representation or return=minimal is allowed on an individual Data Modification Request or
|
||||
* Action Request within a batch, subject to the same restrictions, but SHOULD return a 4xx Client Error if specified
|
||||
* on the batch request itself.
|
||||
* <br/>
|
||||
* A preference of return=minimal requests that the service invoke the request but does not return content in the
|
||||
* response. The service MAY apply this preference by returning 204 No Content in which case it MAY include a
|
||||
* Preference-Applied response header containing the return=minimal preference.
|
||||
* <br/>
|
||||
* A preference of return=representation requests that the service invokes the request and returns the modified
|
||||
* entity. The service MAY apply this preference by returning the successfully modified resource in the body of the
|
||||
* response, formatted according to the rules specified for the requested format. In this case the service MAY include
|
||||
* a Preference-Applied response header containing the return=representation preference.
|
||||
* <br/><br/>
|
||||
* Supported by OData version 4.0 only.
|
||||
*
|
||||
* @see HeaderName#prefer
|
||||
* @return preference.
|
||||
*/
|
||||
public String returnRepresentation() {
|
||||
return PreferenceNames.odataReturn.isSupportedBy(serviceVersion).toString() + "=representation";
|
||||
}
|
||||
|
||||
private static enum PreferenceNames {
|
||||
|
||||
returnContent("return-content", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
returnNoContent("return-no-content", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
keyAsSegment("KeyAsSegment", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
|
||||
allowEntityReferences("odata.allow-entityreferences", Arrays.asList(ODataServiceVersion.V40)),
|
||||
callback("odata.callback", Arrays.asList(ODataServiceVersion.V40)),
|
||||
continueOnError("odata.continue-on-error", Arrays.asList(ODataServiceVersion.V40)),
|
||||
includeAnnotations("odata.include-annotations", Arrays.asList(ODataServiceVersion.V40)),
|
||||
maxPageSize("odata.maxpagesize", Arrays.asList(ODataServiceVersion.V40)),
|
||||
trackChanges("odata.track-changes", Arrays.asList(ODataServiceVersion.V40)),
|
||||
respondAsync("respond-async", Arrays.asList(ODataServiceVersion.V40)),
|
||||
wait("wait", Arrays.asList(ODataServiceVersion.V40)),
|
||||
odataReturn("return", Arrays.asList(ODataServiceVersion.V40));
|
||||
|
||||
private final String preferenceName;
|
||||
|
||||
private final List<ODataServiceVersion> supportedVersions;
|
||||
|
||||
private PreferenceNames(final String preferenceName, final List<ODataServiceVersion> supportedVersions) {
|
||||
this.preferenceName = preferenceName;
|
||||
this.supportedVersions = supportedVersions;
|
||||
}
|
||||
|
||||
final PreferenceNames isSupportedBy(final ODataServiceVersion serviceVersion) {
|
||||
if (!supportedVersions.contains(serviceVersion)) {
|
||||
throw new ODataRuntimeException("Unsupported header " + this.toString());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return preferenceName;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,16 +21,20 @@ package org.apache.olingo.client.api.communication.request;
|
|||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import org.apache.olingo.client.api.communication.header.HeaderName;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* Abstract representation of an OData request. Get instance by using factories.
|
||||
*
|
||||
* @see CUDRequestFactory
|
||||
* @see RetrieveRequestFactory
|
||||
* @see BatchRequestFactory
|
||||
* @see InvokeRequestFactory
|
||||
* @see StreamedRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory
|
||||
*/
|
||||
public interface ODataRequest {
|
||||
|
||||
|
@ -175,6 +179,16 @@ public interface ODataRequest {
|
|||
*/
|
||||
ODataRequest addCustomHeader(final String name, final String value);
|
||||
|
||||
/**
|
||||
* Adds a custom OData request header. The method fails in case of the header name is not supported by the current
|
||||
* working version.
|
||||
*
|
||||
* @param name header name.
|
||||
* @param value header value.
|
||||
* @return current object
|
||||
*/
|
||||
ODataRequest addCustomHeader(final HeaderName name, final String value);
|
||||
|
||||
/**
|
||||
* Gets byte array representation of the full request header.
|
||||
*
|
||||
|
|
|
@ -34,6 +34,7 @@ public enum SegmentType {
|
|||
NAVIGATION,
|
||||
DERIVED_ENTITY_TYPE,
|
||||
VALUE("$value"),
|
||||
COUNT("$count"),
|
||||
BOUND_OPERATION,
|
||||
UNBOUND_OPERATION,
|
||||
METADATA("$metadata"),
|
||||
|
|
|
@ -42,8 +42,7 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
|
|||
*
|
||||
* @param inlineCount value
|
||||
* @return current URIBuilder instance
|
||||
* @see QueryOption#INLINECOUNT
|
||||
* @see org.apache.olingo.client.api.uri.QueryOption#INLINECOUNT
|
||||
*/
|
||||
URIBuilder inlineCount(InlineCount inlineCount);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.client.api.uri.v4;
|
||||
|
||||
import java.util.Map;
|
||||
import org.apache.olingo.client.api.uri.CommonURIBuilder;
|
||||
|
||||
public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
|
||||
|
@ -65,7 +66,7 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
|
|||
*
|
||||
* @param idValue opaque token.
|
||||
* @return current URIBuilder instance
|
||||
* @see QueryOption#ID
|
||||
* @see org.apache.olingo.client.api.uri.QueryOption#ID
|
||||
*/
|
||||
URIBuilder id(String idValue);
|
||||
|
||||
|
@ -74,7 +75,7 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
|
|||
*
|
||||
* @param value true or false
|
||||
* @return current URIBuilder instance
|
||||
* @see QueryOption#COUNT
|
||||
* @see org.apache.olingo.client.api.uri.QueryOption#COUNT
|
||||
*/
|
||||
URIBuilder count(boolean value);
|
||||
|
||||
|
@ -83,7 +84,19 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
|
|||
*
|
||||
* @param expression search expression
|
||||
* @return current URIBuilder instance
|
||||
* @see QueryOption#SEARCH
|
||||
* @see org.apache.olingo.client.api.uri.QueryOption#SEARCH
|
||||
*/
|
||||
URIBuilder search(String expression);
|
||||
|
||||
/**
|
||||
* The set of expanded entities can be refined through the application of expand options, expressed as a
|
||||
* semicolon-separated list of system query options, enclosed in parentheses, see [OData-URL].
|
||||
*
|
||||
* @param expandItem item to be expanded.
|
||||
* @param options System query options. Allowed query options are: $filter, $select, $orderby, $skip, $top, $count,
|
||||
* $search, $expand, and $levels.
|
||||
* @return current URIBuilder instance.
|
||||
* @see org.apache.olingo.client.api.uri.QueryOption#EXPAND
|
||||
*/
|
||||
URIBuilder expandWithOptions(String expandItem, Map<String, Object> options);
|
||||
}
|
||||
|
|
|
@ -38,14 +38,10 @@ import org.apache.olingo.client.api.v3.Configuration;
|
|||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||
import org.apache.olingo.client.api.communication.ODataServerErrorException;
|
||||
import org.apache.olingo.client.api.communication.header.HeaderName;
|
||||
import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
|
||||
import org.apache.olingo.client.api.communication.header.ODataHeaders;
|
||||
import org.apache.olingo.client.api.communication.header.ODataPreferences;
|
||||
import org.apache.olingo.client.api.communication.request.ODataRequest;
|
||||
import org.apache.olingo.client.api.communication.request.ODataStreamer;
|
||||
import org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory;
|
||||
import org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory;
|
||||
import org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory;
|
||||
import org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory;
|
||||
import org.apache.olingo.client.api.communication.response.ODataResponse;
|
||||
import org.apache.olingo.commons.api.format.Format;
|
||||
import org.apache.olingo.client.api.http.HttpClientException;
|
||||
|
@ -66,10 +62,14 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
* @param <T> Accepted content-type formats by the request in object.
|
||||
*
|
||||
* @see CUDRequestFactory
|
||||
* @see BatchRequestFactory
|
||||
* @see InvokeRequestFactory
|
||||
* @see StreamedRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory
|
||||
* @see org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory
|
||||
*/
|
||||
public class ODataRequestImpl<T extends Format> implements ODataRequest {
|
||||
|
||||
|
@ -250,6 +250,15 @@ public class ODataRequestImpl<T extends Format> implements ODataRequest {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ODataRequest addCustomHeader(final HeaderName name, final String value) {
|
||||
odataHeaders.setHeader(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -384,7 +393,8 @@ public class ODataRequestImpl<T extends Format> implements ODataRequest {
|
|||
if (odataClient.getServiceVersion() == ODataServiceVersion.V30
|
||||
&& ((Configuration) odataClient.getConfiguration()).isKeyAsSegment()) {
|
||||
addCustomHeader(
|
||||
HeaderName.dataServiceUrlConventions.toString(), ODataHeaderValues.keyAsSegment);
|
||||
HeaderName.dataServiceUrlConventions.toString(),
|
||||
new ODataPreferences(odataClient.getServiceVersion()).keyAsSegment());
|
||||
}
|
||||
|
||||
// Add all available headers
|
||||
|
|
|
@ -57,7 +57,7 @@ public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer<Ab
|
|||
setMetadataContext(tree.get(Constants.JSON_CONTEXT).textValue());
|
||||
}
|
||||
|
||||
for (final Iterator<JsonNode> itor = tree.get(Constants.JSON_VALUE).elements(); itor.hasNext();) {
|
||||
for (final Iterator<JsonNode> itor = tree.get(Constants.VALUE).elements(); itor.hasNext();) {
|
||||
final JsonNode node = itor.next();
|
||||
|
||||
final ServiceDocumentItemImpl item = new ServiceDocumentItemImpl();
|
||||
|
|
|
@ -87,21 +87,22 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Feed getFeed(final ODataEntitySet feed, final Class<? extends Feed> reference) {
|
||||
final Feed feedResource = ResourceFactory.newFeed(reference);
|
||||
public Feed getFeed(final ODataEntitySet entitySet, final Class<? extends Feed> reference) {
|
||||
final Feed feed = ResourceFactory.newFeed(reference);
|
||||
|
||||
feedResource.setCount(feed.getCount());
|
||||
feed.setContextURL(entitySet.getContextURL());
|
||||
feed.setCount(entitySet.getCount());
|
||||
|
||||
final URI next = feed.getNext();
|
||||
final URI next = entitySet.getNext();
|
||||
if (next != null) {
|
||||
feedResource.setNext(next);
|
||||
feed.setNext(next);
|
||||
}
|
||||
|
||||
for (ODataEntity entity : feed.getEntities()) {
|
||||
feedResource.getEntries().add(getEntry(entity, ResourceFactory.entryClassForFeed(reference)));
|
||||
for (ODataEntity entity : entitySet.getEntities()) {
|
||||
feed.getEntries().add(getEntry(entity, ResourceFactory.entryClassForFeed(reference)));
|
||||
}
|
||||
|
||||
return feedResource;
|
||||
return feed;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -112,6 +113,9 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
|
|||
@Override
|
||||
public Entry getEntry(final ODataEntity entity, final Class<? extends Entry> reference, final boolean setType) {
|
||||
final Entry entry = ResourceFactory.newEntry(reference);
|
||||
|
||||
entry.setContextURL(entity.getContextURL());
|
||||
entry.setId(entity.getReference());
|
||||
entry.setType(entity.getName());
|
||||
|
||||
// -------------------------------------------------------------
|
||||
|
@ -269,13 +273,15 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
|
|||
}
|
||||
|
||||
final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
|
||||
|
||||
|
||||
final URI next = resource.getNext();
|
||||
|
||||
final ODataEntitySet entitySet = next == null
|
||||
? client.getObjectFactory().newEntitySet()
|
||||
: client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString()));
|
||||
|
||||
entitySet.setContextURL(resource.getContextURL());
|
||||
|
||||
if (resource.getCount() != null) {
|
||||
entitySet.setCount(resource.getCount());
|
||||
}
|
||||
|
@ -283,7 +289,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
|
|||
for (Entry entryResource : resource.getEntries()) {
|
||||
entitySet.addEntity(getODataEntity(entryResource));
|
||||
}
|
||||
|
||||
|
||||
return entitySet;
|
||||
}
|
||||
|
||||
|
@ -306,16 +312,19 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
|
|||
final ODataEntity entity = resource.getSelfLink() == null
|
||||
? client.getObjectFactory().newEntity(resource.getType())
|
||||
: client.getObjectFactory().newEntity(resource.getType(),
|
||||
URIUtils.getURI(base, resource.getSelfLink().getHref()));
|
||||
URIUtils.getURI(base, resource.getSelfLink().getHref()));
|
||||
|
||||
entity.setContextURL(resource.getContextURL());
|
||||
entity.setReference(resource.getId());
|
||||
|
||||
if (StringUtils.isNotBlank(resource.getETag())) {
|
||||
entity.setETag(resource.getETag());
|
||||
}
|
||||
|
||||
|
||||
if (resource.getEditLink() != null) {
|
||||
entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
|
||||
}
|
||||
|
||||
|
||||
for (Link link : resource.getAssociationLinks()) {
|
||||
entity.addLink(client.getObjectFactory().newAssociationLink(link.getTitle(), base, link.getHref()));
|
||||
}
|
||||
|
@ -327,16 +336,16 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
|
|||
if (inlineEntry == null && inlineFeed == null) {
|
||||
entity.addLink(
|
||||
client.getObjectFactory().newEntityNavigationLink(link.getTitle(), base, link.getHref()));
|
||||
} else if (inlineFeed == null) {
|
||||
} else if (inlineEntry != null) {
|
||||
entity.addLink(client.getObjectFactory().newInlineEntity(
|
||||
link.getTitle(), base, link.getHref(),
|
||||
getODataEntity(inlineEntry,
|
||||
inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI())));
|
||||
inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI())));
|
||||
} else {
|
||||
entity.addLink(client.getObjectFactory().newInlineEntitySet(
|
||||
link.getTitle(), base, link.getHref(),
|
||||
getODataEntitySet(inlineFeed,
|
||||
inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI())));
|
||||
inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,16 +383,16 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
|
|||
value = client.getPrimitiveValueBuilder().
|
||||
setText(resource.getValue().asSimple().get()).
|
||||
setType(resource.getType() == null
|
||||
? null
|
||||
: EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
|
||||
? null
|
||||
: EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
|
||||
} else if (resource.getValue().isGeospatial()) {
|
||||
value = client.getGeospatialValueBuilder().
|
||||
setValue(resource.getValue().asGeospatial().get()).
|
||||
setType(resource.getType() == null
|
||||
|| EdmPrimitiveTypeKind.Geography.getFullQualifiedName().toString().equals(resource.getType())
|
||||
|| EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().toString().equals(resource.getType())
|
||||
? null
|
||||
: EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
|
||||
|| EdmPrimitiveTypeKind.Geography.getFullQualifiedName().toString().equals(resource.getType())
|
||||
|| EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().toString().equals(resource.getType())
|
||||
? null
|
||||
: EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
|
||||
} else if (resource.getValue().isComplex()) {
|
||||
value = new ODataComplexValue(resource.getType());
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.apache.olingo.client.core.uri;
|
|||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -60,9 +61,7 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
|
|||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected final List<Segment> segments = new ArrayList<Segment>();
|
||||
|
||||
/**
|
||||
|
@ -111,17 +110,11 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
|
|||
|
||||
@Override
|
||||
public UB appendKeySegment(final Map<String, Object> segmentValues) {
|
||||
if (segmentValues == null || segmentValues.isEmpty()) {
|
||||
final String key = buildMultiKeySegment(segmentValues, true);
|
||||
if (StringUtils.isEmpty(key)) {
|
||||
segments.add(new Segment(SegmentType.KEY, noKeysWrapper()));
|
||||
} else {
|
||||
final StringBuilder keyBuilder = new StringBuilder().append('(');
|
||||
for (Map.Entry<String, Object> entry : segmentValues.entrySet()) {
|
||||
keyBuilder.append(entry.getKey()).append('=').append(URIUtils.escape(entry.getValue()));
|
||||
keyBuilder.append(',');
|
||||
}
|
||||
keyBuilder.deleteCharAt(keyBuilder.length() - 1).append(')');
|
||||
|
||||
segments.add(new Segment(SegmentType.KEY, keyBuilder.toString()));
|
||||
segments.add(new Segment(SegmentType.KEY, key));
|
||||
}
|
||||
|
||||
return getThis();
|
||||
|
@ -179,7 +172,14 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
|
|||
|
||||
@Override
|
||||
public UB expand(final String... expandItems) {
|
||||
return addQueryOption(QueryOption.EXPAND, StringUtils.join(expandItems, ","));
|
||||
final List<String> values = new ArrayList<String>();
|
||||
if (queryOptions.containsKey(QueryOption.EXPAND.toString())) {
|
||||
values.add(queryOptions.get(QueryOption.EXPAND.toString()));
|
||||
}
|
||||
|
||||
values.addAll(Arrays.asList(expandItems));
|
||||
|
||||
return addQueryOption(QueryOption.EXPAND, StringUtils.join(values, ","));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -199,7 +199,14 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
|
|||
|
||||
@Override
|
||||
public UB select(final String... selectItems) {
|
||||
return addQueryOption(QueryOption.SELECT, StringUtils.join(selectItems, ","));
|
||||
final List<String> values = new ArrayList<String>();
|
||||
if (queryOptions.containsKey(QueryOption.SELECT.toString())) {
|
||||
values.add(queryOptions.get(QueryOption.SELECT.toString()));
|
||||
}
|
||||
|
||||
values.addAll(Arrays.asList(selectItems));
|
||||
|
||||
return addQueryOption(QueryOption.SELECT, StringUtils.join(values, ","));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -271,4 +278,19 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
|
|||
return build().toASCIIString();
|
||||
}
|
||||
|
||||
protected String buildMultiKeySegment(final Map<String, Object> segmentValues, final boolean escape) {
|
||||
if (segmentValues == null || segmentValues.isEmpty()) {
|
||||
return StringUtils.EMPTY;
|
||||
} else {
|
||||
final StringBuilder keyBuilder = new StringBuilder().append('(');
|
||||
for (Map.Entry<String, Object> entry : segmentValues.entrySet()) {
|
||||
keyBuilder.append(entry.getKey()).append('=').append(
|
||||
escape ? URIUtils.escape(entry.getValue()) : entry.getValue());
|
||||
keyBuilder.append(',');
|
||||
}
|
||||
keyBuilder.deleteCharAt(keyBuilder.length() - 1).append(')');
|
||||
|
||||
return keyBuilder.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.client.core.uri.v4;
|
||||
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.client.api.uri.QueryOption;
|
||||
import org.apache.olingo.client.api.uri.SegmentType;
|
||||
|
@ -78,11 +79,6 @@ public class URIBuilderImpl extends AbstractURIBuilder<URIBuilder> implements UR
|
|||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URIBuilder count(final boolean value) {
|
||||
return addQueryOption(QueryOption.COUNT, Boolean.toString(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public URIBuilder appendAllSegment() {
|
||||
segments.add(new Segment(SegmentType.ALL, SegmentType.ALL.getValue()));
|
||||
|
@ -99,4 +95,13 @@ public class URIBuilderImpl extends AbstractURIBuilder<URIBuilder> implements UR
|
|||
return addQueryOption(QueryOption.SEARCH, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URIBuilder count(final boolean value) {
|
||||
return addQueryOption(QueryOption.COUNT, Boolean.toString(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public URIBuilder expandWithOptions(final String expandItem, final Map<String, Object> options) {
|
||||
return expand(expandItem + buildMultiKeySegment(options, false));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,8 +82,8 @@ public class ODataClientImpl extends AbstractODataClient implements ODataClient
|
|||
@Override
|
||||
public ODataHeaders getVersionHeaders() {
|
||||
final ODataHeadersImpl odataHeaders = new ODataHeadersImpl();
|
||||
odataHeaders.setHeader(HeaderName.maxDataServiceVersion, ODataServiceVersion.V40.toString());
|
||||
odataHeaders.setHeader(HeaderName.dataServiceVersion, ODataServiceVersion.V40.toString());
|
||||
odataHeaders.setHeader(HeaderName.odataMaxVersion, ODataServiceVersion.V40.toString());
|
||||
odataHeaders.setHeader(HeaderName.odataVersion, ODataServiceVersion.V40.toString());
|
||||
return odataHeaders;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.LinkedHashMap;
|
|||
import java.util.Set;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.olingo.client.api.communication.header.HeaderName;
|
||||
import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
|
||||
import org.apache.olingo.client.api.communication.header.ODataPreferences;
|
||||
import org.apache.olingo.client.api.communication.request.UpdateType;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
|
||||
|
@ -229,11 +229,11 @@ public class EntityCreateTestITCase extends AbstractTestITCase {
|
|||
|
||||
final ODataEntityCreateRequest createReq = client.getCUDRequestFactory().getEntityCreateRequest(
|
||||
client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Customer").build(), original);
|
||||
createReq.setPrefer(ODataHeaderValues.preferReturnNoContent);
|
||||
createReq.setPrefer(new ODataPreferences(client.getServiceVersion()).returnNoContent());
|
||||
|
||||
final ODataEntityCreateResponse createRes = createReq.execute();
|
||||
assertEquals(204, createRes.getStatusCode());
|
||||
assertEquals(ODataHeaderValues.preferReturnNoContent,
|
||||
assertEquals(new ODataPreferences(client.getServiceVersion()).returnNoContent(),
|
||||
createRes.getHeader(HeaderName.preferenceApplied).iterator().next());
|
||||
|
||||
try {
|
||||
|
@ -260,7 +260,7 @@ public class EntityCreateTestITCase extends AbstractTestITCase {
|
|||
client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), original);
|
||||
createReq.setFormat(ODataPubFormat.JSON_FULL_METADATA);
|
||||
createReq.setContentType(ContentType.APPLICATION_ATOM_XML.getMimeType());
|
||||
createReq.setPrefer(ODataHeaderValues.preferReturnContent);
|
||||
createReq.setPrefer(new ODataPreferences(client.getServiceVersion()).returnContent());
|
||||
|
||||
try {
|
||||
final ODataEntityCreateResponse createRes = createReq.execute();
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.net.URI;
|
|||
import java.util.LinkedHashMap;
|
||||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||
import org.apache.olingo.client.api.communication.header.HeaderName;
|
||||
import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
|
||||
import org.apache.olingo.client.api.communication.header.ODataPreferences;
|
||||
import org.apache.olingo.client.api.communication.request.UpdateType;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
||||
|
@ -210,11 +210,11 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
|
|||
@Test
|
||||
public void updateReturnContent() throws EdmPrimitiveTypeException {
|
||||
final ODataEntityUpdateRequest req = buildMultiKeyUpdateReq(client.getConfiguration().getDefaultPubFormat());
|
||||
req.setPrefer(ODataHeaderValues.preferReturnContent);
|
||||
req.setPrefer(new ODataPreferences(client.getServiceVersion()).returnContent());
|
||||
|
||||
final ODataEntityUpdateResponse res = req.execute();
|
||||
assertEquals(200, res.getStatusCode());
|
||||
assertEquals(ODataHeaderValues.preferReturnContent,
|
||||
assertEquals(new ODataPreferences(client.getServiceVersion()).returnContent(),
|
||||
res.getHeader(HeaderName.preferenceApplied).iterator().next());
|
||||
assertNotNull(res.getBody());
|
||||
}
|
||||
|
|
|
@ -100,11 +100,11 @@ public class PropertyValueTestITCase extends AbstractTestITCase {
|
|||
req.setAccept("application/json");
|
||||
ODataRetrieveResponse<ODataEntity> res = req.execute();
|
||||
assertEquals(200, res.getStatusCode());
|
||||
ODataEntity entitySet = res.getBody();
|
||||
assertNotNull(entitySet);
|
||||
ODataEntity entity = res.getBody();
|
||||
assertNotNull(entity);
|
||||
assertEquals("fi653p3+MklA/LdoBlhWgnMTUUEo8tEgtbMXnF0a3CUNL9BZxXpSRiD9ebTnmNR0zWPjJ"
|
||||
+ "VIDx4tdmCnq55XrJh+RW9aI/b34wAogK3kcORw=",
|
||||
entitySet.getProperties().get(0).getValue().toString());
|
||||
entity.getProperties().get(0).getValue().toString());
|
||||
}
|
||||
|
||||
@Test(expected = ODataClientErrorException.class)
|
||||
|
|
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.client.core.it.v4;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRawResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntity;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntitySet;
|
||||
import org.apache.olingo.commons.api.domain.ODataInlineEntity;
|
||||
import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
|
||||
import org.apache.olingo.commons.api.domain.ODataLink;
|
||||
import org.apache.olingo.commons.api.domain.ODataProperty;
|
||||
import org.apache.olingo.commons.api.format.ODataPubFormat;
|
||||
import org.apache.olingo.client.api.uri.CommonURIBuilder;
|
||||
import org.apache.olingo.commons.core.op.ResourceFactory;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* This is the unit test class to check entity retrieve operations.
|
||||
*/
|
||||
public class EntityRetrieveTestITCase extends AbstractTestITCase {
|
||||
|
||||
protected String getServiceRoot() {
|
||||
return testStaticServiceRootURL;
|
||||
}
|
||||
|
||||
private void withInlineEntry(final ODataPubFormat format) {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
|
||||
appendEntitySetSegment("Customers").appendKeySegment(1).expand("Company");
|
||||
|
||||
final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
|
||||
req.setFormat(format);
|
||||
|
||||
final ODataRetrieveResponse<ODataEntity> res = req.execute();
|
||||
final ODataEntity entity = res.getBody();
|
||||
|
||||
assertNotNull(entity);
|
||||
assertEquals("#Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getName());
|
||||
assertEquals(getServiceRoot() + "/Customers(PersonID=1)", entity.getEditLink().toASCIIString());
|
||||
|
||||
assertEquals(3, entity.getNavigationLinks().size());
|
||||
assertTrue(entity.getAssociationLinks().isEmpty());
|
||||
|
||||
boolean found = false;
|
||||
|
||||
for (ODataLink link : entity.getNavigationLinks()) {
|
||||
if (link instanceof ODataInlineEntity) {
|
||||
final ODataEntity inline = ((ODataInlineEntity) link).getEntity();
|
||||
assertNotNull(inline);
|
||||
|
||||
debugEntry(client.getBinder().getEntry(
|
||||
inline, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)), "Just read");
|
||||
|
||||
final List<ODataProperty> properties = inline.getProperties();
|
||||
assertEquals(5, properties.size());
|
||||
|
||||
assertTrue(properties.get(0).getName().equals("CompanyID")
|
||||
|| properties.get(1).getName().equals("CompanyID")
|
||||
|| properties.get(2).getName().equals("CompanyID")
|
||||
|| properties.get(3).getName().equals("CompanyID")
|
||||
|| properties.get(4).getName().equals("CompanyID"));
|
||||
assertTrue(properties.get(0).getValue().toString().equals("0")
|
||||
|| properties.get(1).getValue().toString().equals("0")
|
||||
|| properties.get(2).getValue().toString().equals("0")
|
||||
|| properties.get(3).getValue().toString().equals("0")
|
||||
|| properties.get(4).getValue().toString().equals("0"));
|
||||
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withInlineEntryFromAtom() {
|
||||
withInlineEntry(ODataPubFormat.ATOM);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void withInlineEntryFromJSON() {
|
||||
// this needs to be full, otherwise there is no mean to recognize links
|
||||
withInlineEntry(ODataPubFormat.JSON_FULL_METADATA);
|
||||
}
|
||||
|
||||
private void withInlineFeed(final ODataPubFormat format) {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
|
||||
appendEntitySetSegment("Customers").appendKeySegment(1).expand("Orders");
|
||||
|
||||
final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
|
||||
req.setFormat(format);
|
||||
|
||||
final ODataRetrieveResponse<ODataEntity> res = req.execute();
|
||||
final ODataEntity entity = res.getBody();
|
||||
assertNotNull(entity);
|
||||
|
||||
boolean found = false;
|
||||
|
||||
for (ODataLink link : entity.getNavigationLinks()) {
|
||||
if (link instanceof ODataInlineEntitySet) {
|
||||
final ODataEntitySet inline = ((ODataInlineEntitySet) link).getEntitySet();
|
||||
assertNotNull(inline);
|
||||
|
||||
debugFeed(client.getBinder().getFeed(inline, ResourceFactory.feedClassForFormat(
|
||||
format == ODataPubFormat.ATOM)), "Just read");
|
||||
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withInlineFeedFromAtom() {
|
||||
withInlineFeed(ODataPubFormat.ATOM);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void withInlineFeedFromJSON() {
|
||||
// this needs to be full, otherwise there is no mean to recognize links
|
||||
withInlineFeed(ODataPubFormat.JSON_FULL_METADATA);
|
||||
}
|
||||
|
||||
private void rawRequest(final ODataPubFormat format) {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
|
||||
appendEntitySetSegment("People").appendKeySegment(5);
|
||||
|
||||
final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
|
||||
req.setFormat(format.toString(client.getServiceVersion()));
|
||||
|
||||
final ODataRawResponse res = req.execute();
|
||||
assertNotNull(res);
|
||||
|
||||
final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
|
||||
assertNull(entitySet);
|
||||
|
||||
final ODataEntity entity = res.getBodyAs(ODataEntity.class);
|
||||
assertTrue(entity.getReference().endsWith("/StaticService/V40/Static.svc/People(5)"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rawRequestAsAtom() {
|
||||
rawRequest(ODataPubFormat.ATOM);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void rawRequestAsJSON() {
|
||||
// this needs to be full, otherwise actions will not be provided
|
||||
rawRequest(ODataPubFormat.JSON_FULL_METADATA);
|
||||
}
|
||||
|
||||
private void multiKey(final ODataPubFormat format) throws EdmPrimitiveTypeException {
|
||||
final LinkedHashMap<String, Object> multiKey = new LinkedHashMap<String, Object>();
|
||||
multiKey.put("ProductID", "6");
|
||||
multiKey.put("ProductDetailID", 1);
|
||||
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
|
||||
appendEntitySetSegment("ProductDetails").appendKeySegment(multiKey);
|
||||
|
||||
final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
|
||||
req.setFormat(format);
|
||||
|
||||
final ODataRetrieveResponse<ODataEntity> res = req.execute();
|
||||
final ODataEntity entity = res.getBody();
|
||||
assertNotNull(entity);
|
||||
assertEquals(Integer.valueOf(1),
|
||||
entity.getProperty("ProductDetailID").getPrimitiveValue().toCastValue(Integer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multiKeyAsAtom() throws EdmPrimitiveTypeException {
|
||||
multiKey(ODataPubFormat.ATOM);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void multiKeyAsJSON() throws EdmPrimitiveTypeException {
|
||||
multiKey(ODataPubFormat.JSON_FULL_METADATA);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForETagAsATOM() {
|
||||
checkForETag(ODataPubFormat.ATOM);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void checkForETagAsJSON() {
|
||||
checkForETag(ODataPubFormat.JSON_FULL_METADATA);
|
||||
}
|
||||
|
||||
private void checkForETag(final ODataPubFormat format) {
|
||||
final CommonURIBuilder<?> uriBuilder =
|
||||
client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Orders").appendKeySegment(8);
|
||||
|
||||
final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
|
||||
req.setFormat(format);
|
||||
|
||||
final ODataRetrieveResponse<ODataEntity> res = req.execute();
|
||||
assertEquals(200, res.getStatusCode());
|
||||
|
||||
final String etag = res.getEtag();
|
||||
assertTrue(StringUtils.isNotBlank(etag));
|
||||
|
||||
final ODataEntity order = res.getBody();
|
||||
assertEquals(etag, order.getETag());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Ignore
|
||||
public void issue99() {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Car");
|
||||
|
||||
final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
|
||||
req.setFormat(ODataPubFormat.JSON);
|
||||
|
||||
// this statement should cause an IllegalArgumentException bearing JsonParseException
|
||||
// since we are attempting to parse an EntitySet as if it was an Entity
|
||||
req.execute().getBody();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveEntityReferenceAsAtom() {
|
||||
retrieveEntityReference(ODataPubFormat.ATOM);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void retrieveEntityReferenceAsJSON() {
|
||||
retrieveEntityReference(ODataPubFormat.JSON_FULL_METADATA);
|
||||
}
|
||||
|
||||
private void retrieveEntityReference(final ODataPubFormat format) {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
|
||||
appendEntitySetSegment("Orders").appendKeySegment(8).appendNavigationSegment("CustomerForOrder").
|
||||
appendRefSegment();
|
||||
|
||||
final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
|
||||
req.setFormat(format);
|
||||
|
||||
final ODataRetrieveResponse<ODataEntity> res = req.execute();
|
||||
assertNotNull(res);
|
||||
|
||||
final ODataEntity entity = res.getBody();
|
||||
assertNotNull(entity);
|
||||
assertTrue(entity.getReference().endsWith("/StaticService/V40/Static.svc/Customers(PersonID=1)"));
|
||||
}
|
||||
}
|
|
@ -104,6 +104,8 @@ public class EntitySetTestITCase extends AbstractTestITCase {
|
|||
|
||||
assertNotNull(feed);
|
||||
|
||||
assertTrue(feed.getContextURL().toASCIIString().endsWith("$metadata#People"));
|
||||
|
||||
debugFeed(client.getBinder().getFeed(feed, ResourceFactory.feedClassForFormat(
|
||||
ODataPubFormat.ATOM == format)), "Just retrieved feed");
|
||||
|
||||
|
@ -151,5 +153,6 @@ public class EntitySetTestITCase extends AbstractTestITCase {
|
|||
|
||||
final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
|
||||
assertNotNull(entitySet);
|
||||
assertTrue(entitySet.getContextURL().toASCIIString().endsWith("$metadata#People"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.client.core.it.v4;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.io.IOException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
|
||||
import org.apache.olingo.commons.api.format.ODataValueFormat;
|
||||
import org.apache.olingo.client.api.uri.CommonURIBuilder;
|
||||
import org.apache.olingo.commons.api.domain.ODataPrimitiveValue;
|
||||
import org.apache.olingo.commons.api.domain.ODataProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.format.ODataPubFormat;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PropertyValueTestITCase extends AbstractTestITCase {
|
||||
|
||||
@Test
|
||||
public void retrieveIntPropertyValueTest() throws EdmPrimitiveTypeException {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("PersonID").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setFormat(ODataValueFormat.TEXT);
|
||||
assertEquals("5", req.execute().getBody().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveBooleanPropertyValueTest() throws EdmPrimitiveTypeException {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("IsRegistered").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setFormat(ODataValueFormat.TEXT);
|
||||
assertEquals("true", req.execute().getBody().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveStringPropertyValueTest() throws EdmPrimitiveTypeException {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("FirstName").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setFormat(ODataValueFormat.TEXT);
|
||||
assertEquals("Peter", req.execute().getBody().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveDatePropertyValueTest() {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("Orders").appendKeySegment(8).appendPropertySegment("OrderDate").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setFormat(ODataValueFormat.TEXT);
|
||||
final ODataPrimitiveValue property = req.execute().getBody();
|
||||
assertEquals("2011-03-04T16:03:57Z", property.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveDecimalPropertyValueTest() throws EdmPrimitiveTypeException {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("Height").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setFormat(ODataValueFormat.TEXT);
|
||||
final ODataPrimitiveValue property = req.execute().getBody();
|
||||
assertEquals("179", property.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveBinaryPropertyValueTest() throws IOException {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("PDC").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setFormat(ODataValueFormat.TEXT);
|
||||
final ODataPrimitiveValue property = req.execute().getBody();
|
||||
assertEquals("fi653p3+MklA/LdoBlhWgnMTUUEo8tEgtbMXnF0a3CUNL9BZxXpSRiD9ebTnmNR0zWPjJ"
|
||||
+ "VIDx4tdmCnq55XrJh+RW9aI/b34wAogK3kcORw=", property.toString());
|
||||
}
|
||||
|
||||
@Test(expected = ODataClientErrorException.class)
|
||||
public void retrieveBinaryPropertyValueTestWithAtom() throws IOException {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("PDC").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setAccept(ODataPubFormat.ATOM.toString(ODataServiceVersion.V40));
|
||||
req.execute().getBody();
|
||||
}
|
||||
|
||||
@Test(expected = ODataClientErrorException.class)
|
||||
public void retrieveBinaryPropertyValueTestWithXML() throws IOException {
|
||||
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("PDC").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setAccept(ODataFormat.XML.toString());
|
||||
req.execute().getBody();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveCollectionPropertyValueTest() {
|
||||
CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("Numbers");
|
||||
final ODataPropertyRequest req = client.getRetrieveRequestFactory().getPropertyRequest(uriBuilder.build());
|
||||
req.setFormat(ODataFormat.XML);
|
||||
final ODataProperty property = req.execute().getBody();
|
||||
assertTrue(property.getValue().isCollection());
|
||||
assertEquals("555-555-5555", property.getCollectionValue().iterator().next().asPrimitive().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveNullPropertyValueTest() {
|
||||
CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
|
||||
appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("MiddleName").
|
||||
appendValueSegment();
|
||||
final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
|
||||
req.setFormat(ODataValueFormat.TEXT);
|
||||
final ODataPrimitiveValue property = req.execute().getBody();
|
||||
assertTrue(StringUtils.isBlank(property.toString()));
|
||||
}
|
||||
}
|
|
@ -104,7 +104,7 @@ public class URIBuilderTest extends AbstractTest {
|
|||
public void unboundAction() throws URISyntaxException {
|
||||
final URIBuilder uriBuilder = getClient().getURIBuilder(SERVICE_ROOT).
|
||||
appendOperationCallSegment("ProductsByCategoryId",
|
||||
Collections.<String, Object>singletonMap("categoryId", 2));
|
||||
Collections.<String, Object>singletonMap("categoryId", 2));
|
||||
|
||||
assertEquals(new org.apache.http.client.utils.URIBuilder(
|
||||
SERVICE_ROOT + "/ProductsByCategoryId(categoryId=2)").build(), uriBuilder.build());
|
||||
|
@ -128,4 +128,22 @@ public class URIBuilderTest extends AbstractTest {
|
|||
assertEquals(new org.apache.http.client.utils.URIBuilder(
|
||||
SERVICE_ROOT + "/Customers/Model/Namespace.VipCustomer(1)").build(), uriBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expandMoreThenOnce() throws URISyntaxException {
|
||||
URI uri = getClient().getURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
|
||||
expand("Orders", "Customers").expand("Info").build();
|
||||
|
||||
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products(5)").
|
||||
addParameter("$expand", "Orders,Customers,Info").build(), uri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectMoreThenOnce() throws URISyntaxException {
|
||||
URI uri = getClient().getURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Customers").appendKeySegment(5).
|
||||
select("Name", "Surname").expand("Info").select("Gender").build();
|
||||
|
||||
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Customers(5)").
|
||||
addParameter("$select", "Name,Surname,Gender").addParameter("$expand", "Info").build(), uri);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.olingo.client.core.v4;
|
|||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.apache.olingo.client.api.v4.ODataClient;
|
||||
import org.apache.olingo.client.api.uri.v4.URIBuilder;
|
||||
|
@ -38,6 +39,22 @@ public class URIBuilderTest extends AbstractTest {
|
|||
return v4Client;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expandWithOptions() throws URISyntaxException {
|
||||
URI uri = getClient().getURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
|
||||
expandWithOptions("ProductDetails", new LinkedHashMap<String, Object>() {
|
||||
private static final long serialVersionUID = 3109256773218160485L;
|
||||
|
||||
{
|
||||
put("$expand", "ProductInfo");
|
||||
put("$select", "Price");
|
||||
}
|
||||
}).expand("Orders", "Customers").build();
|
||||
|
||||
assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products(5)").
|
||||
addParameter("$expand", "ProductDetails($expand=ProductInfo,$select=Price),Orders,Customers").build(), uri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void count() throws URISyntaxException {
|
||||
URI uri = getClient().getURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count().build();
|
||||
|
@ -132,5 +149,4 @@ public class URIBuilderTest extends AbstractTest {
|
|||
assertEquals(new org.apache.http.client.utils.URIBuilder(
|
||||
SERVICE_ROOT + "/Products").addParameter("$search", "blue OR green").build(), uriBuilder.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ public interface Constants {
|
|||
|
||||
public static final QName QNAME_ATTR_XML_BASE = new QName(XMLConstants.XML_NS_URI, ATTR_XML_BASE);
|
||||
|
||||
public static final String CONTEXT = "context";
|
||||
|
||||
public static final String ATTR_REL = "rel";
|
||||
|
||||
public static final String ATTR_TITLE = "title";
|
||||
|
@ -173,7 +175,7 @@ public interface Constants {
|
|||
|
||||
public final static String JSON_NULL = "odata.null";
|
||||
|
||||
public final static String JSON_VALUE = "value";
|
||||
public final static String VALUE = "value";
|
||||
|
||||
public final static String JSON_URL = "url";
|
||||
|
||||
|
@ -192,6 +194,12 @@ public interface Constants {
|
|||
// Atom stuff
|
||||
public final static String ATOM_ELEM_ENTRY = "entry";
|
||||
|
||||
public final static String ATOM_ELEM_ENTRY_REF = "ref";
|
||||
|
||||
public final static String ATOM_ELEM_ENTRY_REF_ID = "id";
|
||||
|
||||
public final static QName QNAME_ATOM_ELEM_ENTRY_REF_ID = new QName(ATOM_ELEM_ENTRY_REF_ID);
|
||||
|
||||
public static final QName QNAME_ATOM_ELEM_ENTRY = new QName(NS_ATOM, ATOM_ELEM_ENTRY);
|
||||
|
||||
public final static String ATOM_ELEM_FEED = "feed";
|
||||
|
|
|
@ -38,6 +38,21 @@ public interface Entry {
|
|||
*/
|
||||
URI getBaseURI();
|
||||
|
||||
/**
|
||||
* The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
|
||||
* fragment identifying the relevant portion of the metadata document.
|
||||
*
|
||||
* @return context URL.
|
||||
*/
|
||||
URI getContextURL();
|
||||
|
||||
/**
|
||||
* Set context URL.
|
||||
*
|
||||
* @param contextURL context URL.
|
||||
*/
|
||||
void setContextURL(final URI contextURL);
|
||||
|
||||
/**
|
||||
* Gets entry type.
|
||||
*
|
||||
|
@ -53,12 +68,19 @@ public interface Entry {
|
|||
void setType(String type);
|
||||
|
||||
/**
|
||||
* Gest entry ID.
|
||||
* Gets entry ID.
|
||||
*
|
||||
* @return entry ID.
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Sets entry ID.
|
||||
*
|
||||
* @param id entry ID.
|
||||
*/
|
||||
void setId(String id);
|
||||
|
||||
/**
|
||||
* Gets entry self link.
|
||||
*
|
||||
|
|
|
@ -30,6 +30,21 @@ public interface Feed {
|
|||
*/
|
||||
URI getBaseURI();
|
||||
|
||||
/**
|
||||
* The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
|
||||
* fragment identifying the relevant portion of the metadata document.
|
||||
*
|
||||
* @return context URL.
|
||||
*/
|
||||
URI getContextURL();
|
||||
|
||||
/**
|
||||
* Set context URL.
|
||||
*
|
||||
* @param contextURL context URL.
|
||||
*/
|
||||
void setContextURL(final URI contextURL);
|
||||
|
||||
/**
|
||||
* Sets number of entries.
|
||||
*
|
||||
|
@ -71,5 +86,4 @@ public interface Feed {
|
|||
* @param next next link.
|
||||
*/
|
||||
void setNext(URI next);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,18 @@
|
|||
*/
|
||||
package org.apache.olingo.commons.api.data;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
public interface Property {
|
||||
|
||||
/**
|
||||
* The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
|
||||
* fragment identifying the relevant portion of the metadata document.
|
||||
*
|
||||
* @return context URL.
|
||||
*/
|
||||
URI getContextURL();
|
||||
|
||||
String getName();
|
||||
|
||||
void setName(String name);
|
||||
|
|
|
@ -16,30 +16,37 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.client.api.communication.header;
|
||||
package org.apache.olingo.commons.api.domain;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Constant header values class.
|
||||
* OData entity.
|
||||
*/
|
||||
public class ODataHeaderValues {
|
||||
public abstract class AbstractODataPayload extends ODataItem {
|
||||
|
||||
private static final long serialVersionUID = -8234709365887433612L;
|
||||
|
||||
/**
|
||||
* <code>Prefer</code> header, return content.
|
||||
* Context URL.
|
||||
*/
|
||||
private URI contextURL;
|
||||
|
||||
public AbstractODataPayload(final String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
|
||||
* fragment identifying the relevant portion of the metadata document.
|
||||
*
|
||||
* @see ODataHeaders.HeaderName#prefer
|
||||
* @return context URL.
|
||||
*/
|
||||
public static final String preferReturnContent = "return-content";
|
||||
|
||||
/**
|
||||
* <code>Prefer</code> header, return no content.
|
||||
*
|
||||
* @see ODataHeaders.HeaderName#prefer
|
||||
*/
|
||||
public static final String preferReturnNoContent = "return-no-content";
|
||||
|
||||
/**
|
||||
* @see ODataHeaders.HeaderName#dataServiceUrlConventions
|
||||
*/
|
||||
public static final String keyAsSegment = "KeyAsSegment";
|
||||
public URI getContextURL() {
|
||||
return contextURL;
|
||||
}
|
||||
|
||||
public void setContextURL(final URI contextURL) {
|
||||
this.contextURL = contextURL;
|
||||
}
|
||||
}
|
|
@ -26,10 +26,15 @@ import org.apache.commons.lang3.StringUtils;
|
|||
/**
|
||||
* OData entity.
|
||||
*/
|
||||
public class ODataEntity extends ODataItem implements ODataInvokeResult {
|
||||
public class ODataEntity extends AbstractODataPayload implements ODataInvokeResult {
|
||||
|
||||
private static final long serialVersionUID = 8360640095932811034L;
|
||||
|
||||
/**
|
||||
* Entity reference.
|
||||
*/
|
||||
private String reference;
|
||||
|
||||
/**
|
||||
* ETag.
|
||||
*/
|
||||
|
@ -89,6 +94,30 @@ public class ODataEntity extends ODataItem implements ODataInvokeResult {
|
|||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* To request entity references in place of the actual entities, the client issues a GET request with /$ref appended
|
||||
* to the resource path.
|
||||
* <br />
|
||||
* If the resource path does not identify an entity or a collection of entities, the service returns 404 Not Found.
|
||||
* <br />
|
||||
* If the resource path terminates on a collection, the response MUST be the format-specific representation of a
|
||||
* collection of entity references pointing to the related entities. If no entities are related, the response is the
|
||||
* format-specific representation of an empty collection.
|
||||
* <br />
|
||||
* If the resource path terminates on a single entity, the response MUST be the format-specific representation of an
|
||||
* entity reference pointing to the related single entity. If the resource path terminates on a single entity and no
|
||||
* such entity exists, the service returns 404 Not Found.
|
||||
*
|
||||
* @return entity reference.
|
||||
*/
|
||||
public String getReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
public void setReference(final String reference) {
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ETag.
|
||||
*
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.util.List;
|
|||
/**
|
||||
* OData entity collection. If pagination was used to get this instance, forward page navigation URI will be available.
|
||||
*/
|
||||
public class ODataEntitySet extends ODataItem implements ODataInvokeResult {
|
||||
public class ODataEntitySet extends AbstractODataPayload implements ODataInvokeResult {
|
||||
|
||||
private static final long serialVersionUID = 9039605899821494024L;
|
||||
|
||||
|
|
|
@ -39,16 +39,16 @@ public abstract class ODataItem implements Serializable {
|
|||
*/
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(ODataItem.class);
|
||||
|
||||
/**
|
||||
* OData item self link.
|
||||
*/
|
||||
protected URI link;
|
||||
|
||||
/**
|
||||
* OData entity name/type.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* OData item self link.
|
||||
*/
|
||||
protected URI link;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
|
@ -58,6 +58,15 @@ public abstract class ODataItem implements Serializable {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns OData entity name.
|
||||
*
|
||||
* @return entity name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns self link.
|
||||
*
|
||||
|
@ -76,15 +85,6 @@ public abstract class ODataItem implements Serializable {
|
|||
this.link = link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns OData entity name.
|
||||
*
|
||||
* @return entity name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*/
|
||||
|
|
|
@ -98,7 +98,6 @@ public class ODataLink extends ODataItem {
|
|||
|
||||
return uri.normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Link type.
|
||||
*/
|
||||
|
@ -186,5 +185,4 @@ public class ODataLink extends ODataItem {
|
|||
public String getMediaETag() {
|
||||
return mediaETag;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,8 +49,15 @@ abstract class AbstractAtomDealer {
|
|||
protected final QName countQName;
|
||||
|
||||
protected final QName uriQName;
|
||||
|
||||
protected final QName nextQName;
|
||||
|
||||
protected final QName contextQName;
|
||||
|
||||
protected final QName entityRefQName;
|
||||
|
||||
protected final QName v4PropertyValueQName;
|
||||
|
||||
public AbstractAtomDealer(final ODataServiceVersion version) {
|
||||
this.version = version;
|
||||
|
||||
|
@ -72,6 +79,12 @@ abstract class AbstractAtomDealer {
|
|||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.ELEM_URI);
|
||||
this.nextQName =
|
||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.NEXT_LINK_REL);
|
||||
this.contextQName =
|
||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.CONTEXT);
|
||||
this.entityRefQName =
|
||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_ENTRY_REF);
|
||||
this.v4PropertyValueQName =
|
||||
new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.VALUE);
|
||||
}
|
||||
|
||||
protected void namespaces(final XMLStreamWriter writer) throws XMLStreamException {
|
||||
|
@ -83,5 +96,4 @@ abstract class AbstractAtomDealer {
|
|||
writer.writeNamespace(Constants.PREFIX_GML, Constants.NS_GML);
|
||||
writer.writeNamespace(Constants.PREFIX_GEORSS, Constants.NS_GEORSS);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ abstract class AbstractAtomObject extends AbstractPayloadObject {
|
|||
|
||||
private URI baseURI;
|
||||
|
||||
private URI contextURL;
|
||||
|
||||
private String id;
|
||||
|
||||
private String title;
|
||||
|
@ -47,10 +49,28 @@ abstract class AbstractAtomObject extends AbstractPayloadObject {
|
|||
this.baseURI = URI.create(baseURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
|
||||
* fragment identifying the relevant portion of the metadata document.
|
||||
*
|
||||
* @return context URL.
|
||||
*/
|
||||
public URI getContextURL() {
|
||||
return contextURL;
|
||||
}
|
||||
|
||||
public void setContextURL(final URI contextURL) {
|
||||
this.contextURL = contextURL;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
@ -74,5 +94,4 @@ abstract class AbstractAtomObject extends AbstractPayloadObject {
|
|||
this.updated = ISO_DATEFORMAT.parse(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.commons.core.data;
|
||||
|
||||
import java.net.URI;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||
|
@ -27,12 +28,29 @@ import org.apache.olingo.commons.api.data.Value;
|
|||
|
||||
public abstract class AbstractPropertyImpl implements Property {
|
||||
|
||||
private URI contextURL;
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private Value value;
|
||||
|
||||
/**
|
||||
* The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
|
||||
* fragment identifying the relevant portion of the metadata document.
|
||||
*
|
||||
* @return context URL.
|
||||
*/
|
||||
@Override
|
||||
public URI getContextURL() {
|
||||
return contextURL;
|
||||
}
|
||||
|
||||
public void setContextURL(final URI contextURL) {
|
||||
this.contextURL = contextURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
|
@ -168,112 +168,135 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
}
|
||||
|
||||
private AtomEntryImpl entry(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
|
||||
if (!Constants.QNAME_ATOM_ELEM_ENTRY.equals(start.getName())) {
|
||||
return null;
|
||||
}
|
||||
final AtomEntryImpl entry;
|
||||
if (entityRefQName.equals(start.getName())) {
|
||||
entry = entryRef(start);
|
||||
} else if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(start.getName())) {
|
||||
entry = new AtomEntryImpl();
|
||||
final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
|
||||
if (xmlBase != null) {
|
||||
entry.setBaseURI(xmlBase.getValue());
|
||||
}
|
||||
|
||||
final AtomEntryImpl entry = new AtomEntryImpl();
|
||||
final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
|
||||
if (xmlBase != null) {
|
||||
entry.setBaseURI(xmlBase.getValue());
|
||||
}
|
||||
final Attribute etag = start.getAttributeByName(etagQName);
|
||||
if (etag != null) {
|
||||
entry.setETag(etag.getValue());
|
||||
}
|
||||
entry.setContextURL(retrieveContextURL(start, entry.getBaseURI()));
|
||||
|
||||
boolean foundEndEntry = false;
|
||||
while (reader.hasNext() && !foundEndEntry) {
|
||||
final XMLEvent event = reader.nextEvent();
|
||||
final Attribute etag = start.getAttributeByName(etagQName);
|
||||
if (etag != null) {
|
||||
entry.setETag(etag.getValue());
|
||||
}
|
||||
|
||||
if (event.isStartElement()) {
|
||||
if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
|
||||
common(reader, event.asStartElement(), entry, "id");
|
||||
} else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
|
||||
common(reader, event.asStartElement(), entry, "title");
|
||||
} else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
|
||||
common(reader, event.asStartElement(), entry, "summary");
|
||||
} else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
|
||||
common(reader, event.asStartElement(), entry, "updated");
|
||||
} else if (Constants.QNAME_ATOM_ELEM_CATEGORY.equals(event.asStartElement().getName())) {
|
||||
final Attribute term = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM));
|
||||
if (term != null) {
|
||||
entry.setType(term.getValue());
|
||||
}
|
||||
} else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
|
||||
final LinkImpl link = new LinkImpl();
|
||||
final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
|
||||
if (rel != null) {
|
||||
link.setRel(rel.getValue());
|
||||
}
|
||||
final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
|
||||
if (title != null) {
|
||||
link.setTitle(title.getValue());
|
||||
}
|
||||
final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
|
||||
if (href != null) {
|
||||
link.setHref(href.getValue());
|
||||
}
|
||||
final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
|
||||
if (type != null) {
|
||||
link.setType(type.getValue());
|
||||
}
|
||||
boolean foundEndEntry = false;
|
||||
while (reader.hasNext() && !foundEndEntry) {
|
||||
final XMLEvent event = reader.nextEvent();
|
||||
|
||||
if (Constants.SELF_LINK_REL.equals(link.getRel())) {
|
||||
entry.setSelfLink(link);
|
||||
} else if (Constants.EDIT_LINK_REL.equals(link.getRel())) {
|
||||
entry.setEditLink(link);
|
||||
} else if (link.getRel().startsWith(version.getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
|
||||
entry.getNavigationLinks().add(link);
|
||||
inline(reader, event.asStartElement(), link);
|
||||
} else if (link.getRel().startsWith(
|
||||
version.getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL))) {
|
||||
|
||||
entry.getAssociationLinks().add(link);
|
||||
} else if (link.getRel().startsWith(
|
||||
version.getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
|
||||
|
||||
final Attribute metag = event.asStartElement().getAttributeByName(etagQName);
|
||||
if (metag != null) {
|
||||
link.setMediaETag(metag.getValue());
|
||||
if (event.isStartElement()) {
|
||||
if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
|
||||
common(reader, event.asStartElement(), entry, "id");
|
||||
} else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
|
||||
common(reader, event.asStartElement(), entry, "title");
|
||||
} else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
|
||||
common(reader, event.asStartElement(), entry, "summary");
|
||||
} else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
|
||||
common(reader, event.asStartElement(), entry, "updated");
|
||||
} else if (Constants.QNAME_ATOM_ELEM_CATEGORY.equals(event.asStartElement().getName())) {
|
||||
final Attribute term = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM));
|
||||
if (term != null) {
|
||||
entry.setType(term.getValue());
|
||||
}
|
||||
entry.getMediaEditLinks().add(link);
|
||||
}
|
||||
} else if (actionQName.equals(event.asStartElement().getName())) {
|
||||
final ODataOperation operation = new ODataOperation();
|
||||
final Attribute metadata = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_METADATA));
|
||||
if (metadata != null) {
|
||||
operation.setMetadataAnchor(metadata.getValue());
|
||||
}
|
||||
final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
|
||||
if (title != null) {
|
||||
operation.setTitle(title.getValue());
|
||||
}
|
||||
final Attribute target = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TARGET));
|
||||
if (target != null) {
|
||||
operation.setTarget(URI.create(target.getValue()));
|
||||
}
|
||||
|
||||
entry.getOperations().add(operation);
|
||||
} else if (Constants.QNAME_ATOM_ELEM_CONTENT.equals(event.asStartElement().getName())) {
|
||||
final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
|
||||
if (type == null || ContentType.APPLICATION_XML.equals(type.getValue())) {
|
||||
properties(reader, skipBeforeFirstStartElement(reader), entry);
|
||||
} else {
|
||||
entry.setMediaContentType(type.getValue());
|
||||
final Attribute src = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_SRC));
|
||||
if (src != null) {
|
||||
entry.setMediaContentSource(src.getValue());
|
||||
} else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
|
||||
final LinkImpl link = new LinkImpl();
|
||||
final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
|
||||
if (rel != null) {
|
||||
link.setRel(rel.getValue());
|
||||
}
|
||||
final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
|
||||
if (title != null) {
|
||||
link.setTitle(title.getValue());
|
||||
}
|
||||
final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
|
||||
if (href != null) {
|
||||
link.setHref(href.getValue());
|
||||
}
|
||||
final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
|
||||
if (type != null) {
|
||||
link.setType(type.getValue());
|
||||
}
|
||||
|
||||
if (Constants.SELF_LINK_REL.equals(link.getRel())) {
|
||||
entry.setSelfLink(link);
|
||||
} else if (Constants.EDIT_LINK_REL.equals(link.getRel())) {
|
||||
entry.setEditLink(link);
|
||||
} else if (link.getRel().startsWith(
|
||||
version.getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
|
||||
entry.getNavigationLinks().add(link);
|
||||
inline(reader, event.asStartElement(), link);
|
||||
} else if (link.getRel().startsWith(
|
||||
version.getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL))) {
|
||||
|
||||
entry.getAssociationLinks().add(link);
|
||||
} else if (link.getRel().startsWith(
|
||||
version.getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
|
||||
|
||||
final Attribute metag = event.asStartElement().getAttributeByName(etagQName);
|
||||
if (metag != null) {
|
||||
link.setMediaETag(metag.getValue());
|
||||
}
|
||||
entry.getMediaEditLinks().add(link);
|
||||
}
|
||||
} else if (actionQName.equals(event.asStartElement().getName())) {
|
||||
final ODataOperation operation = new ODataOperation();
|
||||
final Attribute metadata =
|
||||
event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_METADATA));
|
||||
if (metadata != null) {
|
||||
operation.setMetadataAnchor(metadata.getValue());
|
||||
}
|
||||
final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
|
||||
if (title != null) {
|
||||
operation.setTitle(title.getValue());
|
||||
}
|
||||
final Attribute target = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TARGET));
|
||||
if (target != null) {
|
||||
operation.setTarget(URI.create(target.getValue()));
|
||||
}
|
||||
|
||||
entry.getOperations().add(operation);
|
||||
} else if (Constants.QNAME_ATOM_ELEM_CONTENT.equals(event.asStartElement().getName())) {
|
||||
final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
|
||||
if (type == null || ContentType.APPLICATION_XML.equals(type.getValue())) {
|
||||
properties(reader, skipBeforeFirstStartElement(reader), entry);
|
||||
} else {
|
||||
entry.setMediaContentType(type.getValue());
|
||||
final Attribute src = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_SRC));
|
||||
if (src != null) {
|
||||
entry.setMediaContentSource(src.getValue());
|
||||
}
|
||||
}
|
||||
} else if (propertiesQName.equals(event.asStartElement().getName())) {
|
||||
properties(reader, event.asStartElement(), entry);
|
||||
}
|
||||
} else if (propertiesQName.equals(event.asStartElement().getName())) {
|
||||
properties(reader, event.asStartElement(), entry);
|
||||
}
|
||||
|
||||
if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
|
||||
foundEndEntry = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
|
||||
foundEndEntry = true;
|
||||
}
|
||||
return entry;
|
||||
} else {
|
||||
entry = null;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
private AtomEntryImpl entryRef(final StartElement start) throws XMLStreamException {
|
||||
final AtomEntryImpl entry = new AtomEntryImpl();
|
||||
entry.setContextURL(retrieveContextURL(start, null));
|
||||
|
||||
final Attribute entryRefId = start.getAttributeByName(Constants.QNAME_ATOM_ELEM_ENTRY_REF_ID);
|
||||
|
||||
if (entryRefId != null) {
|
||||
entry.setId(entryRefId.getValue());
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
@ -312,6 +335,8 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
feed.setBaseURI(xmlBase.getValue());
|
||||
}
|
||||
|
||||
feed.setContextURL(retrieveContextURL(start, feed.getBaseURI()));
|
||||
|
||||
boolean foundEndFeed = false;
|
||||
while (reader.hasNext() && !foundEndFeed) {
|
||||
final XMLEvent event = reader.nextEvent();
|
||||
|
@ -365,4 +390,16 @@ public class AtomDeserializer extends AbstractAtomDealer {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private URI retrieveContextURL(final StartElement start, final URI base) {
|
||||
final Attribute context = start.getAttributeByName(contextQName);
|
||||
|
||||
if (context == null) {
|
||||
return base == null
|
||||
? null
|
||||
: URI.create(base.toASCIIString() + "/" + Constants.METADATA);
|
||||
} else {
|
||||
return URI.create(context.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.apache.olingo.commons.core.data;
|
||||
|
||||
import java.net.URI;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.Attribute;
|
||||
|
@ -163,17 +165,29 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
|
|||
|
||||
public AtomPropertyImpl deserialize(final XMLEventReader reader, final StartElement start)
|
||||
throws XMLStreamException {
|
||||
|
||||
final AtomPropertyImpl property = new AtomPropertyImpl();
|
||||
property.setName(start.getName().getLocalPart());
|
||||
|
||||
final Attribute typeAttr = start.getAttributeByName(this.typeQName);
|
||||
final Attribute context = start.getAttributeByName(contextQName);
|
||||
|
||||
property.setContextURL(context == null ? null : URI.create(context.getValue()));
|
||||
|
||||
final QName name = start.getName();
|
||||
|
||||
if (ODataServiceVersion.V40 == version && v4PropertyValueQName.equals(name)) {
|
||||
// retrieve name from context
|
||||
final String contextURL = property.getContextURL().toASCIIString();
|
||||
property.setName(contextURL.substring(contextURL.lastIndexOf("/") + 1));
|
||||
} else {
|
||||
property.setName(name.getLocalPart());
|
||||
}
|
||||
|
||||
final Attribute nullAttr = start.getAttributeByName(this.nullQName);
|
||||
|
||||
Value value;
|
||||
final Attribute nullAttr = start.getAttributeByName(this.nullQName);
|
||||
final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue();
|
||||
|
||||
if (nullAttr == null) {
|
||||
final Attribute typeAttr = start.getAttributeByName(this.typeQName);
|
||||
final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue();
|
||||
|
||||
final EdmTypeInfo typeInfo = StringUtils.isBlank(typeAttrValue)
|
||||
? null
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
|
||||
|
|
|
@ -64,6 +64,14 @@ class AtomPropertySerializer extends AbstractAtomDealer {
|
|||
|
||||
writer.writeStartElement(Constants.PREFIX_DATASERVICES, property.getName(),
|
||||
version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
|
||||
|
||||
if (version == ODataServiceVersion.V40 && property.getContextURL() != null) {
|
||||
writer.writeAttribute(
|
||||
version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
|
||||
Constants.CONTEXT,
|
||||
property.getContextURL().toASCIIString());
|
||||
}
|
||||
|
||||
if (standalone) {
|
||||
namespaces(writer);
|
||||
}
|
||||
|
|
|
@ -127,6 +127,13 @@ public class AtomSerializer extends AbstractAtomDealer {
|
|||
}
|
||||
|
||||
private void entry(final XMLStreamWriter writer, final Entry entry) throws XMLStreamException {
|
||||
if (version == ODataServiceVersion.V40 && entry.getContextURL() != null) {
|
||||
writer.writeAttribute(
|
||||
version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
|
||||
Constants.CONTEXT,
|
||||
entry.getContextURL().toASCIIString());
|
||||
}
|
||||
|
||||
if (entry.getBaseURI() != null) {
|
||||
writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, entry.getBaseURI().toASCIIString());
|
||||
}
|
||||
|
@ -184,6 +191,13 @@ public class AtomSerializer extends AbstractAtomDealer {
|
|||
}
|
||||
|
||||
private void feed(final XMLStreamWriter writer, final Feed feed) throws XMLStreamException {
|
||||
if (version == ODataServiceVersion.V40 && feed.getContextURL() != null) {
|
||||
writer.writeAttribute(
|
||||
version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
|
||||
Constants.CONTEXT,
|
||||
feed.getContextURL().toASCIIString());
|
||||
}
|
||||
|
||||
if (feed.getBaseURI() != null) {
|
||||
writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, feed.getBaseURI().toASCIIString());
|
||||
}
|
||||
|
|
|
@ -23,13 +23,11 @@ import com.fasterxml.jackson.core.JsonParser;
|
|||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.ObjectCodec;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.text.ParseException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
@ -84,14 +82,17 @@ public class JSONEntryDeserializer extends AbstractJsonDeserializer<JSONEntryImp
|
|||
|
||||
final ObjectNode tree = (ObjectNode) parser.getCodec().readTree(parser);
|
||||
|
||||
if (tree.has(Constants.JSON_VALUE) && tree.get(Constants.JSON_VALUE).isArray()) {
|
||||
if (tree.has(Constants.VALUE) && tree.get(Constants.VALUE).isArray()) {
|
||||
throw new JsonParseException("Expected OData Entity, found EntitySet", parser.getCurrentLocation());
|
||||
}
|
||||
|
||||
final JSONEntryImpl entry = new JSONEntryImpl();
|
||||
|
||||
if (tree.hasNonNull(Constants.JSON_METADATA)) {
|
||||
entry.setMetadata(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
|
||||
if (tree.hasNonNull(Constants.JSON_CONTEXT)) {
|
||||
entry.setContextURL(URI.create(tree.get(Constants.JSON_CONTEXT).textValue()));
|
||||
tree.remove(Constants.JSON_CONTEXT);
|
||||
} else if (tree.hasNonNull(Constants.JSON_METADATA)) {
|
||||
entry.setContextURL(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
|
||||
tree.remove(Constants.JSON_METADATA);
|
||||
}
|
||||
|
||||
|
@ -111,11 +112,7 @@ public class JSONEntryDeserializer extends AbstractJsonDeserializer<JSONEntryImp
|
|||
}
|
||||
|
||||
if (tree.hasNonNull(Constants.JSON_ID)) {
|
||||
try {
|
||||
entry.setId(tree.get(Constants.JSON_ID).textValue());
|
||||
} catch (ParseException e) {
|
||||
throw new JsonMappingException("While parsing Atom entry or feed common elements", e);
|
||||
}
|
||||
entry.setId(tree.get(Constants.JSON_ID).textValue());
|
||||
tree.remove(Constants.JSON_ID);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.apache.olingo.commons.core.data;
|
|||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import java.net.URI;
|
||||
import java.text.ParseException;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
|
||||
/**
|
||||
|
@ -33,43 +32,19 @@ public class JSONEntryImpl extends AbstractEntry {
|
|||
|
||||
private static final long serialVersionUID = -5275365545400797758L;
|
||||
|
||||
private URI metadata;
|
||||
|
||||
private String mediaETag;
|
||||
|
||||
public void setId(final String id) throws ParseException {
|
||||
this.setCommonProperty("id", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getBaseURI() {
|
||||
URI baseURI = null;
|
||||
if (metadata != null) {
|
||||
final String metadataURI = getMetadata().toASCIIString();
|
||||
if (getContextURL() != null) {
|
||||
final String metadataURI = getContextURL().toASCIIString();
|
||||
baseURI = URI.create(metadataURI.substring(0, metadataURI.indexOf(Constants.METADATA)));
|
||||
}
|
||||
|
||||
return baseURI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata URI.
|
||||
*
|
||||
* @return the metadata URI
|
||||
*/
|
||||
public URI getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the metadata URI.
|
||||
*
|
||||
* @param metadata metadata URI.
|
||||
*/
|
||||
public void setMetadata(final URI metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* The odata.mediaEtag annotation MAY be included; its value MUST be the ETag of the binary stream represented by this
|
||||
* media entity or named stream property.
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.olingo.commons.api.data.Entry;
|
|||
import org.apache.olingo.commons.api.data.Link;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
||||
/**
|
||||
* Writes out JSON string from an entry.
|
||||
|
@ -44,9 +45,12 @@ public class JSONEntrySerializer extends AbstractJsonSerializer<JSONEntryImpl> {
|
|||
|
||||
jgen.writeStartObject();
|
||||
|
||||
if (entry.getMetadata() != null) {
|
||||
jgen.writeStringField(Constants.JSON_METADATA, entry.getMetadata().toASCIIString());
|
||||
if (entry.getContextURL() != null) {
|
||||
jgen.writeStringField(
|
||||
version == ODataServiceVersion.V40 ? Constants.JSON_CONTEXT : Constants.JSON_METADATA,
|
||||
entry.getContextURL().toASCIIString());
|
||||
}
|
||||
|
||||
if (entry.getId() != null) {
|
||||
jgen.writeStringField(Constants.JSON_ID, entry.getId());
|
||||
}
|
||||
|
|
|
@ -41,15 +41,20 @@ public class JSONFeedDeserializer extends AbstractJsonDeserializer<JSONFeedImpl>
|
|||
|
||||
final ObjectNode tree = (ObjectNode) parser.getCodec().readTree(parser);
|
||||
|
||||
if (!tree.has(Constants.JSON_VALUE)) {
|
||||
if (!tree.has(Constants.VALUE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final JSONFeedImpl feed = new JSONFeedImpl();
|
||||
|
||||
if (tree.hasNonNull(Constants.JSON_METADATA)) {
|
||||
feed.setMetadata(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
|
||||
if (tree.hasNonNull(Constants.JSON_CONTEXT)) {
|
||||
feed.setContextURL(URI.create(tree.get(Constants.JSON_CONTEXT).textValue()));
|
||||
tree.remove(Constants.JSON_CONTEXT);
|
||||
} else if (tree.hasNonNull(Constants.JSON_METADATA)) {
|
||||
feed.setContextURL(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
|
||||
tree.remove(Constants.JSON_METADATA);
|
||||
}
|
||||
|
||||
if (tree.hasNonNull(Constants.JSON_COUNT)) {
|
||||
feed.setCount(tree.get(Constants.JSON_COUNT).asInt());
|
||||
}
|
||||
|
@ -57,8 +62,8 @@ public class JSONFeedDeserializer extends AbstractJsonDeserializer<JSONFeedImpl>
|
|||
feed.setNext(URI.create(tree.get(Constants.JSON_NEXT_LINK).textValue()));
|
||||
}
|
||||
|
||||
if (tree.hasNonNull(Constants.JSON_VALUE)) {
|
||||
for (final Iterator<JsonNode> itor = tree.get(Constants.JSON_VALUE).iterator(); itor.hasNext();) {
|
||||
if (tree.hasNonNull(Constants.VALUE)) {
|
||||
for (final Iterator<JsonNode> itor = tree.get(Constants.VALUE).iterator(); itor.hasNext();) {
|
||||
feed.getEntries().add(itor.next().traverse(parser.getCodec()).readValueAs(JSONEntryImpl.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@ public class JSONFeedImpl extends AbstractPayloadObject implements Feed {
|
|||
|
||||
private static final long serialVersionUID = -3576372289800799417L;
|
||||
|
||||
private String id;
|
||||
private URI contextURL;
|
||||
|
||||
private URI metadata;
|
||||
private String id;
|
||||
|
||||
private Integer count;
|
||||
|
||||
|
@ -51,8 +51,8 @@ public class JSONFeedImpl extends AbstractPayloadObject implements Feed {
|
|||
@Override
|
||||
public URI getBaseURI() {
|
||||
URI baseURI = null;
|
||||
if (metadata != null) {
|
||||
final String metadataURI = getMetadata().toASCIIString();
|
||||
if (getContextURL() != null) {
|
||||
final String metadataURI = getContextURL().toASCIIString();
|
||||
baseURI = URI.create(metadataURI.substring(0, metadataURI.indexOf(Constants.METADATA)));
|
||||
}
|
||||
|
||||
|
@ -60,21 +60,15 @@ public class JSONFeedImpl extends AbstractPayloadObject implements Feed {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata URI.
|
||||
*
|
||||
* @return the metadata URI
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public URI getMetadata() {
|
||||
return metadata;
|
||||
@Override
|
||||
public URI getContextURL() {
|
||||
return contextURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the metadata URI.
|
||||
*
|
||||
* @param metadata metadata URI.
|
||||
*/
|
||||
public void setMetadata(final URI metadata) {
|
||||
this.metadata = metadata;
|
||||
public void setContextURL(final URI context) {
|
||||
this.contextURL = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.SerializerProvider;
|
|||
import java.io.IOException;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Entry;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
||||
public class JSONFeedSerializer extends AbstractJsonSerializer<JSONFeedImpl> {
|
||||
|
||||
|
@ -33,8 +34,10 @@ public class JSONFeedSerializer extends AbstractJsonSerializer<JSONFeedImpl> {
|
|||
|
||||
jgen.writeStartObject();
|
||||
|
||||
if (feed.getMetadata() != null) {
|
||||
jgen.writeStringField(Constants.JSON_METADATA, feed.getMetadata().toASCIIString());
|
||||
if (feed.getContextURL() != null) {
|
||||
jgen.writeStringField(
|
||||
version == ODataServiceVersion.V40 ? Constants.JSON_CONTEXT : Constants.JSON_METADATA,
|
||||
feed.getContextURL().toASCIIString());
|
||||
}
|
||||
if (feed.getId() != null) {
|
||||
jgen.writeStringField(Constants.JSON_ID, feed.getId());
|
||||
|
@ -46,12 +49,11 @@ public class JSONFeedSerializer extends AbstractJsonSerializer<JSONFeedImpl> {
|
|||
jgen.writeStringField(Constants.JSON_NEXT_LINK, feed.getNext().toASCIIString());
|
||||
}
|
||||
|
||||
jgen.writeArrayFieldStart(Constants.JSON_VALUE);
|
||||
jgen.writeArrayFieldStart(Constants.VALUE);
|
||||
for (Entry entry : feed.getEntries()) {
|
||||
jgen.writeObject(entry);
|
||||
}
|
||||
|
||||
jgen.writeEndArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,16 +41,19 @@ public class JSONPropertyDeserializer extends AbstractJsonDeserializer<JSONPrope
|
|||
|
||||
final JSONPropertyImpl property = new JSONPropertyImpl();
|
||||
|
||||
if (tree.hasNonNull(Constants.JSON_METADATA)) {
|
||||
property.setMetadata(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
|
||||
if (tree.hasNonNull(Constants.JSON_CONTEXT)) {
|
||||
property.setContextURL(URI.create(tree.get(Constants.JSON_CONTEXT).textValue()));
|
||||
tree.remove(Constants.JSON_CONTEXT);
|
||||
} else if (tree.hasNonNull(Constants.JSON_METADATA)) {
|
||||
property.setContextURL(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
|
||||
tree.remove(Constants.JSON_METADATA);
|
||||
}
|
||||
|
||||
if (property.getMetadata() != null) {
|
||||
final String metadataURI = property.getMetadata().toASCIIString();
|
||||
final int dashIdx = metadataURI.lastIndexOf('#');
|
||||
if (property.getContextURL() != null) {
|
||||
final String contextURL = property.getContextURL().toASCIIString();
|
||||
final int dashIdx = contextURL.lastIndexOf('#');
|
||||
if (dashIdx != -1) {
|
||||
property.setType(metadataURI.substring(dashIdx + 1));
|
||||
property.setType(contextURL.substring(dashIdx + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +66,7 @@ public class JSONPropertyDeserializer extends AbstractJsonDeserializer<JSONPrope
|
|||
}
|
||||
|
||||
if (property.getValue() == null) {
|
||||
value(property, tree.has(Constants.JSON_VALUE) ? tree.get(Constants.JSON_VALUE) : tree);
|
||||
value(property, tree.has(Constants.VALUE) ? tree.get(Constants.VALUE) : tree);
|
||||
}
|
||||
|
||||
return property;
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.apache.olingo.commons.core.data;
|
|||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* A single property (primitive, complex or collection) represented via JSON.
|
||||
|
@ -31,23 +30,4 @@ public class JSONPropertyImpl extends AbstractPropertyImpl {
|
|||
|
||||
private static final long serialVersionUID = 553414431536637434L;
|
||||
|
||||
private URI metadata;
|
||||
|
||||
/**
|
||||
* Gets metadata URI.
|
||||
*
|
||||
* @return metadata URI.
|
||||
*/
|
||||
public URI getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets metadata URI.
|
||||
*
|
||||
* @param metadata metadata URI.
|
||||
*/
|
||||
public void setMetadata(final URI metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.SerializerProvider;
|
|||
import java.io.IOException;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
|
||||
/**
|
||||
* Writes out JSON string from <tt>JSONPropertyImpl</tt>.
|
||||
|
@ -38,16 +39,18 @@ public class JSONPropertySerializer extends AbstractJsonSerializer<JSONPropertyI
|
|||
|
||||
jgen.writeStartObject();
|
||||
|
||||
if (property.getMetadata() != null) {
|
||||
jgen.writeStringField(Constants.JSON_METADATA, property.getMetadata().toASCIIString());
|
||||
if (property.getContextURL() != null) {
|
||||
jgen.writeStringField(
|
||||
version == ODataServiceVersion.V40 ? Constants.JSON_CONTEXT : Constants.JSON_METADATA,
|
||||
property.getContextURL().toASCIIString());
|
||||
}
|
||||
|
||||
if (property.getValue().isNull()) {
|
||||
jgen.writeBooleanField(Constants.JSON_NULL, true);
|
||||
} else if (property.getValue().isSimple()) {
|
||||
jgen.writeStringField(Constants.JSON_VALUE, property.getValue().asSimple().get());
|
||||
jgen.writeStringField(Constants.VALUE, property.getValue().asSimple().get());
|
||||
} else if (property.getValue().isGeospatial() || property.getValue().isCollection()) {
|
||||
property(jgen, property, Constants.JSON_VALUE);
|
||||
property(jgen, property, Constants.VALUE);
|
||||
} else if (property.getValue().isComplex()) {
|
||||
for (Property cproperty : property.getValue().asComplex().get()) {
|
||||
property(jgen, cproperty, cproperty.getName());
|
||||
|
|
|
@ -96,7 +96,6 @@ public class EdmTypeInfo {
|
|||
baseType = typeExpression.substring(collStartIdx + 11, collEndIdx);
|
||||
}
|
||||
|
||||
|
||||
baseType = baseType.replaceAll("^#", "");
|
||||
|
||||
final String typeName;
|
||||
|
|
Loading…
Reference in New Issue