[OLINGO-482] split server processor interfaces + improved dispatching
Change-Id: Ie57a469299e73662838307f1b96b558d3beb723d Signed-off-by: Christian Amend <chrisam@apache.org>
This commit is contained in:
parent
3e11738125
commit
a405e5b4b5
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a collection of complex-type instances, e.g.,
|
||||
* a property of an entity defined as collection of complex-type instances.
|
||||
*/
|
||||
public interface ComplexTypeCollectionProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads complex-type collection.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readComplexTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -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 org.apache.olingo.server.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a complex type, e.g., a complex property of an entity.
|
||||
*/
|
||||
public interface ComplexTypeProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads complex type.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readComplexType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.api.processor;
|
||||
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling counting a collection of entities, e.g., an Entity Set.
|
||||
*/
|
||||
public interface CountEntityTypeCollectionProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Counts entities from persistence and puts serialized content and status into the response.
|
||||
* Response content type is <code>text/plain</code> by default.
|
||||
*
|
||||
* @param request - OData request object containing raw http information.
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData uri
|
||||
* @throws ODataApplicationException
|
||||
* @throws SerializerException
|
||||
*/
|
||||
void countEntityTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -26,9 +26,9 @@ import org.apache.olingo.server.api.serializer.SerializerException;
|
|||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling EntitySets (i.e. collection of entities).
|
||||
* Processor interface for handling a collection of entities, e.g., an Entity Set.
|
||||
*/
|
||||
public interface EntitySetProcessor extends Processor {
|
||||
public interface EntityTypeCollectionProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads entities data from persistence and puts serialized content and status into the response.
|
||||
|
@ -40,19 +40,6 @@ public interface EntitySetProcessor extends Processor {
|
|||
* @throws ODataApplicationException
|
||||
* @throws SerializerException
|
||||
*/
|
||||
void readEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
|
||||
/**
|
||||
* Count entities from persistence and puts serialized content and status into the response.
|
||||
* Response content type is <code>text/plain</code> by default.
|
||||
*
|
||||
* @param request - OData request object containing raw http information.
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData uri
|
||||
* @throws ODataApplicationException
|
||||
* @throws SerializerException
|
||||
*/
|
||||
void countEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException,
|
||||
SerializerException;
|
||||
void readEntityTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||
ContentType requestedContentType) throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -26,9 +26,9 @@ import org.apache.olingo.server.api.serializer.SerializerException;
|
|||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a single Entity.
|
||||
* Processor interface for handling a single instance of an Entity Type.
|
||||
*/
|
||||
public interface EntityProcessor extends Processor {
|
||||
public interface EntityTypeProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads entity data from persistence and puts serialized content and status into the response.
|
||||
|
@ -39,6 +39,6 @@ public interface EntityProcessor extends Processor {
|
|||
* @throws ODataApplicationException
|
||||
* @throws SerializerException
|
||||
*/
|
||||
void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
|
||||
void readEntityType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a collection of primitive-type instances, e.g.,
|
||||
* a property of an entity defined as collection of primitive-type instances.
|
||||
*/
|
||||
public interface PrimitiveTypeCollectionProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads primitive-type collection.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readPrimitiveTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -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.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a primitive type, e.g., a primitive property of an entity.
|
||||
*/
|
||||
public interface PrimitiveTypeProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads primitive type.
|
||||
* If its value is <code>null</code>, the service responds with 204 No Content.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readPrimitiveType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
|
||||
/**
|
||||
* Reads raw value of a primitive type, e.g., of a primitive property of an entity.
|
||||
* If the value is <code>null</code>, the service responds with 204 No Content.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readPrimitiveTypeAsValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* 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.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a property of an entity.
|
||||
*/
|
||||
public interface PropertyProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads primitive or complex property from entity.
|
||||
* If the property is single-valued and has the null value, the service responds with 204 No Content.
|
||||
* If the property is not available, for example due to permissions, the service responds with 404 Not Found
|
||||
*
|
||||
* @param request - OData request object containing raw HTTP information
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData URI
|
||||
* @param format - requested content type after content negotiation
|
||||
* @throws ODataApplicationException if service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readProperty(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
|
||||
/**
|
||||
* Reads value for primitive property from entity.
|
||||
* If the property is single-valued and has the null value, the service responds with 204 No Content.
|
||||
* If the property is not available, for example due to permissions, the service responds with 404 Not Found
|
||||
*
|
||||
* @param request - OData request object containing raw HTTP information
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData URI
|
||||
* @param format - requested content type after content negotiation
|
||||
* @throws ODataApplicationException if service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readPropertyValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -35,20 +35,24 @@ import org.apache.olingo.server.api.ODataRequest;
|
|||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ODataServerError;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.processor.ComplexTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexTypeProcessor;
|
||||
import org.apache.olingo.server.api.processor.CountEntityTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.DefaultProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntitySetProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityTypeProcessor;
|
||||
import org.apache.olingo.server.api.processor.ExceptionProcessor;
|
||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveTypeProcessor;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
import org.apache.olingo.server.api.processor.PropertyProcessor;
|
||||
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
||||
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
|
||||
import org.apache.olingo.server.api.serializer.RepresentationType;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
|
@ -127,11 +131,10 @@ public class ODataHandler {
|
|||
switch (uriInfo.getKind()) {
|
||||
case metadata:
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
MetadataProcessor mp = selectProcessor(MetadataProcessor.class);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.METADATA);
|
||||
mp.readMetadata(request, response, uriInfo, requestedContentType);
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, RepresentationType.METADATA);
|
||||
selectProcessor(MetadataProcessor.class)
|
||||
.readMetadata(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("HttpMethod " + method + " not allowed for metadata document",
|
||||
ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
|
||||
|
@ -140,15 +143,13 @@ public class ODataHandler {
|
|||
case service:
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
if ("".equals(request.getRawODataPath())) {
|
||||
RedirectProcessor rdp = selectProcessor(RedirectProcessor.class);
|
||||
rdp.redirect(request, response);
|
||||
selectProcessor(RedirectProcessor.class).redirect(request, response);
|
||||
} else {
|
||||
ServiceDocumentProcessor sdp = selectProcessor(ServiceDocumentProcessor.class);
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, RepresentationType.SERVICE);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.SERVICE);
|
||||
|
||||
sdp.readServiceDocument(request, response, uriInfo, requestedContentType);
|
||||
selectProcessor(ServiceDocumentProcessor.class)
|
||||
.readServiceDocument(request, response, uriInfo, requestedContentType);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("HttpMethod " + method + " not allowed for service document",
|
||||
|
@ -185,113 +186,118 @@ public class ODataHandler {
|
|||
|
||||
private void handleResourceDispatching(final ODataRequest request, final ODataResponse response)
|
||||
throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException, SerializerException {
|
||||
final HttpMethod method = request.getMethod();
|
||||
final int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
|
||||
UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
|
||||
final UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
|
||||
|
||||
switch (lastPathSegment.getKind()) {
|
||||
case entitySet:
|
||||
if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
|
||||
|
||||
cp.readEntitySet(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
} else {
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntityProcessor ep = selectProcessor(EntityProcessor.class);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.ENTITY);
|
||||
|
||||
ep.readEntity(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case navigationProperty:
|
||||
if (((UriResourceNavigation) lastPathSegment).isCollection()) {
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
|
||||
if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
|
||||
|
||||
cp.readEntitySet(request, response, uriInfo, requestedContentType);
|
||||
selectProcessor(EntityTypeCollectionProcessor.class)
|
||||
.readEntityTypeCollection(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
} else {
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntityProcessor ep = selectProcessor(EntityProcessor.class);
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, RepresentationType.ENTITY);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.ENTITY);
|
||||
|
||||
ep.readEntity(request, response, uriInfo, requestedContentType);
|
||||
selectProcessor(EntityTypeProcessor.class)
|
||||
.readEntityType(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case count:
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
|
||||
cp.countEntitySet(request, response, uriInfo);
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
if (resource instanceof UriResourceEntitySet || resource instanceof UriResourceNavigation) {
|
||||
selectProcessor(CountEntityTypeCollectionProcessor.class)
|
||||
.countEntityTypeCollection(request, response, uriInfo);
|
||||
} else {
|
||||
throw new ODataHandlerException(
|
||||
"Count of collections of primitive-type or complex-type instances is not implemented.",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
throw new ODataHandlerException("HTTP method " + method + " is not allowed for count.",
|
||||
ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
|
||||
}
|
||||
break;
|
||||
|
||||
case primitiveProperty:
|
||||
case complexProperty:
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
PropertyProcessor ep = selectProcessor(PropertyProcessor.class);
|
||||
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment;
|
||||
final boolean isCollection = propertyResource.isCollection();
|
||||
final boolean isComplex = propertyResource.getKind() == UriResourceKind.complexProperty;
|
||||
final RepresentationType representationType =
|
||||
isComplex ? isCollection ? RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX :
|
||||
isCollection ? RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE;
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, representationType);
|
||||
|
||||
ep.readProperty(request, response, uriInfo, requestedContentType);
|
||||
final RepresentationType representationType = propertyResource.isCollection() ?
|
||||
RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE;
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, representationType);
|
||||
if (representationType == RepresentationType.PRIMITIVE) {
|
||||
selectProcessor(PrimitiveTypeProcessor.class)
|
||||
.readPrimitiveType(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
selectProcessor(PrimitiveTypeCollectionProcessor.class)
|
||||
.readPrimitiveTypeCollection(request, response, uriInfo, requestedContentType);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
break;
|
||||
|
||||
case complexProperty:
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment;
|
||||
final RepresentationType representationType = propertyResource.isCollection() ?
|
||||
RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX;
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, representationType);
|
||||
if (representationType == RepresentationType.COMPLEX) {
|
||||
selectProcessor(ComplexTypeProcessor.class)
|
||||
.readComplexType(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
selectProcessor(ComplexTypeCollectionProcessor.class)
|
||||
.readComplexTypeCollection(request, response, uriInfo, requestedContentType);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
break;
|
||||
|
||||
case value:
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
PropertyProcessor ep = selectProcessor(PropertyProcessor.class);
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
if (resource instanceof UriResourceProperty) {
|
||||
final RepresentationType representationType =
|
||||
(EdmPrimitiveType) ((UriResourceProperty) resource).getType() ==
|
||||
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
|
||||
RepresentationType.BINARY : RepresentationType.VALUE;
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, representationType);
|
||||
|
||||
final UriResourceProperty propertyResource =
|
||||
(UriResourceProperty) uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
final RepresentationType representationType =
|
||||
(EdmPrimitiveType) propertyResource.getType() ==
|
||||
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
|
||||
RepresentationType.BINARY :
|
||||
RepresentationType.VALUE;
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, representationType);
|
||||
|
||||
ep.readPropertyValue(request, response, uriInfo, requestedContentType);
|
||||
selectProcessor(PrimitiveTypeProcessor.class)
|
||||
.readPrimitiveTypeAsValue(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("Media Entity is not implemented.",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
|
|
|
@ -24,7 +24,8 @@ import org.apache.olingo.server.api.ServiceMetadata;
|
|||
import org.apache.olingo.server.api.edmx.EdmxReference;
|
||||
import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
import org.apache.olingo.server.tecsvc.processor.TechnicalProcessor;
|
||||
import org.apache.olingo.server.tecsvc.processor.TechnicalEntityProcessor;
|
||||
import org.apache.olingo.server.tecsvc.processor.TechnicalPrimitiveComplexProcessor;
|
||||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -64,7 +65,8 @@ public class TechnicalServlet extends HttpServlet {
|
|||
}
|
||||
|
||||
ODataHttpHandler handler = odata.createHandler(serviceMetadata);
|
||||
handler.register(new TechnicalProcessor(dataProvider));
|
||||
handler.register(new TechnicalEntityProcessor(dataProvider));
|
||||
handler.register(new TechnicalPrimitiveComplexProcessor(dataProvider));
|
||||
handler.process(req, resp);
|
||||
} catch (RuntimeException e) {
|
||||
LOG.error("Server Error", e);
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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.tecsvc.processor;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
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.EntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpContentType;
|
||||
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.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.processor.CountEntityTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityTypeProcessor;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
|
||||
/**
|
||||
* Technical Processor for entity-related functionality.
|
||||
*/
|
||||
public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||
implements EntityTypeCollectionProcessor, CountEntityTypeCollectionProcessor, EntityTypeProcessor {
|
||||
|
||||
public TechnicalEntityProcessor(final DataProvider dataProvider) {
|
||||
super(dataProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
|
||||
uriInfo.getCountOption() != null && uriInfo.getCountOption().getValue());
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, false, expand, select))
|
||||
.count(uriInfo.getCountOption())
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countEntityTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
|
||||
final int pos = resourceParts.size() - 2;
|
||||
if (pos > 0) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
final EntitySet entitySet =
|
||||
readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
response.setContent(new ByteArrayInputStream(entitySet.getCount().toString().getBytes()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, HttpContentType.TEXT_PLAIN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
|
||||
final Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates());
|
||||
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, expand, select))
|
||||
.count(uriInfo.getCountOption())
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
|
||||
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet, final boolean withCount)
|
||||
throws DataProvider.DataProviderException {
|
||||
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
|
||||
// TODO: set count (correctly) and next link
|
||||
if (withCount && entitySet.getCount() == null) {
|
||||
entitySet.setCount(entitySet.getEntities().size());
|
||||
}
|
||||
return entitySet;
|
||||
}
|
||||
|
||||
private ContextURL getContextUrl(final ODataSerializer serializer,
|
||||
final EdmEntitySet entitySet, final boolean isSingleEntity,
|
||||
final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
return ContextURL.with().entitySet(entitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
|
||||
.suffix(isSingleEntity ? Suffix.ENTITY : null)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* 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.tecsvc.processor;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
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.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.processor.ComplexTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexTypeProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveTypeProcessor;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
|
||||
/**
|
||||
* Technical Processor which provides functionality related to primitive and complex types and collections thereof.
|
||||
*/
|
||||
public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
||||
implements PrimitiveTypeProcessor, PrimitiveTypeCollectionProcessor,
|
||||
ComplexTypeProcessor, ComplexTypeCollectionProcessor {
|
||||
|
||||
public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider) {
|
||||
super(dataProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitiveType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitiveTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readComplexType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readComplexTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType);
|
||||
}
|
||||
|
||||
private void readProperty(ODataResponse response, final UriInfo uriInfo, final ContentType contentType)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||
validateOptions(resource);
|
||||
validatePath(resource);
|
||||
|
||||
final List<UriResource> resourceParts = resource.getUriResourceParts();
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
|
||||
final List<String> path = getPropertyPath(resourceParts);
|
||||
|
||||
final Property property = getPropertyData(resourceEntitySet, path);
|
||||
|
||||
if (property == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
if (property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
|
||||
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
|
||||
|
||||
final ODataFormat format = ODataFormat.fromContentType(contentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
response.setContent(serializer.entityProperty(edmProperty, property,
|
||||
ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
ContextURL.with().entitySet(edmEntitySet)
|
||||
.keyPath(serializer.buildContextURLKeyPredicate(
|
||||
((UriResourceEntitySet) resourceParts.get(0)).getKeyPredicates()))
|
||||
.navOrPropertyPath(buildPropertyPath(path))
|
||||
.build())
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Property getPropertyData(final UriResourceEntitySet resourceEntitySet, final List<String> path)
|
||||
throws ODataApplicationException {
|
||||
final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates());
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
Property property = entity.getProperty(path.get(0));
|
||||
for (final String name : path.subList(1, path.size())) {
|
||||
if (property != null && (property.isLinkedComplex() || property.isComplex())) {
|
||||
final List<Property> complex = property.isLinkedComplex() ?
|
||||
property.asLinkedComplex().getValue() : property.asComplex();
|
||||
property = null;
|
||||
for (final Property innerProperty : complex) {
|
||||
if (innerProperty.getName().equals(name)) {
|
||||
property = innerProperty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return property;
|
||||
}
|
||||
}
|
||||
|
||||
private 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 String buildPropertyPath(final List<String> path) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (final String segment : path) {
|
||||
result.append(result.length() == 0 ? "" : '/').append(segment);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitiveTypeAsValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||
validateOptions(resource);
|
||||
validatePath(resource);
|
||||
|
||||
final List<UriResource> resourceParts = resource.getUriResourceParts();
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
|
||||
final List<String> path = getPropertyPath(resourceParts);
|
||||
|
||||
final Property property = getPropertyData(resourceEntitySet, path);
|
||||
|
||||
if (property == null || property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
|
||||
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
|
||||
if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)) {
|
||||
response.setContent(new ByteArrayInputStream((byte[]) property.getValue()));
|
||||
} else {
|
||||
try {
|
||||
final String value = type.valueToString(property.getValue(),
|
||||
edmProperty.isNullable(), edmProperty.getMaxLength(),
|
||||
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
|
||||
response.setContent(new ByteArrayInputStream(value.getBytes("UTF-8")));
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new ODataApplicationException("Error in value formatting.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
throw new ODataApplicationException("Encoding exception.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
|
||||
}
|
||||
}
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
for (final UriResource segment : resourcePaths.subList(1, resourcePaths.size())) {
|
||||
final UriResourceKind kind = segment.getKind();
|
||||
if (kind != UriResourceKind.primitiveProperty
|
||||
&& kind != UriResourceKind.complexProperty
|
||||
&& kind != UriResourceKind.count
|
||||
&& kind != UriResourceKind.value) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,60 +18,29 @@
|
|||
*/
|
||||
package org.apache.olingo.server.tecsvc.processor;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
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.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
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.HttpContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntitySetProcessor;
|
||||
import org.apache.olingo.server.api.processor.PropertyProcessor;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
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.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
|
||||
/**
|
||||
* Technical Processor which provides currently implemented processor functionality.
|
||||
* Technical Processor base.
|
||||
*/
|
||||
public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor {
|
||||
public abstract class TechnicalProcessor implements Processor {
|
||||
|
||||
private OData odata;
|
||||
private DataProvider dataProvider;
|
||||
protected OData odata;
|
||||
protected DataProvider dataProvider;
|
||||
|
||||
public TechnicalProcessor(final DataProvider dataProvider) {
|
||||
protected TechnicalProcessor(final DataProvider dataProvider) {
|
||||
this.dataProvider = dataProvider;
|
||||
}
|
||||
|
||||
|
@ -80,92 +49,23 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
|
|||
this.odata = odata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
|
||||
uriInfo.getCountOption() != null && uriInfo.getCountOption().getValue());
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, false, expand, select, null, null))
|
||||
.count(uriInfo.getCountOption())
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
protected EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
// first must be entity set
|
||||
if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, expand, select, null, null))
|
||||
.count(uriInfo.getCountOption())
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
|
||||
if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) {
|
||||
throw new ODataApplicationException("Type filters are not supported.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
return uriResource.getEntitySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
|
||||
final int pos = resourceParts.size() - 2;
|
||||
final EntitySet entitySet =
|
||||
readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
response.setContent(new ByteArrayInputStream(entitySet.getCount().toString().getBytes()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, HttpContentType.TEXT_PLAIN);
|
||||
}
|
||||
}
|
||||
|
||||
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet,
|
||||
final boolean withCount) throws DataProvider.DataProviderException {
|
||||
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
|
||||
// TODO: set count (correctly) and next link
|
||||
if (withCount && entitySet.getCount() == null) {
|
||||
entitySet.setCount(entitySet.getEntities().size());
|
||||
}
|
||||
return entitySet;
|
||||
}
|
||||
|
||||
private Entity readEntityInternal(final UriInfoResource uriInfo, final EdmEntitySet entitySet)
|
||||
throws DataProvider.DataProviderException {
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
|
||||
return dataProvider.read(entitySet, resourceEntitySet.getKeyPredicates());
|
||||
}
|
||||
|
||||
private void validateOptions(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
protected void validateOptions(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
if (uriInfo.getCountOption() != null
|
||||
|| !uriInfo.getCustomQueryOptions().isEmpty()
|
||||
|| uriInfo.getFilterOption() != null
|
||||
|
@ -179,151 +79,4 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
|
|||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
private EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
// first must be entity set
|
||||
if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
List<UriResource> subResPaths = resourcePaths.subList(1, resourcePaths.size());
|
||||
for (UriResource subResPath : subResPaths) {
|
||||
UriResourceKind kind = subResPath.getKind();
|
||||
if(kind != UriResourceKind.primitiveProperty
|
||||
&& kind != UriResourceKind.complexProperty
|
||||
&& kind != UriResourceKind.count
|
||||
&& kind != UriResourceKind.value) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
|
||||
if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) {
|
||||
throw new ODataApplicationException("Type filters are not supported.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
return uriResource.getEntitySet();
|
||||
}
|
||||
|
||||
private ContextURL getContextUrl(final ODataSerializer serializer,
|
||||
final EdmEntitySet entitySet, final boolean isSingleEntity,
|
||||
final ExpandOption expand, final SelectOption select,
|
||||
final List<UriParameter> keys, final String propertyPath) throws SerializerException {
|
||||
return ContextURL.with().entitySet(entitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
|
||||
.suffix(isSingleEntity && propertyPath == null ? Suffix.ENTITY : null)
|
||||
.keyPath(serializer.buildContextURLKeyPredicate(keys))
|
||||
.navOrPropertyPath(propertyPath)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final List<UriResource> resourceParts = uriInfo.getUriResourceParts();
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
|
||||
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
|
||||
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final List<String> path = getPropertyPath(resourceParts);
|
||||
EdmProperty edmProperty = edmEntitySet.getEntityType().getStructuralProperty(path.get(0));
|
||||
Property property = entity.getProperty(path.get(0));
|
||||
for (final String name : path.subList(1, path.size())) {
|
||||
if (property != null && (property.isLinkedComplex() || property.isComplex())) {
|
||||
edmProperty = ((EdmComplexType) edmProperty.getType()).getStructuralProperty(name);
|
||||
final List<Property> complex = property.isLinkedComplex() ?
|
||||
property.asLinkedComplex().getValue() :
|
||||
property.asComplex();
|
||||
property = null;
|
||||
for (final Property innerProperty : complex) {
|
||||
if (innerProperty.getName().equals(name)) {
|
||||
property = innerProperty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (property == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
if (property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(contentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
response.setContent(serializer.entityProperty(edmProperty, property,
|
||||
ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, null, null,
|
||||
resourceEntitySet.getKeyPredicates(), buildPropertyPath(path)))
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getPropertyPath(final List<UriResource> path) {
|
||||
List<String> result = new LinkedList<String>();
|
||||
int index = path.size();
|
||||
while (path.get(--index) instanceof UriResourceProperty) {
|
||||
result.add(0, ((UriResourceProperty) path.get(index)).getProperty().getName());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String buildPropertyPath(final List<String> path) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (final String segment : path) {
|
||||
result.append(result.length() == 0 ? "" : '/').append(segment);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPropertyValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final UriResourceProperty uriProperty =
|
||||
(UriResourceProperty) uriInfo.getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 2);
|
||||
final EdmProperty edmProperty = uriProperty.getProperty();
|
||||
final Property property = entity.getProperty(edmProperty.getName());
|
||||
if (property == null || property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
|
||||
if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)) {
|
||||
response.setContent(new ByteArrayInputStream((byte[]) property.getValue()));
|
||||
} else {
|
||||
try {
|
||||
final String value = type.valueToString(property.getValue(),
|
||||
edmProperty.isNullable(), edmProperty.getMaxLength(),
|
||||
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
|
||||
response.setContent(new ByteArrayInputStream(value.getBytes("UTF-8")));
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new ODataApplicationException("Error in value formatting.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
throw new ODataApplicationException("Encoding exception.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
|
||||
}
|
||||
}
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.ODataException;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.edm.provider.EdmProvider;
|
||||
import org.apache.olingo.server.api.edm.provider.EntitySet;
|
||||
import org.apache.olingo.server.api.edmx.EdmxReference;
|
||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ODataHandlerExceptionHandlingTest {
|
||||
private ODataHandler handler;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
OData odata = OData.newInstance();
|
||||
ServiceMetadata metadata = odata.createServiceMetadata(
|
||||
new EdmTechProvider(), Collections.<EdmxReference>emptyList());
|
||||
|
||||
handler = new ODataHandler(odata, metadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongHttpMethodForMetadataDocument() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.POST);
|
||||
request.setRawODataPath("$metadata");
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.PUT);
|
||||
request.setRawODataPath("$metadata");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.PATCH);
|
||||
request.setRawODataPath("$metadata");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.MERGE);
|
||||
request.setRawODataPath("$metadata");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.DELETE);
|
||||
request.setRawODataPath("$metadata");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongHttpMethodForServiceDocument() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.POST);
|
||||
request.setRawODataPath("");
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.PUT);
|
||||
request.setRawODataPath("");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.PATCH);
|
||||
request.setRawODataPath("");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.MERGE);
|
||||
request.setRawODataPath("");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.DELETE);
|
||||
request.setRawODataPath("");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriParserExceptionResultsInRightResponseNotFound() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("NotFound");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriParserExceptionResultsInRightResponseBadRequest() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim('122')");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriParserExceptionResultsInRightResponseEdmCause() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("EdmException");
|
||||
|
||||
OData odata = OData.newInstance();
|
||||
ServiceMetadata serviceMetadata = odata.createServiceMetadata(new EdmProvider() {
|
||||
public EntitySet getEntitySet(final FullQualifiedName entityContainer, final String entitySetName)
|
||||
throws ODataException {
|
||||
throw new ODataException("msg");
|
||||
}
|
||||
}, Collections.<EdmxReference>emptyList());
|
||||
|
||||
ODataHandler localHandler = new ODataHandler(odata, serviceMetadata);
|
||||
|
||||
ODataResponse response = localHandler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithApplicationExceptionInProcessor() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
|
||||
MetadataProcessor metadataProcessor = mock(MetadataProcessor.class);
|
||||
doThrow(new ODataApplicationException("msg", 425, Locale.ENGLISH)).when(metadataProcessor).readMetadata(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
|
||||
handler.register(metadataProcessor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(425, response.getStatusCode());
|
||||
}
|
||||
}
|
|
@ -18,15 +18,21 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.commons.api.ODataException;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpContentType;
|
||||
|
@ -34,311 +40,305 @@ import org.apache.olingo.commons.api.http.HttpHeader;
|
|||
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.edm.provider.EdmProvider;
|
||||
import org.apache.olingo.server.api.edm.provider.EntitySet;
|
||||
import org.apache.olingo.server.api.edmx.EdmxReference;
|
||||
import org.apache.olingo.server.api.processor.EntitySetProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexTypeProcessor;
|
||||
import org.apache.olingo.server.api.processor.CountEntityTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityTypeProcessor;
|
||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||
import org.apache.olingo.server.api.processor.PropertyProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveTypeCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveTypeProcessor;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class ODataHandlerTest {
|
||||
|
||||
private ODataHandler handler;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
OData odata = OData.newInstance();
|
||||
ServiceMetadata metadata = odata.createServiceMetadata(
|
||||
new EdmTechProvider(), Collections.<EdmxReference>emptyList());
|
||||
|
||||
handler = new ODataHandler(odata, metadata);
|
||||
}
|
||||
private static final String BASE_URI = "http://localhost/odata";
|
||||
|
||||
@Test
|
||||
public void testServiceDocumentNonDefault() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawBaseUri("http://localhost/odata");
|
||||
request.setRawODataPath("/");
|
||||
|
||||
ServiceDocumentProcessor processor = mock(ServiceDocumentProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void serviceDocumentNonDefault() throws Exception {
|
||||
final ServiceDocumentProcessor processor = mock(ServiceDocumentProcessor.class);
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "/", processor);
|
||||
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
|
||||
|
||||
verify(processor).readServiceDocument(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
|
||||
dispatchMethodNotAllowed(HttpMethod.POST, "/", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.PUT, "/", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.PATCH, "/", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.MERGE, "/", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.DELETE, "/", processor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceDocumentDefault() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawBaseUri("http://localhost/odata");
|
||||
request.setRawODataPath("/");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void serviceDocumentDefault() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "/", null);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
String ct = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
|
||||
assertTrue(ct.contains("application/json"));
|
||||
assertTrue(ct.contains("odata.metadata=minimal"));
|
||||
assertThat(ct, containsString("application/json"));
|
||||
assertThat(ct, containsString("odata.metadata=minimal"));
|
||||
|
||||
assertNotNull(response.getContent());
|
||||
String doc = IOUtils.toString(response.getContent());
|
||||
|
||||
assertTrue(doc.contains("\"@odata.context\" : \"http://localhost/odata/$metadata\""));
|
||||
assertTrue(doc.contains("\"value\" :"));
|
||||
assertThat(doc, containsString("\"@odata.context\" : \"" + BASE_URI + "/$metadata\""));
|
||||
assertThat(doc, containsString("\"value\" :"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceDocumentRedirect() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawBaseUri("http://localhost/odata");
|
||||
request.setRawRequestUri("http://localhost/odata");
|
||||
request.setRawODataPath("");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void serviceDocumentRedirect() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "", null);
|
||||
assertEquals(HttpStatusCode.TEMPORARY_REDIRECT.getStatusCode(), response.getStatusCode());
|
||||
assertEquals("http://localhost/odata/", response.getHeaders().get(HttpHeader.LOCATION));
|
||||
assertEquals(BASE_URI + "/", response.getHeaders().get(HttpHeader.LOCATION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadataNonDefault() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
|
||||
MetadataProcessor processor = mock(MetadataProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void metadataNonDefault() throws Exception {
|
||||
final MetadataProcessor processor = mock(MetadataProcessor.class);
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", processor);
|
||||
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
|
||||
|
||||
verify(processor).readMetadata(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
|
||||
dispatchMethodNotAllowed(HttpMethod.POST, "$metadata", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.PUT, "$metadata", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.PATCH, "$metadata", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.MERGE, "$metadata", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.DELETE, "$metadata", processor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadataDefault() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void metadataDefault() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
assertEquals(HttpContentType.APPLICATION_XML, response.getHeaders().get(HttpHeader.CONTENT_TYPE));
|
||||
|
||||
assertNotNull(response.getContent());
|
||||
String doc = IOUtils.toString(response.getContent());
|
||||
|
||||
assertTrue(doc.contains("<edmx:Edmx Version=\"4.0\""));
|
||||
assertThat(IOUtils.toString(response.getContent()),
|
||||
containsString("<edmx:Edmx Version=\"4.0\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxVersionNone() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
public void maxVersionNone() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null);
|
||||
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxVersionSupported() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.addHeader(HttpHeader.ODATA_MAX_VERSION, Arrays.asList(ODataServiceVersion.V40.toString()));
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
public void maxVersionSupported() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null,
|
||||
HttpHeader.ODATA_MAX_VERSION, ODataServiceVersion.V40.toString(), null);
|
||||
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxVersionNotSupported() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.addHeader(HttpHeader.ODATA_MAX_VERSION, Arrays.asList(ODataServiceVersion.V30.toString()));
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void maxVersionNotSupported() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null,
|
||||
HttpHeader.ODATA_MAX_VERSION, ODataServiceVersion.V30.toString(), null);
|
||||
|
||||
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentNegotiationSupported() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.setRawQueryPath("$format=xml");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void contentNegotiationSupported() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=xml", null, null, null);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentNegotiationNotSupported() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.setRawQueryPath("$format=not/Supported");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void contentNegotiationNotSupported() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=not/Supported", null, null, null);
|
||||
assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentNegotiationNotSupported2() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.setRawQueryPath("$format=notSupported");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void contentNegotiationNotSupported2() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=notSupported", null, null, null);
|
||||
assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnregisteredProcessor() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void unregisteredProcessor() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "ESAllPrim", null);
|
||||
assertEquals(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCount() throws Exception {
|
||||
public void uriParserExceptionResultsInRightResponseNotFound() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "NotFound", null);
|
||||
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriParserExceptionResultsInRightResponseBadRequest() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "ESAllPrim('122')", null);
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applicationExceptionInProcessor() throws Exception {
|
||||
MetadataProcessor processor = mock(MetadataProcessor.class);
|
||||
doThrow(new ODataApplicationException("msg", 425, Locale.ENGLISH)).when(processor).readMetadata(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", processor);
|
||||
assertEquals(425, response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriParserExceptionResultsInRightResponseEdmCause() throws Exception {
|
||||
final OData odata = OData.newInstance();
|
||||
final ServiceMetadata serviceMetadata = odata.createServiceMetadata(
|
||||
new EdmProvider() {
|
||||
public EntitySet getEntitySet(final FullQualifiedName entityContainer, final String entitySetName)
|
||||
throws ODataException {
|
||||
throw new ODataException("msg");
|
||||
}
|
||||
},
|
||||
Collections.<EdmxReference> emptyList());
|
||||
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim/$count");
|
||||
request.setRawODataPath("EdmException");
|
||||
|
||||
EntitySetProcessor processor = mock(EntitySetProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
final ODataResponse response = new ODataHandler(odata, serviceMetadata).process(request);
|
||||
assertNotNull(response);
|
||||
Mockito.verify(processor).countEntitySet(
|
||||
Mockito.eq(request),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class));
|
||||
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchEntitySet() throws Exception {
|
||||
final EntityTypeCollectionProcessor processor = mock(EntityTypeCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim", processor);
|
||||
|
||||
verify(processor).readEntityTypeCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchEntitySetCount() throws Exception {
|
||||
final CountEntityTypeCollectionProcessor processor = mock(CountEntityTypeCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim/$count", processor);
|
||||
|
||||
verify(processor).countEntityTypeCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
|
||||
|
||||
dispatchMethodNotAllowed(HttpMethod.POST, "ESAllPrim/$count", processor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchCountWithNavigation() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
final CountEntityTypeCollectionProcessor processor = mock(CountEntityTypeCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim(0)/NavPropertyETTwoPrimMany/$count", processor);
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim(0)/NavPropertyETTwoPrimMany/$count");
|
||||
|
||||
EntitySetProcessor processor = mock(EntitySetProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
Mockito.verify(processor).countEntitySet(
|
||||
Mockito.eq(request),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class));
|
||||
verify(processor).countEntityTypeCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchAddressPrimitiveProperty() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
public void dispatchEntity() throws Exception {
|
||||
final EntityTypeProcessor processor = mock(EntityTypeProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim(0)", processor);
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim(0)/PropertyInt16");
|
||||
|
||||
PropertyProcessor processor = mock(PropertyProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
Mockito.verify(processor).readProperty(
|
||||
Mockito.any(ODataRequest.class),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class),
|
||||
Mockito.any(ContentType.class));
|
||||
verify(processor).readEntityType(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchAddressPrimitivePropertyValue() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
public void dispatchPrimitiveProperty() throws Exception {
|
||||
final PrimitiveTypeProcessor processor = mock(PrimitiveTypeProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim(0)/PropertyInt16", processor);
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim(0)/PropertyInt16/$value");
|
||||
|
||||
PropertyProcessor processor = mock(PropertyProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
Mockito.verify(processor).readPropertyValue(
|
||||
Mockito.any(ODataRequest.class),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class),
|
||||
Mockito.any(ContentType.class));
|
||||
verify(processor).readPrimitiveType(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchAddressComplexProperty() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
public void dispatchPrimitivePropertyValue() throws Exception {
|
||||
final PrimitiveTypeProcessor processor = mock(PrimitiveTypeProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim(0)/PropertyInt16/$value", processor);
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESMixPrimCollComp(7)/PropertyComp");
|
||||
|
||||
PropertyProcessor processor = mock(PropertyProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
Mockito.verify(processor).readProperty(
|
||||
Mockito.any(ODataRequest.class),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class),
|
||||
Mockito.any(ContentType.class));
|
||||
verify(processor).readPrimitiveTypeAsValue(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchPrimitiveCollectionProperty() throws Exception {
|
||||
final PrimitiveTypeCollectionProcessor processor = mock(PrimitiveTypeCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/CollPropertyString", processor);
|
||||
|
||||
verify(processor).readPrimitiveTypeCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchComplexProperty() throws Exception {
|
||||
final ComplexTypeProcessor processor = mock(ComplexTypeProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/PropertyComp", processor);
|
||||
|
||||
verify(processor).readComplexType(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchComplexCollectionProperty() throws Exception {
|
||||
final ComplexTypeCollectionProcessor processor = mock(ComplexTypeCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/CollPropertyComp", processor);
|
||||
|
||||
verify(processor).readComplexTypeCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
private ODataResponse dispatch(final HttpMethod method, final String path, final String query,
|
||||
final String headerName, final String headerValue, final Processor processor) {
|
||||
ODataRequest request = new ODataRequest();
|
||||
request.setMethod(method);
|
||||
request.setRawBaseUri(BASE_URI);
|
||||
if (path.isEmpty()) {
|
||||
request.setRawRequestUri(BASE_URI);
|
||||
}
|
||||
request.setRawODataPath(path);
|
||||
request.setRawQueryPath(query);
|
||||
|
||||
if (headerName != null) {
|
||||
request.addHeader(headerName, Collections.singletonList(headerValue));
|
||||
}
|
||||
|
||||
final OData odata = OData.newInstance();
|
||||
final ServiceMetadata metadata = odata.createServiceMetadata(
|
||||
new EdmTechProvider(), Collections.<EdmxReference> emptyList());
|
||||
|
||||
ODataHandler handler = new ODataHandler(odata, metadata);
|
||||
|
||||
if (processor != null) {
|
||||
handler.register(processor);
|
||||
}
|
||||
|
||||
final ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private ODataResponse dispatch(final HttpMethod method, final String path, final Processor processor) {
|
||||
return dispatch(method, path, null, null, null, processor);
|
||||
}
|
||||
|
||||
private void dispatchMethodNotAllowed(final HttpMethod method, final String path, final Processor processor) {
|
||||
final ODataResponse response = dispatch(method, path, processor);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue