You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2008/09/02 22:00:38 UTC

svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Author: fhanik
Date: Tue Sep  2 13:00:36 2008
New Revision: 691359

URL: http://svn.apache.org/viewvc?rev=691359&view=rev
Log:
Added in Bayeux implementation, as per 
https://issues.apache.org/bugzilla/show_bug.cgi?id=45413
to build, 
ant download
ant
ant -f extras.xml bayeux


Added:
    tomcat/trunk/COPYRIGHT
    tomcat/trunk/java/org/apache/cometd/
    tomcat/trunk/java/org/apache/cometd/bayeux/
    tomcat/trunk/java/org/apache/cometd/bayeux/Bayeux.java
    tomcat/trunk/java/org/apache/cometd/bayeux/Channel.java
    tomcat/trunk/java/org/apache/cometd/bayeux/Client.java
    tomcat/trunk/java/org/apache/cometd/bayeux/DataFilter.java
    tomcat/trunk/java/org/apache/cometd/bayeux/Listener.java
    tomcat/trunk/java/org/apache/cometd/bayeux/Message.java
    tomcat/trunk/java/org/apache/cometd/bayeux/SecurityPolicy.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/
    tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxException.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxRequest.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxServlet.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/ChannelImpl.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/ClientImpl.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/HttpError.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/MessageImpl.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/RequestBase.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/RequestFactory.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/TomcatBayeux.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/request/
    tomcat/trunk/java/org/apache/tomcat/bayeux/request/MetaConnectRequest.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/request/MetaDisconnectRequest.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/request/MetaHandshakeRequest.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/request/MetaSubscribeRequest.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/request/MetaUnsubscribeRequest.java
    tomcat/trunk/java/org/apache/tomcat/bayeux/request/PublishRequest.java
    tomcat/trunk/test/org/apache/cometd/
    tomcat/trunk/test/org/apache/cometd/bayeux/
    tomcat/trunk/test/org/apache/cometd/bayeux/samples/
    tomcat/trunk/test/org/apache/cometd/bayeux/samples/EchoChatClient.java
    tomcat/trunk/webapps/cometd/
    tomcat/trunk/webapps/cometd/WEB-INF/
    tomcat/trunk/webapps/cometd/WEB-INF/filters.json
    tomcat/trunk/webapps/cometd/WEB-INF/web.xml
    tomcat/trunk/webapps/cometd/examples/
    tomcat/trunk/webapps/cometd/examples/chat/
    tomcat/trunk/webapps/cometd/examples/chat/chat.css
    tomcat/trunk/webapps/cometd/examples/chat/chat.js
    tomcat/trunk/webapps/cometd/examples/chat/index.html
    tomcat/trunk/webapps/cometd/examples/dojo/
    tomcat/trunk/webapps/cometd/examples/dojo/dojo/
    tomcat/trunk/webapps/cometd/examples/dojo/dojo/dojo.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojo/dojo.js.uncompressed.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojo/dojo.xd.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojo/dojo.xd.js.uncompressed.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/cometd/
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/cometd.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/cometd.js.uncompressed.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/cometd.xd.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/cometd.xd.js.uncompressed.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/cometd/session.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/cometd/timestamp.js
    tomcat/trunk/webapps/cometd/examples/dojo/dojox/cometd/timesync.js
    tomcat/trunk/webapps/cometd/examples/echo/
    tomcat/trunk/webapps/cometd/examples/echo/index.html
    tomcat/trunk/webapps/cometd/examples/simplechat/
    tomcat/trunk/webapps/cometd/examples/simplechat/cometdchat.htm
    tomcat/trunk/webapps/cometd/examples/tictactoe/
    tomcat/trunk/webapps/cometd/examples/tictactoe/resources/
    tomcat/trunk/webapps/cometd/examples/tictactoe/resources/0.gif   (with props)
    tomcat/trunk/webapps/cometd/examples/tictactoe/resources/1.gif   (with props)
    tomcat/trunk/webapps/cometd/examples/tictactoe/resources/10.gif   (with props)
    tomcat/trunk/webapps/cometd/examples/tictactoe/resources/blank.gif   (with props)
    tomcat/trunk/webapps/cometd/examples/tictactoe/resources/tictactoe.css
    tomcat/trunk/webapps/cometd/examples/tictactoe/ttt1.htm
    tomcat/trunk/webapps/cometd/examples/timesync/
    tomcat/trunk/webapps/cometd/examples/timesync/index.html
    tomcat/trunk/webapps/cometd/index.html
Modified:
    tomcat/trunk/.classpath
    tomcat/trunk/build.properties.default
    tomcat/trunk/build.xml
    tomcat/trunk/extras.xml
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/.classpath
URL: http://svn.apache.org/viewvc/tomcat/trunk/.classpath?rev=691359&r1=691358&r2=691359&view=diff
==============================================================================
--- tomcat/trunk/.classpath (original)
+++ tomcat/trunk/.classpath Tue Sep  2 13:00:36 2008
@@ -1,27 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
 <classpath>
-        <classpathentry excluding="**/.svn/**|org/apache/naming/factory/webservices/" kind="src" path="java"/>
+	<classpathentry excluding="**/.svn/**|org/apache/naming/factory/webservices/" kind="src" path="java"/>
 	<classpathentry kind="src" path="test"/>
 	<classpathentry kind="src" path="webapps/examples/WEB-INF/classes"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="var" path="TOMCAT_LIBS_BASE/eclipse/plugins/org.eclipse.jdt.core_3.3.1.v_780_R33x.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
 	<classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/>
+	<classpathentry kind="var" path="TOMCAT_LIBS_BASE/json-20070829/json.jar"/>
 	<classpathentry kind="output" path=".settings/output"/>
 </classpath>

Added: tomcat/trunk/COPYRIGHT
URL: http://svn.apache.org/viewvc/tomcat/trunk/COPYRIGHT?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/COPYRIGHT (added)
+++ tomcat/trunk/COPYRIGHT Tue Sep  2 13:00:36 2008
@@ -0,0 +1,5 @@
+****For the bayeux implementation*********
+* Copyright 2007-2008 Guy Molinari
+* Copyright 2007-2008 Filip Hanik
+* Copyright 2007 Dojo Foundation
+* Copyright 2007 Mort Bay Consulting Pty. Ltd.

Modified: tomcat/trunk/build.properties.default
URL: http://svn.apache.org/viewvc/tomcat/trunk/build.properties.default?rev=691359&r1=691358&r2=691359&view=diff
==============================================================================
--- tomcat/trunk/build.properties.default (original)
+++ tomcat/trunk/build.properties.default Tue Sep  2 13:00:36 2008
@@ -98,3 +98,8 @@
 commons-daemon.jar=${commons-daemon.lib}/commons-daemon.jar
 commons-daemon.loc=${base-commons.loc}/daemon/binaries/commons-daemon-1.0.1.tar.gz
 commons-daemon.jsvc.tar.gz=${commons-daemon.lib}/bin/jsvc.tar.gz
+
+# ----- JSON Libraries, 
+json-lib.home=${base.path}/json-20070829
+json-lib.lib=http://repo1.maven.org/maven2/org/json/json/20070829/json-20070829.jar
+json-lib.jar=json.jar

Modified: tomcat/trunk/build.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/build.xml?rev=691359&r1=691358&r2=691359&view=diff
==============================================================================
--- tomcat/trunk/build.xml (original)
+++ tomcat/trunk/build.xml Tue Sep  2 13:00:36 2008
@@ -112,6 +112,8 @@
 <!-- Comment this in to show unchecked warnings:     <compilerarg value="-Xlint:unchecked"/> -->
       <classpath refid="tomcat.classpath" />
       <exclude name="org/apache/naming/factory/webservices/**" />
+      <exclude name="org/apache/tomcat/bayeux/**" />
+      <exclude name="org/apache/cometd/**" />
     </javac>
     <tstamp>
       <format property="TODAY" pattern="MMM d yyyy" locale="en"/>

Modified: tomcat/trunk/extras.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/extras.xml?rev=691359&r1=691358&r2=691359&view=diff
==============================================================================
--- tomcat/trunk/extras.xml (original)
+++ tomcat/trunk/extras.xml Tue Sep  2 13:00:36 2008
@@ -76,6 +76,11 @@
   <property name="tomcat-juli.jar" value="${tomcat.extras}/tomcat-juli.jar"/>
   <property name="tomcat-juli-adapters.jar" value="${tomcat.extras}/tomcat-juli-adapters.jar"/>
   <property name="catalina-ws.jar" value="${tomcat.extras}/catalina-ws.jar"/>
+
+  <property name="cometd-api.jar" value="${tomcat.extras}/cometd-api.jar"/>
+  <property name="tomcat-bayeux.jar" value="${tomcat.extras}/tomcat-bayeux.jar"/>
+  <property name="cometd.war" value="${tomcat.extras}/cometd.war"/>
+
 	
   <!-- Classpath -->
   <path id="tomcat.classpath">
@@ -220,7 +225,62 @@
 	
   </target>
 
