From ce3c5536c9af5f535d0057498d0d76848b7a4cb5 Mon Sep 17 00:00:00 2001 From: fmoga Date: Sun, 15 Aug 2010 07:25:44 +0000 Subject: Added Javascript proxy generation. Added passing parameters through JSON. Added Gson and jquery-json as dependencies. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@985622 13f79535-47bb-0310-9956-ffa450edef68 --- .../comet/runtime/CometServiceBindingProvider.java | 5 +- .../sca/binding/comet/runtime/ServletFactory.java | 7 ++- .../comet/runtime/handler/CometBindingHandler.java | 69 ++++++++++++++++----- .../runtime/javascript/JavascriptGenerator.java | 72 ++++++++++++++++++++++ .../runtime/javascript/JavascriptResource.java | 13 +++- 5 files changed, 147 insertions(+), 19 deletions(-) create mode 100644 sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/javascript/JavascriptGenerator.java (limited to 'sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca') diff --git a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/CometServiceBindingProvider.java b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/CometServiceBindingProvider.java index 5ad23097b5..1d295d9b4d 100644 --- a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/CometServiceBindingProvider.java +++ b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/CometServiceBindingProvider.java @@ -20,6 +20,7 @@ package org.apache.tuscany.sca.binding.comet.runtime; import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.binding.comet.runtime.javascript.JavascriptGenerator; import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.InterfaceContract; @@ -40,7 +41,9 @@ public class CometServiceBindingProvider implements ServiceBindingProvider { public void start() { ComponentService service = endpoint.getService(); Interface serviceInterface = service.getInterfaceContract().getInterface(); + JavascriptGenerator.generateServiceProxy(service); for (Operation operation : serviceInterface.getOperations()) { + JavascriptGenerator.generateMethodProxy(service, operation); ServletFactory.registerServlet(servletHost, endpoint, operation); } } @@ -49,7 +52,7 @@ public class CometServiceBindingProvider implements ServiceBindingProvider { ComponentService service = endpoint.getService(); Interface serviceInterface = service.getInterfaceContract().getInterface(); for (Operation op : serviceInterface.getOperations()) { - String path = endpoint.getBinding().getURI() + "/" + op.getName(); + String path = service.getName() + "/" + op.getName(); servletHost.removeServletMapping(path); } } diff --git a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/ServletFactory.java b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/ServletFactory.java index 62e90693fa..df1137cb63 100644 --- a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/ServletFactory.java +++ b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/ServletFactory.java @@ -3,6 +3,7 @@ package org.apache.tuscany.sca.binding.comet.runtime; import java.util.HashMap; import java.util.Map; +import org.apache.tuscany.sca.binding.comet.runtime.javascript.JavascriptGenerator; import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.runtime.RuntimeEndpoint; @@ -15,6 +16,8 @@ public class ServletFactory { private static final String JS_PACKAGE_VALUE = "org.apache.tuscany.sca.binding.comet.runtime.javascript"; public static final String ENDPOINTS_KEY = "org.apache.tuscany.sca.binding.comet.endpoints"; public static final String OPERATIONS_KEY = "org.apache.tuscany.sca.binding.comet.operations"; + public static final String JS_KEY = "org.apache.tuscany.sca.binding.comet.javascript"; + public static final String PATH = "/tuscany-comet/*"; public static final String JS_PATH = "/org.apache.tuscany.sca.cometComponentContext.js/*"; @@ -33,8 +36,7 @@ public class ServletFactory { Map operations = new HashMap(); cometServlet.getServletContext().setAttribute(OPERATIONS_KEY, operations); } - String url = endpoint.getBinding().getURI() + "/" + operation.getName(); - System.out.println("Adding endpoint and operation for url: " + url); + String url = "/" + endpoint.getService().getName() + "/" + operation.getName(); Map endpoints = (Map)cometServlet.getServletContext().getAttribute(ENDPOINTS_KEY); endpoints.put(url, endpoint); @@ -46,6 +48,7 @@ public class ServletFactory { javascriptServlet = new AtmosphereServlet(); javascriptServlet.addInitParameter(PACKAGE_KEY, JS_PACKAGE_VALUE); servletHost.addServletMapping(JS_PATH, javascriptServlet); + javascriptServlet.getServletContext().setAttribute(JS_KEY, JavascriptGenerator.javascript); } } diff --git a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java index 88f0460839..c1ffc6ec92 100644 --- a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java +++ b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java @@ -1,6 +1,8 @@ package org.apache.tuscany.sca.binding.comet.runtime.handler; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import javax.servlet.ServletContext; @@ -12,8 +14,8 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; -import org.apache.tuscany.sca.binding.comet.runtime.EventsLogger; import org.apache.tuscany.sca.binding.comet.runtime.ServletFactory; +import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.runtime.RuntimeEndpoint; import org.atmosphere.annotation.Broadcast; @@ -22,6 +24,7 @@ import org.atmosphere.cpr.DefaultBroadcaster; import org.atmosphere.jersey.Broadcastable; import org.atmosphere.jersey.SuspendResponse; +import com.google.gson.Gson; import com.sun.jersey.spi.container.servlet.PerSession; @Path("/") @@ -32,34 +35,72 @@ public class CometBindingHandler { private Broadcaster broadcaster; private Map endpoints; private Map operations; + private Gson gson; @Context private ServletContext sc; @GET public SuspendResponse connect() { - System.out.println("Entering connect..."); broadcaster = new DefaultBroadcaster(); endpoints = (Map)sc.getAttribute(ServletFactory.ENDPOINTS_KEY); operations = (Map)sc.getAttribute(ServletFactory.OPERATIONS_KEY); - return new SuspendResponse.SuspendResponseBuilder().broadcaster(broadcaster).outputComments(true) - .addListener(new EventsLogger()).build(); + gson = new Gson(); + return new SuspendResponse.SuspendResponseBuilder() + .broadcaster(broadcaster) + .outputComments(true) + //.addListener(new EventsLogger()) // use for logging or debugging when needed + .build(); } @POST - @Path("/{component}/{service}/{method}") + @Path("/{service}/{method}") @Broadcast - public Broadcastable callAndRespond(@PathParam("component") String component, - @PathParam("service") String service, + public Broadcastable callAndRespond(@PathParam("service") String service, @PathParam("method") String method, - @FormParam("callback") String callbackMethod) throws InvocationTargetException { - String url = "/" + component + "/" + service + "/" + method; - System.out.println("Entered callAndRespond with url: " + url); - System.out.println("Callback method: " + callbackMethod); + @FormParam("callback") String callbackMethod, + @FormParam("params") String jsonData) throws InvocationTargetException { + String url = "/" + service + "/" + method; RuntimeEndpoint wire = endpoints.get(url); Operation operation = operations.get(url); - Object response = wire.invoke(operation, new Object[] {}); - // TODO: replace with JSON - return new Broadcastable(callbackMethod + "#" + response.toString(), "", broadcaster); + Object[] args = new Object[operation.getInputType().getLogical().size()]; + String[] json = parseArray(jsonData); + int index = 0; + for (DataType dataType : operation.getInputType().getLogical()) { + args[index] = gson.fromJson(json[index], dataType.getPhysical()); + index++; + } + Object response = wire.invoke(operation, args); + return new Broadcastable(callbackMethod + "($.secureEvalJSON('" + gson.toJson(response) + "'))", "", broadcaster); + } + + private String[] parseArray(String jsonArray) { + List objects = new ArrayList(); + int bracketNum = 0; + int parNum = 0; + int startPos = 1; + for (int i = 0; i < jsonArray.length(); i++) { + switch (jsonArray.charAt(i)) { + case '{': + bracketNum++; + break; + case '}': + bracketNum--; + break; + case '[': + parNum++; + break; + case ']': + parNum--; + break; + case ',': + if (bracketNum == 0 && parNum == 1) { + objects.add(jsonArray.substring(startPos, i)); + startPos = i + 1; + } + } + } + objects.add(jsonArray.substring(startPos, jsonArray.length() - 1)); + return objects.toArray(new String[] {}); } } diff --git a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/javascript/JavascriptGenerator.java b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/javascript/JavascriptGenerator.java new file mode 100644 index 0000000000..ffd300cb01 --- /dev/null +++ b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/javascript/JavascriptGenerator.java @@ -0,0 +1,72 @@ +package org.apache.tuscany.sca.binding.comet.runtime.javascript; + +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.interfacedef.Operation; + +public class JavascriptGenerator { + + public static StringBuffer javascript = new StringBuffer(); + private static final String COMPONENT_CONTEXT_NAMESPACE = "cometComponentContext"; + private static final String TUSCANY_COMET_NAMESPACE = "tuscanyComet"; + + public static void generateServiceProxy(ComponentService service) { + javascript.append(COMPONENT_CONTEXT_NAMESPACE + "." + service.getName() + " = new Object();\n"); + } + + public static void generateMethodProxy(ComponentService service, Operation operation) { + javascript.append(COMPONENT_CONTEXT_NAMESPACE + "." + + service.getName() + + "." + + operation.getName() + + " = function("); + for (int i = 0; i < operation.getInputType().getLogical().size(); i++) { + javascript.append("p" + i + ", "); + } + javascript.append("callbackMethod) {\n"); + javascript.append(" var params = [];\n"); + for (int i = 0; i < operation.getInputType().getLogical().size(); i++) { + javascript.append(" params.push(p" + i + ");\n"); + } + javascript.append(" " + TUSCANY_COMET_NAMESPACE + + ".callAsync('" + + service.getName() + + "/" + + operation.getName() + + "', $.toJSON(params), callbackMethod);\n"); + javascript.append("}\n"); + } + +} + +// cometComponentContext.c1 = new Object(); +// cometComponentContext.c1.TemperatureService = new Object(); +// cometComponentContext.c1.TemperatureService.getTemperatureCelsius = +// function(p0, callbackMethod) { +// tuscanyComet.callAsync('c1/TemperatureService/getTemperatureCelsius', x, +// callbackMethod); +// } +// cometComponentContext.c1.TemperatureService.getTemperatureFahrenheit = +// function(callbackMethod) { +// tuscanyComet.callAsync('c1/TemperatureService/getTemperatureFahrenheit', x, +// callbackMethod); +// } +// +// if (cometComponentContext.c1 == null) { +// cometComponentContext.c1 = new Object(); +// } +// cometComponentContext.c1.HumidityService = new Object(); +// cometComponentContext.c1.HumidityService.getHumidity = function(p0, +// callbackMethod) { +// var params = []; +// params.push(p0); +// tuscanyComet.callAsync('c1/HumidityService/getHumidity', $.toJSON(params), +// callbackMethod); +// } +// +// cometComponentContext.c2 = new Object(); +// cometComponentContext.c2.PrecipitationService = new Object(); +// cometComponentContext.c2.PrecipitationService.getPrecipitation = +// function(callbackMethod) { +// tuscanyComet.callAsync('c2/PrecipitationService/getPrecipitation', x, +// callbackMethod); +// } diff --git a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/javascript/JavascriptResource.java b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/javascript/JavascriptResource.java index d6ad8a018f..6df45e4ca8 100644 --- a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/javascript/JavascriptResource.java +++ b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/javascript/JavascriptResource.java @@ -1,20 +1,28 @@ package org.apache.tuscany.sca.binding.comet.runtime.javascript; +import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.SequenceInputStream; +import javax.servlet.ServletContext; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; import javax.ws.rs.core.PathSegment; +import org.apache.tuscany.sca.binding.comet.runtime.ServletFactory; + @Path("/") @Produces("text/javascript") public class JavascriptResource { private static final String[] DEPENDENCIES = {"/jquery-1.4.2.min.js", "/jquery.atmosphere.js", - "/org.apache.tuscany.sca.cometComponentContext.js"}; + "/jquery.json-2.2.min.js", "/cometComponentContext.js"}; + + @Context + private ServletContext sc; @GET public InputStream getJavascript(@PathParam("file") PathSegment fileName) { @@ -26,6 +34,7 @@ public class JavascriptResource { stream = new SequenceInputStream(stream, getClass().getResourceAsStream(dependency)); } } - return stream; + String generatedJs = ((StringBuffer)sc.getAttribute(ServletFactory.JS_KEY)).toString(); + return new SequenceInputStream(stream, new ByteArrayInputStream(generatedJs.getBytes())); } } -- cgit v1.2.3