Index: BayeuxCometHandler.java =================================================================== --- BayeuxCometHandler.java (revision 645) +++ BayeuxCometHandler.java (working copy) @@ -38,13 +38,20 @@ import com.sun.grizzly.comet.CometContext; import com.sun.grizzly.comet.CometEvent; -import com.sun.grizzly.cometd.bayeux.Connect; +import com.sun.grizzly.cometd.bayeux.ConnectRequest; +import com.sun.grizzly.cometd.bayeux.ConnectResponse; +import com.sun.grizzly.cometd.bayeux.Advice; import com.sun.grizzly.cometd.bayeux.Data; -import com.sun.grizzly.cometd.bayeux.Disconnect; -import com.sun.grizzly.cometd.bayeux.Handshake; -import com.sun.grizzly.cometd.bayeux.Reconnect; -import com.sun.grizzly.cometd.bayeux.Subscribe; -import com.sun.grizzly.cometd.bayeux.Unsubscribe; +import com.sun.grizzly.cometd.bayeux.DisconnectRequest; +import com.sun.grizzly.cometd.bayeux.DisconnectResponse; +import com.sun.grizzly.cometd.bayeux.HandshakeRequest; +import com.sun.grizzly.cometd.bayeux.HandshakeResponse; +import com.sun.grizzly.cometd.bayeux.ReconnectRequest; +import com.sun.grizzly.cometd.bayeux.ReconnectResponse; +import com.sun.grizzly.cometd.bayeux.SubscribeRequest; +import com.sun.grizzly.cometd.bayeux.SubscribeResponse; +import com.sun.grizzly.cometd.bayeux.UnsubscribeRequest; +import com.sun.grizzly.cometd.bayeux.UnsubscribeResponse; import com.sun.grizzly.cometd.bayeux.Verb; import java.io.IOException; import java.util.Random; @@ -81,21 +88,24 @@ CometdRequest req = cometdContext.getRequest(); CometdResponse res = cometdContext.getResponse(); - Handshake handshake = (Handshake)cometdContext.getVerb(); - - boolean handshakeOK = true; - String clientId = ""; - synchronized(random){ - clientId = String.valueOf(Long.toHexString(random.nextLong())); + HandshakeRequest handshakeReq = (HandshakeRequest)cometdContext.getVerb(); + HandshakeResponse handshakeRes = new HandshakeResponse(handshakeReq); + handshakeRes.setAdvice(new Advice()); + if (handshakeReq.isValid()) { + String clientId = null; + synchronized(random){ + clientId = String.valueOf(Long.toHexString(random.nextLong())); + } + + // XXX Why do we need to cache the ID. Memory leak right now + handshakeRes.setClientId(clientId); + } else { + handshakeRes.setSuccessful(false); + handshakeRes.setError("501::invalid handshake"); } - - // XXX Why do we need to cache the ID. Memory leak right now - if (handshakeOK){ - handshake.setClientId(clientId); - } res.setContentType(DEFAULT_CONTENT_TYPE); - res.write(handshake.toJSON()); + res.write(handshakeRes.toJSON()); res.flush(); } @@ -105,21 +115,26 @@ CometdRequest req = cometdContext.getRequest(); CometdResponse res = cometdContext.getResponse(); - Connect connect = (Connect)cometdContext.getVerb(); + ConnectRequest connectReq = (ConnectRequest)cometdContext.getVerb(); - String subscribedChannel = activeChannels.get(connect.getClientId()); + ConnectResponse connectRes = new ConnectResponse(connectReq); + connectRes.setAdvice(new Advice()); + if (!connectReq.isValid()) { + connectRes.setError("501::invalid connect"); + } + String subscribedChannel = activeChannels.get(connectReq.getClientId()); if (subscribedChannel != null){ CometContext cometContext = event.getCometContext(); DataHandler dataHandler = new DataHandler(); dataHandler.attach(new Object[]{req,res}); - dataHandler.setChannel(activeChannels.get(connect.getClientId())); - dataHandler.setClientId(connect.getClientId()); - activeCometHandlers.put(connect.getClientId(),dataHandler); + dataHandler.setChannel(subscribedChannel); + dataHandler.setClientId(connectReq.getClientId()); + activeCometHandlers.put(connectReq.getClientId(),dataHandler); event.getCometContext().addCometHandler(dataHandler); - connect.setAdvice(null); + connectRes.setAdvice(null); } String jsonMessage = (subscribedChannel != null ? - connect.toLongPolledJSON() : connect.toJSON()); + connectRes.toLongPolledJSON() : connectRes.toJSON()); res.setContentType(DEFAULT_CONTENT_TYPE); res.write(jsonMessage); @@ -132,9 +147,13 @@ CometdRequest req = cometdContext.getRequest(); CometdResponse res = cometdContext.getResponse(); - Disconnect disconnect = (Disconnect)cometdContext.getVerb(); + DisconnectRequest disconnectReq = (DisconnectRequest)cometdContext.getVerb(); + DisconnectResponse disconnectRes = new DisconnectResponse(disconnectReq); + if (!disconnectReq.isValid()) { + disconnectRes.setError("501::invalid disonnect"); + } DataHandler dataHandler = - activeCometHandlers.remove(disconnect.getClientId()); + activeCometHandlers.remove(disconnectReq.getClientId()); if (dataHandler != null){ event.getCometContext().notify("disconnecting", @@ -142,7 +161,7 @@ } res.setContentType(DEFAULT_CONTENT_TYPE); - res.write(disconnect.toJSON()); + res.write(disconnectRes.toJSON()); res.flush(); } @@ -152,10 +171,14 @@ CometdRequest req = cometdContext.getRequest(); CometdResponse res = cometdContext.getResponse(); - Reconnect reconnect = (Reconnect)cometdContext.getVerb(); + ReconnectRequest reconnectReq = (ReconnectRequest)cometdContext.getVerb(); + ReconnectResponse reconnectRes = new ReconnectResponse(reconnectReq); + if (!reconnectReq.isValid()) { + reconnectRes.setError("501::invalid reconnect"); + } res.setContentType(DEFAULT_CONTENT_TYPE); - res.write(reconnect.toJSON()); + res.write(reconnectRes.toJSON()); res.flush(); } @@ -165,15 +188,20 @@ CometdRequest req = cometdContext.getRequest(); CometdResponse res = cometdContext.getResponse(); - Subscribe subscribe = (Subscribe)cometdContext.getVerb(); - Data data = subscribe.getData(); + SubscribeRequest subscribeReq = (SubscribeRequest)cometdContext.getVerb(); + SubscribeResponse subscribeRes = new SubscribeResponse(subscribeReq); + if (!subscribeReq.isValid()) { + subscribeRes.setError("501::invalid subscribe"); + } + Data data = subscribeReq.getData(); if (data != null){ - subscribe.setDataId(data.getId()); - activeChannels.put(subscribe.getClientId(),data.getChannel()); + subscribeRes.setData(data); + subscribeReq.setDataId(data.getId()); + activeChannels.put(subscribeReq.getClientId(),data.getChannel()); event.getCometContext().notify(data); } res.setContentType(DEFAULT_CONTENT_TYPE); - res.write(subscribe.toJSON()); + res.write(subscribeRes.toJSON()); res.flush(); } @@ -183,15 +211,20 @@ CometdRequest req = cometdContext.getRequest(); CometdResponse res = cometdContext.getResponse(); - Unsubscribe unsubscribe = (Unsubscribe)cometdContext.getVerb(); - Data data = unsubscribe.getData(); + UnsubscribeRequest unsubscribeReq = (UnsubscribeRequest)cometdContext.getVerb(); + UnsubscribeResponse unsubscribeRes = new UnsubscribeResponse(unsubscribeReq); + if (!unsubscribeReq.isValid()) { + unsubscribeRes.setError("501::invalid unsubscribe"); + } + Data data = unsubscribeReq.getData(); if (data != null){ - unsubscribe.setDataId(data.getId()); - activeChannels.remove(unsubscribe.getClientId()); + unsubscribeRes.setData(data); + unsubscribeRes.setDataId(data.getId()); + activeChannels.remove(unsubscribeReq.getClientId()); event.getCometContext().notify(data); } res.setContentType(DEFAULT_CONTENT_TYPE); - res.write(unsubscribe.toJSON()); + res.write(unsubscribeRes.toJSON()); res.flush(); } @@ -258,4 +291,4 @@ // Not supported } -} \ No newline at end of file +} Index: servlet/CometdServlet.java =================================================================== --- servlet/CometdServlet.java (revision 645) +++ servlet/CometdServlet.java (working copy) @@ -78,13 +78,6 @@ private EventRouter eventRouter; - /** - * Is the BayeuxCometHandler initialized and added to the Grizzly - * CometEngine. - */ - private boolean initialized = false; - - public CometdServlet() { } @@ -111,6 +104,13 @@ } cometContext.setBlockingNotification(true); cometContext.setNotificationHandler(new CometdNotificationHandler()); + + bayeuxCometHandler = new BayeuxCometHandler(); + eventRouter = new EventRouterImpl(cometContext); + int mainHandlerHash = + cometContext.addCometHandler(bayeuxCometHandler,true); + cometContext.addAttribute(BayeuxCometHandler.BAYEUX_COMET_HANDLER, + mainHandlerHash); } @@ -149,20 +149,6 @@ } }; - if (!initialized){ - synchronized(cometContext){ - if (!initialized){ - bayeuxCometHandler = new BayeuxCometHandler(); - eventRouter = new EventRouterImpl(cometContext); - int mainHandlerHash = - cometContext.addCometHandler(bayeuxCometHandler,true); - cometContext.addAttribute(BayeuxCometHandler.BAYEUX_COMET_HANDLER, - mainHandlerHash); - initialized = true; - } - } - } - eventRouter.route(cometdReq,cometdRes); } Index: bayeux/VerbUtils.java =================================================================== --- bayeux/VerbUtils.java (revision 645) +++ bayeux/VerbUtils.java (working copy) @@ -46,13 +46,12 @@ */ public class VerbUtils { - private final static String META = "/meta"; - private final static String HANDSHAKE = "/handshake"; - private final static String CONNECT = "/connect"; - private final static String DISCONNECT = "/disconnect"; - private final static String RECONNECT = "/reconnect"; - private final static String SUBSCRIBE = "/subscribe"; - private final static String UNSUBSCRIBE = "/unsubscribe"; + private final static String HANDSHAKE = Handshake.META_HANDSHAKE; + private final static String CONNECT = Connect.META_CONNECT; + private final static String DISCONNECT = Disconnect.META_DISCONNECT; + private final static String RECONNECT = Reconnect.META_RECONNECT; + private final static String SUBSCRIBE = Subscribe.META_SUBSCRIBE; + private final static String UNSUBSCRIBE = Unsubscribe.META_UNSUBSCRIBE; private final static String STATUS = "/status"; private final static String PING = "/ping"; private final static String DATA = "data"; @@ -116,8 +115,8 @@ } - private final static Handshake newHandshake(Map map){ - Handshake handshake = new Handshake(); + private final static HandshakeRequest newHandshake(Map map){ + HandshakeRequest handshake = new HandshakeRequest(); handshake.setAuthScheme((String)map.get("authScheme")); handshake.setAuthUser((String)map.get("authUser")); @@ -126,14 +125,15 @@ handshake.setVersion((String)map.get("version")); handshake.setMinimumVersion((String)map.get("minimumVersion")); handshake.setId((String)map.get("id")); + handshake.setSupportedConnectionTypes((String[])map.get("supportedConnectionTypes")); handshake.setAdvice(new Advice()); return handshake; } - private final static Connect newConnect(Map map){ - Connect connect = new Connect(); + private final static ConnectRequest newConnect(Map map){ + ConnectRequest connect = new ConnectRequest(); connect.setAuthToken((String)map.get("authToken")); connect.setChannel((String)map.get("channel")); @@ -146,8 +146,8 @@ } - private final static Disconnect newDisconnect(Map map){ - Disconnect disconnect = new Disconnect(); + private final static DisconnectRequest newDisconnect(Map map){ + DisconnectRequest disconnect = new DisconnectRequest(); disconnect.setAuthToken((String)map.get("authToken")); disconnect.setChannel((String)map.get("channel")); @@ -159,8 +159,8 @@ } - private final static Reconnect newReconnect(Map map){ - Reconnect reconnect = new Reconnect(); + private final static ReconnectRequest newReconnect(Map map){ + ReconnectRequest reconnect = new ReconnectRequest(); reconnect.setAuthToken((String)map.get("authToken")); reconnect.setChannel((String)map.get("channel")); @@ -184,8 +184,8 @@ } - private final static Subscribe newSubscribe(Map map){ - Subscribe subscribe = new Subscribe(); + private final static SubscribeRequest newSubscribe(Map map){ + SubscribeRequest subscribe = new SubscribeRequest(); subscribe.setChannel((String)map.get("channel")); subscribe.setAuthToken((String)map.get("authToken")); @@ -197,8 +197,8 @@ } - private final static Unsubscribe newUnsubscribe(Map map){ - Unsubscribe unsubscribe = new Unsubscribe(); + private final static UnsubscribeRequest newUnsubscribe(Map map){ + UnsubscribeRequest unsubscribe = new UnsubscribeRequest(); unsubscribe.setChannel((String)map.get("channel")); unsubscribe.setAuthToken((String)map.get("authToken")); Index: bayeux/Reconnect.java =================================================================== --- bayeux/Reconnect.java (revision 645) +++ bayeux/Reconnect.java (working copy) @@ -91,22 +91,14 @@ * ] * @author Jeanfrancois Arcand */ -public class Reconnect extends Connect{ +abstract class Reconnect extends Connect{ - private Advice advise; - + public final static String META_RECONNECT ="/meta/reconnect"; + public Reconnect() { - type = Verb.RECONNECT; + type = Verb.Type.RECONNECT; } - public Advice getAdvise() { - return advise; - } - - public void setAdvise(Advice advise) { - this.advise = advise; - } - public String toJSON() { return "/*[{" + "\"timestamp\":\"" + FastHttpDateFormat.getCurrentDate() + "\"," @@ -115,4 +107,8 @@ + "\"channel\":\"" + channel + "\"" + "}]*/\n" ; } + + protected String getMetaChannel() { + return META_RECONNECT; + } } Index: bayeux/Ext.java =================================================================== --- bayeux/Ext.java (revision 645) +++ bayeux/Ext.java (working copy) @@ -36,6 +36,7 @@ private Map extensionMap; public Ext() { + type = Verb.Type.EXT; } Index: bayeux/Subscribe.java =================================================================== --- bayeux/Subscribe.java (revision 645) +++ bayeux/Subscribe.java (working copy) @@ -83,18 +83,15 @@ * ] * @author Jeanfrancois Arcand */ -public class Subscribe extends VerbBase{ +abstract class Subscribe extends VerbBase{ + public static final String META_SUBSCRIBE = "/meta/subscribe"; protected String subscription; - protected Advice advise; - protected String clientId; - protected String error = ""; - public Subscribe() { - type = Verb.SUBSCRIBE; + type = Verb.Type.SUBSCRIBE; } public String getSubscription() { @@ -105,30 +102,6 @@ this.subscription = subscription; } - - public String toJSON() { - String timeStamp = FastHttpDateFormat.getCurrentDate(); - return "/*[{" - + "\"id\":\"" + id + "\"," - + "\"subscription\":\"" + subscription + "\"," - + "\"successful\":" + successful + "," - + "\"channel\":\"" + channel + "\"},{" - + "\"successful\":" + successful + "," - + "\"channel\":\"" + subscription + "\"," - + "\"timestamp\":\"" + timeStamp + "\"," - + "\"id\":\"" + dataId + "\"}," - + data.toData() - + "]*/"; - } - - public Advice getAdvise() { - return advise; - } - - public void setAdvise(Advice advise) { - this.advise = advise; - } - public String getClientId() { return clientId; } @@ -137,12 +110,49 @@ this.clientId = clientId; } - public String getError() { - return error; + public boolean isValid() { + return (clientId != null && subscription != null && + getMetaChannel().equals(getChannel())); } - public void setError(String error) { - this.error = error; + protected String getMetaChannel() { + return META_SUBSCRIBE; } - + + /** + * @param isResponse + * @param printTimestamp for UnsubscribeResponse + */ + protected String getBody(boolean isResponse, boolean printTimestamp) { + StringBuilder sb = new StringBuilder( + "/*[{" + + "\"channel\":\"" + channel + "\"" + ); + if (isResponse) { + sb.append(",\"successful\":" + successful); + } + sb.append(",\"clientId\":\"" + clientId + "\""); + sb.append(",\"subscription\":\"" + subscription + "\""); + if (isResponse && error != null) { + sb.append(",\"error\":\"" + error + "\""); + } + if (isResponse && advice != null) { + sb.append("," + advice.toJSON()); + } + if (ext != null) { + sb.append("," + ext.toJSON()); + } + if (id != null) { + sb.append(",\"id\":\"" + id + "\""); + } + if (printTimestamp) { + sb.append(",\"timestamp\":\"" + FastHttpDateFormat.getCurrentDate() + "\""); + } + sb.append("}"); + if (data != null) { + sb.append("," + data.toData()); + } + sb.append("]*/\n"); + return sb.toString(); + } } Index: bayeux/Status.java =================================================================== --- bayeux/Status.java (revision 645) +++ bayeux/Status.java (working copy) @@ -44,7 +44,7 @@ public class Status extends VerbBase { public Status() { - type = Verb.STATUS; + type = Verb.Type.STATUS; } public String toJSON() { Index: bayeux/Unsubscribe.java =================================================================== --- bayeux/Unsubscribe.java (revision 645) +++ bayeux/Unsubscribe.java (working copy) @@ -79,22 +79,14 @@ * * @author Jeanfrancois Arcand */ -public class Unsubscribe extends Subscribe{ +abstract class Unsubscribe extends Subscribe { + public static final String META_UNSUBSCRIBE = "/meta/unsubscribe"; public Unsubscribe() { - type = Verb.UNSUBSCRIBE; + type = Verb.Type.UNSUBSCRIBE; } - public String toJSON() { - String timeStamp = FastHttpDateFormat.getCurrentDate(); - return "/*[{" - + "\"id\":\"" + id + "\"," - + "\"subscription\":\"" + subscription + "\"," - + "\"successful\":" + successful + "," - + "\"channel\":\"" + channel + "\"},{" - + "\"successful\":" + successful + "," - + "\"channel\":\"" + subscription + "\"," - + "\"timestamp\":\"" + timeStamp + "\"," - + "\"id\":\"" + dataId + "\"}]*/"; - } + protected String getMetaChannel() { + return META_UNSUBSCRIBE; + } } Index: bayeux/Handshake.java =================================================================== --- bayeux/Handshake.java (revision 645) +++ bayeux/Handshake.java (working copy) @@ -101,27 +101,26 @@ * * @author Jeanfrancois Arcand */ -public class Handshake extends VerbBase{ +abstract class Handshake extends VerbBase{ + public static final String META_HANDSHAKE = "/meta/handshake"; private String version = "1.0"; private String minimumVersion = "0.9"; - private String supportedConnectionTypes - = "[\"long-polling\",\"callback-polling\"]"; + private String[] supportedConnectionTypes + = new String[] {"long-polling", "callback-polling"}; private String authScheme=""; private String authUser=""; - - private String clientId; - - private Boolean authSuccessful = Boolean.TRUE; - private boolean successfull = true; + protected String clientId = null; - public Handshake() { - type = Verb.HANDSHAKE; + protected Boolean authSuccessful = Boolean.TRUE; + + protected Handshake() { + type = Verb.Type.HANDSHAKE; } public String getVersion() { @@ -140,11 +139,11 @@ this.minimumVersion = minimumVersion; } - public String getSupportedConnectionTypes() { + public String[] getSupportedConnectionTypes() { return supportedConnectionTypes; } - public void setSupportedConnectionTypes(String supportedConnectionTypes) { + public void setSupportedConnectionTypes(String[] supportedConnectionTypes) { this.supportedConnectionTypes = supportedConnectionTypes; } @@ -164,43 +163,106 @@ this.authUser = authUser; } - public String getClientId() { - return clientId; - } + public boolean isValid() { + float ver; - public void setClientId(String clientId) { - this.clientId = clientId; - } + try { + ver = Float.parseFloat(getVersion()); + } catch(Exception ex) { + return false; + } - public Boolean getAuthSuccessful() { - return authSuccessful; - } + //XXX need to check supportedConnectionTypes later - public void setAuthSuccessful(Boolean authSuccessful) { - this.authSuccessful = authSuccessful; + return (ver <= 1.0) && (ver >= 0.9) && + META_HANDSHAKE.equals(getChannel()); } - - public String toString(){ - return toJSON(); - } - - public String toJSON() { - String extension = ""; - if (ext != null){ - extension = ext.toJSON(); - } - return "/*[{" - + "\"id\":\"" + id + "\"," - + "\"minimumVersion\":" + minimumVersion + "," - + "\"supportedConnectionTypes\":" + supportedConnectionTypes + "," - + "\"successful\":" + successful + "," - + advice.toJSON() + "," - + "\"channel\":\"" + channel + "\"," - + "\"clientId\":\"" + clientId + "\"," - + extension + "," - + "\"version\":" + version - + "}]*/\n"; + protected String toJSON(boolean isResponse) { + StringBuilder sb = new StringBuilder( + "/*[{" + + "\"channel\":\"" + channel + "\"" + + ",\"version\":\"" + version + "\"" + ); + if (supportedConnectionTypes != null) { + sb.append(",\"supportedConnectionTypes\":["); + boolean first = true; + for (String connType : supportedConnectionTypes) { + if (!first) { + sb.append(","); + } else { + first = false; + } + sb.append("\"" + connType + "\""); + } + sb.append("]"); + } + + if (minimumVersion != null) { + sb.append(",\"minimumVersion\":\"" + minimumVersion + "\""); + } + if (ext != null) { + sb.append("," + ext.toJSON()); + } + if (id != null) { + sb.append(",\"id\":\"" + id + "\""); + } + + if (isResponse) { + sb.append(",\"clientId\":\"" + clientId + "\""); + sb.append(",\"successful\":" + successful); + if (advice != null) { + sb.append("," + advice.toJSON()); + } + if (authSuccessful != null) { + sb.append(",\"authSuccessful\":" + authSuccessful); + } + } + + sb.append("}]*/\n"); + return sb.toString(); } + protected String toErrorResponseJSON() { + StringBuilder sb = new StringBuilder( + "/*[{" + + "\"channel\":\"" + channel + "\"" + + ",\"successful\":" + successful + + ",\"error\":\"" + error + "\"" + ); + + if (version != null) { + sb.append(",\"version\":\"" + version + "\""); + } + if (supportedConnectionTypes != null) { + sb.append(",\"supportedConnectionTypes\":["); + boolean first = true; + for (String connType : supportedConnectionTypes) { + if (!first) { + sb.append(","); + } else { + first = false; + } + sb.append("\"" + connType + "\""); + } + sb.append("]"); + } + + if (minimumVersion != null) { + sb.append(",\"minimumVersion\":\"" + minimumVersion + "\""); + } + if (ext != null) { + sb.append("," + ext.toJSON()); + } + if (id != null) { + sb.append(",\"id\":\"" + id + "\""); + } + + if (authSuccessful != null) { + sb.append(",\"authSuccessful\":" + authSuccessful); + } + + sb.append("}]*/\n"); + return sb.toString(); + } } Index: bayeux/VerbBase.java =================================================================== --- bayeux/VerbBase.java (revision 645) +++ bayeux/VerbBase.java (working copy) @@ -57,17 +57,15 @@ protected String channel; protected Data data; - - protected int type; - - + + protected Type type; + protected String authToken; - protected Boolean successful = Boolean.TRUE; - protected String error =""; + protected String error = null; protected Ext ext; @@ -96,12 +94,12 @@ this.authToken = autheToken; } - - public int getType(){ + + public Type getType() { return type; - } + } - + public Ext getExt() { return ext; } @@ -149,4 +147,8 @@ public void setDataId(String dataId) { this.dataId = dataId; } + + public boolean isValid() { + return true; + } } Index: bayeux/Disconnect.java =================================================================== --- bayeux/Disconnect.java (revision 645) +++ bayeux/Disconnect.java (working copy) @@ -36,26 +36,19 @@ package com.sun.grizzly.cometd.bayeux; -import com.sun.grizzly.util.http.FastHttpDateFormat; - /** - * Reserved Verb not yet defined. * * @author Jeanfrancois Arcand */ -public class Disconnect extends Connect{ - +abstract class Disconnect extends Connect { + + public final static String META_DISCONNECT ="/meta/disconnect"; + public Disconnect() { - type = Verb.DISCONNECT; + type = Verb.Type.DISCONNECT; } - - - public String toJSON() { - return "/*[{" - + "\"id\":\"" + id + "\"," - + "\"timestamp\":\"" + FastHttpDateFormat.getCurrentDate() + "\"," - + "\"successful\":" + successful + "," - + "\"channel\":\"" + channel + "\"" - + "}]*/\n" ; + + protected String getMetaChannel() { + return META_DISCONNECT; } } Index: bayeux/Data.java =================================================================== --- bayeux/Data.java (revision 645) +++ bayeux/Data.java (working copy) @@ -87,7 +87,7 @@ private String timestamp; public Data() { - type = Verb.DATA; + type = Verb.Type.DATA; } public String toData() { Index: bayeux/Connect.java =================================================================== --- bayeux/Connect.java (revision 645) +++ bayeux/Connect.java (working copy) @@ -135,7 +135,7 @@ * * @author Jeanfrancois Arcand */ -public class Connect extends VerbBase{ +abstract class Connect extends VerbBase{ public final static String HTML_HEADER = " 0) { + jsonSb.append("\"hosts\":["); + boolean first = true; + for (String host : hosts) { + if (first) { + first = false; + } else { + jsonSb.append(","); + } + + jsonSb.append("\"" + host + "\""); + } + jsonSb.append("]"); + } + + jsonSb.append("}"); + return jsonSb.toString(); } public String getTransport() { Index: bayeux/Ping.java =================================================================== --- bayeux/Ping.java (revision 645) +++ bayeux/Ping.java (working copy) @@ -44,7 +44,7 @@ public class Ping extends VerbBase{ public Ping() { - type = Verb.PING; + type = Verb.Type.PING; } public String toJSON() { Index: bayeux/Verb.java =================================================================== --- bayeux/Verb.java (revision 645) +++ bayeux/Verb.java (working copy) @@ -51,20 +51,24 @@ * @author Jeanfrancois Arcand */ public interface Verb { + + public static enum Type { + HANDSHAKE, + CONNECT, + DISCONNECT, + RECONNECT, // deprecated + SUBSCRIBE, + UNSUBSCRIBE, + STATUS, // deprecated + PING, // deprecated + + // the following are fields, not channels + DATA, + ADVICE, + EXT + } - //XXX Use enum - public static int HANDSHAKE = 0; - public static int CONNECT = 1; - public static int DISCONNECT = 2; - public static int RECONNECT = 3; - public static int SUBSCRIBE = 4; - public static int UNSUBSCRIBE = 5; - public static int STATUS = 6; - public static int PING = 7; - public static int DATA = 8; - public static int ADVISE = 9; - /** * Return the JSON representation of the Verb. */ @@ -74,5 +78,11 @@ /** * Return the Verb's type. */ - public int getType(); + public Type getType(); + + + /** + * Check whether the Verb is valid. + */ + public boolean isValid(); } Index: BayeuxCometHandlerBase.java =================================================================== --- BayeuxCometHandlerBase.java (revision 645) +++ BayeuxCometHandlerBase.java (working copy) @@ -37,7 +37,8 @@ package com.sun.grizzly.cometd; import com.sun.grizzly.comet.CometEvent; -import com.sun.grizzly.cometd.bayeux.Verb; +import com.sun.grizzly.cometd.bayeux.Verb.Type; +import com.sun.grizzly.cometd.bayeux.Verb.Type.*; import java.io.IOException; /** @@ -53,27 +54,39 @@ Object object = event.attachment(); if (object instanceof CometdContext){ - Verb verb = ((CometdContext)object).getVerb(); + Type type = ((CometdContext)object).getVerb().getType(); - if (verb.getType() == Verb.HANDSHAKE){ - onHandshake(event); - } else if (verb.getType() == Verb.CONNECT){ - onConnect(event); - } else if (verb.getType() == Verb.DISCONNECT){ - onDisconnect(event); - } else if (verb.getType() == Verb.RECONNECT){ - onReconnect(event); - } else if (verb.getType() == Verb.SUBSCRIBE){ - onSubscribe(event); - } else if (verb.getType() == Verb.UNSUBSCRIBE){ - onUnsubscribe(event); - } else if (verb.getType() == Verb.DATA){ - onData(event); - } else if (verb.getType() == Verb.PING){ - onPing(event); - } else if (verb.getType() == Verb.STATUS){ - onStatus(event); - } + switch(type) { + case HANDSHAKE: + onHandshake(event); + break; + case CONNECT: + onConnect(event); + break; + case DISCONNECT: + onDisconnect(event); + break; + case RECONNECT: + onReconnect(event); + break; + case SUBSCRIBE: + onSubscribe(event); + break; + case UNSUBSCRIBE: + onUnsubscribe(event); + break; + case DATA: + onData(event); + break; + case PING: + onPing(event); + break; + case STATUS: + onStatus(event); + break; + default: + break; + } } }