-  <target name="extras" depends="prepare,commons-logging,webservices">
+  <target name="bayeux">
+    <mkdir dir="${tomcat.extras}"/>
+
+    <copy todir="${tomcat.extras}" file="${json-lib.home}/${json-lib.jar}"/>
+    <!-- Classpath -->
+    <path id="tomcat.bayeux.classpath">
+      <pathelement path="${tomcat.classpath}"/>
+      <pathelement path="${json-lib.home}/${json-lib.jar}"/>
+    </path>
+
+    <!-- compile org.apache.tomcat.bayeux -->
+    <!-- compile org.apache.cometd -->
+    <javac srcdir="java" destdir="${tomcat.classes}"
+           debug="${compile.debug}"
+           deprecation="${compile.deprecation}"
+           source="${compile.source}"
+           optimize="${compile.optimize}">
+      <classpath refid="tomcat.bayeux.classpath" />
+      <include name="org/apache/tomcat/bayeux/**" />
+      <include name="org/apache/cometd/**" />
+    </javac>
+    <!-- Cometd API JAR File -->
+    <jar jarfile="${cometd-api.jar}">
+      <fileset dir="${tomcat.classes}">
+        <exclude name="**/package.html" />
+        <exclude name="**/LocalStrings_*" />
+        <include name="org/apache/cometd/**" />
+      </fileset>
+    </jar>
+    <!-- Cometd API JAR File -->
+    <jar jarfile="${tomcat-bayeux.jar}">
+      <fileset dir="${tomcat.classes}">
+        <exclude name="**/package.html" />
+        <exclude name="**/LocalStrings_*" />
+        <include name="org/apache/tomcat/bayeux/**" />
+      </fileset>
+    </jar>
+
+    <zip zipfile="${cometd.war}">
+      <fileset dir="${basedir}/webapps/cometd">
+        <include name="**/**"/>
+      </fileset>
+    </zip>
+    <checksum file="${cometd-api.jar}" forceOverwrite="yes" fileext=".md5" />
+    <checksum file="${tomcat-bayeux.jar}" forceOverwrite="yes" fileext=".md5" />
+    <checksum file="${tomcat.extras}/${json-lib.jar}" forceOverwrite="yes" fileext=".md5" />
+    <echo>You've built the Tomcat Bayeux libraries, simply add the following libraries to your CATALINA_HOME/lib directory:
+          ${cometd-api.jar}
+          ${tomcat-bayeux.jar} 
+          ${tomcat.extras}/${json-lib.jar}
+To run the sample application, copy the following applications into your CATALINA_BASE/webapps directory
+          ${cometd.war}
+    </echo>
+  </target>
+
+  <target name="extras" depends="prepare,commons-logging,webservices,bayeux">
   </target>
 
   <!-- Download and dependency building -->

Added: tomcat/trunk/java/org/apache/cometd/bayeux/Bayeux.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/cometd/bayeux/Bayeux.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/cometd/bayeux/Bayeux.java (added)
+++ tomcat/trunk/java/org/apache/cometd/bayeux/Bayeux.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cometd.bayeux;
+
+import java.util.List;
+
+/** Bayeux Interface.<br/>
+ * This interface represents the server side API for the Bayeux messaging protocol.
+ * Bayeux is a simple subscribe/publish/receive methodology, not far from JMS, but much simplified.<br/>
+ * It is used both by the actual implementation and by server side clients.<br/>
+ * Server side clients use this to create, retrieve and subscribe to channels.
+ * Server side clients are represented, just like remote clients, through the Client interface.
+ * <br/>
+ * The Bayeux implementations is intended to be thread safe and multiple threads may simultaneously call Bayeux methods.
+ * <br/>
+ * The Bayeux object, is the starting point for any cometd application relying on the Bayeux object.
+ * Dependent on the container, the Bayeux object will be stored in the <code>javax.servlet.ServletContext</code> object
+ * as an attribute under the name <code>Bayeux.DOJOX_COMETD_BAYEUX</code><br/>
+ * To retrieve this object, one would simply call<br/>
+ * <code>Bayeux bx = (Bayeux)getServletContext().getAttribute(Bayeux.DOJOX_COMETD_BAYEUX);
+ * <br/><br/>
+ * The Bayeux protocol is pretty straight forward and includes a bunch of messaging that is not needed to be known to clients,
+ * both server side and remote clients.
+ * This object gets initialized by a container dependent servlet, and the servlet then handles all Bayeux communication from the client.
+ * Remote messsages are delivered to channels, and to server side clients using the <code>Listener</code> interface.<br/>
+ * <br/>
+ * A <code>Bayeux session</code> is active as long as the webapp hosting the Bayeux object is active.<br/>
+ * When the webapplication shuts down, the Bayeux object will unsubscribe all clients and remove all the active channels.
+ * 
+ * @author Greg Wilkins
+ * @author Filip Hanik
+ */
+public interface Bayeux {
+    
+    /**Meta definitions for channels*/
+    public static final String META="/meta";
+    /**Meta definitions for channels*/
+    public static final String META_SLASH="/meta/";
+    /**Meta definitions for channels - connect message*/
+    public static final String META_CONNECT="/meta/connect";
+    /**Meta definitions for channels - client messsage*/
+    public static final String META_CLIENT="/meta/client";
+    /**Meta definitions for channels - disconnect messsage*/
+    public static final String META_DISCONNECT="/meta/disconnect";
+    /**Meta definitions for channels - handshake messsage*/
+    public static final String META_HANDSHAKE="/meta/handshake";
+    /**Meta definitions for channels - ping messsage*/
+    public static final String META_PING="/meta/ping";
+    /**Meta definitions for channels - reconnect messsage
+     * @deprecated
+     */
+    public static final String META_RECONNECT="/meta/reconnect";
+    /**Meta definitions for channels - status messsage*/
+    public static final String META_STATUS="/meta/status";
+    /**Meta definitions for channels - subscribe messsage*/
+    public static final String META_SUBSCRIBE="/meta/subscribe";
+    /**Meta definitions for channels - unsubscribe messsage*/
+    public static final String META_UNSUBSCRIBE="/meta/unsubscribe";
+    /*Field names inside Bayeux messages*/
+    /**Field names inside Bayeux messages - clientId field*/
+    public static final String CLIENT_FIELD="clientId";
+    /**Field names inside Bayeux messages - data field*/
+    public static final String DATA_FIELD="data";
+    /**Field names inside Bayeux messages - channel field*/
+    public static final String CHANNEL_FIELD="channel";
+    /**Field names inside Bayeux messages - id field*/
+    public static final String ID_FIELD="id";
+    /**Field names inside Bayeux messages - error field*/
+    public static final String ERROR_FIELD="error";
+    /**Field names inside Bayeux messages - timestamp field*/
+    public static final String TIMESTAMP_FIELD="timestamp";
+    /**Field names inside Bayeux messages - transport field*/
+    public static final String TRANSPORT_FIELD="transport";
+    /**Field names inside Bayeux messages - advice field*/
+    public static final String ADVICE_FIELD="advice";
+    /**Field names inside Bayeux messages - successful field*/
+    public static final String SUCCESSFUL_FIELD="successful";
+    /**Field names inside Bayeux messages - subscription field*/
+    public static final String SUBSCRIPTION_FIELD="subscription";
+    /**Field names inside Bayeux messages - ext field*/
+    public static final String EXT_FIELD="ext";
+    /**Field names inside Bayeux messages - connectionType field*/
+    public static final String CONNECTION_TYPE_FIELD="connectionType";
+    /**Field names inside Bayeux messages - version field*/
+    public static final String VERSION_FIELD="version";
+    /**Field names inside Bayeux messages - minimumVersion field*/
+    public static final String MIN_VERSION_FIELD="minimumVersion";
+    /**Field names inside Bayeux messages - supportedConnectionTypes field*/
+    public static final String SUPP_CONNECTION_TYPE_FIELD="supportedConnectionTypes";
+    /**Field names inside Bayeux messages - json-comment-filtered field*/
+    public static final String JSON_COMMENT_FILTERED_FIELD="json-comment-filtered";
+    /**Field names inside Bayeux messages - reconnect field*/
+    public static final String RECONNECT_FIELD = "reconnect";
+    /**Field names inside Bayeux messages - interval field*/
+    public static final String INTERVAL_FIELD = "interval";
+    /**Field values inside Bayeux messages - retry response*/
+    public static final String RETRY_RESPONSE = "retry";
+    /**Field values inside Bayeux messages - handshake response*/
+    public static final String HANDSHAKE_RESPONSE = "handshake";
+    /**Field values inside Bayeux messages - none response*/
+    public static final String NONE_RESPONSE = "none";
+    /**Service channel names-starts with*/
+    public static final String SERVICE="/service";
+    /**Service channel names-trailing slash*/
+    public static final String SERVICE_SLASH="/service/";
+    /*Transport types*/
+    /**Transport types - long polling*/
+    public static final String TRANSPORT_LONG_POLL="long-polling";
+    /**Transport types - callback polling*/
+    public static final String TRANSPORT_CALLBACK_POLL="callback-polling";
+    /**Transport types - iframe*/
+    public static final String TRANSPORT_IFRAME="iframe";
+    /**Transport types - flash*/
+    public static final String TRANSPORT_FLASH="flash";
+    /** ServletContext attribute name used to obtain the Bayeux object */
+    public static final String DOJOX_COMETD_BAYEUX="dojox.cometd.bayeux";
+    /*http field names*/
+    /**http helpers - text/json content type*/
+    public static final String JSON_CONTENT_TYPE="text/json";
+    /**http helpers - parameter name for json message*/
+    public static final String MESSAGE_PARAMETER="message";
+    /**http helpers - name of the jsonp parameter*/
+    public static final String JSONP_PARAMETER="jsonp";
+    /**http helpers - default name of the jsonp callback function*/
+    public static final String JSONP_DEFAULT_NAME="jsonpcallback";
+
+    /*--Client----------------------------------------------------------- */
+    /**
+     * Creates a new server side client. This method is to be invoked
+     * by server side objects only. You cannot create a remote client by using this method.
+     * A client represents an entity that can subscribe to channels and publish and receive messages
+     * through these channels
+     * @param idprefix String - the prefix string for the id generated, can be null
+     * @param listener Listener - a callback object to be called when messages are to be delivered to the new client
+     * @return Client - returns an implementation of the client interface.
+     */
+    public Client newClient(String idprefix, Listener listener);
+
+    /**
+     * retrieve a client based on an ID. Will return null if the client doesn't exist.
+     * @param clientid String
+     * @return Client-null if the client doesn't exist.returns the client if it does.
+     */
+    public Client getClient(String clientid);
+    
+    /**
+     * Returns a non modifiable list of all the clients that are currently active
+     * in this Bayeux session
+     * @return List<Client> - a list containing all clients. The List can not be modified.
+     */
+    public List<Client> getClients();
+    
+    /**
+     * Returns true if a client with the given id exists.<br/>
+     * Same as executing <code>getClient(id)!=null</code>.
+     * @param clientId String
+     * @return boolean - true if the client exists
+     */
+    public boolean hasClient(String clientId);
+    
+    /**
+     * Removes the client all together.
+     * This will unsubscribe the client to any channels it may be subscribed to
+     * and remove it from the list.
+     * @param client Client
+     * @return Client - returns the client that was removed, or null if no client was removed.
+     */
+    public Client remove(Client client);
+
+    
+    /*--Channel---------------------------------------------------------- */
+    /**
+     * Returns the channel for a given channel id.
+     * If the channel doesn't exist, and the <code>create</code> parameter is set to true,
+     * the channel will be created and added to the list of active channels.<br/>
+     * if <code>create</code> is set to false, and the channel doesn't exist, null will be returned.
+     * @param channelId String - the id of the channel to be retrieved or created
+     * @param create boolean - true if the Bayeux impl should create the channel
+     * @return Channel - null if <code>create</code> is set to false and the channel doesn't exist, 
+     * otherwise it returns a channel object.
+     */
+    public Channel getChannel(String channelId, boolean create);
+    
+    /**
+     * Returns a list of currently active channels in this Bayeux session.
+     * @return List<Channel>
+     */
+    public List<Channel> getChannels();
+
+    /**
+     * Removes a channel from the Bayeux object.
+     * This will also unsubscribe all the clients currently subscribed to the
+     * the channel.
+     * @param channel Channel - the channel to be removed
+     * @return Channel - returns the channel that was removed, or null if no channel was removed.
+     */
+    public Channel remove(Channel channel);
+
+    /**
+     * returns true if a channel with the given channelId exists.
+     * <br/>Same as executing <code>Bayeux.getChannel(channelId,false)!=null</code>
+     * @param channelId String
+     * @return boolean - true if the channel exists.
+     */
+    public boolean hasChannel(String channelId);
+
+    /* --Message---------------------------------------------------------- */
+    /**
+     * Creates a new message to be sent by a server side client.
+     * @return Message - returns a new Message object, that has a unique id.
+     */
+    public Message newMessage(Client from);
+
+
+    /*--Security policy----------------------------------------------------------- */
+    /**
+     * Returns the security policy associated with this Bayeux session
+     * @return SecurityPolicy
+     */
+    public SecurityPolicy getSecurityPolicy();
+   
+    /**
+     * Sets the security policy to be used in this Bayeux session
+     * @param securityPolicy SecurityPolicy
+     */
+    public void setSecurityPolicy(SecurityPolicy securityPolicy);
+
+}
\ No newline at end of file

