001: // ========================================================================
002: // Copyright 2006 Mort Bay Consulting Pty. Ltd.
003: // ------------------------------------------------------------------------
004: // Licensed under the Apache License, Version 2.0 (the "License");
005: // you may not use this file except in compliance with the License.
006: // You may obtain a copy of the License at
007: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014:
015: package org.mortbay.cometd;
016:
017: import java.util.HashMap;
018:
019: import org.mortbay.log.Log;
020: import org.mortbay.util.LazyList;
021:
022: /* ------------------------------------------------------------ */
023: /** A Bayuex Channel
024: *
025: * @author gregw
026: *
027: */
028: public class Channel {
029: private Bayeux _bayeux;
030: private String _id;
031: private long _nextMsgId;
032: private Object _subscribers = null;
033: private Object _dataFilters = null;
034:
035: Channel(String id, Bayeux bayeux) {
036: _id = id;
037: _bayeux = bayeux;
038: }
039:
040: /* ------------------------------------------------------------ */
041: /**
042: * @param client
043: */
044: public void addSubscriber(Client client) {
045: synchronized (this ) {
046: _subscribers = LazyList.add(_subscribers, client);
047: }
048: }
049:
050: /* ------------------------------------------------------------ */
051: /**
052: * @param filter
053: */
054: public void addDataFilter(DataFilter filter) {
055: _dataFilters = LazyList.add(_dataFilters, filter);
056: }
057:
058: /* ------------------------------------------------------------ */
059: /**
060: * @param filter
061: */
062: public void removeDataFilter(DataFilter filter) {
063: _dataFilters = LazyList.remove(_dataFilters, filter);
064: }
065:
066: /* ------------------------------------------------------------ */
067: /**
068: * @return
069: */
070: public String getId() {
071: return _id;
072: }
073:
074: /* ------------------------------------------------------------ */
075: /**
076: * @param client
077: */
078: public void removeSubscriber(Client client) {
079: synchronized (this ) {
080: _subscribers = LazyList.remove(_subscribers, client);
081: }
082: }
083:
084: /* ------------------------------------------------------------ */
085: /** Publish data to a the channel.
086: *
087: * @param data The data object - The data object is filtered by the channel filters and
088: * then any client specific filters. It is then set as the "data" field of a Bayuex message map
089: * before being passed to the {@link Client#deliver(java.util.Map)} method. If not converted by the filters,
090: * the data will be converted in deliver to JSON by the {@link JSON#toString(Object)} method.
091: * @param from The client sending the data or null for anonymous delivery.
092: */
093: public void publish(Object data, Client from) {
094: try {
095: for (int f = 0; f < LazyList.size(_dataFilters); f++) {
096: data = ((DataFilter) LazyList.get(_dataFilters, f))
097: .filter(data, from);
098: if (data == null)
099: return;
100: }
101: } catch (IllegalStateException e) {
102: Log.debug(e);
103: return;
104: }
105:
106: HashMap msg = new HashMap();
107: msg.put(Bayeux.CHANNEL_ATTR, _id);
108: msg.put(Bayeux.TIMESTAMP_ATTR, _bayeux.getTimeOnServer());
109:
110: synchronized (this ) {
111: long id = this .hashCode() * msg.hashCode();
112: id = id < 0 ? -id : id;
113: msg.put("id", Long.toString(id, 36)
114: + Long.toString(_nextMsgId++, 36));
115: int subscribers = LazyList.size(_subscribers);
116: for (int i = 0; i < subscribers; i++) {
117: Client client = (Client) LazyList.get(_subscribers, i);
118: Object client_data = client.filterData(data, from);
119: if (client_data != null) {
120: msg.put(Bayeux.DATA_ATTR, client_data);
121: ((Client) LazyList.get(_subscribers, i))
122: .deliver(msg);
123: }
124: }
125: }
126: }
127:
128: /* ------------------------------------------------------------ */
129: /**
130: * @param client The client for which this token will be valid
131: * @param subscribe True if this token may be used for subscriptions
132: * @param send True if this token may be used for send
133: * @param oneTime True if this token may only be used in one request batch.
134: * @return A new token that can be used for subcriptions and or sending.
135: */
136: public String getToken(Client client, boolean subscribe,
137: boolean send, boolean oneTime) {
138: String token = Long.toString(_bayeux.getRandom(client
139: .hashCode()), 36);
140: // TODO register somewhere ?
141: return token;
142: }
143:
144: /* ------------------------------------------------------------ */
145: public String toString() {
146: return _id + "(" + _subscribers + ")";
147: }
148: }
|