You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ra...@apache.org on 2015/04/20 16:28:41 UTC
[21/22] olingo-odata4 git commit: OLINGO-573: merging to master
OLINGO-573: merging to master
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/3ac433b0
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/3ac433b0
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/3ac433b0
Branch: refs/heads/OLINGO-573
Commit: 3ac433b0771fcfc3edf3c205f4a037c302e547d5
Parents: 547725d
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Sun Apr 5 17:54:44 2015 -0500
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Mon Apr 20 08:59:28 2015 -0500
----------------------------------------------------------------------
lib/server-core-ext/pom.xml | 1 -
.../server/core/ReturnRepresentation.java | 2 +-
.../olingo/server/core/ServiceRequest.java | 17 ++-
.../server/core/requests/ActionRequest.java | 29 ++++-
.../server/core/requests/DataRequest.java | 110 +++++++++++++++----
.../server/core/requests/FunctionRequest.java | 29 +++--
.../server/core/responses/EntityResponse.java | 62 +++++++++--
.../core/responses/EntitySetResponse.java | 13 ++-
.../server/core/responses/MetadataResponse.java | 9 ++
.../core/responses/PrimitiveValueResponse.java | 10 ++
.../server/core/responses/PropertyResponse.java | 15 +++
.../server/core/responses/ResponseUtil.java | 86 +++++++++++++++
.../core/responses/ServiceDocumentResponse.java | 9 ++
.../server/core/responses/ServiceResponse.java | 9 ++
.../server/core/ServiceDispatcherTest.java | 4 -
.../olingo/server/example/TripPinDataModel.java | 93 ++++++++--------
.../olingo/server/example/TripPinHandler.java | 40 ++-----
.../server/example/TripPinServiceTest.java | 22 +++-
.../src/test/resources/airlines.json | 6 +-
.../serializer/json/ODataJsonSerializer.java | 6 +
20 files changed, 437 insertions(+), 135 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/pom.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/pom.xml b/lib/server-core-ext/pom.xml
index 5249ed4..6070052 100644
--- a/lib/server-core-ext/pom.xml
+++ b/lib/server-core-ext/pom.xml
@@ -81,7 +81,6 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReturnRepresentation.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReturnRepresentation.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReturnRepresentation.java
index e9a213e..6779d76 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReturnRepresentation.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReturnRepresentation.java
@@ -19,5 +19,5 @@
package org.apache.olingo.server.core;
public enum ReturnRepresentation {
- REPRESENTATION, MINIMAL
+ REPRESENTATION, MINIMAL, NONE
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java
index e9a8cfe..0fda018 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java
@@ -41,6 +41,7 @@ import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.core.requests.DataRequest;
@@ -155,19 +156,23 @@ public abstract class ServiceRequest {
} else if (serilizerOptions.isAssignableFrom(ComplexSerializerOptions.class)) {
return (T) ComplexSerializerOptions.with().contextURL(contextUrl)
.expand(this.uriInfo.getExpandOption()).select(this.uriInfo.getSelectOption()).build();
+ } else if (serilizerOptions.isAssignableFrom(PrimitiveSerializerOptions.class)) {
+ return (T) PrimitiveSerializerOptions.with().contextURL(contextUrl)
+ .build();
}
return null;
}
public ReturnRepresentation getReturnRepresentation() {
String prefer = this.request.getHeader(HttpHeader.PREFER);
- if (prefer == null) {
- return ReturnRepresentation.REPRESENTATION;
- }
- if (prefer.contains("return=minimal")) { //$NON-NLS-1$
- return ReturnRepresentation.MINIMAL;
+ if (prefer != null) {
+ if (prefer.contains("return=minimal")) { //$NON-NLS-1$
+ return ReturnRepresentation.MINIMAL;
+ } else if (prefer.contains("return=representation")) {
+ return ReturnRepresentation.REPRESENTATION;
+ }
}
- return ReturnRepresentation.REPRESENTATION;
+ return ReturnRepresentation.NONE;
}
public String getHeader(String key) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
index 133ee3e..d4502cc 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
@@ -19,6 +19,9 @@
package org.apache.olingo.server.core.requests;
+import java.io.InputStream;
+
+import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.server.api.OData;
@@ -26,7 +29,9 @@ import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataTranslatedException;
import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.uri.UriResourceAction;
+import org.apache.olingo.server.core.ContentNegotiatorException;
import org.apache.olingo.server.core.ServiceHandler;
import org.apache.olingo.server.core.responses.EntityResponse;
import org.apache.olingo.server.core.responses.EntitySetResponse;
@@ -59,10 +64,7 @@ public class ActionRequest extends OperationRequest {
if (!hasReturnType()) {
handler.invoke(this, getETag(), new NoContentResponse(getServiceMetaData(), response));
} else {
- if (isReturnTypePrimitive()) {
- handler.invoke(this, getETag(),
- PrimitiveValueResponse.getInstance(this, response, isCollection(), getReturnType()));
- } else if (isReturnTypeComplex()) {
+ if (isReturnTypePrimitive() || isReturnTypeComplex()) {
handler.invoke(this, getETag(), PropertyResponse.getInstance(this, response,
getReturnType().getType(), getContextURL(this.odata), isCollection()));
} else {
@@ -83,6 +85,21 @@ public class ActionRequest extends OperationRequest {
// 11.5.4.1 Invoking an Action - only allows POST
return (isPOST());
}
+
+ @Override
+ public <T> T getSerializerOptions(Class<T> serilizerOptions, ContextURL contextUrl, boolean references)
+ throws ContentNegotiatorException {
+ if (hasReturnType() && serilizerOptions.isAssignableFrom(PrimitiveSerializerOptions.class)) {
+ return (T) PrimitiveSerializerOptions.with().contextURL(contextUrl)
+ .nullable(getReturnType().isNullable())
+ .maxLength(getReturnType().getMaxLength())
+ .precision(getReturnType().getPrecision())
+ .scale(getReturnType().getScale())
+ .unicode(null)
+ .build();
+ }
+ return super.getSerializerOptions(serilizerOptions, contextUrl, references);
+ }
public UriResourceAction getUriResourceAction() {
return uriResourceAction;
@@ -117,4 +134,8 @@ public class ActionRequest extends OperationRequest {
public boolean hasReturnType() {
return getAction().getReturnType() != null;
}
+
+ public InputStream getPayload() {
+ return getODataRequest().getBody();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
index cebaf64..8855486 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
@@ -18,27 +18,31 @@
*/
package org.apache.olingo.server.core.requests;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.LinkedList;
import java.util.List;
+import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.commons.core.data.PropertyImpl;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.commons.core.edm.primitivetype.EdmStream;
import org.apache.olingo.server.api.OData;
@@ -66,6 +70,7 @@ import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.UriResourceSingleton;
import org.apache.olingo.server.core.ContentNegotiator;
import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ReturnRepresentation;
import org.apache.olingo.server.core.ServiceHandler;
import org.apache.olingo.server.core.ServiceRequest;
import org.apache.olingo.server.core.responses.CountResponse;
@@ -261,6 +266,11 @@ public class DataRequest extends ServiceRequest {
if (!getNavigations().isEmpty() && !isGET()) {
return false;
}
+
+ if ((isGET() || isDELETE()) && getReturnRepresentation() != ReturnRepresentation.NONE) {
+ return false;
+ }
+
return true;
}
@@ -290,7 +300,8 @@ public class DataRequest extends ServiceRequest {
// an If-None-Match or an If-Modified-Since header fields is undefined
// by this specification.
boolean ifMatch = getHeader(HttpHeader.IF_MATCH) != null;
- boolean ifNoneMatch = getHeader(HttpHeader.IF_NONE_MATCH).equals("*");
+ boolean ifNoneMatch = (getHeader(HttpHeader.IF_NONE_MATCH)!= null
+ && getHeader(HttpHeader.IF_NONE_MATCH).equals("*"));
if(ifMatch) {
handler.updateEntity(DataRequest.this, getEntityFromClient(), isPATCH(), getETag(),
entityResponse);
@@ -332,6 +343,10 @@ public class DataRequest extends ServiceRequest {
@Override
public boolean allowedMethod() {
+ if (getReturnRepresentation() != ReturnRepresentation.NONE) {
+ return false;
+ }
+
return isGET();
}
@@ -359,6 +374,10 @@ public class DataRequest extends ServiceRequest {
@Override
public boolean allowedMethod() {
+ if ((isGET() || isDELETE()) && getReturnRepresentation() != ReturnRepresentation.NONE) {
+ return false;
+ }
+
// references are only allowed on the navigation properties
if (getNavigations().isEmpty()) {
return false;
@@ -448,6 +467,10 @@ public class DataRequest extends ServiceRequest {
@Override
public boolean allowedMethod() {
+ if ((isGET() || isDELETE() || isPropertyStream()) && getReturnRepresentation() != ReturnRepresentation.NONE) {
+ return false;
+ }
+
// create of properties is not allowed,
// only read, update, delete. Note that delete is
// same as update with null
@@ -502,13 +525,11 @@ public class DataRequest extends ServiceRequest {
}
} else if (isDELETE()) {
if (isPropertyStream()) {
- handler.upsertStreamProperty(DataRequest.this, getETag(), request.getBody(),
+ handler.upsertStreamProperty(DataRequest.this, getETag(), null,
new NoContentResponse(getServiceMetaData(), response));
} else {
- Property property = new PropertyImpl();
- property.setName(edmProperty.getName());
- property.setType(edmProperty.getType().getFullQualifiedName()
- .getFullQualifiedNameAsString());
+ Property property = new Property(edmProperty.getType().getFullQualifiedName()
+ .getFullQualifiedNameAsString(), edmProperty.getName());
handler.updateProperty(DataRequest.this, property, false, getETag(),
buildResponse(response, edmProperty));
}
@@ -527,8 +548,8 @@ public class DataRequest extends ServiceRequest {
final UriHelper helper = odata.createUriHelper();
EdmProperty edmProperty = getUriResourceProperty().getProperty();
- ContextURL.Builder builder = ContextURL.with().entitySet(getEntitySet());
- builder = ContextURL.with().entitySet(getEntitySet());
+ ContextURL.Builder builder =
+ ContextURL.with().entitySetOrSingletonOrType(getTargetEntitySet(getEntitySet(), getNavigations()));
builder.keyPath(helper.buildContextURLKeyPredicate(getUriResourceEntitySet()
.getKeyPredicates()));
String navPath = buildNavPath(helper, getEntitySet().getEntityType(), getNavigations(), true);
@@ -551,11 +572,17 @@ public class DataRequest extends ServiceRequest {
@Override
public boolean allowedMethod() {
- //part2-url-conventions # 4.2
+ //part2-url-conventions # 4.7
+ // Properties of type Edm.Stream already return the raw value of
+ // the media stream and do not support appending the $value segment.
if (isPropertyStream() && isGET()) {
return false;
}
+ if ((isGET() || isDELETE() || isPropertyStream()) && getReturnRepresentation() != ReturnRepresentation.NONE) {
+ return false;
+ }
+
return isGET() || isDELETE() || isPUT();
}
@@ -576,17 +603,20 @@ public class DataRequest extends ServiceRequest {
handler.read(DataRequest.this, PrimitiveValueResponse.getInstance(DataRequest.this,
response, isCollection(), getUriResourceProperty().getProperty()));
} else if (isDELETE()) {
- Property property = new PropertyImpl();
- property.setName(edmProperty.getName());
- property.setType(edmProperty.getType().getFullQualifiedName().getFullQualifiedNameAsString());
-
+ Property property = new Property(
+ edmProperty.getType().getFullQualifiedName().getFullQualifiedNameAsString(),
+ edmProperty.getName());
PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response,
edmProperty.getType(), getContextURL(odata), edmProperty.isCollection());
handler.updateProperty(DataRequest.this, property, false, getETag(), propertyResponse);
} else if (isPUT()) {
PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response,
edmProperty.getType(), getContextURL(odata), edmProperty.isCollection());
- handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), false,
+ Property property = new Property(
+ edmProperty.getType().getFullQualifiedName().getFullQualifiedNameAsString(),
+ edmProperty.getName());
+ property.setValue(ValueType.PRIMITIVE, getRawValueFromClient(edmProperty));
+ handler.updateProperty(DataRequest.this, property, false,
getETag(), propertyResponse);
}
}
@@ -659,20 +689,38 @@ public class DataRequest extends ServiceRequest {
private org.apache.olingo.commons.api.data.Property getPropertyValueFromClient(
EdmProperty edmProperty) throws DeserializerException {
- // TODO:this is not right, we should be deserializing the property
- // (primitive, complex, collection of)
- // for now it is responsibility of the user
ODataDeserializer deserializer = odata.createDeserializer(ODataFormat
.fromContentType(getRequestContentType()));
return deserializer.property(getODataRequest().getBody(), edmProperty).getProperty();
}
+
+ private Object getRawValueFromClient(
+ EdmProperty edmProperty) throws DeserializerException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
+ byte[] buffer = new byte[1024];
+ int read = 0;
+ do {
+ try {
+ read = IOUtils.read(getODataRequest().getBody(), buffer, 0, 1024);
+ bos.write(buffer, 0, read);
+ if (read < 1024) {
+ break;
+ }
+ } catch (IOException e) {
+ new DeserializerException("Error reading raw value",
+ SerializerException.MessageKeys.IO_EXCEPTION);
+ }
+ } while (true);
+ return bos.toByteArray();
+ }
static ContextURL.Builder buildEntitySetContextURL(UriHelper helper,
EdmBindingTarget edmEntitySet, List<UriParameter> keyPredicates, UriInfo uriInfo,
LinkedList<UriResourceNavigation> navigations, boolean collectionReturn, boolean singleton)
throws SerializerException {
- ContextURL.Builder builder = ContextURL.with().entitySetOrSingletonOrType(edmEntitySet.getName());
+ ContextURL.Builder builder =
+ ContextURL.with().entitySetOrSingletonOrType(getTargetEntitySet(edmEntitySet, navigations));
String select = helper.buildContextURLSelectList(edmEntitySet.getEntityType(),
uriInfo.getExpandOption(), uriInfo.getSelectOption());
if (!singleton) {
@@ -718,6 +766,30 @@ public class DataRequest extends ServiceRequest {
return result.length() == 0?null:result.toString();
}
+ static String getTargetEntitySet(EdmBindingTarget root, LinkedList<UriResourceNavigation> navigations) {
+ EdmEntityType type = root.getEntityType();
+ EdmBindingTarget targetEntitySet = root;
+ String targetEntitySetName = root.getName();
+ String name = null;
+ for (UriResourceNavigation nav:navigations) {
+ name = nav.getProperty().getName();
+ EdmNavigationProperty property = type.getNavigationProperty(name);
+ if (property.containsTarget()) {
+ return root.getName();
+ }
+ type = nav.getProperty().getType();
+
+ for(EdmNavigationPropertyBinding enb:targetEntitySet.getNavigationPropertyBindings()) {
+ if (enb.getPath().equals(name)) {
+ targetEntitySetName = enb.getTarget();
+ } else if (enb.getPath().endsWith("/"+name)) {
+ targetEntitySetName = enb.getTarget();
+ }
+ }
+ }
+ return targetEntitySetName;
+ }
+
static String buildNavPath(UriHelper helper, EdmEntityType rootType,
LinkedList<UriResourceNavigation> navigations, boolean includeLastPredicates)
throws SerializerException {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/FunctionRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/FunctionRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/FunctionRequest.java
index a9f9341..b77fb2b 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/FunctionRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/FunctionRequest.java
@@ -21,6 +21,7 @@ package org.apache.olingo.server.core.requests;
import java.util.List;
+import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.server.api.OData;
@@ -28,8 +29,10 @@ import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataTranslatedException;
import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResourceFunction;
+import org.apache.olingo.server.core.ContentNegotiatorException;
import org.apache.olingo.server.core.ServiceHandler;
import org.apache.olingo.server.core.responses.EntityResponse;
import org.apache.olingo.server.core.responses.EntitySetResponse;
@@ -52,14 +55,9 @@ public class FunctionRequest extends OperationRequest {
}
// Functions always have return per 11.5.3
- if (isReturnTypePrimitive()) {
- // functions can not return a typed property in the context of entity, so
- // it must be treated
- // as value based response
- handler.invoke(this, getODataRequest().getMethod(),
- PrimitiveValueResponse.getInstance(this, response, isCollection(), getReturnType()));
- } else if (isReturnTypeComplex()) {
- handler.invoke(this, getODataRequest().getMethod(), PropertyResponse.getInstance(this, response,
+ if (isReturnTypePrimitive() || isReturnTypeComplex()) {
+ // per odata-json-format/v4.0 = 11 Individual Property or Operation Response
+ handler.invoke(this, getODataRequest().getMethod(), PropertyResponse.getInstance(this, response,
getReturnType().getType(), getContextURL(this.odata), isCollection()));
} else {
// returnType.getType().getKind() == EdmTypeKind.ENTITY
@@ -83,6 +81,21 @@ public class FunctionRequest extends OperationRequest {
return isGET();
}
+ @Override
+ public <T> T getSerializerOptions(Class<T> serilizerOptions, ContextURL contextUrl, boolean references)
+ throws ContentNegotiatorException {
+ if (serilizerOptions.isAssignableFrom(PrimitiveSerializerOptions.class)) {
+ return (T) PrimitiveSerializerOptions.with().contextURL(contextUrl)
+ .nullable(getReturnType().isNullable())
+ .maxLength(getReturnType().getMaxLength())
+ .precision(getReturnType().getPrecision())
+ .scale(getReturnType().getScale())
+ .unicode(null)
+ .build();
+ }
+ return super.getSerializerOptions(serilizerOptions, contextUrl, references);
+ }
+
public UriResourceFunction getUriResourceFunction() {
return uriResourceFunction;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
index e90681d..eb79c07 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
@@ -22,12 +22,14 @@ import java.util.Map;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ODataTranslatedException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
@@ -42,15 +44,17 @@ public class EntityResponse extends ServiceResponse {
private final ODataSerializer serializer;
private final EntitySerializerOptions options;
private final ContentType responseContentType;
+ private final String baseURL;
private EntityResponse(ServiceMetadata metadata, ODataResponse response,
ODataSerializer serializer, EntitySerializerOptions options, ContentType responseContentType,
- Map<String, String> preferences, ReturnRepresentation returnRepresentation) {
+ Map<String, String> preferences, ReturnRepresentation returnRepresentation, String baseURL) {
super(metadata, response, preferences);
this.serializer = serializer;
this.options = options;
this.responseContentType = responseContentType;
this.returnRepresentation = returnRepresentation;
+ this.baseURL = baseURL;
}
public static EntityResponse getInstance(ServiceRequest request, ContextURL contextURL,
@@ -59,7 +63,8 @@ public class EntityResponse extends ServiceResponse {
EntitySerializerOptions options = request.getSerializerOptions(EntitySerializerOptions.class,
contextURL, references);
return new EntityResponse(request.getServiceMetaData(), response, request.getSerializer(),
- options, request.getResponseContentType(), request.getPreferences(), returnRepresentation);
+ options, request.getResponseContentType(), request.getPreferences(), returnRepresentation,
+ request.getODataRequest().getRawBaseUri());
}
public static EntityResponse getInstance(ServiceRequest request, ContextURL contextURL,
@@ -68,7 +73,8 @@ public class EntityResponse extends ServiceResponse {
EntitySerializerOptions options = request.getSerializerOptions(EntitySerializerOptions.class,
contextURL, references);
return new EntityResponse(request.getServiceMetaData(), response, request.getSerializer(),
- options, request.getResponseContentType(), request.getPreferences(), null);
+ options, request.getResponseContentType(), request.getPreferences(), null,
+ request.getODataRequest().getRawBaseUri());
}
// write single entity
@@ -87,19 +93,24 @@ public class EntityResponse extends ServiceResponse {
close();
}
- public void writeCreatedEntity(EdmEntityType entityType, Entity entity, String locationHeader)
+ public void writeCreatedEntity(EdmEntitySet entitySet, Entity entity)
throws SerializerException {
// upsert/insert must created a entity, otherwise should have throw an
// exception
assert (entity != null);
+
+ String locationHeader = buildLocation(this.baseURL, entity, entitySet.getName(), entitySet.getEntityType());
// Note that if media written just like Stream, but on entity URL
// 8.2.8.7
- if (this.returnRepresentation == ReturnRepresentation.MINIMAL) {
+ if (this.returnRepresentation == ReturnRepresentation.MINIMAL ||
+ this.returnRepresentation == ReturnRepresentation.NONE) {
writeNoContent(false);
writeHeader(HttpHeader.LOCATION, locationHeader);
- writeHeader("Preference-Applied", "return=minimal"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (this.returnRepresentation == ReturnRepresentation.MINIMAL) {
+ writeHeader("Preference-Applied", "return=minimal"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
// 8.3.3
writeHeader("OData-EntityId", entity.getId().toASCIIString()); //$NON-NLS-1$
close();
@@ -107,7 +118,8 @@ public class EntityResponse extends ServiceResponse {
}
// return the content of the created entity
- this.response.setContent(this.serializer.entity(this.metadata, entityType, entity, this.options).getContent());
+ this.response.setContent(this.serializer.entity(this.metadata, entitySet.getEntityType(), entity, this.options)
+ .getContent());
writeCreated(false);
writeHeader(HttpHeader.LOCATION, locationHeader);
writeHeader("Preference-Applied", "return=representation"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -137,4 +149,40 @@ public class EntityResponse extends ServiceResponse {
close();
}
}
+
+ public void writeError(ODataServerError error) {
+ try {
+ writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
+ } catch (SerializerException e) {
+ writeServerError(true);
+ }
+ }
+
+ public void writeNotModified() {
+ this.response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
+ close();
+ }
+
+ public static String buildLocation(String baseURL, Entity entity, String enitySetName, EdmEntityType type) {
+ String location = baseURL + "/" + enitySetName + "(";
+ int i = 0;
+ boolean usename = type.getKeyPredicateNames().size() > 1;
+
+ for (String key : type.getKeyPredicateNames()) {
+ if (i > 0) {
+ location += ",";
+ }
+ i++;
+ if (usename) {
+ location += (key + "=");
+ }
+ if (entity.getProperty(key).getType().equals("Edm.String")) {
+ location = location + "'" + entity.getProperty(key).getValue().toString() + "'";
+ } else {
+ location = location + entity.getProperty(key).getValue().toString();
+ }
+ }
+ location += ")";
+ return location;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
index c70854b..27675c3 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
@@ -21,11 +21,12 @@ package org.apache.olingo.server.core.responses;
import java.util.Map;
import org.apache.olingo.commons.api.data.ContextURL;
-import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ODataTranslatedException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
@@ -58,7 +59,7 @@ public class EntitySetResponse extends ServiceResponse {
// write collection of entities
// TODO: server paging needs to be implemented.
- public void writeReadEntitySet(EdmEntityType entityType, EntitySet entitySet)
+ public void writeReadEntitySet(EdmEntityType entityType, EntityCollection entitySet)
throws SerializerException {
assert (!isClosed());
@@ -80,4 +81,12 @@ public class EntitySetResponse extends ServiceResponse {
ODataApplicationException {
visitor.visit(this);
}
+
+ public void writeError(ODataServerError error) {
+ try {
+ writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
+ } catch (SerializerException e) {
+ writeServerError(true);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
index b325421..a644358 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
@@ -23,6 +23,7 @@ import java.util.Map;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ODataTranslatedException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.ODataSerializer;
@@ -59,4 +60,12 @@ public class MetadataResponse extends ServiceResponse {
ODataApplicationException {
visitor.visit(this);
}
+
+ public void writeError(ODataServerError error) {
+ try {
+ writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
+ } catch (SerializerException e) {
+ writeServerError(true);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PrimitiveValueResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PrimitiveValueResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PrimitiveValueResponse.java
index 005bfca..d5fa32b 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PrimitiveValueResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PrimitiveValueResponse.java
@@ -18,6 +18,7 @@
*/
package org.apache.olingo.server.core.responses;
+import java.io.ByteArrayInputStream;
import java.util.Map;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
@@ -92,6 +93,15 @@ public class PrimitiveValueResponse extends ServiceResponse {
writeOK(HttpContentType.TEXT_PLAIN);
}
+
+ public void writeEdmBinary(byte[] value) throws SerializerException {
+ if (value == null) {
+ writeNoContent(true);
+ return;
+ }
+ this.response.setContent(new ByteArrayInputStream(value));
+ writeOK(HttpContentType.APPLICATION_OCTET_STREAM);
+ }
public boolean isReturnCollection() {
return returnCollection;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
index 79ac90d..86ce46f 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
@@ -27,8 +27,10 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ODataTranslatedException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
@@ -141,4 +143,17 @@ public class PropertyResponse extends ServiceResponse {
public void writePropertyDeleted() {
writeNoContent(true);
}
+
+ public void writeError(ODataServerError error) {
+ try {
+ writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
+ } catch (SerializerException e) {
+ writeServerError(true);
+ }
+ }
+
+ public void writeNotModified() {
+ this.response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
+ close();
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ResponseUtil.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ResponseUtil.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ResponseUtil.java
new file mode 100644
index 0000000..257f8c7
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ResponseUtil.java
@@ -0,0 +1,86 @@
+/*
+ * 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.server.core.responses;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.commons.api.data.ComplexValue;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ValueType;
+import org.apache.olingo.commons.api.domain.ODataLinkType;
+
+public class ResponseUtil {
+ public static Property createPrimitive(final String name, final String type, final Object value) {
+ return new Property(type, name, ValueType.PRIMITIVE, value);
+ }
+
+ public static Property createPrimitiveCollection(final String name, final Object... values) {
+ return new Property(null, name, ValueType.COLLECTION_PRIMITIVE, Arrays.asList(values));
+ }
+
+ public static Property createComplex(final String name, final String type, final Property... properties) {
+ ComplexValue complexValue = new ComplexValue();
+ for (final Property property : properties) {
+ complexValue.getValue().add(property);
+ }
+ return new Property(type, name, ValueType.COMPLEX, complexValue);
+ }
+
+ public static Property createComplexCollection(final String name, final String type,
+ final List<Property>... propertiesList) {
+ List<ComplexValue> complexCollection = new ArrayList<ComplexValue>();
+ for (final List<Property> properties : propertiesList) {
+ ComplexValue complexValue = new ComplexValue();
+ complexValue.getValue().addAll(properties);
+ complexCollection.add(complexValue);
+ }
+ return new Property(type, name, ValueType.COLLECTION_COMPLEX, complexCollection);
+ }
+
+ public static void setLink(Entity entity, final String navigationPropertyName, final Entity target) {
+ Link link = entity.getNavigationLink(navigationPropertyName);
+ if (link == null) {
+ link = new Link();
+ link.setType(ODataLinkType.ENTITY_NAVIGATION.toString());
+ link.setTitle(navigationPropertyName);
+ entity.getNavigationLinks().add(link);
+ }
+ link.setInlineEntity(target);
+ }
+
+ public static void setLinks(Entity entity, final String navigationPropertyName, final Entity... targets) {
+ Link link = entity.getNavigationLink(navigationPropertyName);
+ if (link == null) {
+ link = new Link();
+ link.setType(ODataLinkType.ENTITY_SET_NAVIGATION.toString());
+ link.setTitle(navigationPropertyName);
+ EntityCollection target = new EntityCollection();
+ target.getEntities().addAll(Arrays.asList(targets));
+ link.setInlineEntitySet(target);
+ entity.getNavigationLinks().add(link);
+ } else {
+ link.getInlineEntitySet().getEntities().addAll(Arrays.asList(targets));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
index 8b77684..0f3733c 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
@@ -23,6 +23,7 @@ import java.util.Map;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ODataTranslatedException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.ODataSerializer;
@@ -60,4 +61,12 @@ public class ServiceDocumentResponse extends ServiceResponse {
ODataApplicationException {
visitor.visit(this);
}
+
+ public void writeError(ODataServerError error) {
+ try {
+ writeContent(this.serializer.error(error).getContent(), error.getStatusCode(), true);
+ } catch (SerializerException e) {
+ writeServerError(true);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponse.java
index a306551..bf000e0 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponse.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceResponse.java
@@ -19,6 +19,7 @@
package org.apache.olingo.server.core.responses;
+import java.io.InputStream;
import java.util.Map;
import org.apache.olingo.commons.api.http.HttpHeader;
@@ -105,6 +106,14 @@ public abstract class ServiceResponse {
this.response.setHeader(key, value);
}
}
+
+ public void writeContent(InputStream content, int statusCode, boolean closeResponse) {
+ this.response.setContent(content);
+ this.response.setStatusCode(statusCode);
+ if (closeResponse) {
+ close();
+ }
+ }
/**
* When true; the "Preference-Applied" header is strictly checked.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
index faabafc..a289738 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
@@ -36,7 +36,6 @@ import org.apache.catalina.startup.Tomcat;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
@@ -62,7 +61,6 @@ import org.apache.olingo.server.core.responses.NoContentResponse;
import org.apache.olingo.server.core.responses.PrimitiveValueResponse;
import org.apache.olingo.server.core.responses.PropertyResponse;
import org.apache.olingo.server.core.responses.StreamResponse;
-import org.apache.olingo.server.example.TripPinServiceTest;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -70,7 +68,6 @@ import org.mockito.Mockito;
public class ServiceDispatcherTest {
private static final int TOMCAT_PORT = 9900;
private Tomcat tomcat = new Tomcat();
- private String baseURL;
public class SampleODataServlet extends HttpServlet {
private final ServiceHandler handler; // must be stateless
@@ -103,7 +100,6 @@ public class ServiceDispatcherTest {
Context cxt = tomcat.addContext("/trippin", baseDir.getAbsolutePath());
Tomcat.addServlet(cxt, "trippin", new SampleODataServlet(serviceHandler, edmProvider));
cxt.addServletMapping("/*", "trippin");
- baseURL = "http://" + tomcat.getHost().getName() + ":"+ TOMCAT_PORT;
tomcat.setPort(TOMCAT_PORT);
tomcat.start();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
index 055f073..a960d67 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
@@ -33,7 +33,7 @@ import java.util.Map;
import java.util.UUID;
import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
@@ -45,21 +45,19 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
-import org.apache.olingo.commons.core.data.EntityImpl;
-import org.apache.olingo.commons.core.data.EntitySetImpl;
-import org.apache.olingo.commons.core.data.LinkImpl;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.core.deserializer.json.ODataJsonDeserializer;
+import org.apache.olingo.server.core.responses.EntityResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TripPinDataModel {
private final ServiceMetadata metadata;
- private HashMap<String, EntitySet> entitySetMap;
+ private HashMap<String, EntityCollection> entitySetMap;
private Map<Integer, Map> tripLinks;
private Map<String, Map> peopleLinks;
private Map<Integer, Map> flightLinks;
@@ -70,7 +68,7 @@ public class TripPinDataModel {
}
public void loadData() throws Exception {
- this.entitySetMap = new HashMap<String, EntitySet>();
+ this.entitySetMap = new HashMap<String, EntityCollection>();
this.tripLinks = new HashMap<Integer, Map>();
this.peopleLinks = new HashMap<String, Map>();
this.flightLinks = new HashMap<Integer, Map>();
@@ -78,7 +76,7 @@ public class TripPinDataModel {
EdmEntityContainer ec = metadata.getEdm().getEntityContainer(null);
for (EdmEntitySet edmEntitySet : ec.getEntitySets()) {
String entitySetName = edmEntitySet.getName();
- EntitySet set = loadEnities(entitySetName, edmEntitySet.getEntityType());
+ EntityCollection set = loadEnities(entitySetName, edmEntitySet.getEntityType());
if (set != null) {
this.entitySetMap.put(entitySetName, set);
}
@@ -119,19 +117,19 @@ public class TripPinDataModel {
}
}
- private EntitySet loadEnities(String entitySetName, EdmEntityType type) {
+ private EntityCollection loadEnities(String entitySetName, EdmEntityType type) {
try {
ODataJsonDeserializer deserializer = new ODataJsonDeserializer();
- EntitySet set = deserializer.entityCollection(new FileInputStream(new File(
+ EntityCollection set = deserializer.entityCollection(new FileInputStream(new File(
"src/test/resources/" + entitySetName.toLowerCase() + ".json")), type).getEntityCollection();
// TODO: the count needs to be part of deserializer
set.setCount(set.getEntities().size());
for (Entity entity : set.getEntities()) {
- ((EntityImpl) entity).setETag(UUID.randomUUID().toString());
- ((EntityImpl) entity).setId(new URI(TripPinHandler.buildLocation(entity, entitySetName,
+ entity.setETag(UUID.randomUUID().toString());
+ entity.setId(new URI(EntityResponse.buildLocation("", entity, entitySetName,
type)));
- ((EntityImpl) entity).setType(type.getFullQualifiedName().getFullQualifiedNameAsString());
+ entity.setType(type.getFullQualifiedName().getFullQualifiedNameAsString());
}
return set;
} catch (FileNotFoundException e) {
@@ -149,17 +147,17 @@ public class TripPinDataModel {
return null;
}
- public EntitySet getEntitySet(String name) {
+ public EntityCollection getEntitySet(String name) {
return getEntitySet(name, -1, -1);
}
- public EntitySet getEntitySet(String name, int skip, int pageSize) {
- EntitySet set = this.entitySetMap.get(name);
+ public EntityCollection getEntitySet(String name, int skip, int pageSize) {
+ EntityCollection set = this.entitySetMap.get(name);
if (set == null) {
return null;
}
- EntitySetImpl modifiedES = new EntitySetImpl();
+ EntityCollection modifiedES = new EntityCollection();
int i = 0;
for (Entity e : set.getEntities()) {
if (skip >= 0 && i >= skip && modifiedES.getEntities().size() < pageSize) {
@@ -232,11 +230,11 @@ public class TripPinDataModel {
}
public Entity getEntity(String name, List<UriParameter> keys) throws ODataApplicationException {
- EntitySet es = getEntitySet(name);
+ EntityCollection es = getEntitySet(name);
return getEntity(es, keys);
}
- public Entity getEntity(EntitySet es, List<UriParameter> keys) throws ODataApplicationException {
+ public Entity getEntity(EntityCollection es, List<UriParameter> keys) throws ODataApplicationException {
List<Entity> search = es.getEntities();
for (UriParameter param : keys) {
search = getMatch(param, search);
@@ -247,15 +245,15 @@ public class TripPinDataModel {
return search.get(0);
}
- private EntitySet getFriends(String userName) {
+ private EntityCollection getFriends(String userName) {
Map<String, Object> map = this.peopleLinks.get(userName);
if (map == null) {
return null;
}
ArrayList<String> friends = (ArrayList<String>) map.get("Friends");
- EntitySet set = getEntitySet("People");
+ EntityCollection set = getEntitySet("People");
- EntitySetImpl result = new EntitySetImpl();
+ EntityCollection result = new EntityCollection();
int i = 0;
if (friends != null) {
for (String friend : friends) {
@@ -272,16 +270,16 @@ public class TripPinDataModel {
return result;
}
- private EntitySet getTrips(String userName) {
+ private EntityCollection getTrips(String userName) {
Map<String, Object> map = this.peopleLinks.get(userName);
if (map == null) {
return null;
}
ArrayList<Integer> trips = (ArrayList<Integer>) map.get("Trips");
- EntitySet set = getEntitySet("Trip");
+ EntityCollection set = getEntitySet("Trip");
- EntitySetImpl result = new EntitySetImpl();
+ EntityCollection result = new EntityCollection();
int i = 0;
if (trips != null) {
for (int trip : trips) {
@@ -305,7 +303,7 @@ public class TripPinDataModel {
}
Integer photoID = (Integer) map.get("Photo");
- EntitySet set = getEntitySet("Photos");
+ EntityCollection set = getEntitySet("Photos");
if (photoID != null) {
for (Entity e : set.getEntities()) {
if (e.getProperty("Id").getValue().equals(photoID.longValue())) {
@@ -316,20 +314,20 @@ public class TripPinDataModel {
return null;
}
- private EntitySet getPlanItems(int tripId, EntitySetImpl result) {
+ private EntityCollection getPlanItems(int tripId, EntityCollection result) {
getFlights(tripId, result);
getEvents(tripId, result);
return result;
}
- private EntitySet getEvents(int tripId, EntitySetImpl result) {
+ private EntityCollection getEvents(int tripId, EntityCollection result) {
Map<Integer, Object> map = this.tripLinks.get(tripId);
if (map == null) {
return null;
}
ArrayList<Integer> events = (ArrayList<Integer>) map.get("Events");
- EntitySet set = getEntitySet("Event");
+ EntityCollection set = getEntitySet("Event");
int i = result.getEntities().size();
if (events != null) {
for (int event : events) {
@@ -346,14 +344,14 @@ public class TripPinDataModel {
return result;
}
- private EntitySet getFlights(int tripId, EntitySetImpl result) {
+ private EntityCollection getFlights(int tripId, EntityCollection result) {
Map<Integer, Object> map = this.tripLinks.get(tripId);
if (map == null) {
return null;
}
ArrayList<Integer> flights = (ArrayList<Integer>) map.get("Flights");
- EntitySet set = getEntitySet("Flight");
+ EntityCollection set = getEntitySet("Flight");
int i = result.getEntities().size();
if (flights != null) {
for (int flight : flights) {
@@ -370,7 +368,7 @@ public class TripPinDataModel {
return result;
}
- private EntitySet getTripPhotos(int tripId) {
+ private EntityCollection getTripPhotos(int tripId) {
Map<Integer, Object> map = this.tripLinks.get(tripId);
if (map == null) {
return null;
@@ -378,8 +376,8 @@ public class TripPinDataModel {
ArrayList<Integer> photos = (ArrayList<Integer>) map.get("Photos");
- EntitySet set = getEntitySet("Photos");
- EntitySetImpl result = new EntitySetImpl();
+ EntityCollection set = getEntitySet("Photos");
+ EntityCollection result = new EntityCollection();
int i = 0;
if (photos != null) {
for (int photo : photos) {
@@ -403,7 +401,7 @@ public class TripPinDataModel {
}
String from = (String) map.get("From");
- EntitySet set = getEntitySet("Airports");
+ EntityCollection set = getEntitySet("Airports");
if (from != null) {
for (Entity e : set.getEntities()) {
@@ -422,7 +420,7 @@ public class TripPinDataModel {
}
String to = (String) map.get("To");
- EntitySet set = getEntitySet("Airports");
+ EntityCollection set = getEntitySet("Airports");
if (to != null) {
for (Entity e : set.getEntities()) {
@@ -441,7 +439,7 @@ public class TripPinDataModel {
}
String airline = (String) map.get("Airline");
- EntitySet set = getEntitySet("Airlines");
+ EntityCollection set = getEntitySet("Airlines");
if (airline != null) {
for (Entity e : set.getEntities()) {
@@ -560,7 +558,7 @@ public class TripPinDataModel {
protected static void setLink(Entity entity, final String navigationPropertyName,
final Entity target) {
- Link link = new LinkImpl();
+ Link link = new Link();
link.setTitle(navigationPropertyName);
link.setInlineEntity(target);
entity.getNavigationLinks().add(link);
@@ -607,18 +605,19 @@ public class TripPinDataModel {
return updated;
}
- public Entity createEntity(String entitySetName, Entity entity, String location)
+ public Entity createEntity(EdmEntitySet edmEntitySet, Entity entity, String baseURL)
throws ODataApplicationException {
- EntitySet set = this.entitySetMap.get(entitySetName);
- EntityImpl copy = new EntityImpl();
+ EntityCollection set = this.entitySetMap.get(edmEntitySet.getName());
+ Entity copy = new Entity();
copy.setType(entity.getType());
for (Property p : entity.getProperties()) {
copy.addProperty(p);
}
try {
- copy.setId(new URI(location));
+ copy.setId(new URI(EntityResponse.buildLocation(baseURL, entity, edmEntitySet.getName(), edmEntitySet
+ .getEntityType())));
copy.setETag(UUID.randomUUID().toString());
} catch (URISyntaxException e) {
throw new ODataApplicationException("Failed to create ID for entity", 500,
@@ -630,7 +629,7 @@ public class TripPinDataModel {
}
public boolean deleteEntity(String entitySetName, String eTag, String key, Object keyValue) {
- EntitySet set = getEntitySet(entitySetName);
+ EntityCollection set = getEntitySet(entitySetName);
Iterator<Entity> it = set.getEntities().iterator();
boolean removed = false;
while (it.hasNext()) {
@@ -647,7 +646,7 @@ public class TripPinDataModel {
public boolean updateProperty(String entitySetName, String eTag, String key, Object keyValue,
Property property) {
- EntitySet set = getEntitySet(entitySetName);
+ EntityCollection set = getEntitySet(entitySetName);
Iterator<Entity> it = set.getEntities().iterator();
boolean replaced = false;
while (it.hasNext()) {
@@ -663,20 +662,20 @@ public class TripPinDataModel {
return replaced;
}
- public EntitySet getNavigableEntitySet(Entity parentEntity, UriResourceNavigation navigation) {
+ public EntityCollection getNavigableEntitySet(Entity parentEntity, UriResourceNavigation navigation) {
EdmEntityType type = this.metadata.getEdm().getEntityType(
new FullQualifiedName(parentEntity.getType()));
String key = type.getKeyPredicateNames().get(0);
String linkName = navigation.getProperty().getName();
- EntitySet results = null;
+ EntityCollection results = null;
if (type.getName().equals("Person") && linkName.equals("Friends")) {
results = getFriends((String) parentEntity.getProperty(key).getValue());
} else if (type.getName().equals("Person") && linkName.equals("Trips")) {
results = getTrips((String) parentEntity.getProperty(key).getValue());
} else if (type.getName().equals("Trip") && linkName.equals("PlanItems")) {
- EntitySetImpl planitems = new EntitySetImpl();
+ EntityCollection planitems = new EntityCollection();
if (navigation.getTypeFilterOnCollection() == null) {
results = getPlanItems((Integer) parentEntity.getProperty(key).getValue(), planitems);
} else if (navigation.getTypeFilterOnCollection().getName().equals("Flight")) {
@@ -700,7 +699,7 @@ public class TripPinDataModel {
String key = type.getKeyPredicateNames().get(0);
String linkName = navigation.getProperty().getName();
- EntitySet results = null;
+ EntityCollection results = null;
if (navigation.getProperty().isCollection()) {
results = getNavigableEntitySet(parentEntity, navigation);
return this.getEntity(results, navigation.getKeyPredicates());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
index 040a7da..7172818 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
@@ -27,7 +27,7 @@ import java.util.Locale;
import java.util.Random;
import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmAction;
@@ -36,9 +36,9 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmSingleton;
+import org.apache.olingo.commons.api.edm.provider.EntitySet;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpMethod;
-import org.apache.olingo.commons.core.data.EntitySetImpl;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
@@ -94,7 +94,7 @@ public class TripPinHandler implements ServiceHandler {
}
static class EntityDetails {
- EntitySet entitySet = null;
+ EntityCollection entitySet = null;
Entity entity = null;
EdmEntityType entityType;
String navigationProperty;
@@ -102,7 +102,7 @@ public class TripPinHandler implements ServiceHandler {
}
private EntityDetails process(final DataRequest request) throws ODataApplicationException {
- EntitySet entitySet = null;
+ EntityCollection entitySet = null;
Entity entity = null;
EdmEntityType entityType;
Entity parentEntity = null;
@@ -206,7 +206,7 @@ public class TripPinHandler implements ServiceHandler {
response.writeHeader("Preference-Applied", "odata.maxpagesize="+request.getPreference("odata.maxpagesize"));
}
if (details.entity == null && !request.getNavigations().isEmpty()) {
- response.writeReadEntitySet(details.entityType, new EntitySetImpl());
+ response.writeReadEntitySet(details.entityType, new EntityCollection());
} else {
response.writeReadEntitySet(details.entityType, details.entitySet);
}
@@ -237,8 +237,7 @@ public class TripPinHandler implements ServiceHandler {
throws ODataTranslatedException, ODataApplicationException {
EdmEntitySet edmEntitySet = request.getEntitySet();
- String location = buildLocation(entity, edmEntitySet.getName(), edmEntitySet.getEntityType());
- Entity created = this.dataModel.createEntity(edmEntitySet.getName(), entity, location);
+ Entity created = this.dataModel.createEntity(edmEntitySet, entity, request.getODataRequest().getRawBaseUri());
try {
// create references, they come in "@odata.bind" value
@@ -271,30 +270,7 @@ public class TripPinHandler implements ServiceHandler {
throw new ODataApplicationException(e.getMessage(), 500, Locale.getDefault());
}
- response.writeCreatedEntity(edmEntitySet.getEntityType(), created, location);
- }
-
- static String buildLocation(Entity entity, String name, EdmEntityType type) {
- String location = "/" + name + "(";
- int i = 0;
- boolean usename = type.getKeyPredicateNames().size() > 1;
-
- for (String key : type.getKeyPredicateNames()) {
- if (i > 0) {
- location += ",";
- }
- i++;
- if (usename) {
- location += (key + "=");
- }
- if (entity.getProperty(key).getType().equals("Edm.String")) {
- location = location + "'" + entity.getProperty(key).getValue().toString() + "'";
- } else {
- location = location + entity.getProperty(key).getValue().toString();
- }
- }
- location += ")";
- return location;
+ response.writeCreatedEntity(edmEntitySet, created);
}
@Override
@@ -360,7 +336,7 @@ public class TripPinHandler implements ServiceHandler {
final EdmEntityType type = serviceMetadata.getEdm().getEntityContainer(null)
.getEntitySet("Airports").getEntityType();
- EntitySet es = this.dataModel.getEntitySet("Airports");
+ EntityCollection es = this.dataModel.getEntitySet("Airports");
int i = new Random().nextInt(es.getEntities().size());
final Entity entity = es.getEntities().get(i);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
index 3547b50..1766f1a 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
@@ -147,6 +147,7 @@ public class TripPinServiceTest {
JsonNode node = getJSONNode(response);
assertEquals("$metadata#Airlines/$entity", node.get("@odata.context").asText());
assertEquals("American Airlines", node.get("Name").asText());
+ //assertEquals("/Airlines('AA')/Picture", node.get("Picture@odata.mediaReadLink").asText());
}
@Test
@@ -278,7 +279,7 @@ public class TripPinServiceTest {
@Test
public void testLambdaAny() throws Exception {
- // this is just testing to see the labba expresions are going through the
+ // this is just testing to see the lamda expressions are going through the
// framework, none of the system options are not implemented in example service
String query = "Friends/any(d:d/UserName eq 'foo')";
HttpResponse response = httpGET(baseURL + "/People?$filter="+Encoder.encode(query), 200);
@@ -405,10 +406,10 @@ public class TripPinServiceTest {
HttpResponse response = httpSend(postRequest, 204);
// the below woud be 204, if minimal was not supplied
- assertEquals("/People('olingodude')", getHeader(response, "Location"));
+ assertEquals("http://localhost:9900/trippin/People('olingodude')", getHeader(response, "Location"));
assertEquals("return=minimal", getHeader(response, "Preference-Applied"));
- String location = baseURL+getHeader(response, "Location");
+ String location = getHeader(response, "Location");
response = httpGET(location, 200);
EntityUtils.consumeQuietly(response.getEntity());
@@ -527,6 +528,21 @@ public class TripPinServiceTest {
}
@Test
+ public void testReadNavigationPropertyNoContainsTarget() throws Exception {
+ String editUrl = baseURL + "/People('scottketchum')/Photo";
+ HttpResponse response = httpGET(editUrl, 200);
+
+ JsonNode node = getJSONNode(response);
+ assertEquals("$metadata#Photos/$entity", node.get("@odata.context").asText());
+ }
+
+ @Test
+ public void testReadNavigationPropertyNonExistingNavigation() throws Exception {
+ String editUrl = baseURL + "/People('russellwhyte')/Foobar";
+ httpGET(editUrl, 404);
+ }
+
+ @Test
public void testReadNavigationPropertyEntityCollection2() throws Exception {
String editUrl = baseURL + "/People('russellwhyte')/Friends('scottketchum')/Trips";
HttpResponse response = httpGET(editUrl, 200);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core-ext/src/test/resources/airlines.json
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/resources/airlines.json b/lib/server-core-ext/src/test/resources/airlines.json
index 78eccdc..1d93aa7 100644
--- a/lib/server-core-ext/src/test/resources/airlines.json
+++ b/lib/server-core-ext/src/test/resources/airlines.json
@@ -2,7 +2,11 @@
"value":[
{
"AirlineCode":"AA",
- "Name":"American Airlines"
+ "Name":"American Airlines",
+ "Picture@odata.mediaReadLink": "/Airlines('AA')/Picture",
+ "Picture@odata.mediaEditLink": "/Airlines('AA')/Picture",
+ "Picture@odata.mediaContentType": "image/jpeg",
+ "Picture@odata.mediaEtag": "12345"
},
{
"AirlineCode":"FM",
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ac433b0/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
index ff7eff2..1de8562 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
@@ -229,6 +229,12 @@ public class ODataJsonSerializer implements ODataSerializer {
if (entity.getMediaContentType() != null) {
json.writeStringField(Constants.JSON_MEDIA_CONTENT_TYPE, entity.getMediaContentType());
}
+ if (entity.getMediaContentSource() != null) {
+ json.writeStringField(Constants.JSON_MEDIA_READ_LINK, entity.getMediaContentSource().toString());
+ }
+ if (entity.getMediaEditLinks() != null && !entity.getMediaEditLinks().isEmpty()) {
+ json.writeStringField(Constants.JSON_MEDIA_EDIT_LINK, entity.getMediaEditLinks().get(0).getHref());
+ }
}
}
if (onlyReference) {