Added: tomcat/trunk/java/org/apache/cometd/bayeux/Channel.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/cometd/bayeux/Channel.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/cometd/bayeux/Channel.java (added)
+++ tomcat/trunk/java/org/apache/cometd/bayeux/Channel.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cometd.bayeux;
+
+import java.util.List;
+
+/** 
+ * A Bayeux Channel represents a channel used to receive messages from and to publish messages to.
+ * In order to publish messages to or receive messages from, one must subscribe to the channel.
+ * This is easily done by invoking the <code>subscribe</code> method.
+ * A channel is created by calling the <code>Bayeux.getChannel(channelId,true)</code> method.
+ * A channel can be created either server side by invoking the getChannel, or client side
+ * by using the /meta/subscribe message without a wildcard.
+ * @author Greg Wilkins
+ * @author Filip Hanik
+ */
+public interface Channel
+{
+    /**
+     * Returns the id for this channel. The id is unique within bayeux session.
+     * @return String - will never be null.
+     */
+    public String getId();
+
+    /** 
+     * Publishes a message to all the subscribers of this channel.
+     * The <code>from</code> is contained within the message, by calling
+     * <code>msg.getClient()</code>
+     * @param data - the message to be published, can not be null.
+     */
+    public void publish(Message msg);
+    
+    /** 
+     * Publishes more than one message to all the subscribers of this channel.
+     * The <code>from</code> is contained within the message, by calling
+     * <code>msg[x].getClient()</code>
+     * @param data - the message to be published, can not be null.
+     */
+    public void publish(Message[] msgs);
+
+    /** 
+     * Non persistent channels are removed when the last subscription is
+     * removed. Persistent channels survive periods without any subscribers.
+     * @return true if the Channel will persist without any subscription.
+     */
+    public boolean isPersistent();
+    
+    /**
+     * @param persistent true if the Channel will persist without any subscription.
+     * @see isPersistent
+     */
+    public void setPersistent(boolean persistent);
+    
+    /** 
+     * Subscribes a client to a channel.
+     * @param subscriber - the client to be subscribed. If the client
+     * already is subscribed, this call will not create a duplicate subscription.
+     */
+    public void subscribe(Client subscriber);
+
+    /** 
+     * Unsubscribes a client from a channel
+     * @param subscriber - the client to be subscribed.
+     * @return - returns the client that was unsubscribed, or null if the client wasn't subscribed.
+     */
+    public Client unsubscribe(Client subscriber);
+
+    /**
+     * returns a non modifiable list of all the subscribers to this 
+     * channel.
+     * @return a list of subscribers
+     */
+    public List<Client> getSubscribers();
+    
+    /**
+     * Adds a data filter to this channel. All messages received by this channel 
+     * will run through this filter.
+     * @param filter Filter
+     */
+    public void addFilter(DataFilter filter);
+    
+    /**
+     * Removes a filter from this channel.
+     * returns the filter that was removed, or null if the filter wasn't in the channel.
+     * @param filter Filter
+     * @return Filter - null if no filter was removed otherwise it returns the filter that was removed.
+     */
+    public DataFilter removeFilter(DataFilter filter);
+}
\ No newline at end of file

Added: tomcat/trunk/java/org/apache/cometd/bayeux/Client.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/cometd/bayeux/Client.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/cometd/bayeux/Client.java (added)
+++ tomcat/trunk/java/org/apache/cometd/bayeux/Client.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cometd.bayeux;
+
+
+
+/** A Bayeux Client.
+ * <p>
+ * A client may subscribe to channels and publish messages to channels.
+ * Client instances should not be directly created by uses, but should 
+ * be obtained via the {@link Bayeux#getClient(String)} or {@link Bayeux#newClient(String, Listener)}
+ * methods.
+ * </p>
+ * <p>
+ * Three types of client may be represented by this interface:<nl>
+ * <li>The server representation of a remote client connected via HTTP, 
+ *     automatically created by the Bayeux server when a connect message comes in</li>
+ * <li>A server side client, created by the application using the {@link Bayeux#newClient(String, Listener)} method</li>
+ * <li>A java client connected to a remote Bayeux server - not implemented</li>
+ * </nl>
+ * @author Greg Wilkins
+ * @author Filip Hanik
+ */
+public interface Client
+{
+    /**
+     * Returns a unique id for this client. The id is unique within this Bayeux session.
+     * @return String - will not be null
+     */
+    public String getId();
+
+    /**
+     * Returns true if this client is holding messages to be delivered to the remote client.
+     * This method always returns false for local clients, since messages are delivered instantly using the 
+     * Listener(callback) object
+     * @return boolean
+     */
+    public boolean hasMessages();
+
+    /** 
+     * Deliver a message to this client only
+     * Deliver a message directly to the client. The message is not 
+     * filtered or published to a channel.
+     * @param message
+     */
+    public void deliver(Message message);
+
+    /** 
+     * Deliver a batch of messages to this client only
+     * Deliver a batch messages directly to the client. The messages are not 
+     * filtered or published to a channel.
+     * @param message
+     */
+    public void deliver(Message[] message);
+
+    /**
+     * @return True if the client is local. False if this client is either a remote HTTP client or
+     * a java client to a remote server. 
+     */
+    public boolean isLocal();
+    
+    /**
+     * Starts a batch, no messages will be delivered until endBatch is called.
+     * Batches can be nested, and messages will only be delivered after
+     * the last endBatch has been called.
+     */
+    public void startBatch();
+    
+    /**
+     * Ends a batch. since batches can be nested, messages will only be delivered
+     * after the endBatch has been called as many times as startBatch has.
+     */
+    public void endBatch();
+    
+    
+}
\ No newline at end of file

