/* * 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 java.util.LinkedHashMap; import java.util.List; import org.apache.cometd.bayeux.Bayeux; import org.apache.cometd.bayeux.Channel; import org.apache.cometd.bayeux.Client; import org.apache.cometd.bayeux.Listener; import org.apache.cometd.bayeux.Message; import org.apache.cometd.bayeux.SecurityPolicy; import org.jboss.servlet.http.HttpEvent; /** * * @author Filip Hanik * @version 1.0 */ public class TomcatBayeux implements Bayeux { protected int reconnectInterval = 5000; /** * a list of all active clients */ protected HashMap clients = new HashMap(); /** * a list of all active channels */ protected LinkedHashMap channels = new LinkedHashMap(); /** * security policy to be used. */ protected SecurityPolicy securityPolicy = null; /** * default client to use when we need to send an error message but don't have a client valid reference */ protected static ClientImpl errorClient = new ClientImpl("error-no-client",false); /** * returns the default error client * @return ClientImpl */ public static ClientImpl getErrorClient() { return errorClient; } protected TomcatBayeux() { } /** * should be invoked when the servlet is destroyed or when the context shuts down */ public void destroy() { throw new UnsupportedOperationException("TomcatBayeux.destroy() not yet implemented"); } public Channel getChannel(String channelId, boolean create) { Channel result = channels.get(channelId); if (result==null && create) { result = new ChannelImpl(channelId); channels.put(channelId,result); } return result; } public Channel remove(Channel channel) { return channels.remove(channel.getId()); } public Client remove(Client client) { if (client==null) return null; for (Channel ch : getChannels()) { ch.unsubscribe(client); } return clients.remove(client.getId()); } public Client getClient(String clientId) { return clients.get(clientId); } public boolean hasClient(String clientId) { return clients.containsKey(clientId); } public List getClients() { return java.util.Arrays.asList(clients.entrySet().toArray(new Client[0])); } public SecurityPolicy getSecurityPolicy() { return securityPolicy; } public int getReconnectInterval() { return reconnectInterval; } public boolean hasChannel(String channel) { return channels.containsKey(channel); } public Client newClient(String idprefix, Listener listener, boolean local, HttpEvent event) { String id = createUUID(idprefix); ClientImpl client = new ClientImpl(id, local); client.setListener(listener); clients.put(id, client); return client; } public Client newClient(String idprefix, Listener listener) { assert listener!=null; //if this method gets called, someone is using the API inside //the JVM, this is a local client return newClient(idprefix,listener,true, null); } protected ClientImpl getClientImpl(HttpEvent event) { return (ClientImpl)event.getHttpServletRequest().getAttribute(ClientImpl.COMET_EVENT_ATTR); } protected void remove(HttpEvent event) { ClientImpl client = getClientImpl(event); if (client!=null) { client.removeCometEvent(event); } } public String createUUID(String idprefix) { if (idprefix==null) idprefix=""; return idprefix + TomcatBayeux.toString(UUIDGenerator.randomUUID(false)); } protected static String toString(byte[] data) { return toString(data,0,data!=null?data.length:0); } protected static String toString(byte[] data, int offset, int length) { StringBuffer buf = new StringBuffer("{"); if ( data != null && length > 0 ) { buf.append(data[offset++]); for (int i = offset; i < length; i++) { buf.append(", ").append(data[i]); } } buf.append("}"); return buf.toString(); } public List getChannels() { return java.util.Arrays.asList(channels.entrySet().toArray(new Channel[0])); } protected Message newMessage() { String id = createUUID("msg-"); return new MessageImpl(id); } public Message newMessage(Client from) { MessageImpl msg = (MessageImpl)newMessage(); msg.setClient(from); return msg; } public void setSecurityPolicy(SecurityPolicy securityPolicy) { this.securityPolicy = securityPolicy; } public void setReconnectInterval(int reconnectTimeout) { this.reconnectInterval = reconnectTimeout; } }