diff options
Diffstat (limited to 'sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca')
4 files changed, 185 insertions, 53 deletions
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<Operation> 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<Operation> operations = filterOperationsByHttpMethod(interfaceContract, bindingContext.getHttpRequest().getMethod()); + List<Operation> 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<Operation> filterOperationsByHttpMethod(InterfaceContract interfaceContract, String http_method) { List<Operation> operations = null; - - if(http_method.equalsIgnoreCase("get")) { - operations = (List<Operation>) interfaceContract.getInterface().getAttributes().get(GET.class); - }else if(http_method.equalsIgnoreCase("put")) { - operations = (List<Operation>) interfaceContract.getInterface().getAttributes().get(PUT.class); - }else if(http_method.equalsIgnoreCase("post")) { - operations = (List<Operation>) interfaceContract.getInterface().getAttributes().get(POST.class); - }else if(http_method.equalsIgnoreCase("delete")) { - operations = (List<Operation>) interfaceContract.getInterface().getAttributes().get(DELETE.class); + + if (http_method.equalsIgnoreCase("get")) { + operations = (List<Operation>)interfaceContract.getInterface().getAttributes().get(GET.class); + } else if (http_method.equalsIgnoreCase("put")) { + operations = (List<Operation>)interfaceContract.getInterface().getAttributes().get(PUT.class); + } else if (http_method.equalsIgnoreCase("post")) { + operations = (List<Operation>)interfaceContract.getInterface().getAttributes().get(POST.class); + } else if (http_method.equalsIgnoreCase("delete")) { + operations = (List<Operation>)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<Operation> 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; } } diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingListenerServlet.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingListenerServlet.java index b91c6d7f6d..3ba76f5777 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingListenerServlet.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingListenerServlet.java @@ -19,11 +19,8 @@ package org.apache.tuscany.sca.binding.rest.provider; -import java.io.BufferedReader; -import java.io.CharArrayWriter; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.net.URLDecoder; import java.text.ParseException; @@ -74,10 +71,32 @@ public class RESTBindingListenerServlet extends HttpServlet { this.messageFactory = messageFactory; } + private void write(OutputStream out, Object obj) throws IOException { + if (obj == null) { + return; + } + if (obj instanceof String) { + out.write(((String)obj).getBytes("UTF-8")); + } else if (obj instanceof byte[]) { + out.write((byte[])obj); + } else if (obj instanceof InputStream) { + byte[] buf = new byte[8192]; + InputStream in = (InputStream)obj; + while (true) { + int size = in.read(buf); + if (size < 0) { + break; + } + out.write(buf, 0, size); + } + } else { + out.write(obj.toString().getBytes("UTF-8")); + } + } @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - if( binding.getOperationSelector() != null && binding.getRequestWireFormat() != null) { + if( binding.getOperationSelector() != null || binding.getRequestWireFormat() != null) { // Decode using the charset in the request if it exists otherwise // use UTF-8 as this is what all browser implementations use. String charset = request.getCharacterEncoding(); @@ -85,6 +104,7 @@ public class RESTBindingListenerServlet extends HttpServlet { charset = "UTF-8"; } + /* BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), charset)); // Read the request @@ -94,6 +114,7 @@ public class RESTBindingListenerServlet extends HttpServlet { while ((ret = in.read(buf, 0, 4096)) != -1) { data.write(buf, 0, ret); } + */ HTTPContext bindingContext = new HTTPContext(); bindingContext.setHttpRequest(request); @@ -102,9 +123,14 @@ public class RESTBindingListenerServlet extends HttpServlet { // Dispatch the service interaction to the service invoker Message requestMessage = messageFactory.createMessage(); requestMessage.setBindingContext(bindingContext); + + requestMessage.setBody(new Object[] {request.getInputStream()}); + + /* if(data.size() > 0) { requestMessage.setBody(new Object[]{data}); } + */ Message responseMessage = bindingInvoker.invoke(requestMessage); @@ -116,13 +142,9 @@ public class RESTBindingListenerServlet extends HttpServlet { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); } else { //handle void operations - if(responseMessage.getBody() != null) { - byte[] bout; - bout = responseMessage.<Object>getBody().toString().getBytes("UTF-8"); - response.getOutputStream().write(bout); - response.getOutputStream().flush(); - response.getOutputStream().close(); - } + write(response.getOutputStream(), responseMessage.getBody()); + response.getOutputStream().flush(); + response.getOutputStream().close(); } } else { super.service(request, response); diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java index a8d9c08d08..7e47d5c04d 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java @@ -19,7 +19,10 @@ package org.apache.tuscany.sca.binding.rest.wireformat.json.provider; -import java.io.CharArrayWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; import org.apache.tuscany.sca.common.http.HTTPContext; import org.apache.tuscany.sca.core.ExtensionPointRegistry; @@ -48,6 +51,20 @@ public class JSONWireFormatInterceptor implements Interceptor { public void setNext(Invoker next) { this.next = next; } + + private String read(InputStream in) throws IOException { + StringWriter sw = new StringWriter(); + InputStreamReader reader = new InputStreamReader(in, "UTF-8"); + char[] buf = new char[8192]; + while (true) { + int size = reader.read(buf); + if (size < 0) { + break; + } + sw.write(buf, 0, size); + } + return sw.toString(); + } public Message invoke(Message msg) { HTTPContext bindingContext = (HTTPContext) msg.getBindingContext(); @@ -55,9 +72,9 @@ public class JSONWireFormatInterceptor implements Interceptor { try { if(bindingContext.getHttpRequest().getMethod().equalsIgnoreCase("get") == false && bindingContext.getHttpRequest().getMethod().equalsIgnoreCase("delete") == false && msg.getBody() != null) { Object[] args = msg.getBody(); - CharArrayWriter data = (CharArrayWriter) args[0]; - - JSONObject jsonPayload = new JSONObject(data.toString()); + InputStream in = (InputStream) args[0]; + String data = read(in); + JSONObject jsonPayload = new JSONObject(data); msg.setBody(new Object[]{jsonPayload}); } } catch(Exception e) { diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/provider/XMLWireFormatInterceptor.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/provider/XMLWireFormatInterceptor.java index a1b4255c18..07fdc57082 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/provider/XMLWireFormatInterceptor.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/xml/provider/XMLWireFormatInterceptor.java @@ -19,8 +19,7 @@ package org.apache.tuscany.sca.binding.rest.wireformat.xml.provider; -import java.io.CharArrayReader; -import java.io.CharArrayWriter; +import java.io.InputStream; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; @@ -59,8 +58,8 @@ public class XMLWireFormatInterceptor implements Interceptor { try { if(msg.getBody() != null) { Object[] args = msg.getBody(); - CharArrayWriter data = (CharArrayWriter) args[0]; - XMLStreamReader xmlPayload = inputFactory.createXMLStreamReader(new CharArrayReader(data.toCharArray())); + InputStream data = (InputStream) args[0]; + XMLStreamReader xmlPayload = inputFactory.createXMLStreamReader(data); msg.setBody(new Object[]{xmlPayload}); } } catch(Exception e) { |