Added: tomcat/trunk/java/org/apache/cometd/bayeux/DataFilter.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/cometd/bayeux/DataFilter.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/cometd/bayeux/DataFilter.java (added)
+++ tomcat/trunk/java/org/apache/cometd/bayeux/DataFilter.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cometd.bayeux;
+
+/** 
+ * Data Filter<br/>
+ * Data filters are used to transform data as it is sent to a Channel.
+ * Messages are filtered as the message is published to a channel, invoking the 
+ * {@link Channel#publish(Message)} method.<br/>
+ * This method gets invoked in two different scenarios, the first being when a message is received from
+ * a remote client, and the Bayeux implementation invokes the publish method directly.
+ * The second scenario is when a local client invokes {@link Channel#publish(Message)} directly in the local JVM.
+ * @author Greg Wilkins
+ * @author Filip Hanik
+ *
+ */
+public interface DataFilter
+{
+    /**
+     * Runs a message through the filter. Filtering can only modify an existing object, it can not replace it.
+     * @param data Message - the message to be filtered, may not be null
+     */
+    public void filter(Message data);
+}

Added: tomcat/trunk/java/org/apache/cometd/bayeux/Listener.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/cometd/bayeux/Listener.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/cometd/bayeux/Listener.java (added)
+++ tomcat/trunk/java/org/apache/cometd/bayeux/Listener.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cometd.bayeux;
+
+/** 
+ * Cometd Listener interface.<br/>
+ * For local clients, in order to receive messages, they pass in a callback object
+ * when the local client is created using the {@link Bayeux#newClient(String,Listener)} method.
+ * This callback object, implementing the Listener interface, is used to deliver messages to local, in JVM, clients.
+ * @author Greg Wilkins
+ * @author Filip Hanik
+ *
+ */
+public interface Listener
+{
+    /**
+     * This method is called when the client is removed (explicitly or from a timeout)
+     * @param timeout - true if the client was removed from a timeout
+     * false if it was removed explicitly.
+     */
+    public void removed(boolean timeout);
+    
+    /**
+     * Invoked when a message is delivered to the client.
+     * The message contains the message itself, as well as what channel this message came through
+     * and who the sender is. If someone invoked {@link Client#deliver(Message)} then the channel reference will
+     * be null.
+     * @param msg 
+     */
+    public void deliver(Message[] msg);
+}

Added: tomcat/trunk/java/org/apache/cometd/bayeux/Message.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/cometd/bayeux/Message.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/cometd/bayeux/Message.java (added)
+++ tomcat/trunk/java/org/apache/cometd/bayeux/Message.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cometd.bayeux;
+
+import java.util.Map;
+
+/** 
+ * A Bayeux Message<br/>
+ * A Bayeux message is a Map of String/Object key value pairs representing the data in the message.
+ * The message contains information about the channel it was published through and who the sender was
+ * 
+ * @author Greg Wilkins
+ * @author Filip Hanik
+ */
+public interface Message extends Map<String,Object>
+{
+    /**
+     * Returns a reference to the client that sent this message
+     * @return Client - may be null
+     */
+    public Client getClient();
+    /**
+     * Returns a reference to the channel that this message was published throuhg
+     * @return Channel - may be null
+     */
+    public Channel getChannel();
+    /**
+     * Returns the unique id of this message
+     * @return String
+     */
+    public String getId();
+    
+    /**
+     * Sets the time to live in milliseconds. If the message hasn't been delivered 
+     * when the time passed after the creation time is longer than the TTL the message will
+     * expire and removed from any delivery queues.
+     * @param ttl long
+     */
+    public void setTTL(long ttl);
+    
+    /**
+     * Returns the time to live (in milliseconds) for this message
+     * @return long
+     */
+    public long getTTL();
+    
+    /**
+     * returns the timestamp in milliseconds(System.currentTimeMillis()) of when this message was created.
+     * @return long
+     */
+    public long getCreationTime();
+}
+
+

Added: tomcat/trunk/java/org/apache/cometd/bayeux/SecurityPolicy.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/cometd/bayeux/SecurityPolicy.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/cometd/bayeux/SecurityPolicy.java (added)
+++ tomcat/trunk/java/org/apache/cometd/bayeux/SecurityPolicy.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cometd.bayeux;
+
+/**
+ * @author Greg Wilkins
+ */
+public interface SecurityPolicy
+{
+    boolean canHandshake(Message message);
+    boolean canCreate(Client client,String channel,Message message);
+    boolean canSubscribe(Client client,String channel,Message messsage);
+    boolean canPublish(Client client,String channel,Message messsage);
+}

Added: tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxException.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxException.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxException.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxException.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.bayeux;
+/**
+ * 
+ * @author Filip Hanik
+ * @version 1.0
+ */
+public class BayeuxException extends Exception {
+    public BayeuxException() {
+        super();
+    }
+
+    public BayeuxException(String message) {
+        super(message);
+    }
+
+    public BayeuxException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public BayeuxException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file

Added: tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxRequest.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxRequest.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxRequest.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxRequest.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.bayeux;
+
+import org.apache.tomcat.bayeux.HttpError;
+
+/**
+ * An interface that defines methods for managing Bayeux request meta 
+ * messages.
+ *
+ * @author Guy A. Molinari
+ * @author Filip Hanik
+ * @version 0.9
+ */
+public interface BayeuxRequest {
+
+    public static final String LAST_REQ_ATTR = "org.apache.cometd.bayeux.last_request";
+    public static final String CURRENT_REQ_ATTR = "org.apache.cometd.bayeux.current_request";
+    public static final String JSON_MSG_ARRAY = "org.apache.cometd.bayeux.json_msg_array";
+
+    /**
+     * Validates a specific request. 
+     * This method must be called prior to process()
+     * as a request can do pre processing in the validate method.
+     * <br/>
+     * Should the validation fail, an error object is returned 
+     * containing an error message, and potentially a stack trace
+     * if an exception was generated
+     * @return HttpError - null if no error was detected, an HttpError object containing information about the error.
+     */
+    public HttpError validate();
+    
+    /**
+     * processes a remote client Bayeux message
+     * @param prevops - the operation requested by the previous request, in case of chained requests.
+     * @return int - returns the interest operation for a CometEvent. Currently not used
+     * @throws BayeuxException - if an error was detected, and the appropriate error response couldn't be delivered to the client. 
+     */
+    public int process(int prevops) throws BayeuxException;
+}

Added: tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxServlet.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxServlet.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxServlet.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/bayeux/BayeuxServlet.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.bayeux;
+
+import java.io.IOException;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.CometEvent;
+import org.apache.catalina.CometProcessor;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.apache.cometd.bayeux.Bayeux;
+
+/**
+ * 
+ * @author Filip Hanik
+ * @author Guy Molinari
+ * @version 1.0
+ */
+public class BayeuxServlet implements CometProcessor {
+
+    /**
+     * Attribute to hold the TomcatBayeux object in the servlet context
+     */
+    public static final String TOMCAT_BAYEUX_ATTR = Bayeux.DOJOX_COMETD_BAYEUX;
+    
+    /**
+     * Logger object
+     */
+    protected static Log log = LogFactory.getLog(BayeuxServlet.class);
+
+    /**
+     * Servlet config - for future use
+     */
+    protected ServletConfig servletConfig;
+    
+    /**
+     * Reference to the global TomcatBayeux object
+     */
+    protected TomcatBayeux tb;
+    
+    /**
+     * Upon servlet destruction, the servlet will clean up the 
+     * TomcatBayeux object and terminate any outstanding events.
+     */
+    public void destroy() {
+        servletConfig = null;
+        //to do, close all outstanding comet events
+        //tb.destroy();
+        tb = null;//TO DO, close everything down
+        
+    }
+    
+    /**
+     * Returns the preconfigured connection timeout.
+     * If no timeout has been configured as a servlet init parameter named <code>timeout</code>
+     * then the default of 2min will be used.
+     * @return int - the timeout for a connection in milliseconds
+     */
+    protected int getTimeout() {
+        String timeoutS = servletConfig.getInitParameter("timeout");
+        int timeout = 120*1000; //2 min
+        try {
+            timeout = Integer.parseInt(timeoutS);
+        }catch (NumberFormatException nfe) {
+            //ignore, we have a default value
+        }
+        return timeout;
+    }
+    
+    protected int getReconnectInterval() {
+        String rs = servletConfig.getInitParameter("reconnectInterval");
+        int rct = 5000; //5 seconds
+        try {
+            rct = Integer.parseInt(rs);
+        }catch (NumberFormatException nfe) {
+            //ignore, we have a default value
+        }
+        return rct;
+    }
+
+
+    public void event(CometEvent cometEvent) throws IOException, ServletException {
+        CometEvent.EventType type = cometEvent.getEventType();
+        if (log.isDebugEnabled()) {
+            log.debug("["+Thread.currentThread().getName()+"] Received Comet Event type="+type+" subtype:"+cometEvent.getEventSubType());
+        }
+        synchronized (cometEvent) {
+            if (type==CometEvent.EventType.BEGIN) {
+                //begin event, set the timeout
+                cometEvent.setTimeout(getTimeout());
+                //checkBayeux(cometEvent); - READ event should always come
+            } else if (type==CometEvent.EventType.READ) {
+                checkBayeux(cometEvent);
+            } else if (type==CometEvent.EventType.ERROR) {
+                tb.remove(cometEvent);
+                cometEvent.close();
+            } else if (type==CometEvent.EventType.END) {
+                tb.remove(cometEvent);
+                cometEvent.close();
+            }//end if
+            
+        }//synchronized
+    }//event
+
+    /**
+     * 
+     * @param cometEvent CometEvent
+     * @return boolean - true if we comet event stays open
+     * @throws IOException
+     * @throws UnsupportedOperationException
+     */
+    protected void checkBayeux(CometEvent cometEvent) throws IOException, UnsupportedOperationException {
+        //we actually have data.
+        //data can be text/json or 
+        if (Bayeux.JSON_CONTENT_TYPE.equals(cometEvent.getHttpServletRequest().getContentType())) {
+            //read and decode the bytes according to content length
+            log.warn("["+Thread.currentThread().getName()+"] JSON encoding not supported, will throw an exception and abort the request.");
+            int contentlength = cometEvent.getHttpServletRequest().getContentLength();
+            throw new UnsupportedOperationException("Decoding "+Bayeux.JSON_CONTENT_TYPE+" not yet implemented.");
+        } else { //GET method or application/x-www-form-urlencoded
+            String message = cometEvent.getHttpServletRequest().getParameter(Bayeux.MESSAGE_PARAMETER);
+            if (log.isTraceEnabled()) {
+                log.trace("["+Thread.currentThread().getName()+"] Received JSON message:"+message);
+            }
+            try {
+                int action = handleBayeux(message, cometEvent);
+                if (log.isDebugEnabled()) {
+                    log.debug("["+Thread.currentThread().getName()+"] Bayeux handling complete, action result="+action);
+                }
+                if (action<=0) {
+                    cometEvent.close();
+                }
+            }catch (Exception x) {
+                x.printStackTrace();
+                tb.remove(cometEvent);
+                log.error(x);
+                cometEvent.close();
+            }
+        }
+    }
+    
+    protected int handleBayeux(String message, CometEvent event) throws IOException, ServletException {
+        int result = 0;
+        if (message==null || message.length()==0) return result;
+        try {
+            BayeuxRequest request = null;
+            //a message can be an array of messages
+            JSONArray jsArray = new JSONArray(message);
+            for (int i = 0; i < jsArray.length(); i++) {
+                JSONObject msg = jsArray.getJSONObject(i);
+                
+                if (log.isDebugEnabled()) {
+                    log.debug("["+Thread.currentThread().getName()+"] Processing bayeux message:"+msg);
+                }
+                request = RequestFactory.getRequest(tb,event,msg);
+                if (log.isDebugEnabled()) {
+                    log.debug("["+Thread.currentThread().getName()+"] Processing bayeux message using request:"+request);
+                }
+                result = request.process(result);
+                if (log.isDebugEnabled()) {
+                    log.debug("["+Thread.currentThread().getName()+"] Processing bayeux message result:"+result);
+                }
+            }
+            if (result>0 && request!=null) {
+                event.getHttpServletRequest().setAttribute(BayeuxRequest.LAST_REQ_ATTR, request);
+                ClientImpl ci = (ClientImpl)tb.getClient(((RequestBase)request).getClientId());
+                ci.addCometEvent(event);
+                if (log.isDebugEnabled()) {
+                    log.debug("["+Thread.currentThread().getName()+"] Done bayeux message added to request attribute");
+                }
+            } else if (result == 0 && request!=null) {
+                RequestBase.deliver(event,(ClientImpl)tb.getClient(((RequestBase)request).getClientId()));
+                if (log.isDebugEnabled()) {
+                    log.debug("["+Thread.currentThread().getName()+"] Done bayeux message, delivered to client");
+                }
+            }
+            
+        }catch (JSONException x) {
+            log.error(x);//to do impl error handling
+            result = -1;
+        }catch (BayeuxException x) {
+            log.error(x); //to do impl error handling
+            result = -1;
+        }
+        return result;
+    }
+
+    public ServletConfig getServletConfig() {
+        return servletConfig;
+    }
+
+    public String getServletInfo() {
+        return "Tomcat/BayeuxServlet/1.0";
+    }
+
+    public void init(ServletConfig servletConfig) throws ServletException {
+        
+        this.servletConfig = servletConfig;
+        ServletContext ctx = servletConfig.getServletContext();
+        if (ctx.getAttribute(TOMCAT_BAYEUX_ATTR)==null)
+            ctx.setAttribute(TOMCAT_BAYEUX_ATTR,new TomcatBayeux());
+        this.tb = (TomcatBayeux)ctx.getAttribute(TOMCAT_BAYEUX_ATTR);
+        tb.setReconnectInterval(getReconnectInterval());
+    }
+
+    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
+        if (servletResponse instanceof HttpServletResponse) {
+            ( (HttpServletResponse) servletResponse).sendError(500, "Misconfigured Tomcat server, must be configured to support Comet operations.");
+        } else {
+            throw new ServletException("Misconfigured Tomcat server, must be configured to support Comet operations for the Bayeux protocol.");
+        }
+    }
+}

