summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/trunk/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/trunk/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java')
-rw-r--r--sca-java-2.x/trunk/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java316
1 files changed, 128 insertions, 188 deletions
diff --git a/sca-java-2.x/trunk/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java b/sca-java-2.x/trunk/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java
index 3cd90304b8..c2d2181814 100644
--- a/sca-java-2.x/trunk/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java
+++ b/sca-java-2.x/trunk/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/handler/CometBindingHandler.java
@@ -19,26 +19,21 @@
package org.apache.tuscany.sca.binding.comet.runtime.handler;
-import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
-import java.util.UUID;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
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.MediaType;
+import javax.ws.rs.QueryParam;
import org.apache.tuscany.sca.assembly.EndpointReference;
-import org.apache.tuscany.sca.binding.comet.runtime.CometComponentContext;
-import org.apache.tuscany.sca.binding.comet.runtime.ServletFactory;
+import org.apache.tuscany.sca.binding.comet.runtime.manager.CometEndpointManager;
+import org.apache.tuscany.sca.binding.comet.runtime.manager.CometOperationManager;
+import org.apache.tuscany.sca.binding.comet.runtime.manager.CometSessionManager;
import org.apache.tuscany.sca.core.assembly.impl.RuntimeEndpointImpl;
import org.apache.tuscany.sca.core.assembly.impl.RuntimeEndpointReferenceImpl;
import org.apache.tuscany.sca.core.invocation.Constants;
@@ -51,186 +46,131 @@ import org.atmosphere.cpr.Broadcaster;
import org.atmosphere.jersey.JerseyBroadcaster;
import org.atmosphere.jersey.SuspendResponse;
-import com.sun.jersey.spi.container.servlet.PerSession;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
-/**
- * Class serving calls coming for comet services and operations.
- */
@Path("/")
-@Produces("text/html;charset=ISO-8859-1")
-@PerSession
-public class CometBindingHandler implements Serializable {
-
- /**
- * The object used to suspend the response and send async responses back to
- * client.
- */
- private Broadcaster broadcaster;
-
- /**
- * The underlying servlet context.
- */
- @Context
- private ServletContext sc;
-
- @Context
- private HttpServletRequest request;
-
- private CometComponentContext context;
-
- @GET
- @Path("/sessionId")
- @Produces(MediaType.TEXT_PLAIN)
- public String establishSessionId() {
- request.getSession().invalidate();
- request.getSession(true);
- return "OK";
- }
-
- /**
- * Method called at comet connect time. This suspends the response and keeps
- * the connection opened.
- *
- * @return the suspended response
- */
- @GET
- @Path("/connect")
- public SuspendResponse<String> connect() {
- // System.out.println("-- connect -- Session Id: " +
- // request.getSession().getId());
- if (broadcaster == null) {
- broadcaster = new JerseyBroadcaster(UUID.randomUUID().toString());
- // broadcaster.setBroadcasterLifeCyclePolicy(new
- // Builder().policy(ATMOSPHERE_RESOURCE_POLICY.IDLE_DESTROY)
- // .idleTimeInMS(5000).build());
- context = (CometComponentContext) sc.getAttribute(ServletFactory.COMET_COMPONENT_CONTEXT_KEY);
- }
- CometComponentContext.broadcasters.put(request.getSession().getId(), broadcaster);
- return new SuspendResponse.SuspendResponseBuilder<String>().broadcaster(this.broadcaster).outputComments(true)
- .build();
- }
-
- /**
- * Method called on service calls.
- *
- * @param service
- * service called
- * @param method
- * operation called
- * @param callbackMethod
- * the callback method from Javascript
- * @param jsonData
- * arguments for the method sent as JSON array
- * @return object used by the Broadcaster to send response through the
- * persisted connection
- * @throws InvocationTargetException
- * if problems occur at service invocation
- */
- @POST
- @Path("/{service}/{method}")
- public void handleRequest(@PathParam("service") final String service, @PathParam("method") final String method,
- @FormParam("callbackMethod") final String callbackMethod, @FormParam("params") final String jsonData)
- throws InvocationTargetException {
- // System.out.println("-- handleRequest -- Session Id: " +
- // request.getSession().getId());
- final String url = "/" + service + "/" + method;
- final RuntimeEndpoint wire = context.getEndpoint(url);
- final Operation operation = context.getOperation(url);
-
- final Object[] args = decodeJsonDataForOperation(jsonData, operation);
- Message msg = createMessageWithMockedCometReference(args, callbackMethod);
- boolean isVoidReturnType = operation.getOutputType().getLogical().isEmpty();
- if (!isVoidReturnType) {
- Object response = wire.invoke(operation, args);
- broadcaster.broadcast(callbackMethod + "($.secureEvalJSON('" + CometComponentContext.gson.toJson(response)
- + "'))");
- if (broadcaster.getAtmosphereResources().isEmpty()) {
- CometComponentContext.broadcasters.remove(request.getSession().getId());
- }
- } else {
- wire.invoke(operation, msg);
- }
- }
-
- /**
- * Convert request parameters from JSON to operation parameter types.
- *
- * @param jsonData
- * @param operation
- * @return
- */
- private Object[] decodeJsonDataForOperation(String jsonData, Operation operation) {
- Object[] args = new Object[operation.getInputType().getLogical().size()];
- final String[] json = this.parseArray(jsonData);
- int index = 0;
- // convert each argument to the corresponding class
- for (final DataType<?> dataType : operation.getInputType().getLogical()) {
- args[index] = CometComponentContext.gson.fromJson(json[index], dataType.getPhysical());
- index++;
- }
- return args;
- }
-
- /**
- * Creates the message to be sent with a mocked EndpointReference in the
- * 'from' field as the request comes from a browser (there is no actual
- * comet reference running in a controlled environment).
- *
- * @param args
- * @param callbackMethod
- * @return
- */
- private Message createMessageWithMockedCometReference(Object[] args, String callbackMethod) {
- Message msg = new MessageImpl();
- msg.getHeaders().put(Constants.MESSAGE_ID, request.getSession().getId());
- msg.setBody(args);
- EndpointReference re = new RuntimeEndpointReferenceImpl();
- RuntimeEndpointImpl callbackEndpoint = new RuntimeEndpointImpl();
- callbackEndpoint.setURI(callbackMethod);
- re.setCallbackEndpoint(callbackEndpoint);
- msg.setFrom(re);
- return msg;
- }
-
- /**
- * Parse the JSON array containing the arguments for the method call in
- * order to avoid converting JSON to Object[]. Converting each object
- * separately to it's corresponding type avoids type mismatch problems at
- * service invocation.
- *
- * @param jsonArray
- * the JSON array
- * @return an array of JSON formatted objects
- */
- private String[] parseArray(final String jsonArray) {
- final List<String> objects = new ArrayList<String>();
- 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;
- }
- }
- }
- // add last object
- objects.add(jsonArray.substring(startPos, jsonArray.length() - 1));
- return objects.toArray(new String[] {});
- }
+public class CometBindingHandler {
+
+ private static Gson gson = new GsonBuilder().serializeNulls().create();
+
+ @GET
+ @Path("/connect")
+ public SuspendResponse<String> connect(@QueryParam("sessionId") String sessionId) {
+ System.out.println("-- connect -- Session Id: " + sessionId);
+ Broadcaster broadcaster = CometSessionManager.get(sessionId);
+ if (broadcaster == null) {
+ broadcaster = new JerseyBroadcaster(sessionId);
+ CometSessionManager.add(sessionId, broadcaster);
+ }
+ return new SuspendResponse.SuspendResponseBuilder<String>().broadcaster(broadcaster).outputComments(true)
+ .build();
+ }
+
+ @POST
+ @Path("/{service}/{method}")
+ public void handleRequest(@PathParam("service") String service, @PathParam("method") String method,
+ @FormParam("sessionId") String sessionId, @FormParam("callbackMethod") String callbackMethod,
+ @FormParam("params") String jsonData) throws InvocationTargetException {
+ System.out.println("-- handleRequest -- Session Id: " + sessionId);
+ String url = "/" + service + "/" + method;
+ RuntimeEndpoint wire = CometEndpointManager.get(url);
+ Operation operation = CometOperationManager.get(url);
+
+ final Object[] args = decodeJsonDataForOperation(jsonData, operation);
+ Message msg = createMessageWithMockedCometReference(args, sessionId, callbackMethod);
+ boolean isVoidReturnType = operation.getOutputType().getLogical().isEmpty();
+ if (!isVoidReturnType) {
+ Object response = wire.invoke(operation, args);
+ Broadcaster broadcaster = CometSessionManager.get(sessionId);
+ broadcaster.broadcast(callbackMethod + "($.secureEvalJSON('" + gson.toJson(response) + "'))");
+ if (broadcaster.getAtmosphereResources().isEmpty()) {
+ CometSessionManager.remove(sessionId);
+ }
+ } else {
+ wire.invoke(operation, msg);
+ }
+ }
+
+ /**
+ * Convert request parameters from JSON to operation parameter types.
+ *
+ * @param jsonData
+ * @param operation
+ * @return
+ */
+ private Object[] decodeJsonDataForOperation(String jsonData, Operation operation) {
+ Object[] args = new Object[operation.getInputType().getLogical().size()];
+ final String[] json = this.parseArray(jsonData);
+ int index = 0;
+ // convert each argument to the corresponding class
+ for (final DataType<?> dataType : operation.getInputType().getLogical()) {
+ args[index] = gson.fromJson(json[index], dataType.getPhysical());
+ index++;
+ }
+ return args;
+ }
+
+ /**
+ * Creates the message to be sent with a mocked EndpointReference in the
+ * 'from' field as the request comes from a browser (there is no actual
+ * comet reference running in a controlled environment).
+ *
+ * @param args
+ * @param callbackMethod
+ * @return
+ */
+ private Message createMessageWithMockedCometReference(Object[] args, String sessionId, String callbackMethod) {
+ Message msg = new MessageImpl();
+ msg.getHeaders().put(Constants.MESSAGE_ID, sessionId);
+ msg.setBody(args);
+ EndpointReference re = new RuntimeEndpointReferenceImpl();
+ RuntimeEndpointImpl callbackEndpoint = new RuntimeEndpointImpl();
+ callbackEndpoint.setURI(callbackMethod);
+ re.setCallbackEndpoint(callbackEndpoint);
+ msg.setFrom(re);
+ return msg;
+ }
+
+ /**
+ * Parse the JSON array containing the arguments for the method call in
+ * order to avoid converting JSON to Object[]. Converting each object
+ * separately to it's corresponding type avoids type mismatch problems at
+ * service invocation.
+ *
+ * @param jsonArray
+ * the JSON array
+ * @return an array of JSON formatted objects
+ */
+ private String[] parseArray(final String jsonArray) {
+ final List<String> objects = new ArrayList<String>();
+ 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;
+ }
+ }
+ }
+ // add last object
+ objects.add(jsonArray.substring(startPos, jsonArray.length() - 1));
+ return objects.toArray(new String[] {});
+ }
}