/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2009 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package alma.acs.nc; import alma.ACSErrTypeCommon.wrappers.AcsJCouldntPerformActionEx; import alma.ACSErrTypeCommon.wrappers.AcsJIllegalStateEventEx; import alma.acsErrTypeLifeCycle.wrappers.AcsJEventSubscriptionEx; import alma.acsnc.EventDescription; /** * This interface provides an event subscriber * that can be implemented on top of Corba NC or DDS, in-memory for local testing, * or hopefully also on top of other technologies such as ZeroMQ. *
* Subscriber lifecycle: *
* Discussion: *
Object
or IDLEntity
.
*
* @author jslopez, hsommer
*/
public interface AcsEventSubscriberreceiver
parameter.
* * Note that the same event type can only be subscribed to with one handler, * which means that another handler added for the same type will replace the previous handler. *
* The event type must be that of actual events, not of base classes.
* For example, the AcsEventSubscriber could be parameterized with base type IDLEntity
* and we could then add two subscriptions for events defined as IDL structs,
* say AntennaStatus and TemperatureData.
* If you want to subscribe to events without knowing their exact type,
* use {@link #addGenericSubscription(GenericCallback)} instead.
*
* @param receiver The callback to use when receiving events for the specified type.
*
* @throws AcsJEventSubscriptionEx If there is a problem and the receiver cannot be added
*/
public void addSubscription(Callback receiver)
throws AcsJEventSubscriptionEx;
/**
* Removes the subscription for a specified event type or for all events types, so that the handler previously
* registered for that event type will no longer receive events.
*
* @param structClass
* the event type to be unsubscribed. If null
, then all subscriptions but the generic
* subscription are removed.
*
* @throws AcsJEventSubscriptionEx
* if the specified event type has not been previously subscribed or if the removal fails with a
* technical problem.
*/
public void removeSubscription(Class structClass)
throws AcsJEventSubscriptionEx;
/**
* Adds a generic handler for all types of events.
* This should only be used by monitoring tools and other special applications.
* For normal applications, use one or many calls to {@link #addSubscription(Callback)},
* each with a Callback object that matches exactly the subscribed event type.
*
* It is possible to add a generic handler in addition to event type-specific handlers * (where the latter will get precedence). * Adding another generic handler will replace the previous generic handler. * * @param receiver The callback to use when receiving events * * @throws AcsJEventSubscriptionEx If there is a problem and the generic receiver cannot * be added */ public void addGenericSubscription(GenericCallback receiver) throws AcsJEventSubscriptionEx; /** * Removes the generic event handler, so that it will no longer receive events. * Event specific handlers may still receive events. * * @throws SubscriptionNotFoundException If a generic receiver has not been previously subscribed * @throws AcsJEventSubscriptionEx If there is any problem while unsubscribing the generic receiver */ public void removeGenericSubscription() throws AcsJEventSubscriptionEx; /*===========================================*/ /* Lifecycle methods */ /*===========================================*/ /** * Returns the lifecycle state as obtained from an internal state machine. *
* This state can be used only for debug output. * The state names may change over time and should not be used to control execution. */ public String getLifecycleState(); /** * This method must be called to actually start receiving events. * Typically it is called after the subscriptions are set up. * User may still add and remove subscriptions at any given time, though. * Also, the connection can be suspended and resumed. *
* No further invocations should be attempted on this method after one * has been already successful. Otherwise, an {@link AcsJIllegalStateEventEx} * will be thrown. *
* If this method is not called, no event will ever be received * * @throws AcsJIllegalStateEventEx If the user calls this method on an object that * is already receiving events * @throws AcsJCouldntPerformActionEx If any error happens while trying * to start receiving events */ public void startReceivingEvents() throws AcsJIllegalStateEventEx, AcsJCouldntPerformActionEx; /** * Disconnects this subscriber from the Notification Channel, and releases all * the resources associated with it. After this call, all registered handlers * will stop receiving events, and this subscriber becomes unusable. *
* Calling this method over a subscriber object that has been already disconnected * will throw an {@link AcsJIllegalStateEventEx}. *
* @throws AcsJIllegalStateEventEx If this method is called on an AcsEventSubscriber object * that has been already disconnected */ public void disconnect() throws AcsJIllegalStateEventEx, AcsJCouldntPerformActionEx; /** * Used to temporarily halt receiving events of all types. *
* If the Subscriber has been connected already (method {@link #startReceivingEvents()}, * then after calling this method, incoming events will be buffered instead of being discarded; * unexpired events will be received later, after a call to {@link #resume()}. * *
// * This call has no effect if the Subscriber is not connected, or if it is
// * connected but already suspended.
*
* @throws AcsJIllegalStateEventEx if the subscriber is not connected to an NC.
*/
public void suspend() throws AcsJIllegalStateEventEx, AcsJCouldntPerformActionEx;
/**
* Returns true
if this subscriber has been suspended.
*/
public boolean isSuspended();
/**
* Used to reenable the Subscriber after a call to the
* suspend()
method. Queued events will be received after
* this call, see {@link #suspend()}.
*
* This call has no effect if the Subscriber is not connected, or if it is
* connected and already processing events.
*/
public void resume() throws AcsJIllegalStateEventEx, AcsJCouldntPerformActionEx;
/**
* User callback for received events.
*
* This ACS-defined interface replaces the runtime search for the old
* "Consumer#receive(...)" method that was based on Java introspection.
*/
public static interface Callback {
/**
* Event delivery, from the framework to user code.
* @param eventData The event data, e.g. an IDL-defined struct.
* @param eventDescrip Event meta data.
*/
public void receive(U eventData, EventDescription eventDescrip);
/**
* This method is needed for adding event-specific subscriptions
* and for the type-safety of this API (based on java generics),
* and should be implemented like
*
* public Class<MyEvent> getEventType() {
* return MyEvent.class;
* }
*
*/
public Class getEventType();
}
/**
* Generic event callback, for use with {@link AcsEventSubscriber#addGenericSubscription(GenericCallback)}.
*/
public static interface GenericCallback {
/**
* TODO: Use T instead of Object ?
*/
public void receiveGeneric(Object event, EventDescription eventDescrip);
}
}