Added: tomcat/trunk/java/org/apache/tomcat/bayeux/ChannelImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/bayeux/ChannelImpl.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/bayeux/ChannelImpl.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/bayeux/ChannelImpl.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.bayeux;
+
+import java.util.LinkedList;
+
+import org.apache.cometd.bayeux.Channel;
+import org.apache.cometd.bayeux.Client;
+import org.apache.cometd.bayeux.DataFilter;
+import java.util.Collections;
+import java.util.List;
+import org.apache.cometd.bayeux.Message;
+import java.util.Iterator;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+/**
+ * 
+ * @author Filip Hanik
+ * @version 1.0
+ */
+public class ChannelImpl implements Channel {
+    
+    protected static Log log = LogFactory.getLog(ChannelImpl.class);
+    
+    /**
+     * The unique id of this channel
+     */
+    protected String id = null;
+    
+    /**
+     * A list of the current subscribers
+     */
+    protected LinkedList<Client> subscribers = new LinkedList<Client>();
+    
+    /**
+     * A list of the current filters
+     */
+    protected LinkedList<DataFilter> filters = new LinkedList<DataFilter>();
+    
+    /**
+     * Is this channel persistent, default value is true
+     */
+    protected boolean persistent = true; 
+    
+    /**
+     * Creates a new channel
+     * @param id String - the id of the channel, can not be null
+     */
+    protected ChannelImpl(String id) {
+        assert id != null;
+        this.id = id;
+    }
+
+    /**
+     * returns the id of this channel
+     * @return String
+     */
+    public String getId() {
+        return id;
+    }
+    
+    /**
+     * Returns true if this channel matches the pattern to its id.
+     * The channel pattern can be a complete name like <code>/service/mychannel</code>
+     * or it can be a wild card pattern like <code>/service/app2/**</code>
+     * @param pattern String according to the Bayeux specification section 2.2.1 Channel Globbing, can not be null.
+     * @return boolean true if the id of this channel matches the pattern
+     */
+    public boolean matches(String pattern) {
+        if (pattern == null)
+            throw new NullPointerException("Channel pattern must not be null.");
+        if (getId().equals(pattern))
+            return true;
+        int wildcardPos = pattern.indexOf("/*");
+        if (wildcardPos == -1)
+            return false;
+        boolean multiSegment = pattern.indexOf("**") != -1;
+        String leadSubstring = pattern.substring(0, wildcardPos);
+        if (leadSubstring == null)
+            return false;
+        if (multiSegment) 
+            return getId().startsWith(leadSubstring);
+        else {
+            if (getId().length() <= wildcardPos + 2)
+                return false;
+            return !(getId().substring(wildcardPos + 2).contains("/"));
+        }
+    }
+
+
+
+    /**
+     * @return returns a non modifiable list of the subscribers for this channel.
+     */
+    public List<Client> getSubscribers() {
+        return Collections.unmodifiableList(subscribers);
+    }
+
+    /**
+     * @return true if the Channel will persist without any subscription.
+     */
+    public boolean isPersistent() {
+        return persistent;
+    }
+    
+    public void publish(Message msg) {
+        publish(new Message[] {msg});
+    }
+
+    public void publish(Message[] msgs) {
+        if (msgs==null) return;
+        MessageImpl[] imsgs = new MessageImpl[msgs.length];
+        for (int i=0; msgs!=null && i<msgs.length; i++) {
+            Message data = msgs[i];
+
+            if (!(data instanceof MessageImpl)) 
+                throw new IllegalArgumentException("Invalid message class, you can only publish messages "+
+                                                   "created through the Bayeux.newMessage() method");
+            if (log.isDebugEnabled()) {
+                log.debug("Publishing message:"+data+" to channel:"+this);
+            }
+            //clone it so that we can set this channel as a reference
+            MessageImpl msg = (MessageImpl)((MessageImpl)data).clone();
+            //this is the channel it was delivered through
+            msg.setChannel(this);
+            //pass through filters
+            for (Iterator<DataFilter> it = filters.iterator(); it.hasNext(); ) {
+                it.next().filter(msg);
+            }
+            imsgs[i] = msg;
+        }
+        //deliver it to the clients
+        for (Iterator<Client> it = subscribers.iterator(); it.hasNext(); ) {
+            ClientImpl c = (ClientImpl)it.next();
+            c.deliverInternal(this,imsgs);
+        }
+        
+    }
+
+    public void setPersistent(boolean persistent) {
+        this.persistent = persistent;
+    }
+
+    public void subscribe(Client subscriber) {
+        if (!subscribers.contains((subscriber))) { 
+            subscribers.addLast(subscriber);
+            ((ClientImpl)subscriber).subscribed(this);
+        }
+    }
+
+    public Client unsubscribe(Client subscriber) {
+        if (subscribers.remove(subscriber)) {
+            ((ClientImpl)subscriber).unsubscribed(this);
+            return subscriber;
+        } else
+            return null;
+    }
+    
+    public void addFilter(DataFilter filter) {
+        if (!filters.contains(filter)) 
+            filters.addLast(filter);
+    }
+
+    public DataFilter removeFilter(DataFilter filter) {
+        if ( filters.remove(filter) ) return filter;
+        else return null;
+    }
+    
+    public String toString() {
+        StringBuffer buf = new StringBuffer(super.toString());
+        buf.append("; channelId=").append(getId());
+        return buf.toString();
+    }
+
+}
\ No newline at end of file

