You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/04/04 17:25:35 UTC
[4/7] git commit: [OLINGO-175] Enabling fit to respond to action /
function invocation (V3)
[OLINGO-175] Enabling fit to respond to action / function invocation (V3)
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/bb748ec0
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/bb748ec0
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/bb748ec0
Branch: refs/heads/master
Commit: bb748ec0b78a09d105b9497685756c699372c7d3
Parents: 7dae5ef
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Apr 4 17:20:42 2014 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Apr 4 17:20:42 2014 +0200
----------------------------------------------------------------------
fit/pom.xml | 4 +
.../org/apache/olingo/fit/AbstractServices.java | 385 +++++++-----
.../org/apache/olingo/fit/V3KeyAsSegment.java | 159 +++++
.../java/org/apache/olingo/fit/V3Services.java | 13 +-
.../java/org/apache/olingo/fit/V4NorthWind.java | 11 +-
.../org/apache/olingo/fit/V4NorthWindExt.java | 11 +-
.../java/org/apache/olingo/fit/V4Services.java | 9 +-
.../olingo/fit/utils/AbstractJSONUtilities.java | 25 +-
.../olingo/fit/utils/AbstractUtilities.java | 25 +-
.../olingo/fit/utils/AbstractXMLUtilities.java | 60 +-
.../org/apache/olingo/fit/utils/Commons.java | 5 +-
...ionReturnsCollectionOfComplexTypes.full.json | 1 +
...rojectionReturnsCollectionOfComplexTypes.xml | 618 +++++++++++++++++++
.../resources/v3/GetArgumentPlusOne.full.json | 4 +
.../main/resources/v3/GetArgumentPlusOne.xml | 23 +
.../resources/v3/GetPrimitiveString.full.json | 1 +
.../main/resources/v3/GetPrimitiveString.xml | 23 +
.../resources/v3/GetSpecificCustomer.full.json | 137 ++++
.../main/resources/v3/GetSpecificCustomer.xml | 200 ++++++
.../feed.full.json | 1 +
.../feed.xml | 200 ++++++
.../main/webapp/WEB-INF/applicationContext.xml | 1 +
22 files changed, 1711 insertions(+), 205 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/pom.xml
----------------------------------------------------------------------
diff --git a/fit/pom.xml b/fit/pom.xml
index 6e53597..d4e1e90 100644
--- a/fit/pom.xml
+++ b/fit/pom.xml
@@ -117,6 +117,10 @@
<inherited>true</inherited>
<configuration>
<configuration>
+ <properties>
+ <cargo.jvmargs>-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
+ -noverify -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m</cargo.jvmargs>
+ </properties>
<files>
<file>
<file>${project.build.directory}/classes/esigate.properties</file>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
index fd64d3d..bcc6150 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -18,17 +18,9 @@
*/
package org.apache.olingo.fit;
-import org.apache.olingo.fit.utils.Accept;
-import org.apache.olingo.fit.utils.AbstractXMLUtilities;
-import org.apache.olingo.fit.utils.AbstractJSONUtilities;
-import org.apache.olingo.fit.utils.ODataVersion;
-import org.apache.olingo.fit.utils.FSManager;
-
-import org.apache.olingo.fit.methods.MERGE;
-import org.apache.olingo.fit.methods.PATCH;
-import org.apache.olingo.fit.utils.AbstractUtilities;
-import org.apache.olingo.fit.utils.Commons;
-import org.apache.olingo.fit.utils.LinkInfo;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.util.AbstractMap;
@@ -38,6 +30,8 @@ import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
@@ -50,13 +44,25 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.fit.methods.MERGE;
+import org.apache.olingo.fit.methods.PATCH;
+import org.apache.olingo.fit.utils.AbstractJSONUtilities;
+import org.apache.olingo.fit.utils.AbstractUtilities;
+import org.apache.olingo.fit.utils.AbstractXMLUtilities;
+import org.apache.olingo.fit.utils.Accept;
+import org.apache.olingo.fit.utils.Commons;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
+import org.apache.olingo.fit.utils.FSManager;
+import org.apache.olingo.fit.utils.LinkInfo;
+import org.apache.olingo.fit.utils.ODataVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,13 +75,18 @@ public abstract class AbstractServices {
private static final Set<ODataVersion> INITIALIZED = EnumSet.noneOf(ODataVersion.class);
- protected abstract ODataVersion getVersion();
+ protected final ODataVersion version;
+
protected final AbstractXMLUtilities xml;
protected final AbstractJSONUtilities json;
- public AbstractServices() throws Exception {
- if (ODataVersion.v3 == getVersion()) {
+ @Context
+ protected UriInfo uriInfo;
+
+ public AbstractServices(final ODataVersion version) throws Exception {
+ this.version = version;
+ if (ODataVersion.v3 == version) {
this.xml = new org.apache.olingo.fit.utils.v3.XMLUtilities();
this.json = new org.apache.olingo.fit.utils.v3.JSONUtilities();
} else {
@@ -83,9 +94,9 @@ public abstract class AbstractServices {
this.json = new org.apache.olingo.fit.utils.v4.JSONUtilities();
}
- if (!INITIALIZED.contains(getVersion())) {
+ if (!INITIALIZED.contains(version)) {
xml.retrieveLinkInfoFromMetadata();
- INITIALIZED.add(getVersion());
+ INITIALIZED.add(version);
}
}
@@ -98,14 +109,14 @@ public abstract class AbstractServices {
@GET
public Response getSevices(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept) {
try {
- final Accept acceptType = Accept.parse(accept, getVersion());
+ final Accept acceptType = Accept.parse(accept, version);
if (acceptType == Accept.ATOM) {
throw new UnsupportedMediaTypeException("Unsupported media type");
}
return xml.createResponse(
- FSManager.instance(getVersion()).readFile(Constants.get(getVersion(), ConstantKey.SERVICES), acceptType),
+ FSManager.instance(version).readFile(Constants.get(version, ConstantKey.SERVICES), acceptType),
null, acceptType);
} catch (Exception e) {
return xml.createFaultResponse(accept, e);
@@ -121,22 +132,16 @@ public abstract class AbstractServices {
@Path("/$metadata")
@Produces("application/xml")
public Response getMetadata() {
- return getMetadata(Constants.get(getVersion(), ConstantKey.METADATA));
+ return getMetadata(Constants.get(version, ConstantKey.METADATA));
}
protected Response getMetadata(final String filename) {
try {
- return xml.createResponse(FSManager.instance(getVersion()).readFile(filename, Accept.XML), null, Accept.XML);
+ return xml.createResponse(FSManager.instance(version).readFile(filename, Accept.XML), null, Accept.XML);
} catch (Exception e) {
- return xml.createFaultResponse(Accept.XML.toString(getVersion()), e);
+ return xml.createFaultResponse(Accept.XML.toString(version), e);
}
}
-//
-// @GET
-// @Path("/$entity")
-// public Response getEntityReference(@QueryParam("$id") String id){
-// return null;
-// }
/**
* Retrieve entity reference sample.
@@ -163,7 +168,7 @@ public abstract class AbstractServices {
final String filename = Base64.encodeBase64String(path.getBytes("UTF-8"));
return utils.getValue().createResponse(
- FSManager.instance(getVersion()).readFile(Constants.get(getVersion(), ConstantKey.REF)
+ FSManager.instance(version).readFile(Constants.get(version, ConstantKey.REF)
+ File.separatorChar + filename, utils.getKey()),
null,
utils.getKey());
@@ -174,21 +179,6 @@ public abstract class AbstractServices {
}
@MERGE
- @Path("/{entitySetName}/{entityId}")
- @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
- @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
- public Response mergeEntityKeyAsSegment(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
- @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) String ifMatch,
- @PathParam("entitySetName") String entitySetName,
- @PathParam("entityId") String entityId,
- final String changes) {
-
- return patchEntity(accept, prefer, ifMatch, entitySetName, entityId, changes);
- }
-
- @MERGE
@Path("/{entitySetName}({entityId})")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
@@ -204,20 +194,6 @@ public abstract class AbstractServices {
}
@PATCH
- @Path("/{entitySetName}/{entityId}")
- @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
- @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
- public Response patchEntityKeyAsSegment(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
- @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) String ifMatch,
- @PathParam("entitySetName") String entitySetName,
- @PathParam("entityId") String entityId,
- final String changes) {
- return patchEntity(accept, prefer, ifMatch, entitySetName, entityId, changes);
- }
-
- @PATCH
@Path("/{entitySetName}({entityId})")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
@@ -230,7 +206,7 @@ public abstract class AbstractServices {
final String changes) {
try {
- final Accept acceptType = Accept.parse(accept, getVersion());
+ final Accept acceptType = Accept.parse(accept, version);
if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
throw new UnsupportedMediaTypeException("Unsupported media type");
@@ -259,19 +235,6 @@ public abstract class AbstractServices {
}
@PUT
- @Path("/{entitySetName}/{entityId}")
- @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
- @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
- public Response putNewEntityKeyAsSegment(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
- @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
- @PathParam("entitySetName") String entitySetName,
- @PathParam("entityId") String entityId,
- final String entity) {
- return replaceEntity(accept, prefer, entitySetName, entityId, entity);
- }
-
- @PUT
@Path("/{entitySetName}({entityId})")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
@@ -282,7 +245,7 @@ public abstract class AbstractServices {
@PathParam("entityId") String entityId,
final String entity) {
try {
- final Accept acceptType = Accept.parse(accept, getVersion());
+ final Accept acceptType = Accept.parse(accept, version);
if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
throw new UnsupportedMediaTypeException("Unsupported media type");
@@ -326,7 +289,7 @@ public abstract class AbstractServices {
// default
AbstractUtilities utils = xml;
try {
- final Accept acceptType = Accept.parse(accept, getVersion());
+ final Accept acceptType = Accept.parse(accept, version);
if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
throw new UnsupportedMediaTypeException("Unsupported media type");
@@ -360,6 +323,139 @@ public abstract class AbstractServices {
}
}
+ @POST
+ @Path("/Person({entityId})/{type:.*}/Sack")
+ public Response actionSack(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @PathParam("type") final String type,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final Map.Entry<String, InputStream> entityInfo = utils.getValue().readEntity("Person", entityId, utils.getKey());
+
+ InputStream entity = entityInfo.getValue();
+ try {
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(entity, copy);
+ IOUtils.closeQuietly(entity);
+
+ final String newContent = new String(copy.toByteArray(), "UTF-8").
+ replaceAll("\"Salary\":[0-9]*,", "\"Salary\":0,").
+ replaceAll("\"Title\":\".*\"", "\"Title\":\"[Sacked]\"").
+ replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>.*\\</d:Salary\\>",
+ "<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
+ replaceAll("\\<d:Title\\>.*\\</d:Title\\>", "<d:Title>[Sacked]</d:Title>");
+
+ final FSManager fsManager = FSManager.instance(version);
+ fsManager.putInMemory(IOUtils.toInputStream(newContent, "UTF-8"),
+ fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(version,
+ ConstantKey.ENTITY), utils.getKey()));
+
+ return utils.getValue().createResponse(null, null, utils.getKey(), Response.Status.NO_CONTENT);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ @POST
+ @Path("/Person/{type:.*}/IncreaseSalaries")
+ public Response actionIncreaseSalaries(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("type") final String type,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+ final String body) {
+
+ final String name = "Person";
+ try {
+ final Accept acceptType = Accept.parse(accept, version);
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final JsonNode tree = new ObjectMapper().readTree(body);
+ if (!tree.has("n")) {
+ throw new Exception("Missing parameter: n");
+ }
+ final int n = tree.get("n").asInt();
+
+ final StringBuilder path = new StringBuilder(name).
+ append(File.separatorChar).append(type).
+ append(File.separatorChar);
+ path.append(Commons.getLinkInfo().get(version).isSingleton(name)
+ ? Constants.get(version, ConstantKey.ENTITY)
+ : Constants.get(version, ConstantKey.FEED));
+
+ final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
+
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(feed, copy);
+ IOUtils.closeQuietly(feed);
+
+ String newContent = new String(copy.toByteArray(), "UTF-8");
+ final Pattern salary = Pattern.compile(acceptType == Accept.ATOM
+ ? "\\<d:Salary m:type=\"Edm.Int32\"\\>(-?\\d+)\\</d:Salary\\>"
+ : "\"Salary\":(-?\\d+),");
+ final Matcher salaryMatcher = salary.matcher(newContent);
+ while (salaryMatcher.find()) {
+ final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
+ newContent = newContent.
+ replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
+ "\"Salary\":" + newSalary + ",").
+ replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
+ "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
+ }
+
+ FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, "UTF-8"),
+ FSManager.instance(version).getAbsolutePath(path.toString(), acceptType));
+
+ return xml.createResponse(null, null, acceptType, Response.Status.NO_CONTENT);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
+ /**
+ * Retrieve entities from the given entity set and the given type.
+ *
+ * @param accept Accept header.
+ * @param name entity set.
+ * @param type entity type.
+ * @return entity set.
+ */
+ @GET
+ @Path("/{name}/{type:.*}")
+ public Response getEntitySet(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("name") final String name,
+ @PathParam("type") final String type) {
+
+ try {
+ final Accept acceptType = Accept.parse(accept, version);
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final String basePath = name + File.separatorChar;
+ final StringBuilder path = new StringBuilder(name).
+ append(File.separatorChar).append(type).
+ append(File.separatorChar);
+ path.append(Commons.getLinkInfo().get(version).isSingleton(name)
+ ? Constants.get(version, ConstantKey.ENTITY)
+ : Constants.get(version, ConstantKey.FEED));
+
+ final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
+ return xml.createResponse(feed, Commons.getETag(basePath, version), acceptType);
+ } catch (Exception e) {
+ return xml.createFaultResponse(accept, e);
+ }
+ }
+
/**
* Retrieve entity set or function execution sample.
*
@@ -388,18 +484,18 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else {
- acceptType = Accept.parse(accept, getVersion());
- }
-
- if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
- throw new UnsupportedMediaTypeException("Unsupported media type");
+ acceptType = Accept.parse(accept, version);
}
try {
// search for function ...
- final InputStream func = FSManager.instance(getVersion()).readFile(name, acceptType);
+ final InputStream func = FSManager.instance(version).readFile(name, acceptType);
return xml.createResponse(func, null, acceptType);
} catch (NotFoundException e) {
+ if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
// search for entitySet ...
final String basePath = name + File.separatorChar;
@@ -407,67 +503,75 @@ public abstract class AbstractServices {
builder.append(basePath);
if (StringUtils.isNotBlank(orderby)) {
- builder.append(Constants.get(getVersion(), ConstantKey.ORDERBY)).append(File.separatorChar).
+ builder.append(Constants.get(version, ConstantKey.ORDERBY)).append(File.separatorChar).
append(orderby).append(File.separatorChar);
}
if (StringUtils.isNotBlank(filter)) {
- builder.append(Constants.get(getVersion(), ConstantKey.FILTER)).append(File.separatorChar).
+ builder.append(Constants.get(version, ConstantKey.FILTER)).append(File.separatorChar).
append(filter.replaceAll("/", "."));
} else if (StringUtils.isNotBlank(skiptoken)) {
- builder.append(Constants.get(getVersion(), ConstantKey.SKIP_TOKEN)).append(File.separatorChar).
+ builder.append(Constants.get(version, ConstantKey.SKIP_TOKEN)).append(File.separatorChar).
append(skiptoken);
} else {
- builder.append(Commons.getLinkInfo().get(getVersion()).isSingleton(name)
- ? Constants.get(getVersion(), ConstantKey.ENTITY)
- : Constants.get(getVersion(), ConstantKey.FEED));
+ builder.append(Commons.getLinkInfo().get(version).isSingleton(name)
+ ? Constants.get(version, ConstantKey.ENTITY)
+ : Constants.get(version, ConstantKey.FEED));
}
- InputStream feed = FSManager.instance(getVersion()).readFile(builder.toString(), acceptType);
+ InputStream feed = FSManager.instance(version).readFile(builder.toString(), acceptType);
if ("allpages".equals(inlinecount)) {
int count = xml.countAllElements(name);
feed.close();
if (acceptType == Accept.ATOM) {
feed = xml.addAtomInlinecount(
- FSManager.instance(getVersion()).readFile(builder.toString(), acceptType),
+ FSManager.instance(version).readFile(builder.toString(), acceptType),
count,
acceptType);
} else {
feed = json.addJsonInlinecount(
- FSManager.instance(getVersion()).readFile(builder.toString(), acceptType),
+ FSManager.instance(version).readFile(builder.toString(), acceptType),
count,
acceptType);
}
}
- return xml.createResponse(feed, Commons.getETag(basePath, getVersion()), acceptType);
+ return xml.createResponse(feed, Commons.getETag(basePath, version), acceptType);
}
} catch (Exception e) {
return xml.createFaultResponse(accept, e);
}
}
- /**
- * Retrieve entity with key as segment.
- *
- * @param accept Accept header.
- * @param entitySetName Entity set name.
- * @param entityId entity id.
- * @param format format query option.
- * @param expand expand query option.
- * @param select select query option.
- * @return entity.
- */
@GET
- @Path("/{entitySetName}/{entityId}")
- public Response getEntityKeyAsSegment(
- @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
- @PathParam("entitySetName") String entitySetName,
- @PathParam("entityId") String entityId,
- @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format,
- @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) String expand,
- @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) String select) {
- return getEntity(accept, entitySetName, entityId, format, expand, select, true);
+ @Path("/Person({entityId})")
+ public Response getEntity(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+ @PathParam("entityId") final String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+ final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+ if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+ throw new UnsupportedMediaTypeException("Unsupported media type");
+ }
+
+ final Map.Entry<String, InputStream> entityInfo = utils.getValue().readEntity("Person", entityId, utils.getKey());
+
+ InputStream entity = entityInfo.getValue();
+ try {
+ if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
+ entity = utils.getValue().addOperation(entity, "Sack", "#DefaultContainer.Sack",
+ uriInfo.getAbsolutePath().toASCIIString()
+ + "/Microsoft.Test.OData.Services.AstoriaDefaultService.SpecialEmployee/Sack");
+ }
+
+ return utils.getValue().createResponse(
+ entity, Commons.getETag(entityInfo.getKey(), version), utils.getKey());
+ } catch (Exception e) {
+ LOG.error("Error retrieving entity", e);
+ return xml.createFaultResponse(accept, e);
+ }
}
/**
@@ -491,10 +595,10 @@ public abstract class AbstractServices {
@QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) String expand,
@QueryParam("$select") @DefaultValue(StringUtils.EMPTY) String select) {
- return getEntity(accept, entitySetName, entityId, format, expand, select, false);
+ return getEntityInternal(accept, entitySetName, entityId, format, expand, select, false);
}
- public Response getEntity(
+ protected Response getEntityInternal(
final String accept,
final String entitySetName,
final String entityId,
@@ -518,7 +622,7 @@ public abstract class AbstractServices {
if (keyAsSegment) {
entity = utils.getValue().addEditLink(
entity, entitySetName,
- Constants.get(getVersion(), ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "/" + entityId);
+ Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "/" + entityId);
}
if (StringUtils.isNotBlank(select)) {
@@ -535,9 +639,7 @@ public abstract class AbstractServices {
}
}
- return utils.getValue().createResponse(
- entity, Commons.getETag(entityInfo.getKey(), getVersion()), utils.getKey());
-
+ return utils.getValue().createResponse(entity, Commons.getETag(entityInfo.getKey(), version), utils.getKey());
} catch (Exception e) {
LOG.error("Error retrieving entity", e);
return xml.createFaultResponse(accept, e);
@@ -558,7 +660,7 @@ public abstract class AbstractServices {
final AbstractUtilities utils = getUtilities(null);
final Map.Entry<String, InputStream> entityInfo = utils.readMediaEntity(entitySetName, entityId);
- return utils.createResponse(entityInfo.getValue(), Commons.getETag(entityInfo.getKey(), getVersion()), null);
+ return utils.createResponse(entityInfo.getValue(), Commons.getETag(entityInfo.getKey(), version), null);
} catch (Exception e) {
LOG.error("Error retrieving entity", e);
@@ -567,27 +669,20 @@ public abstract class AbstractServices {
}
@DELETE
- @Path("/{entitySetName}/{entityId}")
- public Response removeEntityKeyAsSegment(
- @PathParam("entitySetName") String entitySetName,
- @PathParam("entityId") String entityId) {
- return removeEntity(entitySetName, entityId);
- }
-
- @DELETE
@Path("/{entitySetName}({entityId})")
public Response removeEntity(
@PathParam("entitySetName") String entitySetName,
@PathParam("entityId") String entityId) {
+
try {
final String basePath =
entitySetName + File.separatorChar + Commons.getEntityKey(entityId) + File.separatorChar;
- FSManager.instance(getVersion()).deleteFile(basePath + Constants.get(getVersion(), ConstantKey.ENTITY));
+ FSManager.instance(version).deleteFile(basePath + Constants.get(version, ConstantKey.ENTITY));
return xml.createResponse(null, null, null, Response.Status.NO_CONTENT);
} catch (Exception e) {
- return xml.createFaultResponse(Accept.XML.toString(getVersion()), e);
+ return xml.createFaultResponse(Accept.XML.toString(version), e);
}
}
@@ -605,7 +700,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else if (StringUtils.isNotBlank(accept)) {
- acceptType = Accept.parse(accept, getVersion(), null);
+ acceptType = Accept.parse(accept, version, null);
}
// if the given path is not about any link then search for property
@@ -652,7 +747,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else if (StringUtils.isNotBlank(accept)) {
- acceptType = Accept.parse(accept, getVersion(), null);
+ acceptType = Accept.parse(accept, version, null);
}
// if the given path is not about any link then search for property
@@ -789,7 +884,7 @@ public abstract class AbstractServices {
} catch (Exception e) {
LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(Accept.JSON.toString(getVersion()), e);
+ return xml.createFaultResponse(Accept.JSON.toString(version), e);
}
}
@@ -848,7 +943,7 @@ public abstract class AbstractServices {
} catch (Exception e) {
LOG.error("Error retrieving entity", e);
- return xml.createFaultResponse(Accept.JSON.toString(getVersion()), e);
+ return xml.createFaultResponse(Accept.JSON.toString(version), e);
}
}
@@ -900,7 +995,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else if (StringUtils.isNotBlank(accept)) {
- acceptType = Accept.parse(accept, getVersion(), null);
+ acceptType = Accept.parse(accept, version, null);
}
utils = getUtilities(acceptType);
@@ -941,7 +1036,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else if (StringUtils.isNotBlank(accept)) {
- acceptType = Accept.parse(accept, getVersion(), null);
+ acceptType = Accept.parse(accept, version, null);
}
try {
@@ -963,7 +1058,7 @@ public abstract class AbstractServices {
final AbstractUtilities utils = getUtilities(null);
final Map.Entry<String, InputStream> entityInfo = utils.readMediaEntity(entitySetName, entityId, path);
- return utils.createResponse(entityInfo.getValue(), Commons.getETag(entityInfo.getKey(), getVersion()), null);
+ return utils.createResponse(entityInfo.getValue(), Commons.getETag(entityInfo.getKey(), version), null);
}
private Response navigateEntity(
@@ -989,7 +1084,7 @@ public abstract class AbstractServices {
stream = xml.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed());
}
- return xml.createResponse(stream, Commons.getETag(basePath, getVersion()), acceptType);
+ return xml.createResponse(stream, Commons.getETag(basePath, version), acceptType);
}
private Response navigateProperty(
@@ -1012,8 +1107,8 @@ public abstract class AbstractServices {
InputStream stream;
if (searchForValue) {
- stream = FSManager.instance(getVersion()).readFile(
- basePath + Constants.get(getVersion(), ConstantKey.ENTITY),
+ stream = FSManager.instance(version).readFile(
+ basePath + Constants.get(version, ConstantKey.ENTITY),
acceptType == null || acceptType == Accept.TEXT ? Accept.XML : acceptType);
stream = utils.getPropertyValue(stream, pathElements);
@@ -1022,7 +1117,7 @@ public abstract class AbstractServices {
stream = utils.getProperty(entitySetName, entityId, pathElements, edmType);
}
- return xml.createResponse(stream, Commons.getETag(basePath, getVersion()), acceptType);
+ return xml.createResponse(stream, Commons.getETag(basePath, version), acceptType);
}
/**
@@ -1048,7 +1143,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else {
- acceptType = Accept.parse(accept, getVersion());
+ acceptType = Accept.parse(accept, version);
}
if (acceptType == Accept.ATOM) {
@@ -1081,7 +1176,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else {
- acceptType = Accept.parse(accept, getVersion());
+ acceptType = Accept.parse(accept, version);
}
if (acceptType == Accept.ATOM) {
@@ -1090,7 +1185,7 @@ public abstract class AbstractServices {
final Accept content;
if (StringUtils.isNotBlank(contentType)) {
- content = Accept.parse(contentType, getVersion());
+ content = Accept.parse(contentType, version);
} else {
content = acceptType;
}
@@ -1158,7 +1253,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else {
- acceptType = Accept.parse(accept, getVersion());
+ acceptType = Accept.parse(accept, version);
}
if (acceptType == Accept.ATOM) {
@@ -1167,7 +1262,7 @@ public abstract class AbstractServices {
final Accept content;
if (StringUtils.isNotBlank(contentType)) {
- content = Accept.parse(contentType, getVersion());
+ content = Accept.parse(contentType, version);
} else {
content = acceptType;
}
@@ -1208,7 +1303,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else {
- acceptType = Accept.parse(accept, getVersion());
+ acceptType = Accept.parse(accept, version);
}
if (acceptType == Accept.ATOM) {
@@ -1251,7 +1346,7 @@ public abstract class AbstractServices {
@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
@PathParam("entitySetName") String entitySetName) {
try {
- final Accept acceptType = Accept.parse(accept, getVersion(), Accept.TEXT);
+ final Accept acceptType = Accept.parse(accept, version, Accept.TEXT);
if (acceptType != Accept.TEXT) {
throw new UnsupportedMediaTypeException("Unsupported type " + accept);
@@ -1273,7 +1368,7 @@ public abstract class AbstractServices {
if (StringUtils.isNotBlank(format)) {
acceptType = Accept.valueOf(format.toUpperCase());
} else {
- acceptType = Accept.parse(accept, getVersion());
+ acceptType = Accept.parse(accept, version);
}
return new AbstractMap.SimpleEntry<Accept, AbstractUtilities>(acceptType, getUtilities(acceptType));
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/V3KeyAsSegment.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V3KeyAsSegment.java b/fit/src/main/java/org/apache/olingo/fit/V3KeyAsSegment.java
new file mode 100644
index 0000000..6ec8651
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/V3KeyAsSegment.java
@@ -0,0 +1,159 @@
+/*
+ * 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.fit;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import static javax.ws.rs.core.Response.status;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.fit.methods.MERGE;
+import org.apache.olingo.fit.methods.PATCH;
+import org.springframework.stereotype.Service;
+
+@Service
+@Path("/V30/KeyAsSegment.svc")
+public class V3KeyAsSegment {
+
+ private final V3Services services;
+
+ public V3KeyAsSegment() throws Exception {
+ this.services = new V3Services();
+ }
+
+ private Response replaceServiceName(final Response response) {
+ try {
+ final String content = IOUtils.toString((InputStream) response.getEntity(), "UTF-8").
+ replaceAll("Static\\.svc", "KeyAsSegment.svc");
+
+ final Response.ResponseBuilder builder = status(response.getStatus());
+ for (String headerName : response.getHeaders().keySet()) {
+ for (Object headerValue : response.getHeaders().get(headerName)) {
+ builder.header(headerName, headerValue);
+ }
+ }
+
+ final InputStream toBeStreamedBack = IOUtils.toInputStream(content, "UTF-8");
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ IOUtils.copy(toBeStreamedBack, baos);
+ IOUtils.closeQuietly(toBeStreamedBack);
+
+ builder.header("Content-Length", baos.size());
+ builder.entity(new ByteArrayInputStream(baos.toByteArray()));
+
+ return builder.build();
+ } catch (Exception e) {
+ return response;
+ }
+ }
+
+ @GET
+ @Path("/{entitySetName}/{entityId}")
+ public Response getEntity(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+ @PathParam("entitySetName") String entitySetName,
+ @PathParam("entityId") String entityId,
+ @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format,
+ @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) String expand,
+ @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) String select) {
+
+ return replaceServiceName(services.getEntityInternal(
+ accept, entitySetName, entityId, format, expand, select, true));
+ }
+
+ @DELETE
+ @Path("/{entitySetName}/{entityId}")
+ public Response removeEntity(
+ @PathParam("entitySetName") String entitySetName,
+ @PathParam("entityId") String entityId) {
+
+ return replaceServiceName(services.removeEntity(entitySetName, entityId));
+ }
+
+ @MERGE
+ @Path("/{entitySetName}/{entityId}")
+ @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
+ @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
+ public Response mergeEntity(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
+ @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) String ifMatch,
+ @PathParam("entitySetName") String entitySetName,
+ @PathParam("entityId") String entityId,
+ final String changes) {
+
+ return replaceServiceName(services.patchEntity(accept, prefer, ifMatch, entitySetName, entityId, changes));
+ }
+
+ @PATCH
+ @Path("/{entitySetName}/{entityId}")
+ @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
+ @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
+ public Response patchEntity(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
+ @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) String ifMatch,
+ @PathParam("entitySetName") String entitySetName,
+ @PathParam("entityId") String entityId,
+ final String changes) {
+
+ return replaceServiceName(services.patchEntity(accept, prefer, ifMatch, entitySetName, entityId, changes));
+ }
+
+ @PUT
+ @Path("/{entitySetName}/{entityId}")
+ @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
+ @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
+ public Response putNewEntity(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
+ @PathParam("entitySetName") String entitySetName,
+ @PathParam("entityId") String entityId,
+ final String entity) {
+
+ return replaceServiceName(services.replaceEntity(accept, prefer, entitySetName, entityId, entity));
+ }
+
+ @POST
+ @Path("/{entitySetName}")
+ @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
+ @Consumes({MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM})
+ public Response postNewEntity(
+ @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+ @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) String prefer,
+ @PathParam("entitySetName") String entitySetName,
+ final String entity) {
+
+ return replaceServiceName(services.postNewEntity(accept, prefer, entitySetName, entity));
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/V3Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V3Services.java b/fit/src/main/java/org/apache/olingo/fit/V3Services.java
index 916ca82..1f379d3 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V3Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V3Services.java
@@ -28,18 +28,15 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.interceptor.InInterceptors;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
+import org.springframework.stereotype.Service;
+@Service
@Path("/V30/Static.svc")
@InInterceptors(classes = XHTTPMethodInterceptor.class)
public class V3Services extends AbstractServices {
public V3Services() throws Exception {
- super();
- }
-
- @Override
- protected ODataVersion getVersion() {
- return ODataVersion.v3;
+ super(ODataVersion.v3);
}
/**
@@ -51,7 +48,7 @@ public class V3Services extends AbstractServices {
@Path("/large/$metadata")
@Produces("application/xml")
public Response getLargeMetadata() {
- return getMetadata("large" + StringUtils.capitalize(Constants.get(getVersion(), ConstantKey.METADATA)));
+ return getMetadata("large" + StringUtils.capitalize(Constants.get(version, ConstantKey.METADATA)));
}
/**
@@ -63,7 +60,7 @@ public class V3Services extends AbstractServices {
@Path("/openType/$metadata")
@Produces("application/xml")
public Response getOpenTypeMetadata() {
- return getMetadata("openType" + StringUtils.capitalize(Constants.get(getVersion(), ConstantKey.METADATA)));
+ return getMetadata("openType" + StringUtils.capitalize(Constants.get(version, ConstantKey.METADATA)));
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/V4NorthWind.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4NorthWind.java b/fit/src/main/java/org/apache/olingo/fit/V4NorthWind.java
index b11d3e5..254b5ae 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4NorthWind.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4NorthWind.java
@@ -25,23 +25,20 @@ import javax.ws.rs.core.Response;
import org.apache.cxf.interceptor.InInterceptors;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
+import org.springframework.stereotype.Service;
+@Service
@Path("/V40/NorthWind.svc")
@InInterceptors(classes = XHTTPMethodInterceptor.class)
public class V4NorthWind extends AbstractServices {
public V4NorthWind() throws Exception {
- super();
- }
-
- @Override
- protected ODataVersion getVersion() {
- return ODataVersion.v4;
+ super(ODataVersion.v4);
}
@Override
public Response getMetadata() {
- return getMetadata("northwind-" + Constants.get(getVersion(), ConstantKey.METADATA));
+ return getMetadata("northwind-" + Constants.get(version, ConstantKey.METADATA));
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/V4NorthWindExt.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4NorthWindExt.java b/fit/src/main/java/org/apache/olingo/fit/V4NorthWindExt.java
index b5d4bda..ba986f0 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4NorthWindExt.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4NorthWindExt.java
@@ -26,23 +26,20 @@ import org.apache.cxf.interceptor.InInterceptors;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
import org.apache.olingo.fit.utils.ResolvingReferencesInterceptor;
+import org.springframework.stereotype.Service;
+@Service
@Path("/V40/NorthWindExt.svc")
@InInterceptors(classes = {XHTTPMethodInterceptor.class, ResolvingReferencesInterceptor.class})
public class V4NorthWindExt extends AbstractServices {
public V4NorthWindExt() throws Exception {
- super();
- }
-
- @Override
- protected ODataVersion getVersion() {
- return ODataVersion.v4;
+ super(ODataVersion.v4);
}
@Override
public Response getMetadata() {
- return getMetadata("northwindExt-" + Constants.get(getVersion(), ConstantKey.METADATA));
+ return getMetadata("northwindExt-" + Constants.get(version, ConstantKey.METADATA));
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/V4Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
index 327e82d..838a4f6 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
@@ -23,17 +23,14 @@ import org.apache.olingo.fit.utils.XHTTPMethodInterceptor;
import javax.ws.rs.Path;
import org.apache.cxf.interceptor.InInterceptors;
import org.apache.olingo.fit.utils.ResolvingReferencesInterceptor;
+import org.springframework.stereotype.Service;
+@Service
@Path("/V40/Static.svc")
@InInterceptors(classes = {XHTTPMethodInterceptor.class, ResolvingReferencesInterceptor.class})
public class V4Services extends AbstractServices {
public V4Services() throws Exception {
- super();
- }
-
- @Override
- protected ODataVersion getVersion() {
- return ODataVersion.v4;
+ super(ODataVersion.v4);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
index 14fff09..6c6b7cc 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractJSONUtilities.java
@@ -140,6 +140,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities {
protected InputStream normalizeLinks(
final String entitySetName, final String entityKey, final InputStream is, final NavigationLinks links)
throws Exception {
+
final ObjectMapper mapper = new ObjectMapper();
final ObjectNode srcNode = (ObjectNode) mapper.readTree(is);
@@ -169,7 +170,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities {
srcNode.set(
Constants.get(version, ConstantKey.JSON_EDITLINK_NAME), new TextNode(
- Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "(" + entityKey + ")"));
+ Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "(" + entityKey + ")"));
return IOUtils.toInputStream(srcNode.toString(), "UTf-8");
}
@@ -326,9 +327,9 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities {
for (String link : links) {
try {
- final Map.Entry<String, String> uri = Commons.parseEntityURI(link);
+ final Map.Entry<String, String> uriMap = Commons.parseEntityURI(link);
final Map.Entry<String, InputStream> entity =
- readEntity(uri.getKey(), uri.getValue(), Accept.JSON_FULLMETA);
+ readEntity(uriMap.getKey(), uriMap.getValue(), Accept.JSON_FULLMETA);
if (bos.size() > 1) {
bos.write(",".getBytes());
@@ -452,7 +453,23 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities {
IOUtils.closeQuietly(content);
srcNode.set(Constants.get(version, ConstantKey.JSON_EDITLINK_NAME), new TextNode(href));
- return IOUtils.toInputStream(srcNode.toString(), "UTf-8");
+ return IOUtils.toInputStream(srcNode.toString(), "UTF-8");
+ }
+
+ @Override
+ public InputStream addOperation(final InputStream content, final String name, final String metaAnchor,
+ final String href) throws Exception {
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final ObjectNode srcNode = (ObjectNode) mapper.readTree(content);
+ IOUtils.closeQuietly(content);
+
+ final ObjectNode action = mapper.createObjectNode();
+ action.set("title", new TextNode(name));
+ action.set("target", new TextNode(href));
+
+ srcNode.set(metaAnchor, action);
+ return IOUtils.toInputStream(srcNode.toString(), "UTF-8");
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
index 8df97e3..360a106 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
@@ -120,6 +120,7 @@ public abstract class AbstractUtilities {
final String key,
final String entitySetName,
final InputStream is) throws Exception {
+
return saveSingleEntity(key, entitySetName, is, null);
}
@@ -154,6 +155,7 @@ public abstract class AbstractUtilities {
public InputStream addOrReplaceEntity(
final String entitySetName, final InputStream is) throws Exception {
+
return addOrReplaceEntity(null, entitySetName, is);
}
@@ -332,7 +334,7 @@ public abstract class AbstractUtilities {
fsManager.putInMemory(
IOUtils.toInputStream(entity), fsManager.getAbsolutePath(path + Constants.get(version, ConstantKey.ENTITY),
- Accept.JSON_FULLMETA));
+ Accept.JSON_FULLMETA));
// -----------------------------------------
return readEntity(entitySetName, entityKey, getDefaultFormat()).getValue();
@@ -344,6 +346,7 @@ public abstract class AbstractUtilities {
final String entityKey,
final String linkName,
final Collection<String> links) throws IOException {
+
final HashSet<String> uris = new HashSet<String>();
if (Commons.linkInfo.get(version).isFeed(entitySetName, linkName)) {
@@ -362,6 +365,7 @@ public abstract class AbstractUtilities {
public void putLinksInMemory(
final String basePath, final String entitySetName, final String linkName, final Collection<String> uris)
throws IOException {
+
fsManager.putInMemory(
Commons.getLinksAsJSON(entitySetName, new SimpleEntry<String, Collection<String>>(linkName, uris)),
Commons.getLinksPath(version, basePath, linkName, Accept.JSON_FULLMETA));
@@ -536,6 +540,19 @@ public abstract class AbstractUtilities {
}
}
sequence.put(entitySetName, Integer.valueOf(res));
+ } else if ("Person".equals(entitySetName)) {
+ try {
+ final Map<String, InputStream> value =
+ getPropertyValues(entity, Collections.<String>singletonList("PersonId"));
+ res = value.isEmpty() ? null : IOUtils.toString(value.values().iterator().next());
+ } catch (Exception e) {
+ if (sequence.containsKey(entitySetName)) {
+ res = String.valueOf(sequence.get(entitySetName) + 1);
+ } else {
+ throw new Exception(String.format("Unable to retrieve entity key value for %s", entitySetName));
+ }
+ }
+ sequence.put(entitySetName, Integer.valueOf(res));
} else if ("ComputerDetail".equals(entitySetName)) {
try {
final Map<String, InputStream> value =
@@ -713,6 +730,7 @@ public abstract class AbstractUtilities {
final Accept accept,
final String ifMatch)
throws Exception {
+
final Map.Entry<String, InputStream> entityInfo = readEntity(entitySetName, entityId, accept);
final String etag = Commons.getETag(entityInfo.getKey(), version);
@@ -791,6 +809,9 @@ public abstract class AbstractUtilities {
public abstract InputStream addEditLink(
final InputStream content, final String title, final String href) throws Exception;
+ public abstract InputStream addOperation(
+ final InputStream content, final String name, final String metaAnchor, final String href) throws Exception;
+
protected abstract InputStream replaceProperty(
final InputStream src, final InputStream replacement, final List<String> path, final boolean justValue)
throws Exception;
@@ -808,4 +829,4 @@ public abstract class AbstractUtilities {
public abstract Map.Entry<String, List<String>> extractLinkURIs(
final String entitySetName, final String entityId, final String linkName) throws Exception;
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
index 88349a9..831ae42 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractXMLUtilities.java
@@ -192,7 +192,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
while (true) {
final Map.Entry<Integer, XmlElement> linkInfo =
extractElement(reader, null,
- Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)), startDepth, 2, 2);
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)), startDepth, 2, 2);
startDepth = linkInfo.getKey();
@@ -243,7 +243,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
try {
final XmlElement inlineElement =
extractElement(link.getContentReader(), null,
- Collections.<String>singletonList(Constants.get(version, ConstantKey.INLINE)), 0, -1, -1).
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.INLINE)), 0, -1, -1).
getValue();
final XMLEventReader inlineReader = inlineElement.getContentReader();
@@ -434,7 +434,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
final ByteArrayOutputStream copy = new ByteArrayOutputStream();
IOUtils.copy(content, copy);
-
IOUtils.closeQuietly(content);
XMLEventReader reader = getEventReader(new ByteArrayInputStream(copy.toByteArray()));
@@ -448,7 +447,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
// check edit link existence
extractElement(reader, writer, Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)),
Collections.<Map.Entry<String, String>>singletonList(
- new AbstractMap.SimpleEntry<String, String>("rel", "edit")), false, 0, -1, -1);
+ new AbstractMap.SimpleEntry<String, String>("rel", "edit")), false, 0, -1, -1);
addAtomElement(IOUtils.toInputStream(editLinkElement), writer);
writer.add(reader);
@@ -481,6 +480,21 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
return new ByteArrayInputStream(bos.toByteArray());
}
+ @Override
+ public InputStream addOperation(final InputStream content, final String name, final String metaAnchor,
+ final String href) throws Exception {
+
+ final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+ IOUtils.copy(content, copy);
+ IOUtils.closeQuietly(content);
+
+ final String action = String.format("<m:action metadata=\"%s%s\" title=\"%s\" target=\"%s\"/>",
+ Constants.get(version, ConstantKey.DEFAULT_SERVICE_URL), metaAnchor, name, href);
+ final String newContent = new String(copy.toByteArray(), "UTF-8").replaceAll("\\<content ", action + "\\<content ");
+
+ return IOUtils.toInputStream(newContent, "UTF-8");
+ }
+
public InputStream addAtomContent(
final InputStream content, final String title, final String href)
throws Exception {
@@ -526,7 +540,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
try {
final XmlElement entryElement =
extractElement(reader, writer, Collections.<String>singletonList(
- Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3).getValue();
+ Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3).getValue();
addAtomElement(
IOUtils.toInputStream("<content type=\"application/xml\">"),
@@ -578,7 +592,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
final String skipTokenDirPath = fsManager.getAbsolutePath(basePath + Constants.get(version, ConstantKey.SKIP_TOKEN),
null);
-
try {
final FileObject skipToken = fsManager.resolve(skipTokenDirPath);
final FileObject[] files = fsManager.findByExtension(skipToken, Accept.XML.getExtension().substring(1));
@@ -592,7 +605,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
LOG.debug("Resource path '{}' not found", skipTokenDirPath);
}
-
return count;
}
@@ -783,7 +795,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
if (event.getEventType() == XMLStreamConstants.START_ELEMENT
&& Constants.get(version, ConstantKey.LINK).equals(event.asStartElement().getName().getLocalPart())
&& !fieldToBeSaved.contains(
- event.asStartElement().getAttributeByName(new QName("title")).getValue())
+ event.asStartElement().getAttributeByName(new QName("title")).getValue())
&& !"edit".equals(event.asStartElement().getAttributeByName(new QName("rel")).getValue())) {
writeCurrent = false;
} else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
@@ -791,13 +803,13 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
writeNext = true;
} else if (event.getEventType() == XMLStreamConstants.START_ELEMENT
&& (Constants.get(version, ConstantKey.PROPERTIES)).equals(
- event.asStartElement().getName().getLocalPart())) {
+ event.asStartElement().getName().getLocalPart())) {
writeCurrent = true;
writeNext = false;
inProperties = true;
} else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
&& (Constants.get(version, ConstantKey.PROPERTIES)).equals(
- event.asEndElement().getName().getLocalPart())) {
+ event.asEndElement().getName().getLocalPart())) {
writeCurrent = true;
} else if (inProperties) {
if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
@@ -814,7 +826,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
} else if (event.getEventType() == XMLStreamConstants.END_ELEMENT
&& StringUtils.isNotBlank(currentName)
&& (Constants.get(version, ConstantKey.ATOM_PROPERTY_PREFIX) + currentName.trim()).equals(
- event.asEndElement().getName().getLocalPart())) {
+ event.asEndElement().getName().getLocalPart())) {
writeNext = false;
currentName = null;
}
@@ -840,7 +852,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
// if (!found.isEmpty()) {
// throw new Exception(String.format("Could not find a properties '%s'", found));
// }
-
return new ByteArrayInputStream(bos.toByteArray());
}
@@ -883,10 +894,10 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
final XmlElement entry =
extractElement(
- getEventReader(readEntity(uri.getKey(), uri.getValue(), Accept.ATOM).getValue()),
- null,
- Collections.<String>singletonList("entry"),
- 0, 1, 1).getValue();
+ getEventReader(readEntity(uri.getKey(), uri.getValue(), Accept.ATOM).getValue()),
+ null,
+ Collections.<String>singletonList("entry"),
+ 0, 1, 1).getValue();
IOUtils.copy(entry.toStream(), writer, encoding);
} catch (Exception e) {
@@ -923,7 +934,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
final Map.Entry<Integer, XmlElement> propertyElement =
extractElement(reader, null,
- Collections.<String>singletonList(Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3);
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3);
reader.close();
reader = propertyElement.getValue().getContentReader();
@@ -947,7 +958,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
while (true) {
final Map.Entry<Integer, XmlElement> linkElement =
extractElement(reader, null,
- Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)), pos, 2, 2);
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)), pos, 2, 2);
res.put("[Constants.get(version, ConstantKey.LINK)]"
+ linkElement.getValue().getStart().getAttributeByName(new QName("title")).getValue(),
@@ -977,7 +988,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
// ---------------------------------
Map.Entry<Integer, XmlElement> propertyElement =
extractElement(reader, writer,
- Collections.<String>singletonList(Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3);
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.PROPERTIES)), 0, 2, 3);
writer.flush();
@@ -1030,7 +1041,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
// ---------------------------------
// add navigationm changes
// ---------------------------------
-
// remove existent links
for (Map.Entry<String, InputStream> remains : properties.entrySet()) {
@@ -1111,9 +1121,9 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
try {
final XmlElement linkElement =
extractElement(reader, writer,
- Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)),
- Collections.<Map.Entry<String, String>>singletonList(new SimpleEntry<String, String>("title", linkName)),
- false, 0, -1, -1).getValue();
+ Collections.<String>singletonList(Constants.get(version, ConstantKey.LINK)),
+ Collections.<Map.Entry<String, String>>singletonList(
+ new SimpleEntry<String, String>("title", linkName)), false, 0, -1, -1).getValue();
writer.add(linkElement.getStart());
// ------------------------------------------
@@ -1155,7 +1165,6 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
final Map.Entry<Integer, XmlElement> prop = extractElement(getEventReader(src), null, atomPathElements, 0, 3, 4);
IOUtils.closeQuietly(src);
-
final Attribute type =
prop.getValue().getStart().getAttributeByName(new QName(Constants.get(version, ConstantKey.TYPE)));
@@ -1216,6 +1225,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
public InputStream getProperty(
final String entitySetName, final String entityId, final List<String> path, final String edmType)
throws Exception {
+
final List<String> pathElements = new ArrayList<String>();
for (String element : path) {
@@ -1224,7 +1234,7 @@ public abstract class AbstractXMLUtilities extends AbstractUtilities {
final InputStream src =
fsManager.readFile(Commons.getEntityBasePath(entitySetName, entityId)
- + Constants.get(version, ConstantKey.ENTITY), Accept.XML);
+ + Constants.get(version, ConstantKey.ENTITY), Accept.XML);
final XMLEventReader reader = getEventReader(src);
final XmlElement property = extractElement(reader, null, pathElements, 0, 3, 4).getValue();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bb748ec0/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
index 09a6db4..89aaf97 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
@@ -68,6 +68,7 @@ public abstract class Commons {
sequence.put("ComputerDetail", 1000);
sequence.put("AllGeoTypesSet", 1000);
sequence.put("Orders", 1000);
+ sequence.put("Person", 1000);
mediaContent.put("CustomerInfo", "CustomerinfoId");
mediaContent.put("Car", "VIN");
@@ -113,7 +114,7 @@ public abstract class Commons {
try {
return FSManager.instance(version)
.getAbsolutePath(basePath + Constants.get(version, ConstantKey.LINKS_FILE_PATH)
- + File.separatorChar + linkName, accept);
+ + File.separatorChar + linkName, accept);
} catch (Exception e) {
throw new IOException(e);
}
@@ -138,6 +139,7 @@ public abstract class Commons {
public static InputStream getLinksAsATOM(final Map.Entry<String, Collection<String>> link)
throws IOException {
+
final StringBuilder builder = new StringBuilder();
builder.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
builder.append("<links xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices\">");
@@ -160,6 +162,7 @@ public abstract class Commons {
public static InputStream getLinksAsJSON(
final String entitySetName, final Map.Entry<String, Collection<String>> link)
throws IOException {
+
final ObjectNode links = new ObjectNode(JsonNodeFactory.instance);
links.put(
Constants.get(ConstantKey.JSON_ODATAMETADATA_NAME),