diff --git a/.gitignore b/.gitignore
index 49134a8..eaf3d7b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,5 +20,5 @@ dist
war
build.properties
target
-com.glines.socketio.sample.gwtchat.GWTChat
+com.codeminders.socketio.sample.gwtchat.GWTChat
samples/chat-gwt/src/main/gwt-unitCache/
\ No newline at end of file
diff --git a/README b/README
deleted file mode 100644
index ef49c8e..0000000
--- a/README
+++ /dev/null
@@ -1,28 +0,0 @@
-Java backend integration for Socket.IO library (http://socket.io/)
-
-To use in a jetty webapp, grant access in your jetty xml file to the jetty server class org.eclipse.jetty.server.HttpConnection
-
-
-
-
-
-
-
- -org.eclipse.jetty.server.HttpConnection
- -org.eclipse.jetty.continuation.
- -org.eclipse.jetty.jndi.
- -org.eclipse.jetty.plus.jaas.
- -org.eclipse.jetty.websocket.
- -org.eclipse.jetty.servlet.DefaultServlet
- org.eclipse.jetty.
-
-
-
-
-
-More info:
-
-mvn eclipse:eclipse # for import the project in eclipse
-mvn install -Dlicense.skip=true # to install the jars in your repo
-
-Lauch from eclipse the Start* sample classes to test it.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6ccfcb0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,43 @@
+Java backend for `Socket.IO` library (http://socket.io/)
+
+Supports `Socket.IO` clients version 1.0+
+Requires JSR 356-compatible server (tested with Jetty 9 and Tomcat 8)
+
+Right now only websocket and XHR polling transports are implemented.
+
+Based on https://github.com/tadglines/Socket.IO-Java
+
+License: MIT
+
+## Websocket endpoint initialization in Jetty
+
+Default websocket endpoint configuration assumes it's located in the root context and accessible via `/socket.io/` path.
+
+When `Socket.IO` backend is integrated into webapp managed by Jetty there is no need to perform additional configuration because Jetty scans for `@ServerEndpoint` annotation and initializes websocket endpoint automatically.
+
+When Jetty server is embedded into your application, websocket endpoint is located in the root context ("/") and expected to be accessible via `/socket.io/` path (default configuration), then in order to initialize endpoint you should add the following code
+
+```java
+ WebSocketServerContainerInitializer.
+ configureContext(context).
+ addEndpoint(WebsocketTransportConnection.class);
+
+```
+
+When Jetty server is embedded into your application, but websocket endpoint is either located not in the root context ("/") or expected to be accessible via path other than `/socket.io/`, then in order to initialize endpoint you should add the following code
+
+```java
+ ServerContainer serverContainer = WebSocketServerContainerInitializer.
+ configureContext(context);
+ serverContainer.
+ addEndpoint(new AnnotatedServerEndpointConfig(serverContainer,
+ WebsocketTransportConnection.class,
+ WebsocketTransportConnection.class.getAnnotation(ServerEndpoint.class),
+ null) {
+ @Override
+ public String getPath() {
+ return "/"; // context-relative path, "/bar" for context "/foo" and path "/foo/bar"
+ }
+ });
+```
+See example in [com.codeminders.socketio.sample.jetty.ChatServer](https://github.com/codeminders/socket.io-server-java/blob/master/samples/jetty/src/main/java/com/codeminders/socketio/sample/jetty/ChatServer.java)
diff --git a/TODO b/TODO
index e6b6aae..1adf1c1 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,2 @@
-1. Maven pom.xml
-
-2. Add unit tests
-
-3. Add embedded containers to run sample webapps
-
-4. Split project in modules (core, samples, gwt, ...)
+* handle b64 flag
+* JSONP polling transport (not sure how to test it)
diff --git a/core/pom.xml b/core/pom.xml
deleted file mode 100644
index 1ed748a..0000000
--- a/core/pom.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
- 4.0.0
-
-
- com.glines.socketio
- socketio
- 0.2.1
- ..
-
-
- socketio-core
- jar
-
- Socket.IO Java Core
- Core Socket.IO classes
-
-
-
- org.mortbay.jetty
- servlet-api
- provided
-
-
- log4j
- log4j
- true
-
-
-
-
diff --git a/core/src/main/java/com/glines/socketio/client/common/SocketIOConnection.java b/core/src/main/java/com/glines/socketio/client/common/SocketIOConnection.java
deleted file mode 100644
index 8cc11ef..0000000
--- a/core/src/main/java/com/glines/socketio/client/common/SocketIOConnection.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.client.common;
-
-import com.glines.socketio.common.ConnectionState;
-import com.glines.socketio.common.DisconnectReason;
-import com.glines.socketio.common.SocketIOException;
-
-public interface SocketIOConnection {
- interface Factory {
- SocketIOConnection create(SocketIOConnectionListener listener,
- String host, short port);
- }
-
- /**
- * Initiate a connection attempt. If the connection succeeds, then the
- * {@link SocketIOConnectionListener#onConnect() onConnect} will be called. If the connection
- * attempt fails, then
- * {@link SocketIOConnectionListener#onDisconnect(DisconnectReason, String) onDisonnect} will
- * be called.
- * @throws IllegalStateException if the socket is not CLOSED.
- */
- void connect();
-
- /**
- * Forcefully disconnect the connection, discarding any unsent messages.
- * This does nothing if the connection is already CLOSED.
- * This will abort an orderly close if one was initiated.
- */
- void disconnect();
-
- /**
- * Initiate an orderly close of the connection.
- *
- * @throws IllegalStateException if the socket is not CONNECTED.
- */
- void close();
-
- /**
- * Return the current socket connection state.
- * @return
- */
- ConnectionState getConnectionState();
-
- /**
- * Send a message.
- *
- * @param message
- * @throws IllegalStateException if the socket is not CONNECTED.
- */
- void sendMessage(String message) throws SocketIOException;
-
- /**
- * Send a message. With a default priority of 0.
- *
- * @param message
- * @throws IllegalStateException if the socket is not CONNECTED.
- * @throws SocketIOException if the message type parser encode() failed.
- */
- void sendMessage(int messageType, String message) throws SocketIOException;
-}
diff --git a/core/src/main/java/com/glines/socketio/client/common/SocketIOConnectionListener.java b/core/src/main/java/com/glines/socketio/client/common/SocketIOConnectionListener.java
deleted file mode 100644
index 4f72ba7..0000000
--- a/core/src/main/java/com/glines/socketio/client/common/SocketIOConnectionListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.client.common;
-
-import com.glines.socketio.common.DisconnectReason;
-
-/**
-* @author Mathieu Carbou (mathieu.carbou@gmail.com)
-*/
-public interface SocketIOConnectionListener {
- void onConnect();
- void onDisconnect(DisconnectReason reason, String errorMessage);
- void onMessage(int messageType, String message);
-}
diff --git a/core/src/main/java/com/glines/socketio/server/AbstractTransport.java b/core/src/main/java/com/glines/socketio/server/AbstractTransport.java
deleted file mode 100644
index daa1ec4..0000000
--- a/core/src/main/java/com/glines/socketio/server/AbstractTransport.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import javax.servlet.ServletConfig;
-
-/**
- * @author Mathieu Carbou
- */
-public abstract class AbstractTransport implements Transport {
-
- private ServletConfig servletConfig;
- private SocketIOConfig config;
- private TransportHandlerProvider transportHandlerProvider;
-
- @Override
- public void destroy() {
- }
-
- @Override
- public final void init(ServletConfig config) throws TransportInitializationException {
- this.servletConfig = config;
- this.config = new ServletBasedSocketIOConfig(servletConfig, getType().toString());
- init();
- }
-
- protected final ServletConfig getServletConfig() {
- return servletConfig;
- }
-
- protected final SocketIOConfig getConfig() {
- return config;
- }
-
- protected void init() throws TransportInitializationException {
- }
-
- protected final TransportHandler newHandler(Class> type, SocketIOSession session) {
- TransportHandler handler = transportHandlerProvider.get(type, getType());
- handler.setSession(session);
- return handler;
- }
-
- @Override
- public String toString() {
- return getType().toString();
- }
-
- @Override
- public final void setTransportHandlerProvider(TransportHandlerProvider transportHandlerProvider) {
- this.transportHandlerProvider = transportHandlerProvider;
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/server/AnnotationTransportHandlerProvider.java b/core/src/main/java/com/glines/socketio/server/AnnotationTransportHandlerProvider.java
deleted file mode 100644
index 5f7bf31..0000000
--- a/core/src/main/java/com/glines/socketio/server/AnnotationTransportHandlerProvider.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import com.glines.socketio.annotation.Handle;
-import com.glines.socketio.util.DefaultLoader;
-import com.glines.socketio.util.ServiceClassLoader;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
-import java.util.EnumMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @author Mathieu Carbou (mathieu.carbou@gmail.com)
- */
-public final class AnnotationTransportHandlerProvider implements TransportHandlerProvider {
-
- private static final Logger LOGGER = Logger.getLogger(AnnotationTransportHandlerProvider.class.getName());
-
- private final Map> handlerClasses = new EnumMap>(TransportType.class);
-
- @Override
- public TransportHandler get(Class> handlerType, TransportType transportType) {
- Class handlerClass = handlerClasses.get(transportType);
- if (handlerClass == null)
- throw new IllegalArgumentException("No TransportHandler found for transport " + transportType);
- if (!handlerType.isAssignableFrom(handlerClass))
- throw new IllegalArgumentException("TransportHandler " + handlerClass.getName() + " is not of required type " + handlerType.getName() + " for transport " + transportType);
- return load(handlerClass);
- }
-
- @Override
- public boolean isSupported(TransportType type) {
- return handlerClasses.containsKey(type);
- }
-
- @Override
- public void init() {
- handlerClasses.clear();
- ServiceClassLoader serviceClassLoader = ServiceClassLoader.load(
- TransportHandler.class,
- new DefaultLoader(Thread.currentThread().getContextClassLoader()));
- Iterator> it = serviceClassLoader.iterator();
- while (it.hasNext()) {
- Class transportHandlerClass;
- try {
- transportHandlerClass = it.next();
- } catch (Throwable e) {
- LOGGER.log(Level.INFO, "Unable to load transport hander class. Error: " + e.getMessage(), e);
- continue;
- }
- // try to load it to see if it is available
- if (load(transportHandlerClass) != null) {
- Handle handle = transportHandlerClass.getAnnotation(Handle.class);
- if (handle != null) {
- for (TransportType type : handle.value()) {
- handlerClasses.put(type, transportHandlerClass);
- }
- }
- }
- }
- }
-
- private static TransportHandler load(Class c) {
- try {
- Constructor ctor = c.getConstructor();
- return ctor.newInstance();
- } catch (InvocationTargetException e) {
- LOGGER.log(Level.INFO, "Unable to load transport handler class " + c.getName() + ". Error: " + e.getTargetException().getMessage(), e.getTargetException());
- } catch (Exception e) {
- LOGGER.log(Level.INFO, "Unable to load transport handler class " + c.getName() + ". Error: " + e.getMessage(), e);
- }
- return null;
- }
-
- @Override
- public Map> listAll() {
- return handlerClasses;
- }
-
-}
diff --git a/core/src/main/java/com/glines/socketio/server/ClasspathTransportDiscovery.java b/core/src/main/java/com/glines/socketio/server/ClasspathTransportDiscovery.java
deleted file mode 100644
index 62113fc..0000000
--- a/core/src/main/java/com/glines/socketio/server/ClasspathTransportDiscovery.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import com.glines.socketio.util.DefaultLoader;
-import com.glines.socketio.util.ServiceClassLoader;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @author Mathieu Carbou
- */
-public final class ClasspathTransportDiscovery implements TransportDiscovery {
-
- private static final Logger LOGGER = Logger.getLogger(ClasspathTransportDiscovery.class.getName());
-
- @Override
- public Iterable discover() {
- List transports = new LinkedList();
- // discover transports lazily
- ServiceClassLoader serviceClassLoader = ServiceClassLoader.load(
- Transport.class,
- new DefaultLoader(Thread.currentThread().getContextClassLoader()));
- Iterator> it = serviceClassLoader.iterator();
- while (it.hasNext()) {
- Class transportClass;
- try {
- transportClass = it.next();
- } catch (Throwable e) {
- LOGGER.log(Level.INFO, "Unable to load transport class: Error: " + e.getMessage(), e);
- continue;
- }
- try {
- Constructor ctor = transportClass.getConstructor();
- transports.add(ctor.newInstance());
- } catch (InvocationTargetException e) {
- LOGGER.log(Level.INFO, "Unable to load transport class " + transportClass.getName() + ". Error: " + e.getTargetException().getMessage(), e.getTargetException());
- } catch (Throwable e) {
- LOGGER.log(Level.INFO, "Unable to load transport class " + transportClass.getName() + ". Error: " + e.getMessage(), e);
- }
- }
- return transports;
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/server/DefaultSession.java b/core/src/main/java/com/glines/socketio/server/DefaultSession.java
deleted file mode 100644
index 9bd639f..0000000
--- a/core/src/main/java/com/glines/socketio/server/DefaultSession.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import com.glines.socketio.common.ConnectionState;
-import com.glines.socketio.common.DisconnectReason;
-import com.glines.socketio.common.SocketIOException;
-
-import java.util.Map;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @author Mathieu Carbou (mathieu.carbou@gmail.com)
- */
-class DefaultSession implements SocketIOSession {
-
- private static final int SESSION_ID_LENGTH = 20;
- private static final Logger LOGGER = Logger.getLogger(DefaultSession.class.getName());
-
- private final SocketIOSessionManager socketIOSessionManager;
- private final String sessionId;
- private final AtomicLong messageId = new AtomicLong(0);
- private final Map attributes = new ConcurrentHashMap();
-
- private SocketIOInbound inbound;
- private TransportHandler handler;
- private ConnectionState state = ConnectionState.CONNECTING;
- private long hbDelay;
- private SessionTask hbDelayTask;
- private long timeout;
- private SessionTask timeoutTask;
- private boolean timedout;
- private String closeId;
-
- DefaultSession(SocketIOSessionManager socketIOSessionManager, SocketIOInbound inbound, String sessionId) {
- this.socketIOSessionManager = socketIOSessionManager;
- this.inbound = inbound;
- this.sessionId = sessionId;
- }
-
- @Override
- public void setAttribute(String key, Object val) {
- attributes.put(key, val);
- }
-
- @Override
- public Object getAttribute(String key) {
- return attributes.get(key);
- }
-
- @Override
- public String getSessionId() {
- return sessionId;
- }
-
- @Override
- public ConnectionState getConnectionState() {
- return state;
- }
-
- @Override
- public SocketIOInbound getInbound() {
- return inbound;
- }
-
- @Override
- public TransportHandler getTransportHandler() {
- return handler;
- }
-
- private void onTimeout() {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Session[" + sessionId + "]: onTimeout");
- if (!timedout) {
- timedout = true;
- state = ConnectionState.CLOSED;
- onDisconnect(DisconnectReason.TIMEOUT);
- handler.abort();
- }
- }
-
- @Override
- public void startTimeoutTimer() {
- clearTimeoutTimer();
- if (!timedout && timeout > 0) {
- timeoutTask = scheduleTask(new Runnable() {
- @Override
- public void run() {
- DefaultSession.this.onTimeout();
- }
- }, timeout);
- }
- }
-
- @Override
- public void clearTimeoutTimer() {
- if (timeoutTask != null) {
- timeoutTask.cancel();
- timeoutTask = null;
- }
- }
-
- private void sendHeartBeat() {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Session[" + sessionId + "]: send heartbeat ");
- try {
- handler.sendMessage(new SocketIOFrame(SocketIOFrame.FrameType.HEARTBEAT, 0, ""));
- } catch (SocketIOException e) {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "handler.sendMessage failed: ", e);
- handler.abort();
- }
- startTimeoutTimer();
- }
-
- @Override
- public void startHeartbeatTimer() {
- clearHeartbeatTimer();
- if (!timedout && hbDelay > 0) {
- hbDelayTask = scheduleTask(new Runnable() {
- @Override
- public void run() {
- sendHeartBeat();
- }
- }, hbDelay);
- }
- }
-
- @Override
- public void clearHeartbeatTimer() {
- if (hbDelayTask != null) {
- hbDelayTask.cancel();
- hbDelayTask = null;
- }
- }
-
- @Override
- public void setHeartbeat(long delay) {
- hbDelay = delay;
- }
-
- @Override
- public long getHeartbeat() {
- return hbDelay;
- }
-
- @Override
- public void setTimeout(long timeout) {
- this.timeout = timeout;
- }
-
- @Override
- public long getTimeout() {
- return timeout;
- }
-
- @Override
- public void startClose() {
- state = ConnectionState.CLOSING;
- closeId = "server";
- try {
- handler.sendMessage(new SocketIOFrame(SocketIOFrame.FrameType.CLOSE, 0, closeId));
- } catch (SocketIOException e) {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "handler.sendMessage failed: ", e);
- handler.abort();
- }
- }
-
- @Override
- public void onMessage(SocketIOFrame message) {
- switch (message.getFrameType()) {
- case CONNECT:
- onPing(message.getData());
- case HEARTBEAT:
- // Ignore this message type as they are only intended to be from server to client.
- startHeartbeatTimer();
- break;
- case CLOSE:
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Session[" + sessionId + "]: onClose: " + message.getData());
- onClose(message.getData());
- break;
- case MESSAGE:
- case JSON_MESSAGE:
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Session[" + sessionId + "]: onMessage: " + message.getData());
- onMessage(message.getData());
- break;
- default:
- // Ignore unknown message types
- break;
- }
- }
-
- @Override
- public void onPing(String data) {
- try {
- handler.sendMessage(new SocketIOFrame(SocketIOFrame.FrameType.CONNECT, 0, data));
- } catch (SocketIOException e) {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "handler.sendMessage failed: ", e);
- handler.abort();
- }
- }
-
- @Override
- public void onPong(String data) {
- clearTimeoutTimer();
- }
-
- @Override
- public void onClose(String data) {
- if (state == ConnectionState.CLOSING) {
- if (closeId != null && closeId.equals(data)) {
- state = ConnectionState.CLOSED;
- onDisconnect(DisconnectReason.CLOSED);
- handler.abort();
- } else {
- try {
- handler.sendMessage(new SocketIOFrame(SocketIOFrame.FrameType.CLOSE, 0, data));
- } catch (SocketIOException e) {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "handler.sendMessage failed: ", e);
- handler.abort();
- }
- }
- } else {
- state = ConnectionState.CLOSING;
- try {
- handler.sendMessage(new SocketIOFrame(SocketIOFrame.FrameType.CLOSE, 0, data));
- handler.disconnectWhenEmpty();
- if ("client".equals(data))
- onDisconnect(DisconnectReason.CLOSED_REMOTELY);
- } catch (SocketIOException e) {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "handler.sendMessage failed: ", e);
- handler.abort();
- }
- }
- }
-
- @Override
- public SessionTask scheduleTask(Runnable task, long delay) {
- final Future> future = socketIOSessionManager.executor.schedule(task, delay, TimeUnit.MILLISECONDS);
- return new SessionTask() {
- @Override
- public boolean cancel() {
- return future.cancel(false);
- }
- };
- }
-
- @Override
- public void onConnect(TransportHandler handler) {
- if (handler == null) {
- state = ConnectionState.CLOSED;
- inbound = null;
- socketIOSessionManager.socketIOSessions.remove(sessionId);
- } else if (this.handler == null) {
- this.handler = handler;
- if (inbound == null) {
- state = ConnectionState.CLOSED;
- handler.abort();
- } else {
- try {
- state = ConnectionState.CONNECTED;
- inbound.onConnect(handler);
- startHeartbeatTimer();
- } catch (Throwable e) {
- if (LOGGER.isLoggable(Level.WARNING))
- LOGGER.log(Level.WARNING, "Session[" + sessionId + "]: Exception thrown by SocketIOInbound.onConnect()", e);
- state = ConnectionState.CLOSED;
- handler.abort();
- }
- }
- } else {
- handler.abort();
- }
- }
-
- @Override
- public void onMessage(String message) {
- if (inbound != null) {
- try {
- inbound.onMessage(SocketIOFrame.TEXT_MESSAGE_TYPE, message);
- } catch (Throwable e) {
- if (LOGGER.isLoggable(Level.WARNING))
- LOGGER.log(Level.WARNING, "Session[" + sessionId + "]: Exception thrown by SocketIOInbound.onMessage()", e);
- }
- }
- }
-
- @Override
- public void onDisconnect(DisconnectReason reason) {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Session[" + sessionId + "]: onDisconnect: " + reason);
- clearTimeoutTimer();
- clearHeartbeatTimer();
- if (inbound != null) {
- state = ConnectionState.CLOSED;
- try {
- inbound.onDisconnect(reason, null);
- } catch (Throwable e) {
- if (LOGGER.isLoggable(Level.WARNING))
- LOGGER.log(Level.WARNING, "Session[" + sessionId + "]: Exception thrown by SocketIOInbound.onDisconnect()", e);
- }
- inbound = null;
- }
- }
-
- @Override
- public void onShutdown() {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Session[" + sessionId + "]: onShutdown");
- if (inbound != null) {
- if (state == ConnectionState.CLOSING) {
- if (closeId != null) {
- onDisconnect(DisconnectReason.CLOSE_FAILED);
- } else {
- onDisconnect(DisconnectReason.CLOSED_REMOTELY);
- }
- } else {
- onDisconnect(DisconnectReason.ERROR);
- }
- }
- socketIOSessionManager.socketIOSessions.remove(sessionId);
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/server/ServletBasedSocketIOConfig.java b/core/src/main/java/com/glines/socketio/server/ServletBasedSocketIOConfig.java
deleted file mode 100644
index 7672617..0000000
--- a/core/src/main/java/com/glines/socketio/server/ServletBasedSocketIOConfig.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import javax.servlet.ServletConfig;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @author Mathieu Carbou
- */
-public final class ServletBasedSocketIOConfig implements SocketIOConfig {
-
- private static final Logger LOGGER = Logger.getLogger(ServletBasedSocketIOConfig.class.getName());
- private static final String KEY_TRANSPORT = SocketIOConfig.class.getName() + ".TRANSPORTS";
-
- private final ServletConfig config;
- private final String namespace;
-
- public ServletBasedSocketIOConfig(ServletConfig config, String namespace) {
- this.namespace = namespace;
- this.config = config;
- }
-
- @Override
- public long getHeartbeatDelay(long def) {
- return getLong(PARAM_HEARTBEAT_DELAY, def);
- }
-
- @Override
- public long getHeartbeatTimeout(long def) {
- return getLong(PARAM_HEARTBEAT_TIMEOUT, def);
- }
-
- @Override
- public long getTimeout(long def) {
- return getLong(PARAM_TIMEOUT, def);
- }
-
- @Override
- public int getBufferSize() {
- return getInt(PARAM_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
- }
-
- @Override
- public int getMaxIdle() {
- return getInt(PARAM_MAX_IDLE, DEFAULT_MAX_IDLE);
- }
-
- @Override
- public void addTransport(Transport transport) {
- getTransportMap().put(transport.getType(), transport);
- }
-
- @Override
- public Collection getTransports() {
- return getTransportMap().values();
- }
-
- @Override
- public Transport getTransport(TransportType type) {
- return getTransportMap().get(type);
- }
-
- @Override
- public void removeTransport(TransportType type) {
- getTransportMap().remove(type);
- }
-
- @Override
- public Transport getWebSocketTransport() {
- return getTransport(TransportType.WEB_SOCKET);
- }
-
- @Override
- public int getInt(String param, int def) {
- String v = getString(param);
- return v == null ? def : Integer.parseInt(v);
- }
-
- @Override
- public long getLong(String param, long def) {
- String v = getString(param);
- return v == null ? def : Long.parseLong(v);
- }
-
- @Override
- public String getNamespace() {
- return namespace;
- }
-
- @Override
- public String getString(String param) {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.fine("Getting InitParameter: " + namespace + "." + param);
- String v = config.getInitParameter(namespace + "." + param);
- if (v == null) {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.fine("Fallback to InitParameter: " + param);
- v = config.getInitParameter(param);
- }
- return v;
- }
-
- @Override
- public String getString(String param, String def) {
- String v = getString(param);
- return v == null ? def : v;
- }
-
- @SuppressWarnings({"unchecked"})
- private Map getTransportMap() {
- Map transports = (Map) config.getServletContext().getAttribute(KEY_TRANSPORT);
- if (transports == null)
- config.getServletContext().setAttribute(KEY_TRANSPORT, transports = new ConcurrentHashMap());
- return transports;
- }
-
-}
diff --git a/core/src/main/java/com/glines/socketio/server/SocketIOFrame.java b/core/src/main/java/com/glines/socketio/server/SocketIOFrame.java
deleted file mode 100644
index 7f5bd2e..0000000
--- a/core/src/main/java/com/glines/socketio/server/SocketIOFrame.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class SocketIOFrame {
- public static final char SEPERATOR_CHAR = ':';
- public static final char MESSAGE_SEPARATOR = '�'; // char code 65535
-
- public enum FrameType {
- UNKNOWN(-1),
- CLOSE(0),
- CONNECT(1),
- HEARTBEAT(2),
- MESSAGE(3),
- JSON_MESSAGE(4),
- EVENT(5),
- ACK(6),
- ERROR(7),
- NOOP(8);
-
- private int value;
-
- FrameType(int value) {
- this.value = value;
- }
-
- public int value() {
- return value;
- }
-
- public static FrameType fromInt(int val) {
- switch (val) {
- case 0:
- return CLOSE;
- case 1:
- return CONNECT;
- case 2:
- return HEARTBEAT;
- case 3:
- return MESSAGE;
- case 4:
- return JSON_MESSAGE;
- case 5:
- return EVENT;
- case 6:
- return ACK;
- case 7:
- return ERROR;
- case 8:
- return NOOP;
- default:
- return UNKNOWN;
- }
- }
- }
-
- public static final int TEXT_MESSAGE_TYPE = 0;
- public static final int JSON_MESSAGE_TYPE = 1;
-
- private static boolean isHexDigit(String str, int start, int end) {
- for (int i = start; i < end; i++) {
- char c = str.charAt(i);
- if (!Character.isDigit(c) &&
- c < 'A' && c > 'F' && c < 'a' && c > 'f') {
- return false;
- }
- }
- return true;
- }
-
- public static List parse(String data) {
- List messages = new ArrayList();
-
- // Parse the data and silently ignore any part that fails to parse properly.
- int messageEnd;
- int start = 0;
- int end = 0;
- while (data.length() > start) {
- if (data.charAt(start) == MESSAGE_SEPARATOR) {
- start += 1;
- end = data.indexOf(MESSAGE_SEPARATOR, start);
- messageEnd = Integer.parseInt(data.substring(start, end));
- start = end + 1;
- end = start + 1;
- messageEnd += start;
- }
- else {
- messageEnd = data.length();
- end = start + 1;
- }
-
- if (!isHexDigit(data, start, end)) {
- break;
- }
-
- int ftype = Integer.parseInt(data.substring(start, end));
-
- FrameType frameType = FrameType.fromInt(ftype);
- if (frameType == FrameType.UNKNOWN) {
- break;
- }
-
- start = end + 1;
- end = data.indexOf(SEPERATOR_CHAR, start);
-
- int messageId = 0;
- if (end - start > 1) {
- messageId = Integer.parseInt(data.substring(start + 1, end));
- }
-
- start = end + 1;
- end = data.indexOf(SEPERATOR_CHAR, start);
-
- String endpoint = "";
- if (end - start > 1) {
- endpoint = data.substring(start + 1, end);
- }
-
- start = end + 1;
- end = messageEnd;
-
- messages.add(new SocketIOFrame(frameType,
- frameType == FrameType.MESSAGE ? TEXT_MESSAGE_TYPE : JSON_MESSAGE_TYPE,
- data.substring(start, end)));
- start = end;
- }
-
- return messages;
- }
-
- public static String encode(FrameType type, String data) {
- StringBuilder str = new StringBuilder(data.length() + 16);
- str.append(Integer.toHexString(type.value()));
- str.append(SEPERATOR_CHAR);
- //str.append("1"); // message id
- str.append(SEPERATOR_CHAR);
- //str.append(""); // endpoint
- str.append(SEPERATOR_CHAR);
- str.append(data);
- return str.toString();
- }
-
- private final FrameType frameType;
- private final int messageType;
- private final String data;
-
- public SocketIOFrame(FrameType frameType, int messageType, String data) {
- this.frameType = frameType;
- this.messageType = messageType;
- this.data = data;
- }
-
- public FrameType getFrameType() {
- return frameType;
- }
-
- public int getMessageType() {
- return messageType;
- }
-
- public String getData() {
- return data;
- }
-
- public String encode() {
- return encode(frameType, data);
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/server/SocketIOInbound.java b/core/src/main/java/com/glines/socketio/server/SocketIOInbound.java
deleted file mode 100644
index 62275ea..0000000
--- a/core/src/main/java/com/glines/socketio/server/SocketIOInbound.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import com.glines.socketio.common.DisconnectReason;
-
-public interface SocketIOInbound {
-
- /**
- * Called when the connection is established. This will only ever be called once.
- *
- * @param outbound The SocketOutbound associated with the connection
- */
- void onConnect(SocketIOOutbound outbound);
-
- /**
- * Called when the socket connection is closed. This will only ever be called once.
- * This method may be called instead of onConnect() if the connection handshake isn't
- * completed successfully.
- *
- * @param reason The reason for the disconnect.
- * @param errorMessage Possibly non null error message associated with the reason for disconnect.
- */
- void onDisconnect(DisconnectReason reason, String errorMessage);
-
- /**
- * Called one per arriving message.
- *
- * @param messageType
- * @param message
- */
- void onMessage(int messageType, String message);
-}
diff --git a/core/src/main/java/com/glines/socketio/server/SocketIOOutbound.java b/core/src/main/java/com/glines/socketio/server/SocketIOOutbound.java
deleted file mode 100644
index 6ca17bc..0000000
--- a/core/src/main/java/com/glines/socketio/server/SocketIOOutbound.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import com.glines.socketio.common.ConnectionState;
-import com.glines.socketio.common.SocketIOException;
-
-public interface SocketIOOutbound {
- /**
- * Terminate the connection. This method may return before the connection disconnect
- * completes. The onDisconnect() method of the associated SocketInbound will be called
- * when the disconnect is completed. The onDisconnect() method may be called during the
- * invocation of this method.
- */
- void disconnect();
-
- /**
- * Initiate an orderly close of the connection. The state will be changed to CLOSING so no
- * new messages can be sent, but messages may still arrive until the distant end has
- * acknowledged the close.
- */
- void close();
-
- ConnectionState getConnectionState();
-
- /**
- * Send a message to the client. This method will block if the message will not fit in the
- * outbound buffer.
- * If the socket is closed, becomes closed, or times out, while trying to send the message,
- * the SocketClosedException will be thrown.
- *
- * @param message The message to send
- * @throws SocketIOException
- */
- void sendMessage(String message) throws SocketIOException;
-
- /**
- * Send a message.
- *
- * @param messageType
- * @param message
- * @throws IllegalStateException if the socket is not CONNECTED.
- * @throws SocketIOException
- */
- void sendMessage(int messageType, String message) throws SocketIOException;
-}
diff --git a/core/src/main/java/com/glines/socketio/server/SocketIOServlet.java b/core/src/main/java/com/glines/socketio/server/SocketIOServlet.java
deleted file mode 100644
index b4727c3..0000000
--- a/core/src/main/java/com/glines/socketio/server/SocketIOServlet.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import com.glines.socketio.util.IO;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public abstract class SocketIOServlet extends HttpServlet {
-
- private static final Logger LOGGER = Logger.getLogger(SocketIOServlet.class.getName());
- private static final long serialVersionUID = 2L;
-
- private final SocketIOSessionManager sessionManager = new SocketIOSessionManager();
- private final TransportHandlerProvider transportHandlerProvider = new AnnotationTransportHandlerProvider();
-
- private SocketIOConfig config;
-
- public final static String DEFAULT_HEARTBEAT_TIMEOUT = "defaultHeartbeatTimeout";
- public final static String DEFAULT_TIMEOUT = "defaultTimeout";
-
- public final static String MAX_TEXT_MESSAGE_SIZE = "maxTextMessageSize";
-
- @Override
- public void init() throws ServletException {
- config = new ServletBasedSocketIOConfig(getServletConfig(), "socketio");
-
- // lazy load available transport handlers
- transportHandlerProvider.init();
- if (LOGGER.isLoggable(Level.INFO))
- LOGGER.log(Level.INFO, "Transport handlers loaded: " + transportHandlerProvider.listAll());
-
- // lazily load available transports
- TransportDiscovery transportDiscovery = new ClasspathTransportDiscovery();
- for (Transport transport : transportDiscovery.discover()) {
- if (transportHandlerProvider.isSupported(transport.getType())) {
- transport.setTransportHandlerProvider(transportHandlerProvider);
- config.addTransport(transport);
- } else {
- LOGGER.log(Level.WARNING, "Transport " + transport.getType() + " ignored since not supported by any TransportHandler");
- }
- }
- // initialize them
- for (Transport t : config.getTransports()) {
- try {
- t.init(getServletConfig());
- } catch (TransportInitializationException e) {
- config.removeTransport(t.getType());
- LOGGER.log(Level.WARNING, "Transport " + t.getType() + " disabled. Initialization failed: " + e.getMessage());
- }
- }
- if (LOGGER.isLoggable(Level.INFO))
- LOGGER.log(Level.INFO, "Transports loaded: " + config.getTransports());
- }
-
- @Override
- public void destroy() {
- for (Transport t : config.getTransports()) {
- t.destroy();
- }
- super.destroy();
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- serve(req, resp);
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- serve(req, resp);
- }
-
- /**
- * Returns an instance of SocketIOInbound or null if the connection is to be denied.
- * The value of cookies and protocols may be null.
- */
- protected abstract SocketIOInbound doSocketIOConnect(HttpServletRequest request);
-
- private void serve(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- String path = request.getPathInfo();
- if (path == null || path.length() == 0 || "/".equals(path)) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing SocketIO transport");
- return;
- }
- if (path.startsWith("/")) path = path.substring(1);
- String[] parts = path.split("/");
-
- if ("GET".equals(request.getMethod()) && "socket.io.js".equals(parts[0])) {
- response.setContentType("text/javascript");
- InputStream is = this.getClass().getClassLoader().getResourceAsStream("com/glines/socketio/socket.io.js");
- OutputStream os = response.getOutputStream();
- IO.copy(is, os);
- return;
- } else if ("GET".equals(request.getMethod()) && "WebSocketMain.swf".equals(parts[0])) {
- response.setContentType("application/x-shockwave-flash");
- InputStream is = this.getClass().getClassLoader().getResourceAsStream("com/glines/socketio/WebSocketMain.swf");
- OutputStream os = response.getOutputStream();
- IO.copy(is, os);
- return;
- } else if (parts.length <= 2) { // handshake
- OutputStream os = response.getOutputStream();
-
- // Format: sessionId : heartbeat : timeout
- String body = request.getSession().getId().toString() +
- ":" + (config.getString(DEFAULT_HEARTBEAT_TIMEOUT) == null ? "15000" : config.getString(DEFAULT_HEARTBEAT_TIMEOUT)) +
- ":" + (config.getString(DEFAULT_TIMEOUT) == null? "10000" : config.getString(DEFAULT_TIMEOUT)) + ":";
-
- String transports = ""; // websocket,flashsocket,xhr-polling,jsonp-polling,htmlfile
- for (Transport transport : config.getTransports()) {
- if (!transports.isEmpty())
- transports += ",";
- transports += transport.getType().toString();
- }
- body += transports;
-
- os.write(body.getBytes());
- return;
- } else {
- Transport transport = config.getTransport(TransportType.from(parts[1]));
- if (transport == null) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown SocketIO transport: " + parts[0]);
- return;
- }
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Handling request from " + request.getRemoteHost() + ":" + request.getRemotePort() + " with transport: " + transport.getType());
-
- transport.handle(request, response, new Transport.InboundFactory() {
- @Override
- public SocketIOInbound getInbound(HttpServletRequest request) {
- return SocketIOServlet.this.doSocketIOConnect(request);
- }
- }, sessionManager);
- }
- }
-
-}
diff --git a/core/src/main/java/com/glines/socketio/server/SocketIOSession.java b/core/src/main/java/com/glines/socketio/server/SocketIOSession.java
deleted file mode 100644
index 39aa9db..0000000
--- a/core/src/main/java/com/glines/socketio/server/SocketIOSession.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server;
-
-import com.glines.socketio.common.ConnectionState;
-import com.glines.socketio.common.DisconnectReason;
-
-public interface SocketIOSession {
- void setAttribute(String key, Object val);
- Object getAttribute(String key);
-
- interface SessionTask {
- /**
- * @return True if task was or was already canceled, false if the task is executing or has executed.
- */
- boolean cancel();
- }
-
- String getSessionId();
-
- ConnectionState getConnectionState();
-
- SocketIOInbound getInbound();
-
- TransportHandler getTransportHandler();
-
- void setHeartbeat(long delay);
- long getHeartbeat();
- void setTimeout(long timeout);
- long getTimeout();
-
- void startTimeoutTimer();
- void clearTimeoutTimer();
-
- void startHeartbeatTimer();
- void clearHeartbeatTimer();
-
- /**
- * Initiate close.
- */
- void startClose();
-
- void onMessage(SocketIOFrame message);
- void onPing(String data);
- void onPong(String data);
- void onClose(String data);
-
- /**
- * Schedule a task (e.g. timeout timer)
- * @param task The task to execute after specified delay.
- * @param delay Delay in milliseconds.
- * @return
- */
- SessionTask scheduleTask(Runnable task, long delay);
-
- /**
- * @param handler The handler or null if the connection failed.
- */
- void onConnect(TransportHandler handler);
-
- /**
- * Pass message through to contained SocketIOInbound
- * If a timeout timer is set, then it will be reset.
- * @param message
- */
- void onMessage(String message);
-
- /**
- * Pass disconnect through to contained SocketIOInbound and update any internal state.
- * @param reason
- */
- void onDisconnect(DisconnectReason reason);
-
- /**
- * Called by handler to report that it is done and the session can be cleaned up.
- * If onDisconnect has not been called yet, then it will be called with DisconnectReason.ERROR.
- */
- void onShutdown();
-}
diff --git a/core/src/main/java/com/glines/socketio/server/transport/AbstractHttpTransport.java b/core/src/main/java/com/glines/socketio/server/transport/AbstractHttpTransport.java
deleted file mode 100644
index ce6068c..0000000
--- a/core/src/main/java/com/glines/socketio/server/transport/AbstractHttpTransport.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server.transport;
-
-import com.glines.socketio.server.*;
-import com.glines.socketio.util.Web;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public abstract class AbstractHttpTransport extends AbstractTransport {
-
- private static final Logger LOGGER = Logger.getLogger(AbstractHttpTransport.class.getName());
- public static final String SESSION_KEY = AbstractHttpTransport.class.getName() + ".Session";
-
- @Override
- public final void handle(HttpServletRequest request,
- HttpServletResponse response,
- Transport.InboundFactory inboundFactory,
- SessionManager sessionFactory) throws IOException {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.fine("Handling request " + request.getRequestURI() + " by " + getClass().getName());
-
- SocketIOSession session = null;
- String sessionId = Web.extractSessionId(request);
- if (sessionId != null && sessionId.length() > 0) {
- session = sessionFactory.getSession(sessionId);
- }
-
- if (session != null) {
- TransportHandler handler = session.getTransportHandler();
- if (handler != null) {
- handler.handle(request, response, session);
- } else {
- session.onShutdown();
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- } else {
- if ("GET".equals(request.getMethod())) {
- session = connect(request, response, inboundFactory,
- sessionFactory, sessionId);
- if (session == null) {
- response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
- }
- } else {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- }
- }
- }
-
- private SocketIOSession connect(HttpServletRequest request,
- HttpServletResponse response,
- InboundFactory inboundFactory,
- SessionManager sessionFactory,
- String sessionId) throws IOException {
- SocketIOInbound inbound = inboundFactory.getInbound(request);
- if (inbound != null) {
- if (sessionId == null)
- sessionId = request.getSession().getId().toString();
- SocketIOSession session = sessionFactory.createSession(inbound, sessionId);
- // get and init data handler
- DataHandler dataHandler = newDataHandler(session);
- dataHandler.init(getConfig());
- // get and init transport handler
- TransportHandler transportHandler = newHandler(ConnectableTransportHandler.class, session);
- ConnectableTransportHandler connectableTransportHandler = ConnectableTransportHandler.class.cast(transportHandler);
- connectableTransportHandler.setDataHandler(dataHandler);
- transportHandler.init(getConfig());
- // connect transport to session
- connectableTransportHandler.connect(request, response);
- return session;
- }
- return null;
- }
-
- protected abstract DataHandler newDataHandler(SocketIOSession session);
-}
diff --git a/core/src/main/java/com/glines/socketio/server/transport/FlashSocketTransport.java b/core/src/main/java/com/glines/socketio/server/transport/FlashSocketTransport.java
deleted file mode 100644
index 167bf4b..0000000
--- a/core/src/main/java/com/glines/socketio/server/transport/FlashSocketTransport.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server.transport;
-
-import com.glines.socketio.server.*;
-import com.glines.socketio.util.IO;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.*;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class FlashSocketTransport extends AbstractTransport {
-
- public static final String PARAM_FLASHPOLICY_DOMAIN = "flashPolicyDomain";
- public static final String PARAM_FLASHPOLICY_SERVER_HOST = "flashPolicyServerHost";
- public static final String PARAM_FLASHPOLICY_SERVER_PORT = "flashPolicyServerPort";
- public static final String PARAM_FLASHPOLICY_PORTS = "flashPolicyPorts";
-
- private static final Logger LOGGER = Logger.getLogger(FlashSocketTransport.class.getName());
- private static final String FLASHFILE_NAME = "WebSocketMain.swf";
- private static final String FLASHFILE_PATH = TransportType.FLASH_SOCKET + "/" + FLASHFILE_NAME;
-
- private ServerSocketChannel flashPolicyServer;
- private ExecutorService executor = Executors.newCachedThreadPool();
- private Future> policyAcceptorThread;
-
- private int flashPolicyServerPort;
- private String flashPolicyServerHost;
- private String flashPolicyDomain;
- private String flashPolicyPorts;
-
- private Transport delegate;
-
- @Override
- public TransportType getType() {
- return TransportType.FLASH_SOCKET;
- }
-
- @Override
- public void init() throws TransportInitializationException {
- this.flashPolicyDomain = getConfig().getString(PARAM_FLASHPOLICY_DOMAIN);
- this.flashPolicyPorts = getConfig().getString(PARAM_FLASHPOLICY_PORTS);
- this.flashPolicyServerHost = getConfig().getString(PARAM_FLASHPOLICY_SERVER_HOST);
- this.flashPolicyServerPort = getConfig().getInt(PARAM_FLASHPOLICY_SERVER_PORT, 843);
- this.delegate = getConfig().getWebSocketTransport();
-
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.fine(getType() + " configuration:\n" +
- " - flashPolicyDomain=" + flashPolicyDomain + "\n" +
- " - flashPolicyPorts=" + flashPolicyPorts + "\n" +
- " - flashPolicyServerHost=" + flashPolicyServerHost + "\n" +
- " - flashPolicyServerPort=" + flashPolicyServerPort + "\n" +
- " - websocket delegate=" + (delegate == null ? "" : delegate.getClass().getName()));
-
- if (delegate == null)
- throw new TransportInitializationException("No WebSocket transport available for this transport: " + getClass().getName());
-
- if (flashPolicyServerHost != null && flashPolicyDomain != null && flashPolicyPorts != null) {
- try {
- startFlashPolicyServer();
- } catch (IOException e) {
- e.printStackTrace();
- // Ignore
- }
- }
- }
-
- @Override
- public void destroy() {
- stopFlashPolicyServer();
- }
-
- @Override
- public void handle(HttpServletRequest request,
- HttpServletResponse response,
- Transport.InboundFactory inboundFactory,
- SessionManager sessionFactory) throws IOException {
-
- String path = request.getPathInfo();
- if (path == null || path.length() == 0 || "/".equals(path)) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid " + TransportType.FLASH_SOCKET + " transport request");
- return;
- }
- if (path.startsWith("/")) path = path.substring(1);
- String[] parts = path.split("/");
- if ("GET".equals(request.getMethod()) && "flashsocket".equals(parts[1])) {
- if (!FLASHFILE_PATH.equals(path)) {
- delegate.handle(request, response, inboundFactory, sessionFactory);
- } else {
- response.setContentType("application/x-shockwave-flash");
- InputStream is = this.getClass().getClassLoader().getResourceAsStream("com/glines/socketio/" + FLASHFILE_NAME);
- OutputStream os = response.getOutputStream();
- try {
- IO.copy(is, os);
- } catch (IOException e) {
- LOGGER.log(Level.FINE, "Error writing " + FLASHFILE_NAME + ": " + e.getMessage(), e);
- }
- }
- } else {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid " + TransportType.FLASH_SOCKET + " transport request");
- }
- }
-
- /**
- * Starts this server, binding to the previously passed SocketAddress.
- */
- public void startFlashPolicyServer() throws IOException {
- final String POLICY_FILE_REQUEST = "";
- flashPolicyServer = ServerSocketChannel.open();
- flashPolicyServer.socket().setReuseAddress(true);
- flashPolicyServer.socket().bind(new InetSocketAddress(flashPolicyServerHost, flashPolicyServerPort));
- flashPolicyServer.configureBlocking(true);
-
- // Spawn a new server acceptor thread, which must accept incoming
- // connections indefinitely - until a ClosedChannelException is thrown.
- policyAcceptorThread = executor.submit(new Runnable() {
- @Override
- public void run() {
- try {
- while (!Thread.currentThread().isInterrupted()) {
- final SocketChannel serverSocket = flashPolicyServer.accept();
- executor.submit(new Runnable() {
- @Override
- public void run() {
- try {
- serverSocket.configureBlocking(true);
- Socket s = serverSocket.socket();
- StringBuilder request = new StringBuilder();
- InputStreamReader in = new InputStreamReader(s.getInputStream());
- int c;
- while ((c = in.read()) != 0 && request.length() <= POLICY_FILE_REQUEST.length()) {
- request.append((char) c);
- }
- if (request.toString().equalsIgnoreCase(POLICY_FILE_REQUEST) ||
- flashPolicyDomain != null && flashPolicyPorts != null) {
- PrintWriter out = new PrintWriter(s.getOutputStream());
- out.println("");
- out.write(0);
- out.flush();
- }
- serverSocket.close();
- } catch (IOException e) {
- LOGGER.log(Level.FINE, "startFlashPolicyServer: " + e.getMessage(), e);
- } finally {
- try {
- serverSocket.close();
- } catch (IOException e) {
- // Ignore error on close.
- }
- }
- }
- });
- }
- } catch (ClosedChannelException e) {
- Thread.currentThread().interrupt();
- } catch (IOException e) {
- Thread.currentThread().interrupt();
- throw new IllegalStateException("Server should not throw a misunderstood IOException", e);
- }
- }
- });
- }
-
- private void stopFlashPolicyServer() {
- if (flashPolicyServer != null) {
- try {
- flashPolicyServer.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- if (policyAcceptorThread != null) {
- try {
- policyAcceptorThread.get();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new IllegalStateException();
- } catch (ExecutionException e) {
- throw new IllegalStateException("Server thread threw an exception", e.getCause());
- }
- if (!policyAcceptorThread.isDone()) {
- throw new IllegalStateException("Server acceptor thread has not stopped.");
- }
- }
- }
-
-}
diff --git a/core/src/main/java/com/glines/socketio/server/transport/HTMLFileDataHandler.java b/core/src/main/java/com/glines/socketio/server/transport/HTMLFileDataHandler.java
deleted file mode 100644
index 3666daf..0000000
--- a/core/src/main/java/com/glines/socketio/server/transport/HTMLFileDataHandler.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server.transport;
-
-import com.glines.socketio.server.SocketIOFrame;
-import com.glines.socketio.server.SocketIOSession;
-import com.glines.socketio.util.JSON;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @author Mathieu Carbou
- */
-final class HTMLFileDataHandler extends AbstractDataHandler {
-
- private static final Logger LOGGER = Logger.getLogger(HTMLFileDataHandler.class.getName());
- private static final long DEFAULT_HEARTBEAT_DELAY = 15 * 1000;
-
- private final SocketIOSession session;
-
- private long hearbeat;
-
- HTMLFileDataHandler(SocketIOSession session) {
- this.session = session;
- }
-
- @Override
- protected void init() {
- this.hearbeat = getConfig().getHeartbeatDelay(DEFAULT_HEARTBEAT_DELAY);
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.fine(getConfig().getNamespace() + " data handler configuration:\n" +
- " - heartbeatDelay=" + hearbeat);
- }
-
- @Override
- public boolean isConnectionPersistent() {
- return true;
- }
-
- @Override
- public void onStartSend(HttpServletResponse response) throws IOException {
- response.setContentType("text/html");
- response.setHeader("Connection", "keep-alive");
- response.setHeader("Transfer-Encoding", "chunked");
- char[] spaces = new char[244];
- Arrays.fill(spaces, ' ');
- ServletOutputStream os = response.getOutputStream();
- os.print("" + new String(spaces));
- response.flushBuffer();
- }
-
- @Override
- public void onWriteData(ServletResponse response, String data) throws IOException {
- response.getOutputStream().print("");
- response.flushBuffer();
- }
-
- @Override
- public void onFinishSend(ServletResponse response) throws IOException {
- }
-
- @Override
- public void onConnect(HttpServletRequest request, HttpServletResponse response) throws IOException {
- onStartSend(response);
- onWriteData(response, SocketIOFrame.encode(SocketIOFrame.FrameType.CONNECT, session.getSessionId()));
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/server/transport/JSONPPollingDataHandler.java b/core/src/main/java/com/glines/socketio/server/transport/JSONPPollingDataHandler.java
deleted file mode 100644
index 64adc9f..0000000
--- a/core/src/main/java/com/glines/socketio/server/transport/JSONPPollingDataHandler.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server.transport;
-
-import com.glines.socketio.server.SocketIOFrame;
-import com.glines.socketio.server.SocketIOSession;
-
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @author Mathieu Carbou
- */
-final class JSONPPollingDataHandler extends AbstractDataHandler {
-
- /**
- * For non persistent connection transports, this is the amount of time to wait
- * for messages before returning empty results.
- */
- private static final long DEFAULT_TIMEOUT = 20 * 1000;
- private static final String FRAME_ID = JSONPPollingDataHandler.class.getName() + "FRAME_ID";
- private static final Logger LOGGER = Logger.getLogger(JSONPPollingDataHandler.class.getName());
-
- private final SocketIOSession session;
- private long timeout;
-
- JSONPPollingDataHandler(SocketIOSession session) {
- this.session = session;
- }
-
- @Override
- protected void init() {
- this.timeout = getConfig().getTimeout(DEFAULT_TIMEOUT);
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.fine(getConfig().getNamespace() + " data handler configuration:\n" +
- " - timeout=" + timeout);
- }
-
- @Override
- public boolean isConnectionPersistent() {
- return false;
- }
-
- @Override
- public void onStartSend(HttpServletResponse response) throws IOException {
- response.setContentType("text/javascript; charset=UTF-8");
- }
-
- @Override
- public void onWriteData(ServletResponse response, String data) throws IOException {
- response.getOutputStream().print("io.j[" + session.getAttribute(FRAME_ID) + "]('");
- response.getOutputStream().print(data);
- response.getOutputStream().print("');");
- }
-
- @Override
- public void onFinishSend(ServletResponse response) throws IOException {
- response.flushBuffer();
- }
-
- @Override
- public void onConnect(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String query = request.getQueryString();
- String[] parts = query.split("&");
- int frameId = 0;
- for (String part : parts) {
- if (part.startsWith("i=")) {
- try {
- frameId = Integer.parseInt(part.substring(2));
- break;
- } catch (NumberFormatException e) { }
- }
- }
- session.setAttribute(FRAME_ID, frameId);
- onStartSend(response);
- onWriteData(response, SocketIOFrame.encode(SocketIOFrame.FrameType.CONNECT, session.getSessionId()));
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/server/transport/XHRMultipartDataHandler.java b/core/src/main/java/com/glines/socketio/server/transport/XHRMultipartDataHandler.java
deleted file mode 100644
index 1352521..0000000
--- a/core/src/main/java/com/glines/socketio/server/transport/XHRMultipartDataHandler.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server.transport;
-
-import com.glines.socketio.server.SocketIOFrame;
-import com.glines.socketio.server.SocketIOSession;
-import com.glines.socketio.util.Web;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @author Mathieu Carbou
- */
-final class XHRMultipartDataHandler extends AbstractDataHandler {
-
- private static final Logger LOGGER = Logger.getLogger(XHRMultipartDataHandler.class.getName());
- private static final int MULTIPART_BOUNDARY_LENGTH = 20;
- private static final long DEFAULT_HEARTBEAT_DELAY = 15 * 1000;
-
- private final SocketIOSession session;
-
- private long hearbeatDelay;
-
- private final String contentType;
- private final String boundarySeperator;
-
- XHRMultipartDataHandler(SocketIOSession session) {
- this.session = session;
- String boundary = Web.generateRandomString(MULTIPART_BOUNDARY_LENGTH);
- boundarySeperator = "--" + boundary;
- contentType = "multipart/x-mixed-replace;boundary=\"" + boundary + "\"";
- }
-
- @Override
- protected void init() {
- this.hearbeatDelay = getConfig().getHeartbeatDelay(DEFAULT_HEARTBEAT_DELAY);
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.fine(getConfig().getNamespace() + " data handler configuration:\n" +
- " - heartbeatDelay=" + hearbeatDelay);
- }
-
- @Override
- public boolean isConnectionPersistent() {
- return true;
- }
-
- @Override
- public void onStartSend(HttpServletResponse response) throws IOException {
- response.setContentType(contentType);
- response.setHeader("Connection", "keep-alive");
- ServletOutputStream os = response.getOutputStream();
- os.print(boundarySeperator);
- response.flushBuffer();
- }
-
- @Override
- public void onWriteData(ServletResponse response, String data) throws IOException {
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Session[" + session.getSessionId() + "]: writeData(START): " + data);
- ServletOutputStream os = response.getOutputStream();
- os.println("Content-Type: text/plain; charset=utf-8");
- os.println();
- os.write(data.getBytes());
- os.println();
- os.println(boundarySeperator);
- response.flushBuffer();
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE, "Session[" + session.getSessionId() + "]: writeData(END): " + data);
- }
-
- @Override
- public void onFinishSend(ServletResponse response) throws IOException {
- }
-
- @Override
- public void onConnect(HttpServletRequest request, HttpServletResponse response) throws IOException {
- onStartSend(response);
- onWriteData(response, SocketIOFrame.encode(SocketIOFrame.FrameType.CONNECT, session.getSessionId()));
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/server/transport/XHRMultipartTransport.java b/core/src/main/java/com/glines/socketio/server/transport/XHRMultipartTransport.java
deleted file mode 100644
index 354166c..0000000
--- a/core/src/main/java/com/glines/socketio/server/transport/XHRMultipartTransport.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server.transport;
-
-import com.glines.socketio.server.SocketIOSession;
-import com.glines.socketio.server.TransportType;
-
-public class XHRMultipartTransport extends AbstractHttpTransport {
- @Override
- public TransportType getType() {
- return TransportType.XHR_MULTIPART;
- }
-
- @Override
- protected DataHandler newDataHandler(SocketIOSession session) {
- return new XHRMultipartDataHandler(session);
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/server/transport/XHRPollingDataHandler.java b/core/src/main/java/com/glines/socketio/server/transport/XHRPollingDataHandler.java
deleted file mode 100644
index a457dd9..0000000
--- a/core/src/main/java/com/glines/socketio/server/transport/XHRPollingDataHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.server.transport;
-
-import com.glines.socketio.server.SocketIOFrame;
-import com.glines.socketio.server.SocketIOSession;
-
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @author Mathieu Carbou
- */
-final class XHRPollingDataHandler extends AbstractDataHandler {
-
- /**
- * For non persistent connection transports, this is the amount of time to wait
- * for messages before returning empty results.
- */
- private static final long DEFAULT_TIMEOUT = 20 * 1000;
- private static final Logger LOGGER = Logger.getLogger(XHRPollingDataHandler.class.getName());
-
- private final SocketIOSession session;
- private long timeout;
-
- XHRPollingDataHandler(SocketIOSession session) {
- this.session = session;
- }
-
- @Override
- protected void init() {
- this.timeout = getConfig().getTimeout(DEFAULT_TIMEOUT);
- if (LOGGER.isLoggable(Level.FINE))
- LOGGER.fine(getConfig().getNamespace() + " data handler configuration:\n" +
- " - timeout=" + timeout);
- }
-
- @Override
- public boolean isConnectionPersistent() {
- return false;
- }
-
- @Override
- public void onStartSend(HttpServletResponse response) throws IOException {
- response.setContentType("text/plain; charset=UTF-8");
- }
-
- @Override
- public void onWriteData(ServletResponse response, String data) throws IOException {
- response.getOutputStream().print(data);
- response.flushBuffer();
- }
-
- @Override
- public void onFinishSend(ServletResponse response) throws IOException {
- }
-
- @Override
- public void onConnect(HttpServletRequest request, HttpServletResponse response) throws IOException {
- onStartSend(response);
- onWriteData(response, SocketIOFrame.encode(SocketIOFrame.FrameType.CONNECT, session.getSessionId()));
- }
-}
diff --git a/core/src/main/java/com/glines/socketio/util/DefaultLoader.java b/core/src/main/java/com/glines/socketio/util/DefaultLoader.java
deleted file mode 100644
index b774f76..0000000
--- a/core/src/main/java/com/glines/socketio/util/DefaultLoader.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.util;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * @author Mathieu Carbou (mathieu.carbou@gmail.com)
- */
-public class DefaultLoader implements Loader {
-
- private final ClassLoader classLoader;
-
- public DefaultLoader() {
- this(getDefaultClassLoader());
- }
-
- public DefaultLoader(ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
- @Override
- public Class> loadClass(String className) {
- try {
- return classLoader.loadClass(className);
- } catch (ClassNotFoundException e) {
- throw new IllegalArgumentException("Unable to load class " + className, e);
- }
- }
-
- @Override
- public URL getResource(String path) {
- return classLoader.getResource(path);
- }
-
- @Override
- public List getResources(String path) {
- List urls = new LinkedList();
- try {
- Enumeration e = classLoader.getResources(path);
- while (e.hasMoreElements())
- urls.add(e.nextElement());
- } catch (IOException ignored) {
- }
- return urls;
- }
-
- private static ClassLoader getDefaultClassLoader() {
- ClassLoader cl = null;
- try {
- cl = Thread.currentThread().getContextClassLoader();
- }
- catch (Throwable ignored) {
- }
- if (cl == null)
- cl = DefaultLoader.class.getClassLoader();
- return cl;
- }
-
-}
\ No newline at end of file
diff --git a/core/src/main/java/com/glines/socketio/util/IO.java b/core/src/main/java/com/glines/socketio/util/IO.java
deleted file mode 100644
index cb18dd4..0000000
--- a/core/src/main/java/com/glines/socketio/util/IO.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.util;
-
-import java.io.*;
-
-/**
- * @author Mathieu Carbou
- */
-public final class IO {
- private IO() {
- }
-
- public static void copy(InputStream is, OutputStream os) throws IOException {
- byte[] buffer = new byte[64 * 1024];
- int len;
- while ((len = is.read(buffer)) >= 0)
- os.write(buffer, 0, len);
- }
-
- public static void copy(Reader in, Writer out) throws IOException {
- char[] buffer = new char[64 * 1024];
- int len;
- while ((len = in.read(buffer)) >= 0)
- out.write(buffer, 0, len);
- }
-
- public static String toString(InputStream in) throws IOException {
- return toString(in, null);
- }
-
- public static String toString(Reader in) throws IOException {
- StringWriter writer = new StringWriter();
- copy(in, writer);
- return writer.toString();
- }
-
- public static String toString(InputStream in, String encoding) throws IOException {
- InputStreamReader reader = encoding == null ? new InputStreamReader(in) : new InputStreamReader(in, encoding);
- return toString(reader);
- }
-
-}
diff --git a/core/src/main/java/com/glines/socketio/util/JSON.java b/core/src/main/java/com/glines/socketio/util/JSON.java
deleted file mode 100644
index 174f88c..0000000
--- a/core/src/main/java/com/glines/socketio/util/JSON.java
+++ /dev/null
@@ -1,1116 +0,0 @@
-/**
- * The MIT License
- * Copyright (c) 2010 Tad Glines
- *
- * Contributors: Ovea.com, Mycila.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.glines.socketio.util;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.lang.reflect.Array;
-import java.util.*;
-
-public final class JSON {
-
- private static final int BUFFER = 1024;
-
- private JSON() {
- }
-
- public static String toString(Object object) {
- StringBuilder buffer = new StringBuilder(BUFFER);
- append(buffer, object);
- return buffer.toString();
- }
-
-
- public static String toString(Map object) {
- StringBuilder buffer = new StringBuilder(BUFFER);
- appendMap(buffer, object);
- return buffer.toString();
- }
-
-
- public static String toString(Object[] array) {
- StringBuilder buffer = new StringBuilder(BUFFER);
- appendArray(buffer, array);
- return buffer.toString();
- }
-
-
- /**
- * @param s String containing JSON object or array.
- * @return A Map, Object array or primitive array parsed from the JSON.
- */
- public static Object parse(String s) {
- return parse(new StringSource(s), false);
- }
-
-
- /**
- * @param s String containing JSON object or array.
- * @param stripOuterComment If true, an outer comment around the JSON is ignored.
- * @return A Map, Object array or primitive array parsed from the JSON.
- */
- public static Object parse(String s, boolean stripOuterComment) {
- return parse(new StringSource(s), stripOuterComment);
- }
-
-
- /**
- * @param in Reader containing JSON object or array.
- * @return A Map, Object array or primitive array parsed from the JSON.
- * @throws java.io.IOException -
- */
- public static Object parse(Reader in) throws IOException {
- return parse(new ReaderSource(in), false);
- }
-
-
- /**
- * @param in Reader containing JSON object or array.
- * @param stripOuterComment If true, an outer comment around the JSON is ignored.
- * @return A Map, Object array or primitive array parsed from the JSON.
- * @throws java.io.IOException -
- */
- public static Object parse(Reader in, boolean stripOuterComment) throws IOException {
- return parse(new ReaderSource(in), stripOuterComment);
- }
-
-
- /**
- * Append object as JSON to string buffer.
- *
- * @param buffer the buffer to append to
- * @param object the object to append
- */
- public static void append(Appendable buffer, Object object) {
- try {
- if (object == null)
- buffer.append("null");
- else if (object instanceof Convertible)
- appendJSON(buffer, (Convertible) object);
- else if (object instanceof Generator)
- appendJSON(buffer, (Generator) object);
- else if (object instanceof Map)
- appendMap(buffer, (Map) object);
- else if (object instanceof Collection)
- appendArray(buffer, (Collection) object);
- else if (object.getClass().isArray())
- appendArray(buffer, object);
- else if (object instanceof Number)
- appendNumber(buffer, (Number) object);
- else if (object instanceof Boolean)
- appendBoolean(buffer, (Boolean) object);
- else if (object instanceof Character)
- appendString(buffer, object.toString());
- else if (object instanceof String)
- appendString(buffer, (String) object);
- else {
- appendString(buffer, object.toString());
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-
- public static void appendNull(Appendable buffer) {
- try {
- buffer.append("null");
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-
- public static void appendJSON(final Appendable buffer, Convertible converter) {
- ConvertableOutput out = new ConvertableOutput(buffer);
- converter.toJSON(out);
- out.complete();
- }
-
-
- public static void appendJSON(Appendable buffer, Generator generator) {
- generator.addJSON(buffer);
- }
-
-
- public static void appendMap(Appendable buffer, Map, ?> map) {
- try {
- if (map == null) {
- appendNull(buffer);
- return;
- }
-
- buffer.append('{');
- Iterator> iter = map.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry, ?> entry = (Map.Entry, ?>) iter.next();
- quote(buffer, entry.getKey().toString());
- buffer.append(':');
- append(buffer, entry.getValue());
- if (iter.hasNext())
- buffer.append(',');
- }
-
- buffer.append('}');
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-
- public static void appendArray(Appendable buffer, Collection collection) {
- try {
- if (collection == null) {
- appendNull(buffer);
- return;
- }
-
- buffer.append('[');
- Iterator iter = collection.iterator();
- boolean first = true;
- while (iter.hasNext()) {
- if (!first)
- buffer.append(',');
-
- first = false;
- append(buffer, iter.next());
- }
-
- buffer.append(']');
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-
- public static void appendArray(Appendable buffer, Object array) {
- try {
- if (array == null) {
- appendNull(buffer);
- return;
- }
-
- buffer.append('[');
- int length = Array.getLength(array);
-
- for (int i = 0; i < length; i++) {
- if (i != 0)
- buffer.append(',');
- append(buffer, Array.get(array, i));
- }
-
- buffer.append(']');
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-
- public static void appendBoolean(Appendable buffer, Boolean b) {
- try {
- if (b == null) {
- appendNull(buffer);
- return;
- }
- buffer.append(b ? "true" : "false");
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-
- public static void appendNumber(Appendable buffer, Number number) {
- try {
- if (number == null) {
- appendNull(buffer);
- return;
- }
- buffer.append(String.valueOf(number));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-
- public static void appendString(Appendable buffer, String string) {
- if (string == null) {
- appendNull(buffer);
- return;
- }
- quote(buffer, string);
- }
-
- // Parsing utilities
-
-
- protected static String toString(char[] buffer, int offset, int length) {
- return new String(buffer, offset, length);
- }
-
-
- protected static Map newMap() {
- return new HashMap();
- }
-
-
- protected static Object[] newArray(int size) {
- return new Object[size];
- }
-
- protected static Object convertTo(Class type, Map map) {
- if (type != null && Convertible.class.isAssignableFrom(type)) {
- try {
- Convertible conv = (Convertible) type.newInstance();
- conv.fromJSON(map);
- return conv;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- return map;
- }
-
-
- public static Object parse(Source source, boolean stripOuterComment) {
- int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
- if (!stripOuterComment)
- return parse(source);
-
- int strip_state = 1; // 0=no strip, 1=wait for /*, 2= wait for */
-
- Object o = null;
- while (source.hasNext()) {
- char c = source.peek();
-
- // handle // or /* comment
- if (comment_state == 1) {
- switch (c) {
- case '/':
- comment_state = -1;
- break;
- case '*':
- comment_state = 2;
- if (strip_state == 1) {
- comment_state = 0;
- strip_state = 2;
- }
- }
- }
- // handle /* */ comment
- else if (comment_state > 1) {
- switch (c) {
- case '*':
- comment_state = 3;
- break;
- case '/':
- if (comment_state == 3) {
- comment_state = 0;
- if (strip_state == 2)
- return o;
- } else
- comment_state = 2;
- break;
- default:
- comment_state = 2;
- }
- }
- // handle // comment
- else if (comment_state < 0) {
- switch (c) {
- case '\r':
- case '\n':
- comment_state = 0;
- default:
- break;
- }
- }
- // handle unknown
- else {
- if (!Character.isWhitespace(c)) {
- if (c == '/')
- comment_state = 1;
- else if (c == '*')
- comment_state = 3;
- else if (o == null) {
- o = parse(source);
- continue;
- }
- }
- }
-
- source.next();
- }
-
- return o;
- }
-
-
- public static Object parse(Source source) {
- int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
-
- while (source.hasNext()) {
- char c = source.peek();
-
- // handle // or /* comment
- if (comment_state == 1) {
- switch (c) {
- case '/':
- comment_state = -1;
- break;
- case '*':
- comment_state = 2;
- }
- }
- // handle /* */ comment
- else if (comment_state > 1) {
- switch (c) {
- case '*':
- comment_state = 3;
- break;
- case '/':
- if (comment_state == 3)
- comment_state = 0;
- else
- comment_state = 2;
- break;
- default:
- comment_state = 2;
- }
- }
- // handle // comment
- else if (comment_state < 0) {
- switch (c) {
- case '\r':
- case '\n':
- comment_state = 0;
- break;
- default:
- break;
- }
- }
- // handle unknown
- else {
- switch (c) {
- case '{':
- return parseObject(source);
- case '[':
- return parseArray(source);
- case '"':
- return parseString(source);
- case '-':
- return parseNumber(source);
-
- case 'n':
- complete("null", source);
- return null;
- case 't':
- complete("true", source);
- return Boolean.TRUE;
- case 'f':
- complete("false", source);
- return Boolean.FALSE;
- case 'u':
- complete("undefined", source);
- return null;
- case 'N':
- complete("NaN", source);
- return null;
-
- case '/':
- comment_state = 1;
- break;
-
- default:
- if (Character.isDigit(c))
- return parseNumber(source);
- else if (Character.isWhitespace(c))
- break;
- return handleUnknown(source, c);
- }
- }
- source.next();
- }
-
- return null;
- }
-
-
- protected static Object handleUnknown(Source source, char c) {
- throw new IllegalStateException("unknown char '" + c + "'(" + (int) c + ") in " + source);
- }
-
-
- private static Object parseObject(Source source) {
- if (source.next() != '{')
- throw new IllegalStateException();
- Map map = newMap();
-
- char next = seekTo("\"}", source);
-
- while (source.hasNext()) {
- if (next == '}') {
- source.next();
- break;
- }
-
- String name = parseString(source);
- seekTo(':', source);
- source.next();
-
- Object value = parse(source);
- map.put(name, value);
-
- seekTo(",}", source);
- next = source.next();
- if (next == '}')
- break;
- else
- next = seekTo("\"}", source);
- }
-
- String classname = (String) map.get("class");
- if (classname != null) {
- try {
- Class c = Thread.currentThread().getContextClassLoader().loadClass(classname);
- return convertTo(c, map);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- return map;
- }
-
-
- protected static Object parseArray(Source source) {
- if (source.next() != '[')
- throw new IllegalStateException();
-
- int size = 0;
- ArrayList