KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > smack > PacketCollector


1 /**
2  * $RCSfile$
3  * $Revision: 2408 $
4  * $Date: 2004-11-02 20:53:30 -0300 (Tue, 02 Nov 2004) $
5  *
6  * Copyright 2003-2004 Jive Software.
7  *
8  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */

20
21 package org.jivesoftware.smack;
22
23 import org.jivesoftware.smack.packet.Packet;
24 import org.jivesoftware.smack.filter.PacketFilter;
25
26 import java.util.LinkedList JavaDoc;
27
28 /**
29  * Provides a mechanism to collect packets into a result queue that pass a
30  * specified filter. The collector lets you perform blocking and polling
31  * operations on the result queue. So, a PacketCollector is more suitable to
32  * use than a {@link PacketListener} when you need to wait for a specific
33  * result.<p>
34  *
35  * Each packet collector will queue up to 2^16 packets for processing before
36  * older packets are automatically dropped.
37  *
38  * @see XMPPConnection#createPacketCollector(PacketFilter)
39  * @author Matt Tucker
40  */

41 public class PacketCollector {
42
43     /**
44      * Max number of packets that any one collector can hold. After the max is
45      * reached, older packets will be automatically dropped from the queue as
46      * new packets are added.
47      */

48     private static final int MAX_PACKETS = 65536;
49
50     private PacketFilter packetFilter;
51     private LinkedList JavaDoc resultQueue;
52     private PacketReader packetReader;
53     private boolean cancelled = false;
54
55     /**
56      * Creates a new packet collector. If the packet filter is <tt>null</tt>, then
57      * all packets will match this collector.
58      *
59      * @param packetReader the packetReader the collector is tied to.
60      * @param packetFilter determines which packets will be returned by this collector.
61      */

62     protected PacketCollector(PacketReader packetReader, PacketFilter packetFilter) {
63         this.packetReader = packetReader;
64         this.packetFilter = packetFilter;
65         this.resultQueue = new LinkedList JavaDoc();
66          // Add the collector to the packet reader's list of active collector.
67
synchronized (packetReader.collectors) {
68             packetReader.collectors.add(this);
69         }
70     }
71
72     /**
73      * Explicitly cancels the packet collector so that no more results are
74      * queued up. Once a packet collector has been cancelled, it cannot be
75      * re-enabled. Instead, a new packet collector must be created.
76      */

77     public void cancel() {
78         // If the packet collector has already been cancelled, do nothing.
79
if (cancelled) {
80             return;
81         }
82         else {
83             cancelled = true;
84             // Remove object from collectors list by setting the value in the
85
// list at the correct index to null. The collector thread will
86
// automatically remove the actual list entry when it can.
87
synchronized (packetReader.collectors) {
88                 int index = packetReader.collectors.indexOf(this);
89                 packetReader.collectors.set(index, null);
90             }
91         }
92     }
93
94     /**
95      * Returns the packet filter associated with this packet collector. The packet
96      * filter is used to determine what packets are queued as results.
97      *
98      * @return the packet filter.
99      */

100     public PacketFilter getPacketFilter() {
101         return packetFilter;
102     }
103
104     /**
105      * Polls to see if a packet is currently available and returns it, or
106      * immediately returns <tt>null</tt> if no packets are currently in the
107      * result queue.
108      *
109      * @return the next packet result, or <tt>null</tt> if there are no more
110      * results.
111      */

112     public synchronized Packet pollResult() {
113         if (resultQueue.isEmpty()) {
114             return null;
115         }
116         else {
117             return (Packet)resultQueue.removeLast();
118         }
119     }
120
121     /**
122      * Returns the next available packet. The method call will block (not return)
123      * until a packet is available.
124      *
125      * @return the next available packet.
126      */

127     public synchronized Packet nextResult() {
128         // Wait indefinitely until there is a result to return.
129
while (resultQueue.isEmpty()) {
130             try {
131                 wait();
132             }
133             catch (InterruptedException JavaDoc ie) { }
134         }
135         return (Packet)resultQueue.removeLast();
136     }
137
138     /**
139      * Returns the next available packet. The method call will block (not return)
140      * until a packet is available or the <tt>timeout</tt> has elapased. If the
141      * timeout elapses without a result, <tt>null</tt> will be returned.
142      *
143      * @param timeout the amount of time to wait for the next packet (in milleseconds).
144      * @return the next available packet.
145      */

146     public synchronized Packet nextResult(long timeout) {
147         // Wait up to the specified amount of time for a result.
148
if (resultQueue.isEmpty()) {
149             try {
150                 wait(timeout);
151             }
152             catch (InterruptedException JavaDoc ie) { }
153         }
154         // If still no result, return null.
155
if (resultQueue.isEmpty()) {
156             return null;
157         }
158         else {
159             return (Packet)resultQueue.removeLast();
160         }
161     }
162
163     /**
164      * Processes a packet to see if it meets the criteria for this packet collector.
165      * If so, the packet is added to the result queue.
166      *
167      * @param packet the packet to process.
168      */

169     protected synchronized void processPacket(Packet packet) {
170         if (packet == null) {
171             return;
172         }
173         if (packetFilter == null || packetFilter.accept(packet)) {
174             // If the max number of packets has been reached, remove the oldest one.
175
if (resultQueue.size() == MAX_PACKETS) {
176                 resultQueue.removeLast();
177             }
178             // Add the new packet.
179
resultQueue.addFirst(packet);
180             // Notify waiting threads a result is available.
181
notifyAll();
182         }
183     }
184 }
185
Popular Tags