Added: tomcat/trunk/java/org/apache/tomcat/bayeux/ClientImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/bayeux/ClientImpl.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/bayeux/ClientImpl.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/bayeux/ClientImpl.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,278 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.bayeux;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.catalina.CometEvent;
+import org.json.JSONObject;
+import org.apache.cometd.bayeux.Bayeux;
+import org.apache.cometd.bayeux.Client;
+import org.apache.cometd.bayeux.Listener;
+import org.apache.cometd.bayeux.Message;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+public class ClientImpl implements Client {
+    
+    public static final int SUPPORT_CALLBACK_POLL = 0x1;
+    public static final int SUPPORT_LONG_POLL = 0x2; 
+
+    public static final String COMET_EVENT_ATTR = "org.apache.cometd.bayeux.client";
+    
+    protected static Log log = LogFactory.getLog(ClientImpl.class);
+
+    protected static LinkedList<Message> EMPTY_LIST = new LinkedList<Message>();
+    /**
+     * queued message for remote clients.
+     */
+    protected LinkedList<Message> messages = null;
+    
+    /**
+     * 
+     */
+    protected Queue<CometEvent> events = new LinkedList<CometEvent>();
+    
+    /**
+     * Unique id representing this client
+     */
+    protected String id;
+    
+    /**
+     * supported connection types, defaults to long-polling
+     */
+    protected int supportedConnTypes = SUPPORT_LONG_POLL | SUPPORT_CALLBACK_POLL;
+    
+    /**
+     * The desired connection type
+     */
+    protected int desirectConnType = SUPPORT_LONG_POLL;
+    
+    /**
+     * Does this client use json-comment-filtered messages
+     */
+    protected boolean useJsonFiltered = false;
+    
+    /**
+     * Same JVM clients, get local=true
+     */
+    protected boolean local;
+    
+    /**
+     * The callback object for local clients
+     */
+    protected Listener listener;
+    
+    protected AtomicInteger nrofsubscriptions = new AtomicInteger(0);
+    
+    protected ClientImpl(String id, boolean local) {
+        this.id = id;
+        this.local = local;
+        if (!local) messages = new LinkedList<Message>();
+    }
+    
+    protected ClientImpl(String id, CometEvent event) {
+        this(id,false);
+        events = new ConcurrentLinkedQueue<CometEvent>();
+        addCometEvent(event);
+    }
+
+    public synchronized void deliver(Message message) {
+        deliverInternal(null,new MessageImpl[] {(MessageImpl)message});
+    }
+    
+    public synchronized void deliver(Message[] message) {
+        deliverInternal(null,message);
+    }
+
+    protected synchronized void deliverInternal(ChannelImpl channel, MessageImpl message) {
+        deliverInternal(channel,new MessageImpl[] {message});
+    }
+
+    protected synchronized void deliverInternal(ChannelImpl channel, Message[] msgs) {
+        if (isLocal()) {
+            //local clients must have a listener
+            ArrayList<Message> list = new ArrayList<Message>();
+            for (int i=0; msgs!=null && i<msgs.length; i++) {
+                if (this!=msgs[i].getClient()) list.add(msgs[i]);
+            }
+            if (getListener() != null) {
+                getListener().deliver(list.toArray(new Message[0]));
+            }
+        } else {
+            for (int i=0; msgs!=null && i<msgs.length; i++) {
+                MessageImpl message = (MessageImpl)msgs[i];
+                if (this==message.getClient()) { 
+                    //dont deliver to ourself
+                    continue;
+                }
+                //we are not implementing forever responses, if the client is connected
+                //then we will fire off the message
+                //first we check to see if we have any existing connections we can piggy back on
+                CometEvent event = events.poll();
+                boolean delivered = false;
+                //TODO TODO - check on thread safety, for writing and for getting last request.
+                if (event!=null) {
+                    synchronized (event) {
+                        RequestBase rq = (RequestBase)event.getHttpServletRequest().getAttribute(RequestBase.LAST_REQ_ATTR);
+                        if (rq!=null) {
+                            Map map = new HashMap();
+                            try {
+                                map.put(Bayeux.CHANNEL_FIELD,message.getChannel().getId());
+                                map.put(Bayeux.DATA_FIELD,message);
+                                JSONObject json = new JSONObject(map);
+                                if (log.isDebugEnabled()) {
+                                    log.debug("Message instantly delivered to remote client["+this+"] message:"+json);
+                                }
+                                rq.addToDeliveryQueue(this, json);
+                                //deliver the batch
+                                if (i==(msgs.length-1)) {
+                                    rq.deliver(event, this);
+                                    event.close(); //todo, figure out a better way, this means only one message gets delivered
+                                    removeCometEvent(event); //and delivered instantly
+                                }
+                                delivered = true;
+                            } catch (Exception x) {
+                                log.error(x);
+                            }
+                        }
+                    }
+                } 
+                if (!delivered) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Message added to queue for remote client["+this+"] message:"+message);
+                    }
+                    //queue the message for the next round
+                    messages.add(message);
+                }
+            }
+        }
+    }
+
+    public String getId() {
+        return this.id;
+    }
+
+    protected Listener getListener() {
+        return listener;
+    }
+
+    public boolean hasMessages() {
+        if (isLocal()) return false;
+        else {
+            return messages.size() > 0;
+        }
+    }
+
+    public boolean isLocal() {
+        return local;
+    }
+
+    public int getSupportedConnTypes() {
+        return supportedConnTypes;
+    }
+
+    public int getDesirectConnType() {
+        return desirectConnType;
+    }
+
+    public boolean useJsonFiltered() {
+        return useJsonFiltered;
+    }
+
+    public void setListener(Listener listener) {
+        this.listener = listener;
+    }
+
+    public void setSupportedConnTypes(int supportedConnTypes) {
+        this.supportedConnTypes = supportedConnTypes;
+    }
+
+    public void setUseJsonFiltered(boolean useJsonFiltered) {
+        this.useJsonFiltered = useJsonFiltered;
+    }
+
+    public void setDesirectConnType(int desirectConnType) {
+        this.desirectConnType = desirectConnType;
+    }
+
+    public boolean supportsCallbackPoll() {
+        return (supportedConnTypes & SUPPORT_CALLBACK_POLL) == SUPPORT_CALLBACK_POLL;
+    }
+
+    public boolean supportsLongPoll() {
+        return (supportedConnTypes & SUPPORT_LONG_POLL) == SUPPORT_LONG_POLL;
+    }
+
+    public synchronized List<Message> takeMessages() {
+        if (isLocal()) return null;
+        if (messages.size()==0) return EMPTY_LIST;
+        List result = new LinkedList(messages);
+        messages.clear();
+        return result;
+    }
+    
+    public String toString() {
+        StringBuffer buf = new StringBuffer(super.toString());
+        buf.append(" id=").append(getId());
+        return buf.toString();
+    }
+    
+    public boolean isSubscribed() {
+        return nrofsubscriptions.get()>0;
+    }
+    
+    protected synchronized boolean addCometEvent(CometEvent event) {
+        boolean result = false;
+        if (!events.contains(event)) {
+            events.add(event);
+            result = true;
+        }
+        event.getHttpServletRequest().setAttribute(COMET_EVENT_ATTR,this);
+        return result;
+    }
+    
+    protected synchronized boolean removeCometEvent(CometEvent event) {
+        boolean result = events.remove(event);
+        event.getHttpServletRequest().removeAttribute(COMET_EVENT_ATTR);
+        return result;
+    }
+    
+    
+    protected void subscribed(ChannelImpl ch) {
+        nrofsubscriptions.addAndGet(1);
+    }
+    
+    protected void unsubscribed(ChannelImpl ch) {
+        nrofsubscriptions.addAndGet(-1);
+    }
+    
+    public void startBatch(){
+        //noop until improved
+    }
+    public void endBatch() {
+        //noop until improved
+    }
+        
+}

