001: package org.jacorb.events;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import org.jacorb.orb.*;
024:
025: /**
026: * Implementation of COSEventChannelAdmin interface; ProxyPullConsumer.
027: * This defines connect_pull_supplier() and disconnect_pull_consumer().
028: *
029: * 2002/23/08 JFC OMG EventService Specification 1.1 page 2-7 states:
030: * "Registration is a two step process. An event-generating application
031: * first obtains a proxy consumer from a channel, then 'connects' to the
032: * proxy consumer by providing it with a supplier. ... The reason for
033: * the two step registration process..."
034: * Modifications to support the above have been made as well as to support
035: * section 2.1.5 "Disconnection Behavior" on page 2-4.
036: *
037: * @author Jeff Carlson
038: * @author Joerg v. Frantzius
039: * @author Rainer Lischetzki
040: * @author Gerald Brose
041: * $Id: ProxyPullConsumerImpl.java,v 1.10 2004/05/06 12:39:58 nicolas Exp $
042: */
043: public class ProxyPullConsumerImpl extends
044: org.omg.CosEventChannelAdmin.ProxyPullConsumerPOA implements
045: Runnable {
046: private EventChannelImpl myEventChannel;
047: private org.omg.CosEventComm.PullSupplier myPullSupplier;
048: private org.omg.PortableServer.POA myPoa = null;
049: private boolean connected = false;
050:
051: /**
052: * Constructor - gets called by the EventChannel
053: */
054: protected ProxyPullConsumerImpl(EventChannelImpl ec,
055: org.omg.CORBA.ORB orb, org.omg.PortableServer.POA poa) {
056: myEventChannel = ec;
057: myPoa = poa;
058: connected = false;
059: _this _object(orb);
060: }
061:
062: /**
063: * ProxyPullConsumer Interface:
064: * As stated by the EventService specification 1.1 section 2.3.6:
065: * "If a <b>ProxyPullSupplier</b> is already connected to a <b>PullConsumer</b>,
066: * then the <b>AlreadyConnected</b> exception is raised."
067: * and
068: * "Implementations shall raise the CORBA standard <b>BAD_PARAM</b> exception if
069: * a nil object reference is passed to the <b>connect_pull_supplier</b> operation.
070: * and
071: * "An implementation of a <b>ProxyPullConsumer</b> may put additional
072: * requirements on the interface supported by the pull supplier. If t he pull
073: * supplier does not meet those requirements, the <b>ProxyPullConsumer</b>
074: * raises the <b>TypeError</b> exception. (See section 2.5.2 on page 2-15
075: * for an example)"
076: */
077:
078: public void connect_pull_supplier(
079: org.omg.CosEventComm.PullSupplier pullSupplier)
080: throws org.omg.CosEventChannelAdmin.AlreadyConnected,
081: org.omg.CosEventChannelAdmin.TypeError {
082: if (connected) {
083: throw new org.omg.CosEventChannelAdmin.AlreadyConnected();
084: }
085: if (pullSupplier == null) {
086: throw new org.omg.CORBA.BAD_PARAM();
087: }
088:
089: myPullSupplier = pullSupplier;
090: connected = true;
091: new Thread(this ).start();
092: }
093:
094: /**
095: * See EventService v 1.1 specification section 2.1.4.
096: * 'disconnect_pull_consumer terminates the event communication; it releases
097: * resources used at the consumer to support event communication. Calling
098: * this causes the implementation to call disconnect_pull_supplier operation
099: * on the corresponding PullSupplier interface (if that iterface is known).'
100: * See EventService v 1.1 specification section 2.1.5. This method should
101: * adhere to the spec as it a) causes a call to the corresponding disconnect
102: * on the connected supplier, b) 'If a consumer or supplier has received a
103: * disconnect call and subsequently receives another disconnect call, it
104: * shall raise a CORBA::OBJECT_NOT_EXIST exception.
105: */
106:
107: public void disconnect_pull_consumer() {
108:
109: if (connected) {
110: if (myPullSupplier != null) {
111: myPullSupplier.disconnect_pull_supplier();
112: myPullSupplier = null;
113: }
114: connected = false;
115: } else {
116: throw new org.omg.CORBA.OBJECT_NOT_EXIST();
117: }
118: }
119:
120: /**
121: * Start being a good PullConsumer and ask for loads of events.
122: */
123:
124: public void run() {
125: org.omg.CORBA.BooleanHolder hasEvent = new org.omg.CORBA.BooleanHolder();
126: org.omg.CORBA.Any event = null;
127: while (connected) {
128: synchronized (this ) {
129: try {
130: event = myPullSupplier.try_pull(hasEvent);
131: } catch (org.omg.CORBA.UserException userEx) {
132: connected = false;
133: // userEx.printStackTrace();
134: return;
135: } catch (org.omg.CORBA.SystemException sysEx) {
136: connected = false;
137: // sysEx.printStackTrace();
138: return;
139: }
140:
141: if (hasEvent.value) {
142: myEventChannel.push_event(event);
143: }
144: // Let other threads get some time on the CPU in case we're
145: // in a cooperative environment.
146: Thread.yield();
147: }
148: }
149: }
150:
151: /**
152: * Override this method from the Servant baseclass. Fintan Bolton
153: * in his book "Pure CORBA" suggests that you override this method to
154: * avoid the risk that a servant object (like this one) could be
155: * activated by the <b>wrong</b> POA object.
156: */
157: public org.omg.PortableServer.POA _default_POA() {
158: return myPoa;
159: }
160: }
|