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/03/31 18:35:54 UTC
[08/11] olingo-odata4 git commit: OLINGO-573: New processing
framework on server side with single interface with TripPin as example
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/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
new file mode 100644
index 0000000..32bf26a
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
@@ -0,0 +1,769 @@
+/*
+ * 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.requests;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.LinkedList;
+import java.util.List;
+
+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.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.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;
+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.deserializer.DeserializerException;
+import org.apache.olingo.server.api.deserializer.DeserializerException.MessageKeys;
+import org.apache.olingo.server.api.deserializer.ODataDeserializer;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
+import org.apache.olingo.server.api.serializer.RepresentationType;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriHelper;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriInfoCrossjoin;
+import org.apache.olingo.server.api.uri.UriInfoResource;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
+import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
+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.ServiceHandler;
+import org.apache.olingo.server.core.ServiceRequest;
+import org.apache.olingo.server.core.responses.CountResponse;
+import org.apache.olingo.server.core.responses.EntityResponse;
+import org.apache.olingo.server.core.responses.EntitySetResponse;
+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;
+
+public class DataRequest extends ServiceRequest {
+ protected UriResourceEntitySet uriResourceEntitySet;
+ private boolean countRequest;
+ private UriResourceProperty uriResourceProperty;
+ private boolean valueRequest;
+ private final LinkedList<UriResourceNavigation> uriNavigations = new LinkedList<UriResourceNavigation>();
+ private boolean references;
+
+ private RequestType type;
+ private UriResourceSingleton uriResourceSingleton;
+
+ /**
+ * This sub-categorizes the request so that code can be simplified
+ */
+ interface RequestType {
+ public boolean allowedMethod();
+
+ public ContentType getResponseContentType() throws ContentNegotiatorException;
+
+ public ContextURL getContextURL(OData odata) throws SerializerException;
+
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException;
+ }
+
+ public DataRequest(OData odata, ServiceMetadata serviceMetadata) {
+ super(odata, serviceMetadata);
+ }
+
+ public UriResourceEntitySet getUriResourceEntitySet() {
+ return uriResourceEntitySet;
+ }
+
+ public void setUriResourceEntitySet(UriResourceEntitySet uriResourceEntitySet) {
+ this.uriResourceEntitySet = uriResourceEntitySet;
+ this.type = new EntityRequest();
+ }
+
+ public void setCrossJoin(UriInfoCrossjoin info) {
+ this.type = new CrossJoinRequest(info.getEntitySetNames());
+ }
+
+ public boolean isSingleton() {
+ return this.uriResourceSingleton != null;
+ }
+
+ public boolean isCollection() {
+ if (!this.uriNavigations.isEmpty()) {
+ return this.uriNavigations.getLast().isCollection();
+ }
+ return this.uriResourceEntitySet != null && this.uriResourceEntitySet.isCollection();
+ }
+
+ public EdmEntitySet getEntitySet() {
+ return this.uriResourceEntitySet.getEntitySet();
+ }
+
+ public boolean isCountRequest() {
+ return countRequest;
+ }
+
+ public void setCountRequest(boolean countRequest) {
+ this.countRequest = countRequest;
+ this.type = new CountRequest();
+ }
+
+ public boolean isPropertyRequest() {
+ return this.uriResourceProperty != null;
+ }
+
+ public boolean isPropertyComplex() {
+ return (this.uriResourceProperty instanceof UriResourceComplexProperty);
+ }
+
+ public boolean isPropertyStream() {
+ if (isPropertyComplex()) {
+ return false;
+ }
+ EdmProperty property = ((UriResourcePrimitiveProperty)this.uriResourceProperty).getProperty();
+ return (property.getType() instanceof EdmStream);
+ }
+
+ public UriResourceProperty getUriResourceProperty() {
+ return uriResourceProperty;
+ }
+
+ public void setUriResourceProperty(UriResourceProperty uriResourceProperty) {
+ this.uriResourceProperty = uriResourceProperty;
+ this.type = new PropertyRequest();
+ }
+
+ public LinkedList<UriResourceNavigation> getNavigations() {
+ return this.uriNavigations;
+ }
+
+ public void addUriResourceNavigation(UriResourceNavigation uriResourceNavigation) {
+ this.uriNavigations.add(uriResourceNavigation);
+ }
+
+ public UriResourceSingleton getUriResourceSingleton() {
+ return this.uriResourceSingleton;
+ }
+
+ public void setUriResourceSingleton(UriResourceSingleton info) {
+ this.uriResourceSingleton = info;
+ this.type = new SingletonRequest();
+ }
+
+ public List<UriParameter> getKeyPredicates() {
+ if (this.uriResourceEntitySet != null) {
+ return this.uriResourceEntitySet.getKeyPredicates();
+ }
+ return null;
+ }
+
+ public boolean isReferenceRequest() {
+ return this.references;
+ }
+
+ public void setReferenceRequest(boolean ref) {
+ this.references = ref;
+ this.type = new ReferenceRequest();
+ }
+
+ public boolean isValueRequest() {
+ return valueRequest;
+ }
+
+ private boolean hasMediaStream() {
+ return this.uriResourceEntitySet != null && this.uriResourceEntitySet.getEntityType().hasStream();
+ }
+
+ private InputStream getMediaStream() {
+ return this.request.getBody();
+ }
+
+ public void setValueRequest(boolean valueRequest) {
+ this.valueRequest = valueRequest;
+ this.type = new ValueRequest();
+ }
+
+ @Override
+ public boolean allowedMethod() {
+ return this.type.allowedMethod();
+ }
+
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ return type.getContextURL(odata);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+
+ if (!this.type.allowedMethod()) {
+ methodNotAllowed();
+ }
+
+ this.type.execute(handler, response);
+ }
+
+ @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)
+ .facetsFrom(getUriResourceProperty().getProperty()).build();
+ }
+ return super.getSerializerOptions(serilizerOptions, contextUrl, references);
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ return type.getResponseContentType();
+ }
+
+ class EntityRequest implements RequestType {
+
+ @Override
+ public boolean allowedMethod() {
+ // the create/update/delete to navigation property is done through references
+ // see # 11.4.6
+ if (!getNavigations().isEmpty() && !isGET()) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), getODataRequest(),
+ getCustomContentTypeSupport(), isCollection() ? RepresentationType.COLLECTION_ENTITY
+ : RepresentationType.ENTITY);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+
+ EntityResponse entityResponse = EntityResponse.getInstance(DataRequest.this,
+ getContextURL(odata), false, response);
+
+ if (isGET()) {
+ if (isCollection()) {
+ handler.read(DataRequest.this,
+ EntitySetResponse.getInstance(DataRequest.this, getContextURL(odata), false, response));
+ } else {
+ handler.read(DataRequest.this,entityResponse);
+ }
+ } else if (isPUT() || isPATCH()) {
+ // RFC 2616: he result of a request having both an If-Match header field and either
+ // 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("*");
+ if(ifMatch) {
+ handler.updateEntity(DataRequest.this, getEntityFromClient(), isPATCH(), getETag(),
+ entityResponse);
+ } else if (ifNoneMatch) {
+ // 11.4.4
+ entityResponse = EntityResponse.getInstance(DataRequest.this,
+ getContextURL(odata), false, response, getReturnRepresentation());
+ handler.createEntity(DataRequest.this, getEntityFromClient(), entityResponse);
+ } else {
+ handler.updateEntity(DataRequest.this, getEntityFromClient(), isPATCH(), getETag(),
+ entityResponse);
+ }
+ } else if (isPOST()) {
+ entityResponse = EntityResponse.getInstance(DataRequest.this,
+ getContextURL(odata), false, response, getReturnRepresentation());
+ handler.createEntity(DataRequest.this, getEntityFromClient(),entityResponse);
+ } else if (isDELETE()) {
+ handler.deleteEntity(DataRequest.this, getETag(), entityResponse);
+ }
+ }
+
+ private Entity getEntityFromClient() throws DeserializerException {
+ ODataDeserializer deserializer = odata.createDeserializer(ODataFormat
+ .fromContentType(getRequestContentType()));
+ return deserializer.entity(getODataRequest().getBody(), getEntitySet().getEntityType());
+ }
+
+ @Override
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ // EntitySet based return
+ final UriHelper helper = odata.createUriHelper();
+ ContextURL.Builder builder = buildEntitySetContextURL(helper, getEntitySet(),
+ getKeyPredicates(), getUriInfo(), getNavigations(), isCollection(), false);
+ return builder.build();
+ }
+ }
+
+ class CountRequest implements RequestType {
+
+ @Override
+ public boolean allowedMethod() {
+ return isGET();
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ return ContentType.TEXT_PLAIN;
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+ handler.read(DataRequest.this, CountResponse.getInstance(DataRequest.this, response));
+ }
+
+ @Override
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ return null;
+ }
+ }
+
+ /**
+ * Is NavigationProperty Reference.
+ */
+ class ReferenceRequest implements RequestType {
+
+ @Override
+ public boolean allowedMethod() {
+ // references are only allowed on the navigation properties
+ if (getNavigations().isEmpty()) {
+ return false;
+ }
+
+ // 11.4.6.1 - post allowed on only collection valued navigation
+ if (isPOST() && !getNavigations().getLast().isCollection()) {
+ return false;
+ }
+
+ // 11.4.6.3 - PUT allowed on single valued navigation
+ if (isPUT() && getNavigations().getLast().isCollection()) {
+ return false;
+ }
+
+ // No defined behavior in spec
+ if (isPATCH()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), getODataRequest(),
+ getCustomContentTypeSupport(), isCollection() ? RepresentationType.COLLECTION_REFERENCE
+ : RepresentationType.REFERENCE);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+ if (isGET()) {
+ if (isCollection()) {
+ handler.read(DataRequest.this,
+ EntitySetResponse.getInstance(DataRequest.this, getContextURL(odata), true, response));
+ } else {
+ handler.read(DataRequest.this,
+ EntityResponse.getInstance(DataRequest.this, getContextURL(odata), true, response));
+ }
+ } else if (isDELETE()) {
+ // if this against the collection, user need to look at $id param for entity ref #11.4.6.2
+ String id = getQueryParameter("$id");
+ if (id == null) {
+ handler.deleteReference(DataRequest.this, null, getETag(), new NoContentResponse(
+ getServiceMetaData(), response));
+ } else {
+ try {
+ handler.deleteReference(DataRequest.this, new URI(id), getETag(), new NoContentResponse(
+ getServiceMetaData(), response));
+ } catch (URISyntaxException e) {
+ throw new DeserializerException("failed to read $id", e, MessageKeys.UNKOWN_CONTENT);
+ }
+ }
+ } else if (isPUT()) {
+ // note this is always against single reference
+ handler.updateReference(DataRequest.this, getETag(), getPayload().get(0), new NoContentResponse(
+ getServiceMetaData(), response));
+ } else if (isPOST()) {
+ // this needs to be against collection of references
+ handler.addReference(DataRequest.this, getETag(), getPayload(), new NoContentResponse(
+ getServiceMetaData(), response));
+ }
+ }
+
+ // http://docs.oasis-open.org/odata/odata-json-format/v4.0/errata02/os
+ // /odata-json-format-v4.0-errata02-os-complete.html#_Toc403940643
+ // The below code reads as property and converts to an URI
+ private List<URI> getPayload() throws DeserializerException {
+ ODataDeserializer deserializer = odata.createDeserializer(ODataFormat
+ .fromContentType(getRequestContentType()));
+ return deserializer.entityReferences(getODataRequest().getBody());
+ }
+
+ @Override
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ ContextURL.Builder builder = ContextURL.with().suffix(Suffix.REFERENCE);
+ if (isCollection()) {
+ builder.asCollection();
+ }
+ return builder.build();
+ }
+ }
+
+ class PropertyRequest implements RequestType {
+
+ @Override
+ public boolean allowedMethod() {
+ // create of properties is not allowed,
+ // only read, update, delete. Note that delete is
+ // same as update with null
+ if (isPOST()) {
+ return false;
+ }
+
+ // 11.4.9.4, collection properties are not supported with merge
+ if (isPATCH() && (isCollection() || isPropertyStream())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ if (isPropertyComplex()) {
+ return ContentNegotiator.doContentNegotiation(getUriInfo().getFormatOption(),
+ getODataRequest(), getCustomContentTypeSupport(),
+ isCollection() ? RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX);
+ } else if (isPropertyStream()) {
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
+ getCustomContentTypeSupport(), RepresentationType.BINARY);
+ }
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), getODataRequest(),
+ getCustomContentTypeSupport(), isCollection() ? RepresentationType.COLLECTION_PRIMITIVE
+ : RepresentationType.PRIMITIVE);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+
+ EdmProperty edmProperty = getUriResourceProperty().getProperty();
+
+ if (isGET()) {
+ if (isPropertyStream()) {
+ handler.read(DataRequest.this, new StreamResponse(getServiceMetaData(), response));
+ } else {
+ handler.read(DataRequest.this, buildResponse(response, edmProperty));
+ }
+ } else if (isPATCH()) {
+ handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), true,
+ getETag(), buildResponse(response, edmProperty));
+ } else if (isPUT()) {
+ if (isPropertyStream()) {
+ handler.upsertStreamProperty(DataRequest.this, getETag(), request.getBody(),
+ new NoContentResponse(getServiceMetaData(), response));
+ } else {
+ handler.updateProperty(DataRequest.this, getPropertyValueFromClient(edmProperty), false,
+ getETag(), buildResponse(response, edmProperty));
+ }
+ } else if (isDELETE()) {
+ if (isPropertyStream()) {
+ handler.upsertStreamProperty(DataRequest.this, getETag(), request.getBody(),
+ new NoContentResponse(getServiceMetaData(), response));
+ } else {
+ Property property = new PropertyImpl();
+ property.setName(edmProperty.getName());
+ property.setType(edmProperty.getType().getFullQualifiedName()
+ .getFullQualifiedNameAsString());
+ handler.updateProperty(DataRequest.this, property, false, getETag(),
+ buildResponse(response, edmProperty));
+ }
+ }
+ }
+
+ private PropertyResponse buildResponse(ODataResponse response, EdmProperty edmProperty)
+ throws ContentNegotiatorException, SerializerException {
+ PropertyResponse propertyResponse = PropertyResponse.getInstance(DataRequest.this, response,
+ edmProperty.getType(), getContextURL(odata), edmProperty.isCollection());
+ return propertyResponse;
+ }
+
+ @Override
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ final UriHelper helper = odata.createUriHelper();
+ EdmProperty edmProperty = getUriResourceProperty().getProperty();
+
+ ContextURL.Builder builder = ContextURL.with().entitySet(getEntitySet());
+ builder = ContextURL.with().entitySet(getEntitySet());
+ builder.keyPath(helper.buildContextURLKeyPredicate(getUriResourceEntitySet()
+ .getKeyPredicates()));
+ String navPath = buildNavPath(helper, getEntitySet().getEntityType(), getNavigations(), true);
+ if (navPath != null && !navPath.isEmpty()) {
+ builder.navOrPropertyPath(navPath+"/"+edmProperty.getName());
+ } else {
+ builder.navOrPropertyPath(edmProperty.getName());
+ }
+ if (isPropertyComplex()) {
+ EdmComplexType type = ((UriResourceComplexProperty) uriResourceProperty).getComplexType();
+ String select = helper.buildContextURLSelectList(type, getUriInfo().getExpandOption(),
+ getUriInfo().getSelectOption());
+ builder.selectList(select);
+ }
+ return builder.build();
+ }
+ }
+
+ class ValueRequest extends PropertyRequest {
+
+ @Override
+ public boolean allowedMethod() {
+ //part2-url-conventions # 4.2
+ if (isPropertyStream() && isGET()) {
+ return false;
+ }
+
+ return isGET() || isDELETE() || isPUT();
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ RepresentationType valueRepresentationType = uriResourceProperty.getType() == EdmPrimitiveTypeFactory
+ .getInstance(EdmPrimitiveTypeKind.Binary) ? RepresentationType.BINARY
+ : RepresentationType.VALUE;
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
+ getCustomContentTypeSupport(), valueRepresentationType);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+ EdmProperty edmProperty = getUriResourceProperty().getProperty();
+ if (isGET()) {
+ 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());
+
+ 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,
+ getETag(), propertyResponse);
+ }
+ }
+
+ @Override
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ return null;
+ }
+ }
+
+ class SingletonRequest implements RequestType {
+
+ @Override
+ public boolean allowedMethod() {
+ return isGET();
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), getODataRequest(),
+ getCustomContentTypeSupport(), RepresentationType.ENTITY);
+ }
+
+ @Override
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ final UriHelper helper = odata.createUriHelper();
+ ContextURL.Builder builder = buildEntitySetContextURL(helper,
+ uriResourceSingleton.getSingleton(), null, getUriInfo(), getNavigations(), isCollection(), true);
+ return builder.build();
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+ handler.read(DataRequest.this,
+ EntityResponse.getInstance(DataRequest.this, getContextURL(odata), false, response));
+ }
+ }
+
+ class CrossJoinRequest implements RequestType {
+ private final List<String> entitySetNames;
+
+ public CrossJoinRequest(List<String> entitySetNames) {
+ this.entitySetNames = entitySetNames;
+ }
+
+ @Override
+ public boolean allowedMethod() {
+ return isGET();
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ return ContentNegotiator.doContentNegotiation(getUriInfo().getFormatOption(),
+ getODataRequest(), getCustomContentTypeSupport(), RepresentationType.COLLECTION_COMPLEX);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+ handler.crossJoin(DataRequest.this, this.entitySetNames, response);
+ }
+
+ @Override
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ ContextURL.Builder builder = ContextURL.with().asCollection();
+ return builder.build();
+ }
+ }
+
+ 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);
+ }
+
+ 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());
+ String select = helper.buildContextURLSelectList(edmEntitySet.getEntityType(),
+ uriInfo.getExpandOption(), uriInfo.getSelectOption());
+ if (!singleton) {
+ builder.suffix(collectionReturn ? null : Suffix.ENTITY);
+ }
+
+ builder.selectList(select);
+
+ final UriInfoResource resource = uriInfo.asUriInfoResource();
+ final List<UriResource> resourceParts = resource.getUriResourceParts();
+ final List<String> path = getPropertyPath(resourceParts);
+ String propertyPath = buildPropertyPath(path);
+ final String navPath = buildNavPath(helper, edmEntitySet.getEntityType(), navigations, collectionReturn);
+ if (navPath != null && !navPath.isEmpty()) {
+ if (keyPredicates != null) {
+ builder.keyPath(helper.buildContextURLKeyPredicate(keyPredicates));
+ }
+ if (propertyPath != null) {
+ propertyPath = navPath+"/"+propertyPath;
+ } else {
+ propertyPath = navPath;
+ }
+ }
+ builder.navOrPropertyPath(propertyPath);
+ return builder;
+ }
+
+ private static List<String> getPropertyPath(final List<UriResource> path) {
+ List<String> result = new LinkedList<String>();
+ int index = 1;
+ while (index < path.size() && path.get(index) instanceof UriResourceProperty) {
+ result.add(((UriResourceProperty) path.get(index)).getProperty().getName());
+ index++;
+ }
+ return result;
+ }
+
+ private static String buildPropertyPath(final List<String> path) {
+ StringBuilder result = new StringBuilder();
+ for (final String segment : path) {
+ result.append(result.length() == 0 ? "" : '/').append(segment); //$NON-NLS-1$
+ }
+ return result.length() == 0?null:result.toString();
+ }
+
+ static String buildNavPath(UriHelper helper, EdmEntityType rootType,
+ LinkedList<UriResourceNavigation> navigations, boolean includeLastPredicates)
+ throws SerializerException {
+ if (navigations.isEmpty()) {
+ return null;
+ }
+ StringBuilder sb = new StringBuilder();
+ boolean containsTarget = false;
+ EdmEntityType type = rootType;
+ for (UriResourceNavigation nav:navigations) {
+ String name = nav.getProperty().getName();
+ EdmNavigationProperty property = type.getNavigationProperty(name);
+ if (property.containsTarget()) {
+ containsTarget = true;
+ }
+ type = nav.getProperty().getType();
+ }
+
+ if (containsTarget) {
+ for (int i = 0; i < navigations.size(); i++) {
+ UriResourceNavigation nav = navigations.get(i);
+ if (i > 0) {
+ sb.append("/");
+ }
+ sb.append(nav.getProperty().getName());
+
+ boolean skipKeys = false;
+ if (navigations.size() == i+1 && !includeLastPredicates ) {
+ skipKeys = true;
+ }
+
+ if (!skipKeys && !nav.getKeyPredicates().isEmpty()) {
+ sb.append("(");
+ sb.append(helper.buildContextURLKeyPredicate(nav.getKeyPredicates()));
+ sb.append(")");
+ }
+
+ if (nav.getTypeFilterOnCollection() != null) {
+ sb.append("/")
+ .append(nav.getTypeFilterOnCollection().getFullQualifiedName().getFullQualifiedNameAsString());
+ } else if (nav.getTypeFilterOnEntry() != null) {
+ sb.append("/")
+ .append(nav.getTypeFilterOnEntry().getFullQualifiedName().getFullQualifiedNameAsString());
+ }
+ }
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/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
new file mode 100644
index 0000000..a9f9341
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/FunctionRequest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.requests;
+
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.EdmFunction;
+import org.apache.olingo.commons.api.edm.EdmReturnType;
+import org.apache.olingo.server.api.OData;
+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.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResourceFunction;
+import org.apache.olingo.server.core.ServiceHandler;
+import org.apache.olingo.server.core.responses.EntityResponse;
+import org.apache.olingo.server.core.responses.EntitySetResponse;
+import org.apache.olingo.server.core.responses.PrimitiveValueResponse;
+import org.apache.olingo.server.core.responses.PropertyResponse;
+
+public class FunctionRequest extends OperationRequest {
+ private UriResourceFunction uriResourceFunction;
+
+ public FunctionRequest(OData odata, ServiceMetadata serviceMetadata) {
+ super(odata, serviceMetadata);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+
+ if (!allowedMethod()) {
+ methodNotAllowed();
+ }
+
+ // 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,
+ getReturnType().getType(), getContextURL(this.odata), isCollection()));
+ } else {
+ // returnType.getType().getKind() == EdmTypeKind.ENTITY
+ if (isCollection()) {
+ handler.invoke(this, getODataRequest().getMethod(),
+ EntitySetResponse.getInstance(this, getContextURL(odata), false, response));
+ } else {
+ handler.invoke(this, getODataRequest().getMethod(),
+ EntityResponse.getInstance(this, getContextURL(odata), false, response));
+ }
+ }
+ }
+
+ @Override
+ public boolean allowedMethod() {
+ // look for discussion about composable functions in odata-discussion
+ // group with thread "Clarification on "Function" invocations"
+ if (getFunction().isComposable()) {
+ return (isGET() || isPATCH() || isDELETE() || isPOST() || isPUT());
+ }
+ return isGET();
+ }
+
+ public UriResourceFunction getUriResourceFunction() {
+ return uriResourceFunction;
+ }
+
+ public void setUriResourceFunction(UriResourceFunction uriResourceFunction) {
+ this.uriResourceFunction = uriResourceFunction;
+ }
+
+ @Override
+ public boolean isBound() {
+ return this.uriResourceFunction.getFunctionImport() != null;
+ }
+
+ public EdmFunction getFunction() {
+ return this.uriResourceFunction.getFunction();
+ }
+
+ public List<UriParameter> getParameters() {
+ return this.uriResourceFunction.getParameters();
+ }
+
+ @Override
+ public boolean isCollection() {
+ return getFunction().getReturnType().isCollection();
+ }
+
+ @Override
+ public EdmReturnType getReturnType() {
+ return getFunction().getReturnType();
+ }
+
+ @Override
+ public boolean hasReturnType() {
+ // Part3 {12.1} says must have return type
+ return true;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/MediaRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/MediaRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/MediaRequest.java
new file mode 100644
index 0000000..a4a333a
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/MediaRequest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.requests;
+
+import java.io.InputStream;
+import java.util.List;
+
+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.server.api.OData;
+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.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ServiceHandler;
+import org.apache.olingo.server.core.ServiceRequest;
+import org.apache.olingo.server.core.responses.NoContentResponse;
+import org.apache.olingo.server.core.responses.StreamResponse;
+
+public class MediaRequest extends ServiceRequest {
+ private UriResourceEntitySet uriResourceEntitySet;
+
+ public MediaRequest(OData odata, ServiceMetadata serviceMetadata) {
+ super(odata, serviceMetadata);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+ if (!allowedMethod()) {
+ methodNotAllowed();
+ }
+ // POST will not be here, because the media is created as part of media
+ // entity creation
+ if (isGET()) {
+ handler.readMediaStream(this, new StreamResponse(getServiceMetaData(), response));
+ } else if (isPUT()) {
+ handler.upsertMediaStream(this, getETag(), getMediaStream(), new NoContentResponse(
+ getServiceMetaData(), response));
+ } else if (isDELETE()) {
+ handler.upsertMediaStream(this, getETag(), null, new NoContentResponse(getServiceMetaData(),
+ response));
+ }
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ // the request must specify the content type requested.
+ return getRequestContentType();
+ }
+
+ public EdmEntitySet getEntitySet() {
+ return this.uriResourceEntitySet.getEntitySet();
+ }
+
+ public EdmEntityType getEntityType() {
+ return this.uriResourceEntitySet.getEntitySet().getEntityType();
+ }
+
+ public void setUriResourceEntitySet(UriResourceEntitySet uriResourceEntitySet) {
+ this.uriResourceEntitySet = uriResourceEntitySet;
+ }
+
+ public List<UriParameter> getKeyPredicates() {
+ if (this.uriResourceEntitySet != null) {
+ return this.uriResourceEntitySet.getKeyPredicates();
+ }
+ return null;
+ }
+
+ private InputStream getMediaStream() {
+ return this.request.getBody();
+ }
+
+ @Override
+ public boolean allowedMethod() {
+ return isGET() || isPUT() || isDELETE();
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/MetadataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/MetadataRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/MetadataRequest.java
new file mode 100644
index 0000000..e2c5c54
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/MetadataRequest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.requests;
+
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.server.api.OData;
+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.RepresentationType;
+import org.apache.olingo.server.api.uri.UriInfoMetadata;
+import org.apache.olingo.server.core.ContentNegotiator;
+import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ServiceHandler;
+import org.apache.olingo.server.core.ServiceRequest;
+import org.apache.olingo.server.core.responses.MetadataResponse;
+
+public class MetadataRequest extends ServiceRequest {
+
+ public MetadataRequest(OData odata, ServiceMetadata serviceMetadata) {
+ super(odata, serviceMetadata);
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ return ContentNegotiator.doContentNegotiation(this.uriInfo.getFormatOption(), this.request,
+ this.customContentType, RepresentationType.METADATA);
+ }
+
+ public UriInfoMetadata getUriInfoMetadata() {
+ return uriInfo.asUriInfoMetadata();
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+
+ if (!allowedMethod()) {
+ methodNotAllowed();
+ }
+
+ handler.readMetadata(this, MetadataResponse.getInstance(this, response));
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/OperationRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/OperationRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/OperationRequest.java
new file mode 100644
index 0000000..1f1b194
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/OperationRequest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.requests;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.edm.EdmReturnType;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.RepresentationType;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriHelper;
+import org.apache.olingo.server.core.ContentNegotiator;
+import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ServiceRequest;
+
+public abstract class OperationRequest extends ServiceRequest {
+
+ public OperationRequest(OData odata, ServiceMetadata serviceMetadata) {
+ super(odata, serviceMetadata);
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ if (!hasReturnType()) {
+ // this default content type
+ return ContentType.APPLICATION_OCTET_STREAM;
+ }
+
+ if (isReturnTypePrimitive()) {
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), this.request,
+ getCustomContentTypeSupport(), isCollection() ? RepresentationType.COLLECTION_PRIMITIVE
+ : RepresentationType.PRIMITIVE);
+ } else if (isReturnTypeComplex()) {
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), this.request,
+ getCustomContentTypeSupport(), isCollection() ? RepresentationType.COLLECTION_COMPLEX
+ : RepresentationType.COMPLEX);
+ } else {
+ return ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), this.request,
+ getCustomContentTypeSupport(), isCollection() ? RepresentationType.COLLECTION_ENTITY
+ : RepresentationType.ENTITY);
+ }
+ }
+
+ public abstract boolean isBound();
+
+ public abstract boolean isCollection();
+
+ public abstract EdmReturnType getReturnType();
+
+ public abstract boolean hasReturnType();
+
+ public ContextURL getContextURL(OData odata) throws SerializerException {
+ if (!hasReturnType()) {
+ return null;
+ }
+
+ final UriHelper helper = odata.createUriHelper();
+
+ if (isReturnTypePrimitive() || isReturnTypeComplex()) {
+ // Part 1 {10.14, 10.14} since the function return properties does not
+ // represent a Entity property
+ ContextURL.Builder builder = ContextURL.with().type(getReturnType().getType());
+ if (isCollection()) {
+ builder.asCollection();
+ }
+ return builder.build();
+ }
+
+ /*
+ // EdmTypeKind.ENTITY;
+ if (isBound()) {
+ // Bound means, we know the EnitySet of the return type. Part 1 {10.2,
+ // 10.3}
+ EdmEntitySet entitySet = this.uriResourceFunction.getFunctionImport().getReturnedEntitySet();
+ ContextURL.Builder builder = DataRequest.buildEntitySetContextURL(helper, entitySet,
+ this.uriInfo, isCollection(), false);
+ return builder.build();
+ }
+ */
+
+ // EdmTypeKind.ENTITY; Not Bound
+ // Here we do not know the EntitySet, then follow directions from
+ // Part-1{10.2. 10.3} to use
+ // {context-url}#{type-name}
+ ContextURL.Builder builder = ContextURL.with().type(getReturnType().getType());
+ if (isCollection()) {
+ builder.asCollection();
+ }
+ return builder.build();
+ }
+
+ public boolean isReturnTypePrimitive() {
+ return getReturnType().getType().getKind() == EdmTypeKind.PRIMITIVE;
+ }
+
+ public boolean isReturnTypeComplex() {
+ return getReturnType().getType().getKind() == EdmTypeKind.COMPLEX;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ServiceDocumentRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ServiceDocumentRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ServiceDocumentRequest.java
new file mode 100644
index 0000000..f99aaf5
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ServiceDocumentRequest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.requests;
+
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.server.api.OData;
+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.RepresentationType;
+import org.apache.olingo.server.core.ContentNegotiator;
+import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ServiceHandler;
+import org.apache.olingo.server.core.ServiceRequest;
+import org.apache.olingo.server.core.responses.ServiceDocumentResponse;
+
+public class ServiceDocumentRequest extends ServiceRequest {
+
+ public ServiceDocumentRequest(OData odata, ServiceMetadata serviceMetadata) {
+ super(odata, serviceMetadata);
+ }
+
+ @Override
+ public ContentType getResponseContentType() throws ContentNegotiatorException {
+ return ContentNegotiator.doContentNegotiation(getUriInfo().getFormatOption(),
+ getODataRequest(), getCustomContentTypeSupport(), RepresentationType.SERVICE);
+ }
+
+ @Override
+ public void execute(ServiceHandler handler, ODataResponse response)
+ throws ODataTranslatedException, ODataApplicationException {
+
+ if (!allowedMethod()) {
+ methodNotAllowed();
+ }
+ handler.readServiceDocument(this,
+ ServiceDocumentResponse.getInstace(this, response, getResponseContentType()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/CountResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/CountResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/CountResponse.java
new file mode 100644
index 0000000..f7cde33
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/CountResponse.java
@@ -0,0 +1,60 @@
+/*
+ * 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.Map;
+
+import org.apache.olingo.commons.api.http.HttpContentType;
+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.FixedFormatSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.ServiceRequest;
+
+public class CountResponse extends ServiceResponse {
+ private final FixedFormatSerializer serializer;
+
+ public static CountResponse getInstance(ServiceRequest request, ODataResponse response) {
+ FixedFormatSerializer serializer = request.getOdata().createFixedFormatSerializer();
+ return new CountResponse(request.getServiceMetaData(), serializer, response,
+ request.getPreferences());
+ }
+
+ private CountResponse(ServiceMetadata metadata, FixedFormatSerializer serializer,
+ ODataResponse response, Map<String, String> preferences) {
+ super(metadata, response, preferences);
+ this.serializer = serializer;
+ }
+
+ public void writeCount(int count) throws SerializerException {
+ assert (!isClosed());
+
+ this.response.setContent(this.serializer.count(count));
+ writeOK(HttpContentType.TEXT_PLAIN);
+ close();
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor) throws ODataTranslatedException,
+ ODataApplicationException {
+ visitor.visit(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/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
new file mode 100644
index 0000000..fd29bbd
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntityResponse.java
@@ -0,0 +1,140 @@
+/*
+ * 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.Map;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+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.ODataTranslatedException;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ReturnRepresentation;
+import org.apache.olingo.server.core.ServiceRequest;
+
+public class EntityResponse extends ServiceResponse {
+ private final ReturnRepresentation returnRepresentation;
+ private final ODataSerializer serializer;
+ private final EntitySerializerOptions options;
+ private final ContentType responseContentType;
+
+ private EntityResponse(ServiceMetadata metadata, ODataResponse response,
+ ODataSerializer serializer, EntitySerializerOptions options, ContentType responseContentType,
+ Map<String, String> preferences, ReturnRepresentation returnRepresentation) {
+ super(metadata, response, preferences);
+ this.serializer = serializer;
+ this.options = options;
+ this.responseContentType = responseContentType;
+ this.returnRepresentation = returnRepresentation;
+ }
+
+ public static EntityResponse getInstance(ServiceRequest request, ContextURL contextURL,
+ boolean references, ODataResponse response, ReturnRepresentation returnRepresentation)
+ throws ContentNegotiatorException, SerializerException {
+ EntitySerializerOptions options = request.getSerializerOptions(EntitySerializerOptions.class,
+ contextURL, references);
+ return new EntityResponse(request.getServiceMetaData(), response, request.getSerializer(),
+ options, request.getResponseContentType(), request.getPreferences(), returnRepresentation);
+ }
+
+ public static EntityResponse getInstance(ServiceRequest request, ContextURL contextURL,
+ boolean references, ODataResponse response)
+ throws ContentNegotiatorException, SerializerException {
+ EntitySerializerOptions options = request.getSerializerOptions(EntitySerializerOptions.class,
+ contextURL, references);
+ return new EntityResponse(request.getServiceMetaData(), response, request.getSerializer(),
+ options, request.getResponseContentType(), request.getPreferences(), null);
+ }
+
+ // write single entity
+ public void writeReadEntity(EdmEntityType entityType, Entity entity) throws SerializerException {
+
+ assert (!isClosed());
+
+ if (entity == null) {
+ writeNotFound(true);
+ return;
+ }
+
+ // write the entity to response
+ this.response.setContent(this.serializer.entity(this.metadata, entityType, entity, this.options));
+ writeOK(this.responseContentType.toContentTypeString());
+ close();
+ }
+
+ public void writeCreatedEntity(EdmEntityType entityType, Entity entity, String locationHeader)
+ throws SerializerException {
+ // upsert/insert must created a entity, otherwise should have throw an
+ // exception
+ assert (entity != null);
+
+ // Note that if media written just like Stream, but on entity URL
+
+ // 8.2.8.7
+ if (this.returnRepresentation == ReturnRepresentation.MINIMAL) {
+ writeNoContent(false);
+ writeHeader(HttpHeader.LOCATION, locationHeader);
+ writeHeader("Preference-Applied", "return=minimal"); //$NON-NLS-1$ //$NON-NLS-2$
+ // 8.3.3
+ writeHeader("OData-EntityId", entity.getId().toASCIIString()); //$NON-NLS-1$
+ close();
+ return;
+ }
+
+ // return the content of the created entity
+ this.response.setContent(this.serializer.entity(this.metadata, entityType, entity, this.options));
+ writeCreated(false);
+ writeHeader(HttpHeader.LOCATION, locationHeader);
+ writeHeader("Preference-Applied", "return=representation"); //$NON-NLS-1$ //$NON-NLS-2$
+ writeHeader(HttpHeader.CONTENT_TYPE, this.responseContentType.toContentTypeString());
+ close();
+ }
+
+ public void writeUpdatedEntity() {
+ // spec says just success response; so either 200 or 204. 200 typically has
+ // payload
+ writeNoContent(true);
+ }
+
+ public void writeDeletedEntityOrReference() {
+ writeNoContent(true);
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor) throws ODataTranslatedException,
+ ODataApplicationException {
+ visitor.visit(this);
+ }
+
+ public void writeCreated(boolean closeResponse) {
+ this.response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
+ if (closeResponse) {
+ close();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/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
new file mode 100644
index 0000000..40276d2
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/EntitySetResponse.java
@@ -0,0 +1,82 @@
+/*
+ * 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.Map;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.EntitySet;
+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.ODataTranslatedException;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ServiceRequest;
+
+public class EntitySetResponse extends ServiceResponse {
+ private final ODataSerializer serializer;
+ private final EntityCollectionSerializerOptions options;
+ private final ContentType responseContentType;
+
+ private EntitySetResponse(ServiceMetadata metadata, ODataResponse response, ODataSerializer serializer,
+ EntityCollectionSerializerOptions options,
+ ContentType responseContentType, Map<String, String> preferences) {
+ super(metadata, response, preferences);
+ this.serializer = serializer;
+ this.options = options;
+ this.responseContentType = responseContentType;
+ }
+
+ public static EntitySetResponse getInstance(ServiceRequest request, ContextURL contextURL,
+ boolean referencesOnly, ODataResponse response) throws ContentNegotiatorException, SerializerException {
+ EntityCollectionSerializerOptions options = request.getSerializerOptions(
+ EntityCollectionSerializerOptions.class, contextURL, referencesOnly);
+ return new EntitySetResponse(request.getServiceMetaData(),response, request.getSerializer(), options,
+ request.getResponseContentType(), request.getPreferences());
+ }
+
+ // write collection of entities
+ // TODO: server paging needs to be implemented.
+ public void writeReadEntitySet(EdmEntityType entityType, EntitySet entitySet)
+ throws SerializerException {
+
+ assert (!isClosed());
+
+ if (entitySet == null) {
+ writeNotFound(true);
+ return;
+ }
+
+ // write the whole collection to response
+ this.response.setContent(this.serializer.entityCollection(metadata, entityType, entitySet, this.options));
+ writeOK(this.responseContentType.toContentTypeString());
+ close();
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor) throws ODataTranslatedException,
+ ODataApplicationException {
+ visitor.visit(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/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
new file mode 100644
index 0000000..055c0b0
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/MetadataResponse.java
@@ -0,0 +1,62 @@
+/*
+ * 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.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.ODataTranslatedException;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ServiceRequest;
+
+public class MetadataResponse extends ServiceResponse {
+ private final ODataSerializer serializer;
+ private final ContentType responseContentType;
+
+ public static MetadataResponse getInstance(ServiceRequest request,
+ ODataResponse response) throws ContentNegotiatorException, SerializerException {
+ return new MetadataResponse(request.getServiceMetaData(), response, request.getSerializer(),
+ request.getResponseContentType(), request.getPreferences());
+ }
+
+ private MetadataResponse(ServiceMetadata metadata, ODataResponse response, ODataSerializer serializer,
+ ContentType responseContentType, Map<String, String> preferences) {
+ super(metadata, response, preferences);
+ this.serializer = serializer;
+ this.responseContentType = responseContentType;
+ }
+
+ public void writeMetadata()throws ODataTranslatedException {
+ assert (!isClosed());
+ this.response.setContent(this.serializer.metadataDocument(this.metadata));
+ writeOK(this.responseContentType.toContentTypeString());
+ close();
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor) throws ODataTranslatedException,
+ ODataApplicationException {
+ visitor.visit(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/NoContentResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/NoContentResponse.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/NoContentResponse.java
new file mode 100644
index 0000000..eb16365
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/NoContentResponse.java
@@ -0,0 +1,100 @@
+/*
+ * 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.Collections;
+
+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.ODataTranslatedException;
+import org.apache.olingo.server.api.ServiceMetadata;
+
+public class NoContentResponse extends ServiceResponse {
+
+ public NoContentResponse(ServiceMetadata metadata, ODataResponse response) {
+ super(metadata, response, Collections.EMPTY_MAP);
+ }
+
+ // 200
+ public void writeOK() {
+ this.response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ close();
+ }
+
+ // 201
+ public void writeCreated() {
+ this.response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
+ close();
+ }
+
+ // 202
+ public void writeAccepted() {
+ this.response.setStatusCode(HttpStatusCode.ACCEPTED.getStatusCode());
+ close();
+ }
+
+ // 204
+ public void writeNoContent() {
+ writeNoContent(true);
+ }
+
+ // 304
+ public void writeNotModified() {
+ this.response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
+ close();
+ }
+
+ // error response codes
+
+ // 404
+ public void writeNotFound() {
+ writeNotFound(true);
+ }
+
+ // 501
+ public void writeNotImplemented() {
+ this.response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode());
+ close();
+ }
+
+ // 405
+ public void writeMethodNotAllowed() {
+ this.response.setStatusCode(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode());
+ close();
+ }
+
+ // 410
+ public void writeGone() {
+ this.response.setStatusCode(HttpStatusCode.GONE.getStatusCode());
+ close();
+ }
+
+ // 412
+ public void writePreConditionFailed() {
+ this.response.setStatusCode(HttpStatusCode.PRECONDITION_FAILED.getStatusCode());
+ close();
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor) throws ODataTranslatedException,
+ ODataApplicationException {
+ visitor.visit(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/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
new file mode 100644
index 0000000..005bfca
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PrimitiveValueResponse.java
@@ -0,0 +1,105 @@
+/*
+ * 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.Map;
+
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmReturnType;
+import org.apache.olingo.commons.api.http.HttpContentType;
+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.FixedFormatSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.ServiceRequest;
+
+public class PrimitiveValueResponse extends ServiceResponse {
+ private final boolean returnCollection;
+ private EdmProperty type;
+ private EdmReturnType returnType;
+ private final FixedFormatSerializer serializer;
+
+ public static PrimitiveValueResponse getInstance(ServiceRequest request, ODataResponse response,
+ boolean collection, EdmProperty type) {
+ FixedFormatSerializer serializer = request.getOdata().createFixedFormatSerializer();
+ return new PrimitiveValueResponse(request.getServiceMetaData(), serializer, response,
+ collection, type, request.getPreferences());
+ }
+
+ public static PrimitiveValueResponse getInstance(ServiceRequest request, ODataResponse response,
+ boolean collection, EdmReturnType type) {
+ FixedFormatSerializer serializer = request.getOdata().createFixedFormatSerializer();
+ return new PrimitiveValueResponse(request.getServiceMetaData(), serializer, response,
+ collection, type, request.getPreferences());
+ }
+
+ private PrimitiveValueResponse(ServiceMetadata metadata, FixedFormatSerializer serializer,
+ ODataResponse response, boolean collection, EdmProperty type, Map<String, String> preferences) {
+ super(metadata, response, preferences);
+ this.returnCollection = collection;
+ this.type = type;
+ this.serializer = serializer;
+ }
+
+ private PrimitiveValueResponse(ServiceMetadata metadata, FixedFormatSerializer serializer,
+ ODataResponse response, boolean collection, EdmReturnType type,
+ Map<String, String> preferences) {
+ super(metadata, response, preferences);
+ this.returnCollection = collection;
+ this.returnType = type;
+ this.serializer = serializer;
+ }
+
+ public void write(Object value) throws SerializerException {
+ if (value == null) {
+ writeNoContent(true);
+ return;
+ }
+
+ if (this.type != null) {
+ PrimitiveValueSerializerOptions options = PrimitiveValueSerializerOptions.with()
+ .facetsFrom(this.type).build();
+
+ this.response.setContent(this.serializer.primitiveValue((EdmPrimitiveType) this.type.getType(),
+ value, options));
+ } else {
+ PrimitiveValueSerializerOptions options = PrimitiveValueSerializerOptions.with()
+ .nullable(this.returnType.isNullable()).maxLength(this.returnType.getMaxLength())
+ .precision(this.returnType.getPrecision()).scale(this.returnType.getScale()).build();
+ this.response.setContent(this.serializer.primitiveValue(
+ (EdmPrimitiveType) this.returnType.getType(), value, options));
+ }
+
+ writeOK(HttpContentType.TEXT_PLAIN);
+ }
+
+ public boolean isReturnCollection() {
+ return returnCollection;
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor) throws ODataTranslatedException,
+ ODataApplicationException {
+ visitor.visit(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/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
new file mode 100644
index 0000000..e6b951d
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/PropertyResponse.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core.responses;
+
+import java.util.Map;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
+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.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.ComplexSerializerOptions;
+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.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ServiceRequest;
+
+public class PropertyResponse extends ServiceResponse {
+ private PrimitiveSerializerOptions primitiveOptions;
+ private ComplexSerializerOptions complexOptions;
+ private final ContentType responseContentType;
+ private final ODataSerializer serializer;
+ private final boolean collection;
+
+ public static PropertyResponse getInstance(ServiceRequest request, ODataResponse response,
+ EdmType edmType, ContextURL contextURL, boolean collection) throws ContentNegotiatorException,
+ SerializerException {
+ if (edmType.getKind() == EdmTypeKind.PRIMITIVE) {
+ PrimitiveSerializerOptions options = request.getSerializerOptions(
+ PrimitiveSerializerOptions.class, contextURL, false);
+ ContentType type = request.getResponseContentType();
+ return new PropertyResponse(request.getServiceMetaData(), request.getSerializer(), response,
+ options, type, collection, request.getPreferences());
+ }
+ ComplexSerializerOptions options = request.getSerializerOptions(ComplexSerializerOptions.class,
+ contextURL, false);
+ ContentType type = request.getResponseContentType();
+ return new PropertyResponse(request.getServiceMetaData(), request.getSerializer(), response,
+ options, type, collection, request.getPreferences());
+ }
+
+ private PropertyResponse(ServiceMetadata metadata, ODataSerializer serializer,
+ ODataResponse response, PrimitiveSerializerOptions options, ContentType contentType,
+ boolean collection, Map<String, String> preferences) {
+ super(metadata, response, preferences);
+ this.serializer = serializer;
+ this.primitiveOptions = options;
+ this.responseContentType = contentType;
+ this.collection = collection;
+ }
+
+ private PropertyResponse(ServiceMetadata metadata, ODataSerializer serializer, ODataResponse response,
+ ComplexSerializerOptions options, ContentType contentType, boolean collection,
+ Map<String, String> preferences) {
+ super(metadata, response, preferences);
+ this.serializer = serializer;
+ this.complexOptions = options;
+ this.responseContentType = contentType;
+ this.collection = collection;
+ }
+
+ public void writeProperty(EdmType edmType, Property property) throws SerializerException {
+ assert (!isClosed());
+
+ if (property == null) {
+ writeNotFound(true);
+ return;
+ }
+
+ if (property.getValue() == null) {
+ writeNoContent(true);
+ return;
+ }
+
+ if (edmType.getKind() == EdmTypeKind.PRIMITIVE) {
+ writePrimitiveProperty((EdmPrimitiveType) edmType, property);
+ } else {
+ writeComplexProperty((EdmComplexType) edmType, property);
+ }
+ }
+
+ private void writeComplexProperty(EdmComplexType type, Property property)
+ throws SerializerException {
+ if (this.collection) {
+ this.response.setContent(this.serializer.complexCollection(this.metadata, type, property,
+ this.complexOptions));
+ } else {
+ this.response.setContent(this.serializer.complex(this.metadata, type, property,
+ this.complexOptions));
+ }
+ writeOK(this.responseContentType.toContentTypeString());
+ close();
+ }
+
+ private void writePrimitiveProperty(EdmPrimitiveType type, Property property)
+ throws SerializerException {
+ if(this.collection) {
+ this.response.setContent(this.serializer.primitiveCollection(type, property, this.primitiveOptions));
+ } else {
+ this.response.setContent(this.serializer.primitive(type, property, this.primitiveOptions));
+ }
+ writeOK(this.responseContentType.toContentTypeString());
+ close();
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor) throws ODataTranslatedException,
+ ODataApplicationException {
+ visitor.visit(this);
+ }
+
+ public void writePropertyUpdated() {
+ // spec says just success response; so either 200 or 204. 200 typically has
+ // payload
+ writeNoContent(true);
+ }
+
+ public void writePropertyDeleted() {
+ writeNoContent(true);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/2b73abcc/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
new file mode 100644
index 0000000..86c420b
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/responses/ServiceDocumentResponse.java
@@ -0,0 +1,63 @@
+/*
+ * 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.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.ODataTranslatedException;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.ContentNegotiatorException;
+import org.apache.olingo.server.core.ServiceRequest;
+
+public class ServiceDocumentResponse extends ServiceResponse {
+ private final ODataSerializer serializer;
+ private final ContentType responseContentType;
+
+ public static ServiceDocumentResponse getInstace(ServiceRequest request, ODataResponse respose,
+ ContentType responseContentType) throws ContentNegotiatorException, SerializerException {
+ return new ServiceDocumentResponse(request.getServiceMetaData(), respose,
+ request.getSerializer(), responseContentType, request.getPreferences());
+ }
+
+ private ServiceDocumentResponse(ServiceMetadata metadata, ODataResponse respose,
+ ODataSerializer serializer, ContentType responseContentType, Map<String, String> preferences) {
+ super(metadata, respose, preferences);
+ this.serializer = serializer;
+ this.responseContentType = responseContentType;
+ }
+
+ public void writeServiceDocument(String serviceRoot)
+ throws ODataTranslatedException {
+ assert (!isClosed());
+ this.response.setContent(this.serializer.serviceDocument(this.metadata.getEdm(), serviceRoot));
+ writeOK(this.responseContentType.toContentTypeString());
+ close();
+ }
+
+ @Override
+ public void accepts(ServiceResponseVisior visitor) throws ODataTranslatedException,
+ ODataApplicationException {
+ visitor.visit(this);
+ }
+}