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.ArrayList;
018: import java.util.List;
019: import java.util.Map;
020:
021: import org.mortbay.log.Log;
022: import org.mortbay.util.LazyList;
023: import org.mortbay.util.ajax.Continuation;
024:
025: /* ------------------------------------------------------------ */
026: /**
027: * @author gregw
028: *
029: */
030: public class Client {
031: private Bayeux _bayeux;
032: private String _id;
033: private String _type;
034: private ArrayList _messages = new ArrayList();
035: private Object _continuations;
036: private int _responsesPending;
037: private Object _dataFilters = null;
038: private Channel _connection = null;
039:
040: /* ------------------------------------------------------------ */
041: Client(Bayeux bayeux, String idPrefix) {
042: _bayeux = bayeux;
043: if (idPrefix == null)
044: _id = Long.toString(bayeux.getRandom(System
045: .identityHashCode(this )
046: ^ System.currentTimeMillis()), 36);
047: else
048: _id = idPrefix
049: + "_"
050: + Long.toString(bayeux.getRandom(System
051: .identityHashCode(this )
052: ^ System.currentTimeMillis()), 36);
053: }
054:
055: /* ------------------------------------------------------------ */
056: /**
057: * @param filter
058: */
059: public void addDataFilter(DataFilter filter) {
060: _dataFilters = LazyList.add(_dataFilters, filter);
061: }
062:
063: /* ------------------------------------------------------------ */
064: public String getConnectionType() {
065: return _type;
066: }
067:
068: /* ------------------------------------------------------------ */
069: public String getId() {
070: return _id;
071: }
072:
073: /* ------------------------------------------------------------ */
074: /**
075: * @return the meta Channel for the connection or null if not connected.
076: */
077: public Channel connect() {
078: synchronized (this ) {
079: String connection_id = "/meta/connections/" + getId();
080: _connection = _bayeux.newChannel(connection_id);
081: _connection.addSubscriber(this );
082: return _connection;
083: }
084: }
085:
086: /* ------------------------------------------------------------ */
087: /**
088: * @return the meta Channel for the connection or null if not connected.
089: */
090: public Channel getConnection() {
091: return _connection;
092: }
093:
094: /* ------------------------------------------------------------ */
095: public boolean hasMessages() {
096: synchronized (this ) {
097: return _messages != null && _messages.size() > 0;
098: }
099: }
100:
101: /* ------------------------------------------------------------ */
102: /**
103: * @param filter
104: */
105: public void removeDataFilter(DataFilter filter) {
106: _dataFilters = LazyList.remove(_dataFilters, filter);
107: }
108:
109: /* ------------------------------------------------------------ */
110: public List takeMessages() {
111: synchronized (this ) {
112: if (_messages == null || _messages.size() == 0)
113: return null;
114: List list = _messages;
115: _messages = new ArrayList();
116: return list;
117: }
118: }
119:
120: /* ------------------------------------------------------------ */
121: public String toString() {
122: return _id;
123: }
124:
125: /* ------------------------------------------------------------ */
126: void addContinuation(Continuation continuation) {
127: synchronized (this ) {
128: _continuations = LazyList.add(_continuations, continuation);
129: }
130: }
131:
132: /* ------------------------------------------------------------ */
133: void deliver(Map message) {
134: synchronized (this ) {
135: if (_connection == null)
136: return;
137:
138: _messages.add(message);
139:
140: if (_responsesPending < 1) {
141: if (_continuations != null) {
142: for (int i = 0; i < LazyList.size(_continuations); i++) {
143: Continuation continuation = (Continuation) LazyList
144: .get(_continuations, i);
145: continuation.resume();
146: }
147: }
148: }
149: }
150: }
151:
152: /* ------------------------------------------------------------ */
153: Object filterData(Object data, Client from) {
154: synchronized (this ) {
155: try {
156: for (int f = 0; f < LazyList.size(_dataFilters); f++) {
157: data = ((DataFilter) LazyList.get(_dataFilters, f))
158: .filter(data, from);
159: if (data == null)
160: return null;
161: }
162: } catch (IllegalStateException e) {
163: Log.debug(e);
164: return null;
165: }
166: }
167: return data;
168: }
169:
170: /* ------------------------------------------------------------ */
171: void removeContinuation(Continuation continuation) {
172: synchronized (this ) {
173: _continuations = LazyList.remove(_continuations,
174: continuation);
175: }
176: }
177:
178: /* ------------------------------------------------------------ */
179: int responded() {
180: synchronized (this ) {
181: return _responsesPending--;
182: }
183: }
184:
185: /* ------------------------------------------------------------ */
186: int responsePending() {
187: synchronized (this ) {
188: return ++_responsesPending;
189: }
190: }
191:
192: /* ------------------------------------------------------------ */
193: void setConnectionType(String type) {
194: _type = type;
195: }
196:
197: /* ------------------------------------------------------------ */
198: void setId(String _id) {
199: this._id = _id;
200: }
201: }
|