KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > excalibur > event > impl > LossyMultiCastSink


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

17 package org.apache.excalibur.event.impl;
18
19 import java.util.Collection JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.LinkedList JavaDoc;
22
23 import org.apache.excalibur.event.PreparedEnqueue;
24 import org.apache.excalibur.event.Sink;
25 import org.apache.excalibur.event.SinkException;
26 import org.apache.excalibur.event.SinkFullException;
27
28 /**
29  * This is a {@link org.apache.excalibur.event.seda.event.Sink}
30  * implementation that multicasts enqueue operations to the
31  * contained and concrete sink objects. Compared to the
32  * regular {@link org.apache.excalibur.event.seda.event.impl.MultiCastSink}
33  * this sink works in that it delivers zero, one or more sinks.
34  * It can be configured to fail when less than one sink was
35  * delivered to.
36  *
37  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
38  * @version $Revision: 1.4 $
39  */

40 public class LossyMultiCastSink implements Sink
41 {
42     /**
43      * A collection of sink arrays representing the
44      * sinks to enqueue the element to.
45      */

46     private final Collection JavaDoc m_sinks;
47
48     /**
49      * The size of the sink.
50      */

51     private final int m_size;
52
53     /**
54      * indicates if at least one enqueue operation must succeed.
55      */

56     private final boolean m_oneSuccess;
57
58     //---------------------- LossyMultiCastSink constructors
59
/**
60      * This constructor creates a failure tolerant sink
61      * based on the collection of sink arrays. None of
62      * the enqueue operations must succeed.
63      * @since May 16, 2002
64      *
65      * @param sinks
66      * A collection of sink arrays for each stage.
67      */

68     public LossyMultiCastSink(Collection JavaDoc sinks)
69     {
70         this(sinks, false);
71     }
72
73     /**
74      * This constructor creates a failure tolerant sink
75      * based on the collection of sink arrays. The additional
76      * boolean flag describes whether at least one or none
77      * of the enqueue operations must succeed.
78      * @since May 16, 2002
79      *
80      * @param sinks
81      * A collection of sink arrays for each stage.
82      */

83     public LossyMultiCastSink(Collection JavaDoc sinks, boolean oneSuccess)
84     {
85         m_sinks = sinks;
86         m_size = -1;
87         m_oneSuccess = oneSuccess;
88     }
89
90     //---------------------- Sink implementation
91
/**
92      * @see Sink#canAccept()
93      */

94     public int canAccept()
95     {
96         return 0;
97     }
98
99     /**
100      * @see Sink#isFull()
101      */

102     public boolean isFull()
103     {
104         return false;
105     }
106
107     /**
108      * @see Sink#maxSize()
109      */

110     public int maxSize()
111     {
112         return 0;
113     }
114
115     /**
116      * @see Sink#enqueue(Object)
117      */

118     public void enqueue(Object JavaDoc element) throws SinkException
119     {
120         final Iterator JavaDoc sinks = m_sinks.iterator();
121
122         int successful = 0;
123
124         //checkEnqueuePredicate(new Object[] { element });
125

126         // iterate through the sinks and try to enqueue
127
while (sinks.hasNext())
128         {
129             final Sink sink = (Sink) sinks.next();
130
131             final boolean enqueued = sink.tryEnqueue(element);
132
133             // enqueue only to the first successful sink
134
if (enqueued)
135             {
136                 successful++;
137                 break;
138             }
139         }
140
141         if (successful == 0 && m_oneSuccess)
142         {
143             throw new SinkFullException("Could not deliver one single element.");
144         }
145     }
146
147     /**
148      * @see Sink#enqueue(Object[])
149      */

150     public void enqueue(Object JavaDoc[] elements) throws SinkException
151     {
152         final Iterator JavaDoc sinks = m_sinks.iterator();
153
154         int successful = 0;
155
156         //checkEnqueuePredicate(elements);
157

158         // iterate through the sinks and try to enqueue
159
while (sinks.hasNext())
160         {
161             final Sink sink = (Sink) sinks.next();
162
163             try
164             {
165                 sink.enqueue(elements);
166             }
167             catch (SinkFullException e)
168             {
169                 continue;
170             }
171
172             // if enqueue successful break here
173
successful++;
174             break;
175         }
176
177         if (successful == 0 && m_oneSuccess)
178         {
179             throw new SinkFullException("Could not deliver one single elements.");
180         }
181     }
182
183     /**
184      * @see Sink#tryEnqueue(Object)
185      */

186     public boolean tryEnqueue(Object JavaDoc element)
187     {
188         try
189         {
190             enqueue(element);
191             return true;
192         }
193         catch (SinkException e)
194         {
195             return !m_oneSuccess;
196         }
197     }
198
199     /**
200      * @see Sink#prepareEnqueue(Object[])
201      */

202     public PreparedEnqueue prepareEnqueue(Object JavaDoc[] elements)
203         throws SinkException
204     {
205         final Iterator JavaDoc sinks = m_sinks.iterator();
206         final DefaultPreparedEnqueue prepares = new DefaultPreparedEnqueue();
207
208         int successful = 0;
209
210         //checkEnqueuePredicate(elements);
211

212         // iterate through the sinks and try to enqueue
213
while (sinks.hasNext())
214         {
215             final Sink sink = (Sink) sinks.next();
216
217             try
218             {
219                 prepares.addPreparedEnqueue(sink.prepareEnqueue(elements));
220             }
221             catch (SinkFullException e)
222             {
223                 continue;
224             }
225
226             // if enqueue successful break here
227
successful++;
228             break;
229         }
230         if (successful == 0 && m_oneSuccess)
231         {
232             throw new SinkFullException("Could not deliver elements at all.");
233         }
234
235         return prepares;
236     }
237
238     /**
239      * @see Sink#size()
240      */

241     public int size()
242     {
243         return m_size;
244     }
245
246     //------------------------- LossyMultiCastSink inner classes
247
/**
248      * A prepared enqueue object that holds other prepared
249      * enqueue objects and allows to perform a commit / abort
250      * on all of these objects.
251      * @since May 16, 2002
252      *
253      * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
254      */

255     private static final class DefaultPreparedEnqueue
256         implements PreparedEnqueue
257     {
258         /**
259          * A collection of prepared enqueue objects
260          */

261         private final Collection JavaDoc m_preparedEnqueues = new LinkedList JavaDoc();
262
263         //------------------------ PreparedEnqueue implementation
264
/**
265          * @see PreparedEnqueue#abort()
266          */

267         public void abort()
268         {
269             final Iterator JavaDoc iter = m_preparedEnqueues.iterator();
270
271             while (iter.hasNext())
272             {
273                 ((PreparedEnqueue) iter.next()).abort();
274             }
275         }
276
277         /**
278          * @see PreparedEnqueue#commit()
279          */

280         public void commit()
281         {
282             final Iterator JavaDoc iter = m_preparedEnqueues.iterator();
283
284             while (iter.hasNext())
285             {
286                 ((PreparedEnqueue) iter.next()).commit();
287             }
288         }
289
290         //------------------------ DefaultPreparedEnqueue specific implementation
291
/**
292          * Adds a prepared enqueue object to the list
293          * of prepared enqueues.
294          * @since May 16, 2002
295          *
296          * @param preparedEnqueue
297          * The prepared enqueue object to be added.
298          */

299         public void addPreparedEnqueue(PreparedEnqueue preparedEnqueue)
300         {
301             m_preparedEnqueues.add(preparedEnqueue);
302         }
303     } //-- end DefaultPreparedEnqueue inner class
304
}
305
Popular Tags