From 1491d3d1338236d1dfba96aa2387075c6a74dbb3 Mon Sep 17 00:00:00 2001 From: fmoga Date: Mon, 2 Aug 2010 20:25:24 +0000 Subject: Implemented comet binding using Atmosphere Framework. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@981675 13f79535-47bb-0310-9956-ffa450edef68 --- .../comet/runtime/CometBindingProviderFactory.java | 3 + .../sca/binding/comet/runtime/CometInvoker.java | 125 +---------------- .../runtime/CometReferenceBindingProvider.java | 8 +- .../comet/runtime/CometServiceBindingProvider.java | 15 +- .../sca/binding/comet/runtime/CometServlet.java | 152 ++++++--------------- .../sca/binding/comet/runtime/EventsLogger.java | 67 +++++++++ .../sca/binding/comet/runtime/ScriptFilter.java | 20 +++ 7 files changed, 155 insertions(+), 235 deletions(-) create mode 100644 sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/EventsLogger.java create mode 100644 sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/ScriptFilter.java (limited to 'sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany') diff --git a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/CometBindingProviderFactory.java b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/CometBindingProviderFactory.java index 747ea4d78e..cc30fdd518 100644 --- a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/CometBindingProviderFactory.java +++ b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/CometBindingProviderFactory.java @@ -34,6 +34,7 @@ public class CometBindingProviderFactory implements BindingProviderFactory filters; + + public CometServlet() { + } + public CometServlet(RuntimeEndpoint wire, Operation operation) { + System.out.println("Entering CometServlet constructor..."); this.wire = wire; this.operation = operation; - this.mapper = new ObjectMapper(); + filters = new LinkedList(); + filters.add(new XSSHtmlFilter()); + filters.add(new ScriptFilter()); } @Override - public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { - String jsonRequest = getJSONRequest(servletRequest); - Object[] args = jsonToObjects(jsonRequest); - Object response = invokeService(args); - String jsonResponse = getJSONResponse(servletRequest, response); - servletResponse.getOutputStream().println(jsonResponse); - } - - /** - * Turn the request into JSON - */ - protected String getJSONRequest(ServletRequest servletRequest) throws IOException, JsonParseException, JsonMappingException { - - List types = operation.getInputType().getLogical(); - int typesIndex = 0; - - String jsonRequest = ""; - for (String name : getOrderedParameterNames(servletRequest)) { - if (!name.startsWith("_") && !"callback".equals(name)) { - if (jsonRequest.length() > 1) { - jsonRequest += ", "; - } - - // automatically quote string parammeters so clients work in the usual javascript way - if (typesIndex < types.size() && String.class.equals(types.get(typesIndex).getGenericType())) { - String x = servletRequest.getParameter(name); - // TODO: do this more properly - if (!x.startsWith("\"")) { - jsonRequest += "\"" + x + "\""; - } else { - jsonRequest += x; - } - } else { - jsonRequest += servletRequest.getParameter(name); - } - - } - } - - return "[" + jsonRequest + "]"; + public void init(ServletConfig config) throws ServletException { + System.out.println("Entering CometServlet#init..."); + super.init(config); + filters = new LinkedList(); + filters.add(new XSSHtmlFilter()); + filters.add(new ScriptFilter()); } - /** - * Get the request parameter names in the correct order. - * The request args need to be in the correct order to invoke the service so work out the - * order from the order in the query string. Eg, the url: - * http://localhost:8085/HelloWorldService/sayHello2?first=petra&last=arnold&callback=foo" - * should invoke: - * sayHello2("petra", "arnold") - * so the parameter names should be ordered: "first", "last" - */ - protected SortedSet getOrderedParameterNames(ServletRequest servletRequest) { - final String queryString = ((HttpServletRequest)servletRequest).getQueryString(); - - SortedSet sortedNames = new TreeSet(new Comparator(){ - public int compare(String o1, String o2) { - int i = queryString.indexOf(o1); - int j = queryString.indexOf(o2); - return i - j; - }}); - - Set parameterNames = servletRequest.getParameterMap().keySet(); - for (String name : parameterNames) { - sortedNames.add(name); - } - - return sortedNames; - } - - /** - * Turn the response object into JSON - */ - protected String getJSONResponse(ServletRequest servletRequest, Object response) throws IOException, JsonParseException { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - mapper.writeValue(os , response); - String jsonResponse = os.toString(); - - String callback = servletRequest.getParameter("callback"); - if (callback != null && callback.length() > 1) { - jsonResponse = callback + "(" + jsonResponse + ");"; - } - - return jsonResponse; + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + System.out.println("Entering CometServlet#doGet..."); + Meteor meteor = Meteor.build(req, SCOPE.REQUEST, filters, null); + meteor.addListener(new EventsLogger()); + req.getSession().setAttribute(METEOR_KEY, meteor); + resp.setContentType("text/html"); + meteor.suspend(-1); } - /** - * Turn the request JSON into objects - */ - protected Object[] jsonToObjects(String jsonRequest) throws IOException, JsonParseException, JsonMappingException { - Class c = new Object[0].getClass(); - Object[] args = (Object[])mapper.readValue(jsonRequest, c); - return args; + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + System.out.println("Entering CometServlet#doPost..."); + System.out.println("Getting attributes from servlet context..."); + this.wire = (RuntimeEndpoint)getServletContext().getAttribute("org.apache.tuscany.sca.binding.comet.endpoint"); + this.operation = (Operation)getServletContext().getAttribute("org.apache.tuscany.sca.binding.comet.operation"); + System.out.println("Getting Meteor..."); + Meteor meteor = (Meteor)req.getSession().getAttribute(METEOR_KEY); + meteor.broadcast(invokeService(new Object[] {})); } - /** - * Send the request down the wire to invoke the service - */ protected Object invokeService(Object[] args) { try { return wire.invoke(operation, args); @@ -160,4 +94,4 @@ public class CometServlet extends GenericServlet { throw new RuntimeException(e); } } -} \ No newline at end of file +} diff --git a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/EventsLogger.java b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/EventsLogger.java new file mode 100644 index 0000000000..934f5ef907 --- /dev/null +++ b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/EventsLogger.java @@ -0,0 +1,67 @@ +/* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can obtain + * a copy of the License at https://jersey.dev.java.net/CDDL+GPL.html + * or jersey/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at jersey/legal/LICENSE.txt. + * Sun designates this particular file as subject to the "Classpath" exception + * as provided by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the License + * Header, with the fields enclosed by brackets [] replaced by your own + * identifying information: "Portions Copyrighted [year] + * [name of copyright owner]" + * + * Contributor(s): + * + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package org.apache.tuscany.sca.binding.comet.runtime; + +import org.atmosphere.cpr.AtmosphereResourceEvent; +import org.atmosphere.cpr.AtmosphereResourceEventListener; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class EventsLogger implements AtmosphereResourceEventListener { + + public EventsLogger() { + } + + public void onSuspend(final AtmosphereResourceEvent event) { + System.out.println("onSuspend: " + event.getResource().getRequest().getRemoteAddr() + + event.getResource().getRequest().getRemotePort()); + } + + public void onResume(AtmosphereResourceEvent event) { + System.out.println("onResume: " + event.getResource().getRequest().getRemoteAddr()); + } + + public void onDisconnect(AtmosphereResourceEvent event) { + System.out.println("onDisconnect: " + event.getResource().getRequest().getRemoteAddr() + + event.getResource().getRequest().getRemotePort()); + } + + public void onBroadcast(AtmosphereResourceEvent event) { + System.out.println("onBroadcast: " + event.getMessage()); + } +} diff --git a/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/ScriptFilter.java b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/ScriptFilter.java new file mode 100644 index 0000000000..8964db68cc --- /dev/null +++ b/sca-java-2.x/contrib/modules/binding-comet-runtime/src/main/java/org/apache/tuscany/sca/binding/comet/runtime/ScriptFilter.java @@ -0,0 +1,20 @@ +package org.apache.tuscany.sca.binding.comet.runtime; + +import org.atmosphere.cpr.BroadcastFilter; + +public class ScriptFilter implements BroadcastFilter { + + private static final String BEGIN_SCRIPT_TAG = "\n"; + // TODO: add dynamic function configuration + private static final String DEFAULT_FUNCTION = "window.parent.update"; + + public BroadcastAction filter(Object o) { + if (o instanceof String) { + String message = (String)o; + return new BroadcastAction(BEGIN_SCRIPT_TAG + DEFAULT_FUNCTION + "('" + message + "');\n" + END_SCRIPT_TAG); + } else { + return new BroadcastAction(o); + } + } +} -- cgit v1.2.3