KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > events > ProxyPullSupplierImpl


1 package org.jacorb.events;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import org.omg.CosEventComm.*;
24 import org.jacorb.orb.*;
25 import java.util.*;
26
27
28 /**
29  * Implementation of COSEventChannelAdmin interface; ProxyPullSupplier.
30  * This defines connect_pull_consumer(), disconnect_pull_supplier() and the all
31  * important pull() and try_pull() methods that the Consumer can call to
32  * actuall deliver a message.
33  *
34  * 2002/23/08 JFC OMG EventService Specification 1.1 page 2-7 states:
35  * "Registration is a two step process. An event-generating application
36  * first obtains a proxy consumer from a channel, then 'connects' to the
37  * proxy consumer by providing it with a supplier. ... The reason for
38  * the two step registration process..."
39  * Modifications to support the above have been made as well as to support
40  * section 2.1.5 "Disconnection Behavior" on page 2-4.
41  *
42  * @author Jeff Carlson
43  * @author Joerg v. Frantzius
44  * @author Rainer Lischetzki
45  * @author Gerald Brose
46  * @version $Id: ProxyPullSupplierImpl.java,v 1.11 2004/05/06 12:39:58 nicolas Exp $
47  */

48 public class ProxyPullSupplierImpl
49     extends org.omg.CosEventChannelAdmin.ProxyPullSupplierPOA
50 {
51     private EventChannelImpl myEventChannel = null;
52     private PullConsumer myPullConsumer = null;
53     private org.omg.PortableServer.POA JavaDoc myPoa = null;
54     private boolean connected = false;
55     private LinkedList pendingEvents = new LinkedList();
56     private final int maxListSize = 200;
57     private static org.omg.CORBA.Any JavaDoc undefinedAny = null;
58
59     /**
60      * Constructor - to be called by EventChannel
61      */

62     protected ProxyPullSupplierImpl ( EventChannelImpl ec,
63                                       org.omg.CORBA.ORB JavaDoc orb,
64                                       org.omg.PortableServer.POA JavaDoc poa )
65     {
66         myEventChannel = ec;
67         myPoa = poa;
68         connected = false;
69         _this_object(orb);
70         undefinedAny = org.omg.CORBA.ORB.init().create_any();
71     }
72
73     /**
74      * ProxyPullSupplier Interface:
75      * As stated by the EventService specification 1.1 section 2.3.5:
76      * "If a ProxyPullSupplier is already connected to a PullConsumer, then the
77      * AlreadyConnected exception is raised."
78      * and
79      * "If a non-nil reference is passed to connect_push_supplier..." implying
80      * that a null reference is acceptable.
81      */

82
83     public void connect_pull_consumer ( PullConsumer pullConsumer )
84         throws org.omg.CosEventChannelAdmin.AlreadyConnected
85     {
86         if ( connected ) { throw new org.omg.CosEventChannelAdmin.AlreadyConnected(); }
87         myPullConsumer = pullConsumer;
88         connected = true;
89     }
90
91     /**
92      * See EventService v 1.1 specification section 2.1.3.
93      * 'disconnect_pull_supplier terminates the event communication; it releases
94      * resources used at the consumer to support event communication. Calling
95      * this causes the implementation to call disconnect_pull_consumer operation
96      * on the corresponding PullConsumer interface (if that iterface is known).'
97      * See EventService v 1.1 specification section 2.1.5. This method should
98      * adhere to the spec as it a) causes a call to the corresponding disconnect
99      * on the connected supplier, b) 'If a consumer or supplier has received a
100      * disconnect call and subsequently receives another disconnect call, it
101      * shall raise a CORBA::OBJECT_NOT_EXIST exception.
102      * See EventService v 1.1 specification section 2.3.5. If [a nil object
103      * reference is passed to connect_pull_consumer] a channel cannot invoke a
104      * disconnect_pull_consumer operation on the consumer.
105      */

106
107     public void disconnect_pull_supplier()
108     {
109         if ( connected )
110         {
111             if ( myPullConsumer != null )
112             {
113                 myPullConsumer.disconnect_pull_consumer();
114                 myPullConsumer = null;
115             }
116             connected = false;
117         }
118         else
119         {
120             throw new org.omg.CORBA.OBJECT_NOT_EXIST JavaDoc();
121         }
122     }
123
124     /**
125      * PullSupplier Interface.
126      * section 2.1.3 states that "The <b>pull</b> operation blocks until the
127      * event data is available or an exception is raised. It returns data to
128      * the consumer."
129      */

130
131     public org.omg.CORBA.Any JavaDoc pull ()
132         throws org.omg.CosEventComm.Disconnected
133     {
134         org.omg.CORBA.Any JavaDoc event = null;
135         org.omg.CORBA.BooleanHolder JavaDoc hasEvent = new org.omg.CORBA.BooleanHolder JavaDoc();
136         while ( true )
137         {
138             event = try_pull( hasEvent );
139             if ( hasEvent.value )
140             {
141                 return event;
142             }
143             Thread.yield();
144         }
145     }
146
147     /**
148      * PullSupplier Interface.
149      * section 2.1.3 states that "The <b>try_pull</b> operation does not block:
150      * if the event data is available, it returns the event data and sets the
151      * <b>has_event</b> parameter to true; if the event is not available, it
152      * sets the <b>has_event</b> parameter to false and the event data is
153      * returned as long with an undefined value.
154      * It seems that the event queue should be defined as a LIFO queue. Finton
155      * Bolton in his book Pure CORBA states that this is the "norm". I think
156      * that is really stupid. Who wants events in reverse order with a
157      * possibility of never getting the first messge? I will therefore implement
158      * this as a FIFO queue and wait for someone to convince me otherwise.
159      */

160
161     public org.omg.CORBA.Any JavaDoc try_pull ( org.omg.CORBA.BooleanHolder JavaDoc hasEvent )
162         throws org.omg.CosEventComm.Disconnected
163     {
164         if ( !connected ) { throw new org.omg.CosEventComm.Disconnected(); }
165
166         org.omg.CORBA.Any JavaDoc event = null;
167
168         synchronized( pendingEvents )
169         {
170             int listSize = pendingEvents.size();
171             if ( listSize > 0 )
172             {
173                 event = (org.omg.CORBA.Any JavaDoc)pendingEvents.getFirst();
174                 pendingEvents.remove( event );
175                 hasEvent.value = true;
176                 return event;
177             }
178             else
179             {
180                 hasEvent.value = false;
181                 return undefinedAny;
182             }
183         }
184     }
185
186     /**
187      * Have to be able to get to the internal list of events. This is how
188      * to add stuff to this list.
189      * I have to decide whether to a) just ignore the event, b) add the event
190      * to the queue and remove the oldest event, c) throw an runtime exception.
191      * Right now, I'm going with option b.
192      */

193
194     public void push_to_supplier( org.omg.CORBA.Any JavaDoc event)
195     {
196         synchronized( pendingEvents )
197         {
198             if ( pendingEvents.size() > maxListSize )
199             {
200                 pendingEvents.remove( pendingEvents.getFirst() );
201             }
202             pendingEvents.add( event );
203         }
204     }
205
206     /**
207      * Override this method from the Servant baseclass. Fintan Bolton
208      * in his book "Pure CORBA" suggests that you override this method to
209      * avoid the risk that a servant object (like this one) could be
210      * activated by the <b>wrong</b> POA object.
211      */

212
213     public org.omg.PortableServer.POA JavaDoc _default_POA()
214     {
215         return myPoa;
216     }
217 }
218
Popular Tags