From 71f0288a921a3098858cda3ab7d784fc8b70da99 Mon Sep 17 00:00:00 2001 From: rfeng Date: Fri, 30 Apr 2010 23:26:18 +0000 Subject: Add basic support for binary data types for binding.rest git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@939874 13f79535-47bb-0310-9956-ffa450edef68 --- .../JAXRSOperationSelectorInterceptor.java | 162 ++++++++++++++++----- 1 file changed, 128 insertions(+), 34 deletions(-) (limited to 'sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector') diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java index d71762f11e..a79cd7dcf9 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java @@ -19,10 +19,17 @@ package org.apache.tuscany.sca.binding.rest.operationselector.jaxrs.provider; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.StringWriter; import java.lang.reflect.Method; import java.net.URLDecoder; import java.util.List; +import javax.activation.DataSource; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -49,22 +56,22 @@ import org.apache.tuscany.sca.runtime.RuntimeEndpoint; public class JAXRSOperationSelectorInterceptor implements Interceptor { private ExtensionPointRegistry extensionPoints; private RuntimeEndpoint endpoint; - + private RuntimeComponentService service; private InterfaceContract interfaceContract; private List serviceOperations; - + private Invoker next; public JAXRSOperationSelectorInterceptor(ExtensionPointRegistry extensionPoints, RuntimeEndpoint endpoint) { this.extensionPoints = extensionPoints; this.endpoint = endpoint; - + this.service = (RuntimeComponentService)endpoint.getService(); this.interfaceContract = service.getInterfaceContract(); this.serviceOperations = service.getInterfaceContract().getInterface().getOperations(); } - + public Invoker getNext() { return next; } @@ -75,35 +82,122 @@ public class JAXRSOperationSelectorInterceptor implements Interceptor { public Message invoke(Message msg) { try { - HTTPContext bindingContext = (HTTPContext) msg.getBindingContext(); + HTTPContext bindingContext = (HTTPContext)msg.getBindingContext(); String path = URLDecoder.decode(HTTPUtil.getRequestPath(bindingContext.getHttpRequest()), "UTF-8"); - - if(path.startsWith("/")) { + + if (path.startsWith("/")) { path = path.substring(1); } - List operations = filterOperationsByHttpMethod(interfaceContract, bindingContext.getHttpRequest().getMethod()); + List operations = + filterOperationsByHttpMethod(interfaceContract, bindingContext.getHttpRequest().getMethod()); Operation operation = findOperation(path, operations); - final JavaOperation javaOperation = (JavaOperation) operation; + final JavaOperation javaOperation = (JavaOperation)operation; final Method method = javaOperation.getJavaMethod(); - - if(path != null && path.length() > 0) { - if(method.getAnnotation(Path.class) != null) { - msg.setBody(new Object[]{path}); + + if (path != null && path.length() > 0) { + if (method.getAnnotation(Path.class) != null) { + msg.setBody(new Object[] {path}); } } - + + // FIXME: [rfeng] We should follow JAX-RS rules to identify the entity parameter + Class[] paramTypes = method.getParameterTypes(); + if (paramTypes.length == 1) { + Class type = paramTypes[0]; + InputStream is = (InputStream)((Object[])msg.getBody())[0]; + Object target = convert(is, bindingContext.getHttpRequest().getContentType(), type); + msg.setBody(new Object[] {target}); + } else if (paramTypes.length == 0) { + msg.setBody(null); + } + msg.setOperation(operation); return getNext().invoke(msg); - } catch(Exception e) { + } catch (Exception e) { throw new RuntimeException(e); } } + private Object convert(InputStream content, String contentType, Class type) { + if (type == DataSource.class) { + return type.cast(new InputStreamDataSource(content, contentType)); + } else if (type == InputStream.class) { + return type.cast(content); + } else if (type == String.class) { + try { + StringWriter sw = new StringWriter(); + InputStreamReader reader = new InputStreamReader(content, "UTF-8"); + char[] buf = new char[8192]; + while (true) { + int size = reader.read(buf); + if (size < 0) { + break; + } + sw.write(buf, 0, size); + } + return type.cast(sw.toString()); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } else if (type == byte[].class) { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buf = new byte[8192]; + while (true) { + int size = content.read(buf); + if (size < 0) { + break; + } + bos.write(buf, 0, size); + } + return type.cast(bos.toByteArray()); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } else { + return content; + } + } + + public static final class InputStreamDataSource implements DataSource { + + public static final String DEFAULT_TYPE = "application/octet-stream"; + + private final InputStream in; + private final String ctype; + + public InputStreamDataSource(InputStream in) { + this(in, null); + } + + public InputStreamDataSource(InputStream in, String ctype) { + this.in = in; + this.ctype = (ctype != null) ? ctype : DEFAULT_TYPE; + } + + public String getContentType() { + return ctype; + } + + public String getName() { + return null; + } + + public InputStream getInputStream() throws IOException { + return in; + } + + public OutputStream getOutputStream() throws IOException { + return null; + } + + } + /** * Find the operation from the component service contract * @param componentService @@ -112,20 +206,20 @@ public class JAXRSOperationSelectorInterceptor implements Interceptor { */ private static List filterOperationsByHttpMethod(InterfaceContract interfaceContract, String http_method) { List operations = null; - - if(http_method.equalsIgnoreCase("get")) { - operations = (List) interfaceContract.getInterface().getAttributes().get(GET.class); - }else if(http_method.equalsIgnoreCase("put")) { - operations = (List) interfaceContract.getInterface().getAttributes().get(PUT.class); - }else if(http_method.equalsIgnoreCase("post")) { - operations = (List) interfaceContract.getInterface().getAttributes().get(POST.class); - }else if(http_method.equalsIgnoreCase("delete")) { - operations = (List) interfaceContract.getInterface().getAttributes().get(DELETE.class); + + if (http_method.equalsIgnoreCase("get")) { + operations = (List)interfaceContract.getInterface().getAttributes().get(GET.class); + } else if (http_method.equalsIgnoreCase("put")) { + operations = (List)interfaceContract.getInterface().getAttributes().get(PUT.class); + } else if (http_method.equalsIgnoreCase("post")) { + operations = (List)interfaceContract.getInterface().getAttributes().get(POST.class); + } else if (http_method.equalsIgnoreCase("delete")) { + operations = (List)interfaceContract.getInterface().getAttributes().get(DELETE.class); } - + return operations; } - + /** * Find the operation from the component service contract * @param componentService @@ -134,24 +228,24 @@ public class JAXRSOperationSelectorInterceptor implements Interceptor { */ private Operation findOperation(String path, List operations) { Operation operation = null; - - for(Operation op : operations) { - final JavaOperation javaOperation = (JavaOperation) op; + + for (Operation op : operations) { + final JavaOperation javaOperation = (JavaOperation)op; final Method method = javaOperation.getJavaMethod(); - - if(path != null && path.length() > 0) { - if(method.getAnnotation(Path.class) != null) { + + if (path != null && path.length() > 0) { + if (method.getAnnotation(Path.class) != null) { operation = op; break; } } else { - if(method.getAnnotation(Path.class) == null) { + if (method.getAnnotation(Path.class) == null) { operation = op; break; } } } - + return operation; } } -- cgit v1.2.3