[OLINGO-328] refactor content negotiation
This commit is contained in:
parent
0ffc26d1b2
commit
acc12ff742
|
@ -46,6 +46,11 @@
|
||||||
<version>2.5</version>
|
<version>2.5</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.api;
|
package org.apache.olingo.server.api;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class ODataRequest {
|
||||||
String key = name.toUpperCase();
|
String key = name.toUpperCase();
|
||||||
if (headers.containsKey(key)) {
|
if (headers.containsKey(key)) {
|
||||||
List<String> oldValues = headers.get(key);
|
List<String> oldValues = headers.get(key);
|
||||||
|
|
||||||
List<String> newValues = new ArrayList<String>();
|
List<String> newValues = new ArrayList<String>();
|
||||||
newValues.addAll(oldValues);
|
newValues.addAll(oldValues);
|
||||||
newValues.addAll(values);
|
newValues.addAll(values);
|
||||||
|
|
|
@ -20,8 +20,9 @@ package org.apache.olingo.server.api.processor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface SupportCustomContentTypes {
|
public interface CustomContentTypeSupport {
|
||||||
|
|
||||||
|
public List<FormatContentTypeMapping> modifySupportedContentTypes(
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes, Class<? extends Processor> processorClass);
|
||||||
|
|
||||||
public List<String> getSupportedContentTypes(Class<? extends Processor> processorClass);
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,8 +19,6 @@
|
||||||
package org.apache.olingo.server.api.processor;
|
package org.apache.olingo.server.api.processor;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.edm.Edm;
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||||
|
@ -33,7 +31,7 @@ import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||||
import org.apache.olingo.server.api.uri.UriInfo;
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
|
|
||||||
public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProcessor {
|
public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProcessor {
|
||||||
|
|
||||||
private OData odata;
|
private OData odata;
|
||||||
private Edm edm;
|
private Edm edm;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
public class FormatContentTypeMapping {
|
||||||
|
|
||||||
|
private String formatAlias;
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
|
public FormatContentTypeMapping(String formatAlias, String contentType) {
|
||||||
|
super();
|
||||||
|
this.formatAlias = formatAlias;
|
||||||
|
this.contentType = contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormatAlias() {
|
||||||
|
return formatAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentType() {
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFormatAlias(String formatAlias) {
|
||||||
|
this.formatAlias = formatAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentType(String contentType) {
|
||||||
|
this.contentType = contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "('" + formatAlias + "', '" + contentType + "')";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ import org.apache.olingo.server.api.ODataRequest;
|
||||||
import org.apache.olingo.server.api.ODataResponse;
|
import org.apache.olingo.server.api.ODataResponse;
|
||||||
import org.apache.olingo.server.api.uri.UriInfo;
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
|
|
||||||
public interface MetadataProcessor extends Processor{
|
public interface MetadataProcessor extends Processor {
|
||||||
|
|
||||||
void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format);
|
void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.api.processor;
|
package org.apache.olingo.server.api.processor;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.edm.Edm;
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.server.api.OData;
|
import org.apache.olingo.server.api.OData;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* 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 java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.format.ContentType;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpContentType;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||||
|
import org.apache.olingo.server.api.ODataRequest;
|
||||||
|
import org.apache.olingo.server.api.processor.CustomContentTypeSupport;
|
||||||
|
import org.apache.olingo.server.api.processor.FormatContentTypeMapping;
|
||||||
|
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||||
|
import org.apache.olingo.server.api.processor.Processor;
|
||||||
|
import org.apache.olingo.server.api.uri.queryoption.FormatOption;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ContentNegotiator {
|
||||||
|
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(ContentNegotiator.class);
|
||||||
|
|
||||||
|
private List<FormatContentTypeMapping> getDefaultSupportedContentTypes(Class<? extends Processor> processorClass) {
|
||||||
|
List<FormatContentTypeMapping> defaults = new ArrayList<FormatContentTypeMapping>();
|
||||||
|
|
||||||
|
if (processorClass == MetadataProcessor.class) {
|
||||||
|
defaults.add(new FormatContentTypeMapping("xml", ContentType.APPLICATION_XML.toContentTypeString()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
defaults.add(new FormatContentTypeMapping("json", ContentType.APPLICATION_JSON.toContentTypeString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FormatContentTypeMapping> getSupportedContentTypes(Processor processor,
|
||||||
|
Class<? extends Processor> processorClass) {
|
||||||
|
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes = getDefaultSupportedContentTypes(processorClass);
|
||||||
|
|
||||||
|
if (processor instanceof CustomContentTypeSupport) {
|
||||||
|
supportedContentTypes =
|
||||||
|
((CustomContentTypeSupport) processor).modifySupportedContentTypes(supportedContentTypes, processorClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return supportedContentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String doContentNegotiation(FormatOption formatOption, ODataRequest request,
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes) {
|
||||||
|
String requestedContentType = null;
|
||||||
|
|
||||||
|
List<String> acceptHeaderValues = request.getHeader(HttpHeader.ACCEPT);
|
||||||
|
|
||||||
|
boolean supported = false;
|
||||||
|
|
||||||
|
if (formatOption != null) {
|
||||||
|
|
||||||
|
if ("json".equalsIgnoreCase(formatOption.getText())) {
|
||||||
|
requestedContentType = HttpContentType.APPLICATION_JSON;
|
||||||
|
for (FormatContentTypeMapping entry : supportedContentTypes) {
|
||||||
|
if (requestedContentType.equalsIgnoreCase(entry.getContentType())){
|
||||||
|
supported = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
requestedContentType = formatOption.getText();
|
||||||
|
for (FormatContentTypeMapping entry : supportedContentTypes) {
|
||||||
|
if (requestedContentType.equalsIgnoreCase(entry.getFormatAlias())){
|
||||||
|
supported = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (acceptHeaderValues != null) {
|
||||||
|
List<String> acceptedContentTypes = new ArrayList<String>();
|
||||||
|
|
||||||
|
// for (String acceptHeaderValue : acceptHeaderValues) {
|
||||||
|
// acceptedContentTypes.addAll(parseAcceptHeader(acceptHeaderValue));
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (String acceptedContentType : acceptedContentTypes) {
|
||||||
|
// if (isContentTypeSupported(acceptedContentType, supportedContentTypes)) {
|
||||||
|
// requestedContentType = acceptedContentType;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestedContentType == null) {
|
||||||
|
throw new RuntimeException("unsupported accept content type: " + acceptedContentTypes + " != "
|
||||||
|
+ supportedContentTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestedContentType = null;
|
||||||
|
} else {
|
||||||
|
requestedContentType = HttpContentType.APPLICATION_JSON;
|
||||||
|
for (FormatContentTypeMapping entry : supportedContentTypes) {
|
||||||
|
if (requestedContentType.equalsIgnoreCase(entry.getContentType())){
|
||||||
|
supported = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!supported) {
|
||||||
|
throw new RuntimeException("unsupported accept content type: " + requestedContentType + " != "
|
||||||
|
+ supportedContentTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("requested content type: " + requestedContentType);
|
||||||
|
|
||||||
|
return requestedContentType;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core;
|
package org.apache.olingo.server.core;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -25,6 +29,8 @@ import java.util.Map;
|
||||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.commons.api.edm.Edm;
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||||
|
import org.apache.olingo.commons.api.format.AcceptType;
|
||||||
|
import org.apache.olingo.commons.api.format.ContentType;
|
||||||
import org.apache.olingo.commons.api.http.HttpContentType;
|
import org.apache.olingo.commons.api.http.HttpContentType;
|
||||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||||
|
@ -32,20 +38,27 @@ import org.apache.olingo.server.api.OData;
|
||||||
import org.apache.olingo.server.api.ODataRequest;
|
import org.apache.olingo.server.api.ODataRequest;
|
||||||
import org.apache.olingo.server.api.ODataResponse;
|
import org.apache.olingo.server.api.ODataResponse;
|
||||||
import org.apache.olingo.server.api.processor.CollectionProcessor;
|
import org.apache.olingo.server.api.processor.CollectionProcessor;
|
||||||
|
import org.apache.olingo.server.api.processor.FormatContentTypeMapping;
|
||||||
import org.apache.olingo.server.api.processor.DefaultProcessor;
|
import org.apache.olingo.server.api.processor.DefaultProcessor;
|
||||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||||
import org.apache.olingo.server.api.processor.Processor;
|
import org.apache.olingo.server.api.processor.Processor;
|
||||||
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
||||||
|
import org.apache.olingo.server.api.processor.CustomContentTypeSupport;
|
||||||
import org.apache.olingo.server.api.uri.UriInfo;
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
import org.apache.olingo.server.api.uri.UriResource;
|
import org.apache.olingo.server.api.uri.UriResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||||
|
import org.apache.olingo.server.api.uri.queryoption.FormatOption;
|
||||||
import org.apache.olingo.server.core.uri.parser.Parser;
|
import org.apache.olingo.server.core.uri.parser.Parser;
|
||||||
import org.apache.olingo.server.core.uri.validator.UriValidator;
|
import org.apache.olingo.server.core.uri.validator.UriValidator;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class ODataHandler {
|
public class ODataHandler {
|
||||||
|
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(ODataHandler.class);
|
||||||
|
|
||||||
private final OData odata;
|
private final OData odata;
|
||||||
private final Edm edm;
|
private final Edm edm;
|
||||||
private Map<Class<? extends Processor>, Processor> processors = new HashMap<Class<? extends Processor>, Processor>();
|
private Map<Class<? extends Processor>, Processor> processors = new HashMap<Class<? extends Processor>, Processor>();
|
||||||
|
@ -72,12 +85,17 @@ public class ODataHandler {
|
||||||
UriValidator validator = new UriValidator();
|
UriValidator validator = new UriValidator();
|
||||||
validator.validate(uriInfo, request.getMethod());
|
validator.validate(uriInfo, request.getMethod());
|
||||||
|
|
||||||
String requestedContentType = doContentNegotiation();
|
String requestedContentType = null;
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes = null;
|
||||||
|
|
||||||
switch (uriInfo.getKind()) {
|
switch (uriInfo.getKind()) {
|
||||||
case metadata:
|
case metadata:
|
||||||
MetadataProcessor mp = selectProcessor(MetadataProcessor.class);
|
MetadataProcessor mp = selectProcessor(MetadataProcessor.class);
|
||||||
mp.readMetadata(request, response, uriInfo, HttpContentType.APPLICATION_XML);
|
|
||||||
|
/* TODO content negotiation */
|
||||||
|
requestedContentType = ContentType.APPLICATION_XML.toContentTypeString();
|
||||||
|
|
||||||
|
mp.readMetadata(request, response, uriInfo, requestedContentType);
|
||||||
break;
|
break;
|
||||||
case service:
|
case service:
|
||||||
if ("".equals(request.getRawODataPath())) {
|
if ("".equals(request.getRawODataPath())) {
|
||||||
|
@ -85,11 +103,15 @@ public class ODataHandler {
|
||||||
rdp.redirect(request, response);
|
rdp.redirect(request, response);
|
||||||
} else {
|
} else {
|
||||||
ServiceDocumentProcessor sdp = selectProcessor(ServiceDocumentProcessor.class);
|
ServiceDocumentProcessor sdp = selectProcessor(ServiceDocumentProcessor.class);
|
||||||
|
|
||||||
|
/* TODO content negotiation */
|
||||||
|
requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
|
||||||
|
|
||||||
sdp.readServiceDocument(request, response, uriInfo, requestedContentType);
|
sdp.readServiceDocument(request, response, uriInfo, requestedContentType);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case resource:
|
case resource:
|
||||||
handleResourceDispatching(request, response, uriInfo, requestedContentType);
|
handleResourceDispatching(request, response, uriInfo);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ODataRuntimeException("not implemented");
|
throw new ODataRuntimeException("not implemented");
|
||||||
|
@ -102,27 +124,32 @@ public class ODataHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String doContentNegotiation() {
|
private void handleResourceDispatching(final ODataRequest request, ODataResponse response, UriInfo uriInfo) {
|
||||||
// TODO: Content Negotiation
|
|
||||||
return HttpContentType.APPLICATION_JSON;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleResourceDispatching(final ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
|
||||||
String requestedContentType) {
|
|
||||||
int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
|
int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
|
||||||
UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
|
UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
|
||||||
|
String requestedContentType = null;
|
||||||
|
List<String> supportedContentTypes = null;
|
||||||
|
|
||||||
switch (lastPathSegment.getKind()) {
|
switch (lastPathSegment.getKind()) {
|
||||||
case entitySet:
|
case entitySet:
|
||||||
if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
|
if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
|
||||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||||
CollectionProcessor esp = selectProcessor(CollectionProcessor.class);
|
CollectionProcessor cp = selectProcessor(CollectionProcessor.class);
|
||||||
esp.readCollection(request, response, uriInfo, requestedContentType);
|
|
||||||
|
/* TODO content negotiation */
|
||||||
|
requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
|
||||||
|
|
||||||
|
cp.readCollection(request, response, uriInfo, requestedContentType);
|
||||||
} else {
|
} else {
|
||||||
throw new ODataRuntimeException("not implemented");
|
throw new ODataRuntimeException("not implemented");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||||
EntityProcessor ep = selectProcessor(EntityProcessor.class);
|
EntityProcessor ep = selectProcessor(EntityProcessor.class);
|
||||||
|
|
||||||
|
/* TODO content negotiation */
|
||||||
|
requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
|
||||||
|
|
||||||
ep.readEntity(request, response, uriInfo, requestedContentType);
|
ep.readEntity(request, response, uriInfo, requestedContentType);
|
||||||
} else {
|
} else {
|
||||||
throw new ODataRuntimeException("not implemented");
|
throw new ODataRuntimeException("not implemented");
|
||||||
|
@ -132,14 +159,22 @@ public class ODataHandler {
|
||||||
case navigationProperty:
|
case navigationProperty:
|
||||||
if (((UriResourceNavigation) lastPathSegment).isCollection()) {
|
if (((UriResourceNavigation) lastPathSegment).isCollection()) {
|
||||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||||
CollectionProcessor esp = selectProcessor(CollectionProcessor.class);
|
CollectionProcessor cp = selectProcessor(CollectionProcessor.class);
|
||||||
esp.readCollection(request, response, uriInfo, requestedContentType);
|
|
||||||
|
/* TODO content negotiation */
|
||||||
|
requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
|
||||||
|
|
||||||
|
cp.readCollection(request, response, uriInfo, requestedContentType);
|
||||||
} else {
|
} else {
|
||||||
throw new ODataRuntimeException("not implemented");
|
throw new ODataRuntimeException("not implemented");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||||
EntityProcessor ep = selectProcessor(EntityProcessor.class);
|
EntityProcessor ep = selectProcessor(EntityProcessor.class);
|
||||||
|
|
||||||
|
/* TODO content negotiation */
|
||||||
|
requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
|
||||||
|
|
||||||
ep.readEntity(request, response, uriInfo, requestedContentType);
|
ep.readEntity(request, response, uriInfo, requestedContentType);
|
||||||
} else {
|
} else {
|
||||||
throw new ODataRuntimeException("not implemented");
|
throw new ODataRuntimeException("not implemented");
|
||||||
|
|
|
@ -182,7 +182,7 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
|
||||||
odRequest.setRawServiceResolutionUri(rawServiceResolutionUri);
|
odRequest.setRawServiceResolutionUri(rawServiceResolutionUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void extractHeaders(ODataRequest odRequest, final HttpServletRequest req) {
|
static void extractHeaders(ODataRequest odRequest, final HttpServletRequest req) {
|
||||||
for (Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
|
for (Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
|
||||||
String headerName = (String) headerNames.nextElement();
|
String headerName = (String) headerNames.nextElement();
|
||||||
List<String> headerValues = new ArrayList<String>();
|
List<String> headerValues = new ArrayList<String>();
|
||||||
|
|
|
@ -0,0 +1,327 @@
|
||||||
|
/*
|
||||||
|
* 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.mockito.Mockito.*;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||||
|
import org.apache.olingo.server.api.OData;
|
||||||
|
import org.apache.olingo.server.api.ODataRequest;
|
||||||
|
import org.apache.olingo.server.api.ODataResponse;
|
||||||
|
import org.apache.olingo.server.api.processor.CollectionProcessor;
|
||||||
|
import org.apache.olingo.server.api.processor.CustomContentTypeSupport;
|
||||||
|
import org.apache.olingo.server.api.processor.FormatContentTypeMapping;
|
||||||
|
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||||
|
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.api.uri.queryoption.FormatOption;
|
||||||
|
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ContentNegotiatorTest {
|
||||||
|
|
||||||
|
static final private String ACCEPT_CASE_JSON = "application/json;odata=verbose;q=0.2";
|
||||||
|
static final private String ACCEPT_CASE_XML = "application/xml";
|
||||||
|
static final private String ACCEPT_CASE_TEXT = "text/plain;q=0.5";
|
||||||
|
static final private String ACCEPT_CASE_MULTI = "text/plain;q=0.5,application/aaa;q=0.4";
|
||||||
|
|
||||||
|
//@formatter:off (Eclipse formatter)
|
||||||
|
//CHECKSTYLE:OFF (Maven checkstyle)
|
||||||
|
|
||||||
|
String[][] casesServiceDocument = {
|
||||||
|
/* expected $format accept alias ct mapping */
|
||||||
|
{ "application/json", null, null, null ,null },
|
||||||
|
{ "application/json", "json", null, null ,null },
|
||||||
|
{ "application/json", "json", "application/json", null ,null },
|
||||||
|
{ "a", "a", null, "a" ,"a/a" },
|
||||||
|
|
||||||
|
// { "application/json", null, "application/json", null ,null },
|
||||||
|
// { "application/json", null, ACCEPT_CASE_JSON, null ,null },
|
||||||
|
// { "application/json", null, "*/*", null ,null },
|
||||||
|
// { "a/a", "a", null, "a, b" ,"a/a,b/b" },
|
||||||
|
// { "a", null, "*/*", "a, b" ,null },
|
||||||
|
// { "a", "a", "*/*", "a, b" ,null },
|
||||||
|
};
|
||||||
|
|
||||||
|
String[][] casesMetadata = {
|
||||||
|
/* expected $format accept alias ct mapping */
|
||||||
|
{ "application/xml", null, null, null ,null },
|
||||||
|
{ "application/xml", "xml", null, null ,null },
|
||||||
|
{ "application/xml", null, "application/xml", null ,null },
|
||||||
|
{ "application/xml", "xml", "application/xml", null ,null },
|
||||||
|
{ "application/xml", null, ACCEPT_CASE_XML, null ,null },
|
||||||
|
{ "application/xml", null, "*/*", null ,null },
|
||||||
|
{ "a", "a", null, "a, b" ,null },
|
||||||
|
{ "a", "a", null, "a, b" ,null },
|
||||||
|
{ "a", null, "*/*", "a, b" ,null },
|
||||||
|
{ "a", "a", "*/*", "a, b" ,null },
|
||||||
|
};
|
||||||
|
|
||||||
|
// String[][] casesEntitySet = {
|
||||||
|
// /* expected $format accept supported $formatmapping */
|
||||||
|
// { "application/json", null, null, null ,null },
|
||||||
|
// { "application/json", "json", null, null ,null },
|
||||||
|
// { "application/json", "json", "application/json", null ,null },
|
||||||
|
// { "application/json", null, "application/json", null ,null },
|
||||||
|
// { "application/json", null, ACCEPT_CASE_JSON, null ,null },
|
||||||
|
// { "application/json", null, "*/*", null ,null },
|
||||||
|
// { "a", "a", null, "a, b" ,null },
|
||||||
|
// { "a", null, "*/*", "a, b" ,null },
|
||||||
|
// { "a", "a", "*/*", "a, b" ,null },
|
||||||
|
// };
|
||||||
|
//CHECKSTYLE:ON
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(ContentNegotiatorTest.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServiceDocumentSingleCase() {
|
||||||
|
String[] useCase = { "application/json", null, null, null, null };
|
||||||
|
|
||||||
|
testContentNegotiation(useCase, ServiceDocumentProcessor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServiceDocumentDefault() {
|
||||||
|
for (String[] useCase : casesServiceDocument) {
|
||||||
|
testContentNegotiation(useCase, ServiceDocumentProcessor.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testContentNegotiation(String[] useCase, Class<ServiceDocumentProcessor> processorClass) {
|
||||||
|
|
||||||
|
LOG.debug(Arrays.asList(useCase).toString());
|
||||||
|
|
||||||
|
ODataRequest request = new ODataRequest();
|
||||||
|
request.setMethod(HttpMethod.GET);
|
||||||
|
request.setRawODataPath("/" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
|
||||||
|
|
||||||
|
ContentNegotiator cn = new ContentNegotiator();
|
||||||
|
|
||||||
|
ProcessorStub p = new ProcessorStub(createCustomContentTypeMapping(useCase[3], useCase[4]));
|
||||||
|
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes =
|
||||||
|
cn.getSupportedContentTypes(p, processorClass);
|
||||||
|
|
||||||
|
FormatOption fo = null;
|
||||||
|
if (useCase[1] != null) {
|
||||||
|
fo = mock(FormatOption.class);
|
||||||
|
when(fo.getText()).thenReturn(useCase[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
String requestedContentType = cn.doContentNegotiation(fo, request, supportedContentTypes);
|
||||||
|
|
||||||
|
assertNotNull(requestedContentType);
|
||||||
|
assertEquals(useCase[0], requestedContentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<FormatContentTypeMapping> createCustomContentTypeMapping(String formatString, String contentTypeString) {
|
||||||
|
List<FormatContentTypeMapping> map = null;
|
||||||
|
|
||||||
|
assertTrue(!(formatString == null ^ contentTypeString == null));
|
||||||
|
|
||||||
|
if (formatString != null) {
|
||||||
|
String[] formats = formatString.split(",");
|
||||||
|
String[] contentTypes = contentTypeString.split(",");
|
||||||
|
|
||||||
|
assertEquals(formats.length, contentTypes.length);
|
||||||
|
|
||||||
|
map = new ArrayList<FormatContentTypeMapping>();
|
||||||
|
for (int i = 0; i < formats.length; i++) {
|
||||||
|
map.add(new FormatContentTypeMapping(formats[i], contentTypes[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testMetadataDefault() {
|
||||||
|
|
||||||
|
for (String[] useCase : casesMetadata) {
|
||||||
|
ODataRequest request = new ODataRequest();
|
||||||
|
request.setMethod(HttpMethod.GET);
|
||||||
|
request.setRawODataPath("/$metadata" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
|
||||||
|
|
||||||
|
// ODataResponse response = callHandler(useCase, request);
|
||||||
|
//
|
||||||
|
// assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void testEntitySet() {
|
||||||
|
//
|
||||||
|
// for (String[] useCase : casesEntitySet) {
|
||||||
|
// ODataRequest request = new ODataRequest();
|
||||||
|
// request.setMethod(HttpMethod.GET);
|
||||||
|
// request.setRawODataPath("/ESAllPrim" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
|
||||||
|
//
|
||||||
|
// ODataResponse response = callHandler(useCase, request, new CollectionProcessorStub());
|
||||||
|
//
|
||||||
|
// assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private ODataResponse callHandler(String[] useCase, ODataRequest request,
|
||||||
|
// Processor defaultProcessor) {
|
||||||
|
// ODataHandler handler = createHandler();
|
||||||
|
//
|
||||||
|
// if (useCase[2] != null) {
|
||||||
|
// request.addHeader(HttpHeader.ACCEPT, Arrays.asList(useCase[2]));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (useCase[3] != null) {
|
||||||
|
// String[] aliase = useCase[3].split(",");
|
||||||
|
// String[] mappings = useCase[4].split(",");
|
||||||
|
//
|
||||||
|
// FormatContentTypeMapping[] formatCTMap = new FormatContentTypeMapping[aliase.length];
|
||||||
|
//
|
||||||
|
// for(int i=0; i< formatCTMap.length; i++) {
|
||||||
|
// formatCTMap[i] = new FormatContentTypeMapping(aliase[i], mappings[i]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ProcessorStub stub = new ProcessorStub(formatCTMap);
|
||||||
|
// handler.register(stub);
|
||||||
|
// } else {
|
||||||
|
// if (defaultProcessor != null) {
|
||||||
|
// handler.register(defaultProcessor);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ODataResponse response = handler.process(request);
|
||||||
|
// return response;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ODataResponse callHandler(String[] useCase, ODataRequest request) {
|
||||||
|
// return callHandler(useCase, request, null);
|
||||||
|
// }
|
||||||
|
|
||||||
|
private class CollectionProcessorStub implements CollectionProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(OData odata, Edm edm) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultSupportedContentTypesServiceDocument() {
|
||||||
|
ContentNegotiator cn = new ContentNegotiator();
|
||||||
|
|
||||||
|
ProcessorStub p = new ProcessorStub(null);
|
||||||
|
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes =
|
||||||
|
cn.getSupportedContentTypes(p, ServiceDocumentProcessor.class);
|
||||||
|
|
||||||
|
assertNotNull(supportedContentTypes);
|
||||||
|
assertEquals(1, supportedContentTypes.size());
|
||||||
|
assertEquals("json", supportedContentTypes.get(0).getFormatAlias());
|
||||||
|
assertEquals("application/json", supportedContentTypes.get(0).getContentType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultSupportedContentTypesMetadata() {
|
||||||
|
ContentNegotiator cn = new ContentNegotiator();
|
||||||
|
|
||||||
|
ProcessorStub p = new ProcessorStub(null);
|
||||||
|
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes = cn.getSupportedContentTypes(p, MetadataProcessor.class);
|
||||||
|
|
||||||
|
assertNotNull(supportedContentTypes);
|
||||||
|
assertEquals(1, supportedContentTypes.size());
|
||||||
|
assertEquals("xml", supportedContentTypes.get(0).getFormatAlias());
|
||||||
|
assertEquals("application/xml", supportedContentTypes.get(0).getContentType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomSupportedContentTypesServiceDocument() {
|
||||||
|
ContentNegotiator cn = new ContentNegotiator();
|
||||||
|
|
||||||
|
ProcessorStub p = new ProcessorStub(Arrays.asList(new FormatContentTypeMapping("a", "a/a")));
|
||||||
|
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes =
|
||||||
|
cn.getSupportedContentTypes(p, ServiceDocumentProcessor.class);
|
||||||
|
|
||||||
|
assertNotNull(supportedContentTypes);
|
||||||
|
assertEquals(2, supportedContentTypes.size());
|
||||||
|
assertEquals("json", supportedContentTypes.get(0).getFormatAlias());
|
||||||
|
assertEquals("application/json", supportedContentTypes.get(0).getContentType());
|
||||||
|
assertEquals("a", supportedContentTypes.get(1).getFormatAlias());
|
||||||
|
assertEquals("a/a", supportedContentTypes.get(1).getContentType());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProcessorStub implements ServiceDocumentProcessor, MetadataProcessor,
|
||||||
|
CollectionProcessor,
|
||||||
|
CustomContentTypeSupport {
|
||||||
|
|
||||||
|
List<FormatContentTypeMapping> customMapping;
|
||||||
|
|
||||||
|
ProcessorStub(List<FormatContentTypeMapping> mapping) {
|
||||||
|
this.customMapping = mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(OData odata, Edm edm) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FormatContentTypeMapping> modifySupportedContentTypes(
|
||||||
|
List<FormatContentTypeMapping> supportedContentTypes,
|
||||||
|
Class<? extends Processor> processorClass) {
|
||||||
|
if (customMapping != null) {
|
||||||
|
supportedContentTypes.addAll(customMapping);
|
||||||
|
}
|
||||||
|
return supportedContentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readServiceDocument(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,8 @@ import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
|
|
|
@ -1,201 +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.mockito.Matchers.*;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.mockito.Mockito.withSettings;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.edm.Edm;
|
|
||||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
|
||||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
|
||||||
import org.apache.olingo.server.api.OData;
|
|
||||||
import org.apache.olingo.server.api.ODataRequest;
|
|
||||||
import org.apache.olingo.server.api.ODataResponse;
|
|
||||||
import org.apache.olingo.server.api.processor.CollectionProcessor;
|
|
||||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
|
||||||
import org.apache.olingo.server.api.processor.Processor;
|
|
||||||
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
|
||||||
import org.apache.olingo.server.api.processor.SupportCustomContentTypes;
|
|
||||||
import org.apache.olingo.server.api.uri.UriInfo;
|
|
||||||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ContentNegotiationTest {
|
|
||||||
|
|
||||||
// static final private String ACCEPT_CASE1 = "text/plain;q=0.5";
|
|
||||||
// static final private String ACCEPT_CASE2 = "application/json;odata=verbose;q=0.2";
|
|
||||||
|
|
||||||
//@formatter:off (Eclipse formatter)
|
|
||||||
//CHECKSTYLE:OFF (Maven checkstyle)
|
|
||||||
|
|
||||||
String[][] casesServiceDocument = {
|
|
||||||
/* expected $format accept supported */
|
|
||||||
{ "application/json", null, null, null },
|
|
||||||
{ "application/json", "json", null, null },
|
|
||||||
{ "application/json", "json", "application/json", null },
|
|
||||||
{ "application/json", null, "application/json", null },
|
|
||||||
{ "application/json", null, "*/*", null },
|
|
||||||
// { "aaa", "aaa", null, "aaa, bbb" },
|
|
||||||
// { "aaa", null, "*/*", "aaa, bbb" },
|
|
||||||
};
|
|
||||||
|
|
||||||
String[][] casesMetadata = {
|
|
||||||
/* expected $format accept supported */
|
|
||||||
{ "application/xml", null, null, null },
|
|
||||||
{ "application/xml", "xml", null, null },
|
|
||||||
{ "application/xml", null, "application/xml", null },
|
|
||||||
{ "application/xml", "xml", "application/xml", null },
|
|
||||||
{ "application/xml", null, "*/*", null },
|
|
||||||
// { "aaa", "aaa", null, "aaa, bbb" },
|
|
||||||
};
|
|
||||||
|
|
||||||
String[][] casesEntitySet = {
|
|
||||||
/* expected $format accept supported */
|
|
||||||
{ "application/json", null, null, null },
|
|
||||||
{ "application/json", "json", null, null },
|
|
||||||
{ "application/json", "json", "application/json", null },
|
|
||||||
{ "application/json", null, "*/*", null },
|
|
||||||
};
|
|
||||||
|
|
||||||
//CHECKSTYLE:ON
|
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
private ODataHandler createHandler() {
|
|
||||||
OData odata = OData.newInstance();
|
|
||||||
Edm edm = odata.createEdm(new EdmTechProvider());
|
|
||||||
return new ODataHandler(odata, edm);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testServiceDocumentDefault() {
|
|
||||||
|
|
||||||
for (String[] useCase : casesServiceDocument) {
|
|
||||||
ODataRequest request = new ODataRequest();
|
|
||||||
request.setMethod(HttpMethod.GET);
|
|
||||||
request.setRawODataPath("/" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
|
|
||||||
|
|
||||||
ODataResponse response = callHandler(useCase, request);
|
|
||||||
|
|
||||||
assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMetadataDefault() {
|
|
||||||
|
|
||||||
for (String[] useCase : casesMetadata) {
|
|
||||||
ODataRequest request = new ODataRequest();
|
|
||||||
request.setMethod(HttpMethod.GET);
|
|
||||||
request.setRawODataPath("/$metadata" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
|
|
||||||
|
|
||||||
ODataResponse response = callHandler(useCase, request);
|
|
||||||
|
|
||||||
assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEntitySet() {
|
|
||||||
|
|
||||||
for (String[] useCase : casesEntitySet) {
|
|
||||||
ODataRequest request = new ODataRequest();
|
|
||||||
request.setMethod(HttpMethod.GET);
|
|
||||||
request.setRawODataPath("/ESAllPrim" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
|
|
||||||
|
|
||||||
ODataResponse response = callHandler(useCase, request, new CollectionProcessorStub());
|
|
||||||
|
|
||||||
assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ODataResponse callHandler(String[] useCase, ODataRequest request,
|
|
||||||
Processor defaultProcessor) {
|
|
||||||
ODataHandler handler = createHandler();
|
|
||||||
|
|
||||||
if (useCase[3] != null) {
|
|
||||||
ProcessorStub stub = new ProcessorStub(useCase[3].split(","));
|
|
||||||
handler.register(stub);
|
|
||||||
} else {
|
|
||||||
if (defaultProcessor != null) {
|
|
||||||
handler.register(defaultProcessor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ODataResponse response = handler.process(request);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
ODataResponse callHandler(String[] useCase, ODataRequest request) {
|
|
||||||
return callHandler(useCase, request, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ProcessorStub implements ServiceDocumentProcessor, MetadataProcessor, CollectionProcessor,
|
|
||||||
SupportCustomContentTypes {
|
|
||||||
|
|
||||||
String[] formats;
|
|
||||||
|
|
||||||
ProcessorStub(String[] strings) {
|
|
||||||
this.formats = strings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(OData odata, Edm edm) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getSupportedContentTypes(Class<? extends Processor> processorClass) {
|
|
||||||
return Arrays.asList(formats);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readServiceDocument(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
|
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
|
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
|
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CollectionProcessorStub implements CollectionProcessor {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(OData odata, Edm edm) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
|
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue