[OLINGO-1198]Create a sample project for bound actions
This commit is contained in:
parent
dd09d61ab2
commit
dd992163b7
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* 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 myservice.mynamespace.data;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
|
|
||||||
|
public class DemoEntityActionResult {
|
||||||
|
private Entity entity;
|
||||||
|
private boolean created = false;
|
||||||
|
|
||||||
|
public Entity getEntity() {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DemoEntityActionResult setEntity(final Entity entity) {
|
||||||
|
this.entity = entity;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DemoEntityActionResult setCreated(final boolean created) {
|
||||||
|
this.created = created;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,11 +23,14 @@ import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||||
|
import org.apache.olingo.commons.api.data.Parameter;
|
||||||
import org.apache.olingo.commons.api.data.Property;
|
import org.apache.olingo.commons.api.data.Property;
|
||||||
import org.apache.olingo.commons.api.data.ValueType;
|
import org.apache.olingo.commons.api.data.ValueType;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmAction;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||||
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
|
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
|
||||||
|
@ -47,6 +50,10 @@ public class Storage {
|
||||||
|
|
||||||
private List<Entity> productList;
|
private List<Entity> productList;
|
||||||
private List<Entity> categoryList;
|
private List<Entity> categoryList;
|
||||||
|
public static final String ACTION_PROVIDE_DISCOUNT = "DiscountProducts";
|
||||||
|
public static final String ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT = "DiscountProduct";
|
||||||
|
public static final String AMOUNT_PROPERTY = "Amount";
|
||||||
|
public static final String PRICE_PROPERTY= "Price";
|
||||||
|
|
||||||
public Storage() {
|
public Storage() {
|
||||||
|
|
||||||
|
@ -378,6 +385,7 @@ public class Storage {
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"));
|
"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"));
|
||||||
|
entity.addProperty(new Property(null, "Price", ValueType.PRIMITIVE, 100));
|
||||||
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
@ -387,6 +395,7 @@ public class Storage {
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Professional 17"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Professional 17"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"Notebook Professional, 2.8GHz - 15 XGA - 8GB DDR3 RAM - 500GB"));
|
"Notebook Professional, 2.8GHz - 15 XGA - 8GB DDR3 RAM - 500GB"));
|
||||||
|
entity.addProperty(new Property(null, "Price", ValueType.PRIMITIVE, 200));
|
||||||
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
@ -396,6 +405,7 @@ public class Storage {
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"));
|
"Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"));
|
||||||
|
entity.addProperty(new Property(null, "Price", ValueType.PRIMITIVE, 300));
|
||||||
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
@ -405,6 +415,7 @@ public class Storage {
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Comfort Easy"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Comfort Easy"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"32 GB Digital Assitant with high-resolution color screen"));
|
"32 GB Digital Assitant with high-resolution color screen"));
|
||||||
|
entity.addProperty(new Property(null, "Price", ValueType.PRIMITIVE, 100));
|
||||||
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
@ -414,6 +425,7 @@ public class Storage {
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"));
|
"19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"));
|
||||||
|
entity.addProperty(new Property(null, "Price", ValueType.PRIMITIVE, 400));
|
||||||
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
@ -423,6 +435,7 @@ public class Storage {
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Flat Basic"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Flat Basic"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"Optimum Hi-Resolution max. 1600 x 1200 @ 85Hz, Dot Pitch: 0.24mm"));
|
"Optimum Hi-Resolution max. 1600 x 1200 @ 85Hz, Dot Pitch: 0.24mm"));
|
||||||
|
entity.addProperty(new Property(null, "Price", ValueType.PRIMITIVE, 100));
|
||||||
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
@ -479,4 +492,35 @@ public class Storage {
|
||||||
}
|
}
|
||||||
return entity.getType();
|
return entity.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityCollection processBoundActionEntityCollection(EdmAction action, Map<String, Parameter> parameters) {
|
||||||
|
EntityCollection collection = new EntityCollection();
|
||||||
|
if (ACTION_PROVIDE_DISCOUNT.equals(action.getName())) {
|
||||||
|
for (Entity entity : categoryList) {
|
||||||
|
Entity en = getRelatedEntity(entity, (EdmEntityType) action.getReturnType().getType());
|
||||||
|
Integer currentValue = (Integer)en.getProperty(PRICE_PROPERTY).asPrimitive();
|
||||||
|
Integer newValue = currentValue - (Integer)parameters.get(AMOUNT_PROPERTY).asPrimitive();
|
||||||
|
en.getProperty(PRICE_PROPERTY).setValue(ValueType.PRIMITIVE, newValue);
|
||||||
|
collection.getEntities().add(en);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DemoEntityActionResult processBoundActionEntity(EdmAction action, Map<String, Parameter> parameters,
|
||||||
|
List<UriParameter> keyParams) throws ODataApplicationException {
|
||||||
|
DemoEntityActionResult result = new DemoEntityActionResult();
|
||||||
|
if (ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT.equals(action.getName())) {
|
||||||
|
for (Entity entity : categoryList) {
|
||||||
|
Entity en = getRelatedEntity(entity, (EdmEntityType) action.getReturnType().getType(), keyParams);
|
||||||
|
Integer currentValue = (Integer)en.getProperty(PRICE_PROPERTY).asPrimitive();
|
||||||
|
Integer newValue = currentValue - (Integer)parameters.get(AMOUNT_PROPERTY).asPrimitive();
|
||||||
|
en.getProperty(PRICE_PROPERTY).setValue(ValueType.PRIMITIVE, newValue);
|
||||||
|
result.setEntity(en);
|
||||||
|
result.setCreated(true);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,21 @@
|
||||||
*/
|
*/
|
||||||
package myservice.mynamespace.service;
|
package myservice.mynamespace.service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.data.ContextURL;
|
||||||
|
import org.apache.olingo.commons.api.data.ContextURL.Builder;
|
||||||
|
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
|
||||||
|
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||||
import org.apache.olingo.commons.api.data.Parameter;
|
import org.apache.olingo.commons.api.data.Parameter;
|
||||||
import org.apache.olingo.commons.api.edm.EdmAction;
|
import org.apache.olingo.commons.api.edm.EdmAction;
|
||||||
|
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.format.ContentType;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
import org.apache.olingo.server.api.OData;
|
import org.apache.olingo.server.api.OData;
|
||||||
import org.apache.olingo.server.api.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
|
@ -32,16 +41,27 @@ import org.apache.olingo.server.api.ODataRequest;
|
||||||
import org.apache.olingo.server.api.ODataResponse;
|
import org.apache.olingo.server.api.ODataResponse;
|
||||||
import org.apache.olingo.server.api.ServiceMetadata;
|
import org.apache.olingo.server.api.ServiceMetadata;
|
||||||
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
|
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
|
||||||
|
import org.apache.olingo.server.api.prefer.Preferences.Return;
|
||||||
|
import org.apache.olingo.server.api.prefer.PreferencesApplied;
|
||||||
|
import org.apache.olingo.server.api.processor.ActionEntityCollectionProcessor;
|
||||||
|
import org.apache.olingo.server.api.processor.ActionEntityProcessor;
|
||||||
import org.apache.olingo.server.api.processor.ActionVoidProcessor;
|
import org.apache.olingo.server.api.processor.ActionVoidProcessor;
|
||||||
|
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
|
||||||
|
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||||
import org.apache.olingo.server.api.uri.UriInfo;
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceAction;
|
import org.apache.olingo.server.api.uri.UriResourceAction;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||||
|
|
||||||
|
import myservice.mynamespace.data.DemoEntityActionResult;
|
||||||
import myservice.mynamespace.data.Storage;
|
import myservice.mynamespace.data.Storage;
|
||||||
|
|
||||||
public class DemoActionProcessor implements ActionVoidProcessor {
|
public class DemoActionProcessor implements ActionVoidProcessor, ActionEntityCollectionProcessor, ActionEntityProcessor {
|
||||||
|
|
||||||
private OData odata;
|
private OData odata;
|
||||||
private Storage storage;
|
private Storage storage;
|
||||||
|
private ServiceMetadata serviceMetadata;
|
||||||
|
|
||||||
public DemoActionProcessor(final Storage storage) {
|
public DemoActionProcessor(final Storage storage) {
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
|
@ -50,6 +70,7 @@ public class DemoActionProcessor implements ActionVoidProcessor {
|
||||||
@Override
|
@Override
|
||||||
public void init(final OData odata, final ServiceMetadata serviceMetadata) {
|
public void init(final OData odata, final ServiceMetadata serviceMetadata) {
|
||||||
this.odata = odata;
|
this.odata = odata;
|
||||||
|
this.serviceMetadata = serviceMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -82,4 +103,157 @@ public class DemoActionProcessor implements ActionVoidProcessor {
|
||||||
|
|
||||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processActionEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||||
|
ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||||
|
|
||||||
|
EdmAction action = null;
|
||||||
|
Map<String, Parameter> parameters = new HashMap<String, Parameter>();
|
||||||
|
DemoEntityActionResult entityResult = null;
|
||||||
|
if (requestFormat == null) {
|
||||||
|
throw new ODataApplicationException("The content type has not been set in the request.",
|
||||||
|
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ODataDeserializer deserializer = odata.createDeserializer(requestFormat);
|
||||||
|
final List<UriResource> resourcePaths = uriInfo.asUriInfoResource().getUriResourceParts();
|
||||||
|
UriResourceEntitySet boundEntity = (UriResourceEntitySet) resourcePaths.get(0);
|
||||||
|
if (resourcePaths.size() > 1) {
|
||||||
|
if (resourcePaths.get(1) instanceof UriResourceNavigation) {
|
||||||
|
action = ((UriResourceAction) resourcePaths.get(2))
|
||||||
|
.getAction();
|
||||||
|
throw new ODataApplicationException("Action " + action.getName() + " is not yet implemented.",
|
||||||
|
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
|
||||||
|
} else if (resourcePaths.get(0) instanceof UriResourceEntitySet) {
|
||||||
|
action = ((UriResourceAction) resourcePaths.get(1))
|
||||||
|
.getAction();
|
||||||
|
parameters = deserializer.actionParameters(request.getBody(), action)
|
||||||
|
.getActionParameters();
|
||||||
|
entityResult =
|
||||||
|
storage.processBoundActionEntity(action, parameters, boundEntity.getKeyPredicates());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final EdmEntitySet edmEntitySet = boundEntity.getEntitySet();
|
||||||
|
final EdmEntityType type = (EdmEntityType) action.getReturnType().getType();
|
||||||
|
|
||||||
|
if (entityResult == null || entityResult.getEntity() == null) {
|
||||||
|
if (action.getReturnType().isNullable()) {
|
||||||
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
|
} else {
|
||||||
|
// Not nullable return type so we have to give back a 500
|
||||||
|
throw new ODataApplicationException("The action could not be executed.",
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
|
||||||
|
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
|
||||||
|
response.setContent(odata.createSerializer(responseFormat).entity(
|
||||||
|
serviceMetadata,
|
||||||
|
type,
|
||||||
|
entityResult.getEntity(),
|
||||||
|
EntitySerializerOptions.with()
|
||||||
|
.contextURL(isODataMetadataNone(responseFormat) ? null :
|
||||||
|
getContextUrl(action.getReturnedEntitySet(edmEntitySet), type, true))
|
||||||
|
.build())
|
||||||
|
.getContent());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
|
response.setStatusCode((entityResult.isCreated() ? HttpStatusCode.CREATED : HttpStatusCode.OK)
|
||||||
|
.getStatusCode());
|
||||||
|
} else {
|
||||||
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
|
}
|
||||||
|
if (returnPreference != null) {
|
||||||
|
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
|
||||||
|
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
|
||||||
|
}
|
||||||
|
if (entityResult.isCreated()) {
|
||||||
|
final String location = request.getRawBaseUri() + '/'
|
||||||
|
+ odata.createUriHelper().buildCanonicalURL(edmEntitySet, entityResult.getEntity());
|
||||||
|
response.setHeader(HttpHeader.LOCATION, location);
|
||||||
|
if (returnPreference == Return.MINIMAL) {
|
||||||
|
response.setHeader(HttpHeader.ODATA_ENTITY_ID, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entityResult.getEntity().getETag() != null) {
|
||||||
|
response.setHeader(HttpHeader.ETAG, entityResult.getEntity().getETag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processActionEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||||
|
ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||||
|
|
||||||
|
Map<String, Parameter> parameters = new HashMap<String, Parameter>();
|
||||||
|
EdmAction action = null;
|
||||||
|
EntityCollection collection = null;
|
||||||
|
|
||||||
|
if (requestFormat == null) {
|
||||||
|
throw new ODataApplicationException("The content type has not been set in the request.",
|
||||||
|
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UriResource> resourcePaths = uriInfo.asUriInfoResource().getUriResourceParts();
|
||||||
|
final ODataDeserializer deserializer = odata.createDeserializer(requestFormat);
|
||||||
|
UriResourceEntitySet boundEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
|
||||||
|
if (resourcePaths.size() > 1) {
|
||||||
|
if (resourcePaths.get(1) instanceof UriResourceNavigation) {
|
||||||
|
action = ((UriResourceAction) resourcePaths.get(2))
|
||||||
|
.getAction();
|
||||||
|
throw new ODataApplicationException("Action " + action.getName() + " is not yet implemented.",
|
||||||
|
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
|
||||||
|
} else {
|
||||||
|
action = ((UriResourceAction) resourcePaths.get(1))
|
||||||
|
.getAction();
|
||||||
|
parameters = deserializer.actionParameters(request.getBody(), action)
|
||||||
|
.getActionParameters();
|
||||||
|
collection =
|
||||||
|
storage.processBoundActionEntityCollection(action, parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Collections must never be null.
|
||||||
|
// Not nullable return types must not contain a null value.
|
||||||
|
if (collection == null
|
||||||
|
|| collection.getEntities().contains(null) && !action.getReturnType().isNullable()) {
|
||||||
|
throw new ODataApplicationException("The action could not be executed.",
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
|
||||||
|
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
|
||||||
|
final EdmEntitySet edmEntitySet = boundEntitySet.getEntitySet();
|
||||||
|
final EdmEntityType type = (EdmEntityType) action.getReturnType().getType();
|
||||||
|
final EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions.with()
|
||||||
|
.contextURL(isODataMetadataNone(responseFormat) ? null :
|
||||||
|
getContextUrl(action.getReturnedEntitySet(edmEntitySet), type, false))
|
||||||
|
.build();
|
||||||
|
response.setContent(odata.createSerializer(responseFormat)
|
||||||
|
.entityCollection(serviceMetadata, type, collection, options).getContent());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
} else {
|
||||||
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
|
}
|
||||||
|
if (returnPreference != null) {
|
||||||
|
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
|
||||||
|
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContextURL getContextUrl(final EdmEntitySet entitySet, final EdmEntityType entityType,
|
||||||
|
final boolean isSingleEntity) throws ODataLibraryException {
|
||||||
|
Builder builder = ContextURL.with();
|
||||||
|
builder = entitySet == null ?
|
||||||
|
isSingleEntity ? builder.type(entityType) : builder.asCollection().type(entityType) :
|
||||||
|
builder.entitySet(entitySet);
|
||||||
|
builder = builder.suffix(isSingleEntity && entitySet != null ? Suffix.ENTITY : null);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isODataMetadataNone(final ContentType contentType) {
|
||||||
|
return contentType.isCompatible(ContentType.APPLICATION_JSON)
|
||||||
|
&& ContentType.VALUE_ODATA_METADATA_NONE.equalsIgnoreCase(
|
||||||
|
contentType.getParameter(ContentType.PARAMETER_ODATA_METADATA));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,14 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
public static final String ACTION_RESET = "Reset";
|
public static final String ACTION_RESET = "Reset";
|
||||||
public static final FullQualifiedName ACTION_RESET_FQN = new FullQualifiedName(NAMESPACE, ACTION_RESET);
|
public static final FullQualifiedName ACTION_RESET_FQN = new FullQualifiedName(NAMESPACE, ACTION_RESET);
|
||||||
|
|
||||||
|
//Bound Action
|
||||||
|
public static final String ACTION_PROVIDE_DISCOUNT = "DiscountProducts";
|
||||||
|
public static final FullQualifiedName ACTION_PROVIDE_DISCOUNT_FQN = new FullQualifiedName(NAMESPACE, ACTION_PROVIDE_DISCOUNT);
|
||||||
|
|
||||||
|
//Bound Action
|
||||||
|
public static final String ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT = "DiscountProduct";
|
||||||
|
public static final FullQualifiedName ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT);
|
||||||
|
|
||||||
// Function
|
// Function
|
||||||
public static final String FUNCTION_COUNT_CATEGORIES = "CountCategories";
|
public static final String FUNCTION_COUNT_CATEGORIES = "CountCategories";
|
||||||
public static final FullQualifiedName FUNCTION_COUNT_CATEGORIES_FQN
|
public static final FullQualifiedName FUNCTION_COUNT_CATEGORIES_FQN
|
||||||
|
@ -78,11 +86,14 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
// Function/Action Parameters
|
// Function/Action Parameters
|
||||||
public static final String PARAMETER_AMOUNT = "Amount";
|
public static final String PARAMETER_AMOUNT = "Amount";
|
||||||
|
|
||||||
|
//Bound Action Binding Parameter
|
||||||
|
public static final String PARAMETER_CATEGORY = "ParamCategory";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<CsdlAction> getActions(final FullQualifiedName actionName) {
|
public List<CsdlAction> getActions(final FullQualifiedName actionName) {
|
||||||
if(actionName.equals(ACTION_RESET_FQN)) {
|
|
||||||
// It is allowed to overload actions, so we have to provide a list of Actions for each action name
|
// It is allowed to overload actions, so we have to provide a list of Actions for each action name
|
||||||
final List<CsdlAction> actions = new ArrayList<CsdlAction>();
|
final List<CsdlAction> actions = new ArrayList<CsdlAction>();
|
||||||
|
if(actionName.equals(ACTION_RESET_FQN)) {
|
||||||
|
|
||||||
// Create parameters
|
// Create parameters
|
||||||
final List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
|
final List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
|
||||||
|
@ -97,6 +108,50 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
action.setParameters(parameters);
|
action.setParameters(parameters);
|
||||||
actions.add(action);
|
actions.add(action);
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
} else if (actionName.equals(ACTION_PROVIDE_DISCOUNT_FQN)) {
|
||||||
|
// Create parameters
|
||||||
|
final List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
|
||||||
|
CsdlParameter parameter = new CsdlParameter();
|
||||||
|
parameter.setName(PARAMETER_CATEGORY);
|
||||||
|
parameter.setType(ET_CATEGORY_FQN);
|
||||||
|
parameter.setCollection(true);
|
||||||
|
parameters.add(parameter);
|
||||||
|
parameter = new CsdlParameter();
|
||||||
|
parameter.setName(PARAMETER_AMOUNT);
|
||||||
|
parameter.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
|
||||||
|
parameters.add(parameter);
|
||||||
|
|
||||||
|
// Create the Csdl Action
|
||||||
|
final CsdlAction action = new CsdlAction();
|
||||||
|
action.setName(ACTION_PROVIDE_DISCOUNT_FQN.getName());
|
||||||
|
action.setBound(true);
|
||||||
|
action.setParameters(parameters);
|
||||||
|
action.setReturnType(new CsdlReturnType().setType(ET_PRODUCT_FQN).setCollection(true));
|
||||||
|
actions.add(action);
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
} else if (actionName.equals(ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT_FQN)) {
|
||||||
|
// Create parameters
|
||||||
|
final List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
|
||||||
|
CsdlParameter parameter = new CsdlParameter();
|
||||||
|
parameter.setName(PARAMETER_CATEGORY);
|
||||||
|
parameter.setType(ET_CATEGORY_FQN);
|
||||||
|
parameter.setCollection(false);
|
||||||
|
parameters.add(parameter);
|
||||||
|
parameter = new CsdlParameter();
|
||||||
|
parameter.setName(PARAMETER_AMOUNT);
|
||||||
|
parameter.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
|
||||||
|
parameters.add(parameter);
|
||||||
|
|
||||||
|
// Create the Csdl Action
|
||||||
|
final CsdlAction action = new CsdlAction();
|
||||||
|
action.setName(ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT_FQN.getName());
|
||||||
|
action.setBound(true);
|
||||||
|
action.setParameters(parameters);
|
||||||
|
action.setReturnType(new CsdlReturnType().setType(ET_PRODUCT_FQN).setCollection(false));
|
||||||
|
actions.add(action);
|
||||||
|
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +229,8 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
|
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
|
||||||
CsdlProperty description = new CsdlProperty().setName("Description")
|
CsdlProperty description = new CsdlProperty().setName("Description")
|
||||||
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
|
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
|
||||||
|
CsdlProperty price = new CsdlProperty().setName("Price")
|
||||||
|
.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
|
||||||
|
|
||||||
// create PropertyRef for Key element
|
// create PropertyRef for Key element
|
||||||
CsdlPropertyRef propertyRef = new CsdlPropertyRef();
|
CsdlPropertyRef propertyRef = new CsdlPropertyRef();
|
||||||
|
@ -189,7 +246,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
// configure EntityType
|
// configure EntityType
|
||||||
entityType = new CsdlEntityType();
|
entityType = new CsdlEntityType();
|
||||||
entityType.setName(ET_PRODUCT_NAME);
|
entityType.setName(ET_PRODUCT_NAME);
|
||||||
entityType.setProperties(Arrays.asList(id, name, description));
|
entityType.setProperties(Arrays.asList(id, name, description, price));
|
||||||
entityType.setKey(Arrays.asList(propertyRef));
|
entityType.setKey(Arrays.asList(propertyRef));
|
||||||
entityType.setNavigationProperties(navPropList);
|
entityType.setNavigationProperties(navPropList);
|
||||||
|
|
||||||
|
@ -279,6 +336,8 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
// add actions
|
// add actions
|
||||||
List<CsdlAction> actions = new ArrayList<CsdlAction>();
|
List<CsdlAction> actions = new ArrayList<CsdlAction>();
|
||||||
actions.addAll(getActions(ACTION_RESET_FQN));
|
actions.addAll(getActions(ACTION_RESET_FQN));
|
||||||
|
actions.addAll(getActions(ACTION_PROVIDE_DISCOUNT_FQN));
|
||||||
|
actions.addAll(getActions(ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT_FQN));
|
||||||
schema.setActions(actions);
|
schema.setActions(actions);
|
||||||
|
|
||||||
// add functions
|
// add functions
|
||||||
|
|
Loading…
Reference in New Issue