Added: tomcat/trunk/java/org/apache/tomcat/bayeux/HttpError.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/bayeux/HttpError.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/bayeux/HttpError.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/bayeux/HttpError.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,43 @@
+package org.apache.tomcat.bayeux;
+
+public class HttpError {
+    private int code;
+    private String status;
+    private Throwable cause;
+    public HttpError(int code, String status, Throwable cause) {
+        this.code = code;
+        this.status = status;
+        this.cause = cause;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public void setCause(Throwable exception) {
+        this.cause = exception;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public Throwable getCause() {
+        return cause;
+    }
+
+    public String toString() {
+        if (cause != null)
+            return code + ":" + status + " - [" + cause + "]";
+        else
+            return code + ":" + status;
+    }
+}

Added: tomcat/trunk/java/org/apache/tomcat/bayeux/MessageImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/bayeux/MessageImpl.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/bayeux/MessageImpl.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/bayeux/MessageImpl.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.bayeux;
+
+import java.util.HashMap;
+
+import org.apache.cometd.bayeux.Channel;
+import org.apache.cometd.bayeux.Client;
+import org.apache.cometd.bayeux.Message;
+
+public class MessageImpl extends HashMap<String,Object> implements Message {
+    
+    protected Channel channel;
+    protected Client client;
+    protected String id;
+    private long TTL = 1000*60*5; //5min is the default TTL for a message
+    protected long creationTime = System.currentTimeMillis();
+
+    public Object clone() {
+        MessageImpl copy = new MessageImpl(id);
+        copy.putAll(this);
+        copy.channel = channel;
+        copy.client = client;
+        copy.id = id;
+        copy.creationTime = creationTime;
+        copy.TTL = TTL;
+        return copy;
+    }
+
+    protected MessageImpl(String id) {
+        assert id != null;
+        this.id = id;
+    }
+
+    public Channel getChannel() {
+        return channel;
+    }
+
+    public Client getClient() {
+        return client;
+    }
+
+    public long getCreationTime() {
+        return creationTime;
+    }
+
+    public long getTTL() {
+        return TTL;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    protected void setChannel(Channel channel) {
+        this.channel = channel;
+    }
+
+    protected void setClient(Client client) {
+        this.client = client;
+    }
+
+    public void setTTL(long TTL) {
+        this.TTL = TTL;
+    }
+}
\ No newline at end of file

Added: tomcat/trunk/java/org/apache/tomcat/bayeux/RequestBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/bayeux/RequestBase.java?rev=691359&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/bayeux/RequestBase.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/bayeux/RequestBase.java Tue Sep  2 13:00:36 2008
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.bayeux;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import javax.servlet.ServletException;
+
+import org.apache.catalina.CometEvent;
+import org.apache.tomcat.bayeux.HttpError;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.apache.cometd.bayeux.Bayeux;
+import org.apache.cometd.bayeux.Message;
+
+/**
+ * Common functionality and member variables for all Bayeux requests.
+ *
+ * @author Guy A. Molinari
+ * @author Filip Hanik
+ * @version 0.9
+ *
+ */
+public abstract class RequestBase implements BayeuxRequest {
+    
+    protected static final SimpleDateFormat timestampFmt =
+        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+    static {
+        timestampFmt.setTimeZone(TimeZone.getTimeZone("GMT"));
+    }
+    //message properties, combined for all messages
+    protected TomcatBayeux tomcatBayeux;
+    protected String channel;
+    protected String id;
+    protected String clientId;
+    protected String version = null;
+    protected String[] suppConnTypes = null;
+    protected int suppConnTypesFlag = 0;
+    protected int desiredConnTypeFlag = 0;
+    protected String minVersion = null;
+    protected String subscription = null;
+    protected String data = null;
+    protected String conType = null;
+    protected LinkedHashMap<String, Object> ext = new LinkedHashMap<String, Object> ();
+
+    
+    protected CometEvent event;
+    
+    protected HashMap<String, Object> response = null;
+    
+    protected static Log log = LogFactory.getLog(RequestBase.class);
+    
+    protected int reconnectInterval;
+    
+    protected RequestBase(TomcatBayeux tb, CometEvent event, JSONObject jsReq) throws JSONException {
+        this.tomcatBayeux = tb;
+        this.event = event;
+        channel = jsReq.optString(Bayeux.CHANNEL_FIELD);
+        id = jsReq.optString(Bayeux.ID_FIELD);
+        clientId = jsReq.optString(Bayeux.CLIENT_FIELD);
+        version = jsReq.optString(Bayeux.VERSION_FIELD);
+        minVersion = jsReq.optString(Bayeux.MIN_VERSION_FIELD);
+        conType = jsReq.optString(Bayeux.CONNECTION_TYPE_FIELD);
+        subscription = jsReq.optString(Bayeux.SUBSCRIPTION_FIELD);
+        data = jsReq.optString(Bayeux.DATA_FIELD);
+        reconnectInterval = tb.getReconnectInterval();
+        if (jsReq.has(Bayeux.EXT_FIELD)) {
+            JSONObject jext = jsReq.getJSONObject(Bayeux.EXT_FIELD);
+            for (Iterator<String> i = jext.keys(); i.hasNext(); ) {
+                String key = i.next();
+                ext.put(key, jext.get(key));
+            }//for
+        }//end if
+        
+        if (jsReq.has(Bayeux.SUPP_CONNECTION_TYPE_FIELD)) {
+            JSONArray types = jsReq.getJSONArray(Bayeux.SUPP_CONNECTION_TYPE_FIELD);
+            suppConnTypes = new String[types.length()];
+            for (int i = 0; i < types.length(); i++) {
+                suppConnTypes[i] = types.getString(i);
+                if (Bayeux.TRANSPORT_CALLBACK_POLL.equals(suppConnTypes[i]))
+                    suppConnTypesFlag = suppConnTypesFlag|ClientImpl.SUPPORT_CALLBACK_POLL;
+                else if (Bayeux.TRANSPORT_LONG_POLL.equals(suppConnTypes[i]))
+                    suppConnTypesFlag = suppConnTypesFlag|ClientImpl.SUPPORT_LONG_POLL;
+            }//for
+        }//end if
+
+        if (conType!=null) {
+            if (Bayeux.TRANSPORT_CALLBACK_POLL.equals(conType))
+                desiredConnTypeFlag = ClientImpl.SUPPORT_CALLBACK_POLL;
+            else if (Bayeux.TRANSPORT_LONG_POLL.equals(conType))
+                desiredConnTypeFlag = ClientImpl.SUPPORT_LONG_POLL;
+        }//end if
+        
+        //due to the fact that the javascript doesn't send up a required field
+        //we have to fake it
+        suppConnTypesFlag = ClientImpl.SUPPORT_CALLBACK_POLL | ClientImpl.SUPPORT_LONG_POLL;
+
+    }
+
+    public HttpError validate() {
+        HttpError result = null;
+//        if (clientId == null) {
+//            result = new HttpError(401,"No Client ID.", null);
+//        }
+        return result;
+    }
+
+    public TomcatBayeux getTomcatBayeux() {
+        return tomcatBayeux;
+    }
+
+    public String getChannel() {
+        return channel;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public LinkedHashMap getExt() {
+        return ext;
+    }
+
+    public CometEvent getEvent() {
+        return event;
+    }
+    
+    protected static void deliver(CometEvent event, ClientImpl to) throws IOException, ServletException, BayeuxException {
+        JSONArray jarray = getJSONArray(event,true);
+        if ( jarray == null ) throw new BayeuxException("No message to send!");
+        String jsonstring = jarray.toString();
+        if (log.isDebugEnabled()) {
+            log.debug("["+Thread.currentThread().getName()+"] Delivering message to[" + to + "] message:" + jsonstring);
+        }
+
+        PrintWriter out = event.getHttpServletResponse().getWriter();
+        if (to==null) {
+            //do nothing
+        }else if ( (to.getDesirectConnType() == 0 && to.supportsLongPoll()) || to.getDesirectConnType() == ClientImpl.SUPPORT_LONG_POLL) {
+            if (to.useJsonFiltered())
+                out.print("/*");
+        } else if ( (to.getDesirectConnType() == 0 && to.supportsCallbackPoll()) || to.getDesirectConnType() == ClientImpl.SUPPORT_CALLBACK_POLL) {
+            String jsonp = event.getHttpServletRequest().getParameter(Bayeux.JSONP_PARAMETER);
+            if (jsonp == null)
+                jsonp = Bayeux.JSONP_DEFAULT_NAME;
+            out.print(jsonp);
+            out.print('(');
+        } else {
+            throw new BayeuxException("Client doesn't support any appropriate connection type.");
+        }
+        out.print(jsonstring);
+        if ( to == null ) {
+            //do nothing
+        } else if ( (to.getDesirectConnType() == 0 && to.supportsLongPoll()) || to.getDesirectConnType() == ClientImpl.SUPPORT_LONG_POLL) {
+            if (to.useJsonFiltered())
+                out.print("*/");
+        } else if ( (to.getDesirectConnType() == 0 && to.supportsCallbackPoll()) || to.getDesirectConnType() == ClientImpl.SUPPORT_CALLBACK_POLL) {
+            out.print(");");
+        } 
+        out.flush();
+        event.getHttpServletResponse().flushBuffer();
+
+        
+    }
+
+    protected static JSONArray getJSONArray(CometEvent event, boolean nullok) {
+        synchronized(event) {
+            JSONArray jarray = (JSONArray) event.getHttpServletRequest().getAttribute(JSON_MSG_ARRAY);
+            if (jarray == null && (!nullok)) {
+                jarray = new JSONArray();
+                event.getHttpServletRequest().setAttribute(JSON_MSG_ARRAY, jarray);
+            }
+            return jarray;
+        }
+    }
+
+    protected JSONArray getJSONArray() {
+        return getJSONArray(event,false);
+    }
+
+    protected void addToDeliveryQueue(ClientImpl to, JSONObject msg) throws IOException, ServletException, BayeuxException {
+        synchronized (event) {
+            getJSONArray().put(msg);
+        }
+    }
+    
+    protected void flushMessages(ClientImpl client) throws BayeuxException {
+        List<Message> msgs = client.takeMessages();
+        synchronized (event) {
+            try {
+                for (Iterator<Message> it = msgs.iterator(); it.hasNext(); ){
+                    MessageImpl msg = (MessageImpl)it.next();
+                    Map map = new HashMap();
+                    map.put(Bayeux.CHANNEL_FIELD,msg.getChannel().getId());
+                    if (msg.getClient()!=null) map.put(Bayeux.CLIENT_FIELD,msg.getClient().getId());
+                    map.put(Bayeux.DATA_FIELD,msg);
+                    JSONObject obj = new JSONObject(map);
+                    addToDeliveryQueue(client, obj);
+                }
+            } catch (ServletException x) {
+                throw new BayeuxException(x);
+            } catch (IOException x) {
+                throw new BayeuxException(x);
+            }
+        }
+    }
+    
+    public int process(int prevops) throws BayeuxException {
+        event.getHttpServletRequest().setAttribute(CURRENT_REQ_ATTR,this);
+        return prevops;
+    }
+    
+    public int getReconnectInterval() {
+        return reconnectInterval;
+    }
+
+    public String getTimeStamp() {
+        return timestampFmt.format(new Date(System.currentTimeMillis()));
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
Remy Maucherat wrote:
> On Tue, 2008-09-02 at 23:37 +0100, Mark Thomas wrote:
>   
>> Therefore, I vote -1 for this contribution as it does not comply with the
>> published ASF source headers policy. I am happy for this contribution to
>> remain in trunk providing that the necessary changes are made in a
>> reasonable time scale.
>>     
>
> I will look at this. There's obviously no need to revert for now (esp
> since it doing it too much would kill my email).
>   
I have no problem reverting, if we are not comfortable.
The org.apache.cometd.bayeux is an API derived from the works over at 
Dojo Foundation.
It was under this URL
https://svn.codehaus.org/jetty-contrib/jetty/trunk/contrib/cometd/api/src/main/java/dojox/cometd
But that code base is no longer available.

So what we did, was take what we like, remove a bunch of stuff and 
rework the API into what we thought be more usable to the Tomcat project.
The reason for this was that we waited for very long for to contribute 
to a shared API, and simply write our implementation against a standard 
API (something I would still like to do if it can happen)

If we are not comfortable with that, I can revert the change and we can 
discuss the way we want to approach this

Filip

> Rémy
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Posted by Remy Maucherat <re...@apache.org>.
On Tue, 2008-09-02 at 23:37 +0100, Mark Thomas wrote:
> Therefore, I vote -1 for this contribution as it does not comply with the
> published ASF source headers policy. I am happy for this contribution to
> remain in trunk providing that the necessary changes are made in a
> reasonable time scale.

I will look at this. There's obviously no need to revert for now (esp
since it doing it too much would kill my email).

Rémy



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Posted by Mark Thomas <ma...@apache.org>.
Mark Thomas wrote:
> Therefore, I vote -1 for this contribution as it does not comply with the
> published ASF source headers policy. I am happy for this contribution to
> remain in trunk providing that the necessary changes are made in a
> reasonable time scale.

I have re-read the policy and the .js files can be considered a third
party work so they are fine. The only real issue was the COPYRIGHT file
and that has been fixed so I withdraw my -1.

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Posted by Mark Thomas <ma...@apache.org>.
Remy Maucherat wrote:
> On Tue, 2008-09-02 at 23:10 +0100, Mark Thomas wrote:
>> Remy Maucherat wrote:
>>> +****For the bayeux implementation*********
>>> +* Copyright 2007-2008 Guy Molinari
>>> +* Copyright 2007-2008 Filip Hanik
>>> +* Copyright 2007 Dojo Foundation
>>> +* Copyright 2007 Mort Bay Consulting Pty. Ltd.
>>>
>>> Personally, I don't like that. As far as I am concerned, I like the code
>>> in ASF repositories to be (c) ASF, as it's always been.
>> That isn't the case. The collective work is (c) ASF but individual
>> contributions are (c) to the committer / contributor that provided them. I
>> may not have used exactly the right language to express this - the
>> legal-dicuss list is the place to get a better answer.
> 
> Is this code also (c) ASF then, in addition to the people listed ? (= if
> the code is copied, can it be only labelled (c) ASF ?)

It is the collective work that is copyright ASF. This is stated in the
notice file. We can only change/remove copyright notices in very specific
circumstances.

> If yes, then +1 for the code, otherwise -1 (please gives pointers to
> where this is approved and in which projects it has been done).

http://www.apache.org/legal/src-headers.html should answer all your questions.

Looking at some other files there are a number of issues with copyright
notices that need to be fixed in addition to the removal of the COPYRIGHT file.

Therefore, I vote -1 for this contribution as it does not comply with the
published ASF source headers policy. I am happy for this contribution to
remain in trunk providing that the necessary changes are made in a
reasonable time scale.

Mark



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Posted by Remy Maucherat <re...@apache.org>.
On Tue, 2008-09-02 at 23:10 +0100, Mark Thomas wrote:
> Remy Maucherat wrote:
> > +****For the bayeux implementation*********
> > +* Copyright 2007-2008 Guy Molinari
> > +* Copyright 2007-2008 Filip Hanik
> > +* Copyright 2007 Dojo Foundation
> > +* Copyright 2007 Mort Bay Consulting Pty. Ltd.
> > 
> > Personally, I don't like that. As far as I am concerned, I like the code
> > in ASF repositories to be (c) ASF, as it's always been.
> 
> That isn't the case. The collective work is (c) ASF but individual
> contributions are (c) to the committer / contributor that provided them. I
> may not have used exactly the right language to express this - the
> legal-dicuss list is the place to get a better answer.

Is this code also (c) ASF then, in addition to the people listed ? (= if
the code is copied, can it be only labelled (c) ASF ?)

If yes, then +1 for the code, otherwise -1 (please gives pointers to
where this is approved and in which projects it has been done).

Rémy



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Posted by Mark Thomas <ma...@apache.org>.
Remy Maucherat wrote:
> +****For the bayeux implementation*********
> +* Copyright 2007-2008 Guy Molinari
> +* Copyright 2007-2008 Filip Hanik
> +* Copyright 2007 Dojo Foundation
> +* Copyright 2007 Mort Bay Consulting Pty. Ltd.
> 
> Personally, I don't like that. As far as I am concerned, I like the code
> in ASF repositories to be (c) ASF, as it's always been.

That isn't the case. The collective work is (c) ASF but individual
contributions are (c) to the committer / contributor that provided them. I
may not have used exactly the right language to express this - the
legal-dicuss list is the place to get a better answer.

That said, the COPYRIGHT file needs to go. That information should be in
NOTICE.

Mark



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
Remy Maucherat wrote:
> On Tue, 2008-09-02 at 20:00 +0000, fhanik@apache.org wrote:
>   
>> Author: fhanik
>> Date: Tue Sep  2 13:00:36 2008
>> New Revision: 691359
>>
>> URL: http://svn.apache.org/viewvc?rev=691359&view=rev
>> Log:
>> Added in Bayeux implementation, as per 
>> https://issues.apache.org/bugzilla/show_bug.cgi?id=45413
>> to build, 
>> ant download
>> ant
>> ant -f extras.xml bayeux
>>
>>
>> Added:
>>     tomcat/trunk/java/org/apache/tomcat/bayeux/
>>     
>
> org/apache/catalina/bayeux ?
>
>   
>>     tomcat/trunk/test/org/apache/cometd/
>>     
>
> Ok.
>
> There's a *lot* of syncs in there though.
>
> +****For the bayeux implementation*********
> +* Copyright 2007-2008 Guy Molinari
> +* Copyright 2007-2008 Filip Hanik
> +* Copyright 2007 Dojo Foundation
> +* Copyright 2007 Mort Bay Consulting Pty. Ltd.
>
> Personally, I don't like that. As far as I am concerned, I like the code
> in ASF repositories to be (c) ASF, as it's always been. Can it be a
> binary dependency instead ?
>   
oops, that should go into the NOTICE file, as per
http://www.apache.org/legal/src-headers.html

Filip
> Rémy
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r691359 [1/8] - in /tomcat/trunk: ./ java/org/apache/cometd/ java/org/apache/cometd/bayeux/ java/org/apache/tomcat/bayeux/ java/org/apache/tomcat/bayeux/request/ test/org/apache/cometd/ test/org/apache/cometd/bayeux/ test/org/apache/cometd/...

Posted by Remy Maucherat <re...@apache.org>.
On Tue, 2008-09-02 at 20:00 +0000, fhanik@apache.org wrote:
> Author: fhanik
> Date: Tue Sep  2 13:00:36 2008
> New Revision: 691359
> 
> URL: http://svn.apache.org/viewvc?rev=691359&view=rev
> Log:
> Added in Bayeux implementation, as per 
> https://issues.apache.org/bugzilla/show_bug.cgi?id=45413
> to build, 
> ant download
> ant
> ant -f extras.xml bayeux
> 
> 
> Added:
>     tomcat/trunk/java/org/apache/tomcat/bayeux/

org/apache/catalina/bayeux ?

>     tomcat/trunk/test/org/apache/cometd/

Ok.

There's a *lot* of syncs in there though.

+****For the bayeux implementation*********
+* Copyright 2007-2008 Guy Molinari
+* Copyright 2007-2008 Filip Hanik
+* Copyright 2007 Dojo Foundation
+* Copyright 2007 Mort Bay Consulting Pty. Ltd.

Personally, I don't like that. As far as I am concerned, I like the code
in ASF repositories to be (c) ASF, as it's always been. Can it be a
binary dependency instead ?

Rémy



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org