
net.sf.eBus.client.EPublisher Maven / Gradle / Ivy
//
// Copyright 2005-2011, 2015, 2016 Charles W. Rapp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package net.sf.eBus.client;
/**
* Classes wanting to send eBus notifications need to implement
* this interface. A publisher must build and
* {@link IEPublishFeed#advertise() advertise} the
* notification feeds it supports. Once eBus accepts the
* advertisement, a publisher has two options:
*
* -
* Wait for a call to its
* {@link #publishStatus(EFeedState, IEPublishFeed)}
* method where {@code feedState} set to
* {@link EFeedState#UP up} before publishing {@code feed}.
* In this option, it is necessary to call
* {@link IEPublishFeed#updateFeedState(EFeedState)}
* with {@link EFeedState#UP up} status before
* publishing the first notification.
*
* When there are no more subscribers, eBus calls
* {@link #publishStatus(EFeedState, IEPublishFeed)} with a
* {@link EFeedState#DOWN down} feed state. The publisher
* must then stop publishing on the {@link IEPublishFeed}.
*
*
* -
* Call {@link IEPublishFeed#updateFeedState(EFeedState)} with
* {@link EFeedState#UP up} feed state and then start
* publishing notifications on that feed after
* checking that {@link IEPublishFeed#isFeedUp()} returns
* {@code true} before calling
* {@link IEPublishFeed#publish(net.sf.eBus.messages.ENotificationMessage)}.
* Alternatively, catch {@link IllegalStateException} thrown
* by {@code IEPublishFeed.publish()} when the feed is down.
*
*
*
* When the application publisher shuts down, then it should
* {@link IEPublishFeed#unadvertise() unadvertise} or
* {@link IEPublishFeed#close()} the feed. There is no need to
* call
* {@code IEPublishFeed.updateFeedState(EFeedState.DOWN)} as this
* is automatically done by {@code unadvertise} and
* {@code close}. If the publisher does not do this, eBus will
* automatically retract the advertisement when it detects the
* publisher is finalized.
*
*
* As of eBus v. 4.2.0, implementing the interface methods is no
* longer necessary. Instead, Java lambda expressions may be used
* to handle publisher callbacks. This is done by calling
* {@link EPublishFeed.Builder#statusCallback(FeedStatusCallback)}
* and using a lambda expression to specify the callback target.
* Still, the application must either override {@code EPublisher}
* callback method or put the status callback in place. Failure
* to do either results in {@link IEPublishFeed#advertise()}
* failing. A class wishing to publish notification messages must
* still implement {@code EPublisher} even though it is no longer
* necessary to override the interface method.
*
*
* The reason for separate {@link IEPublishFeed#advertise()} and
* {@link IEPublishFeed#updateFeedState(EFeedState)} methods is
* to distinguish between the publisher existing or not and
* whether the publisher is able to publish the notification.
* Here are two examples of how to use {@code updateFeedState}.
*
* Example 1: External Monitor Publisher
* An eBus-based application routinely reads input from a serial
* port and publishes those readings in a notification message.
* On start up, the application publisher
* {@link EPublishFeed.Builder builds} its notification feed and
* {@link IEPublishFeed#advertise() advertises} it. Once the
* application publisher opens the serial port and establishes
* communication with the monitor, the publisher then
* {@link IEPublishFeed#updateFeedState(EFeedState) reports} the
* feed is {@link EFeedState#UP up}. If communication to the
* monitor is lost, then a {@link EFeedState#DOWN down} feed
* state is reported. This feed state continues until monitor
* communications is re-established.
* Example 2: Value-added Publisher
* An application instance implements both {@link ESubscriber}
* and {@code EPublisher}. This instance performs value-added
* computation on the received notifications and publishes the
* results. Again, the instance opens and advertises its feed but
* leaves its initial publish status in the down state. The
* instance then subscribes to its inbound feeds. When all those
* feeds are up, the instance then sets its outbound feed state
* to up. If any of the inbound feeds receives a
* {@link ESubscriber#feedStatus(EFeedState, IESubscribeFeed) feed state update}
* with a {@link EFeedState#DOWN down} state, then the published
* feed is then set to down. This continues until the inbound
* feed comes back up. This is an example of a publish state
* change cascading along a publisher, subscriber chain.
*
* If the application publisher is always capable of publishing
* its feed without interruption, then it is sufficient to call
* {@code IEPublishFeed.updateFeedState(FeedState.UP)} immediately
* after {@code IEPublishFeed.advertise()}.
*
*
* @see ENotifySubject
* @see ESubscriber
* @see EPublishFeed
* @see IEPublishFeed
* @see net.sf.eBus.messages.ENotificationMessage
*
* @author Charles Rapp
*/
public interface EPublisher
extends EObject
{
/**
* eBus is requesting that the publisher either start or stop
* publishing the specified feed. If {@code feedState} is
* {@link EFeedState#UP up}, the publisher is free to start
* publishing notification messages on the feed when
* {@link IEPublishFeed#updateFeedState(EFeedState)} is called
* with an up state. If {@code feedState} is
* {@link EFeedState#DOWN down}, then the publisher may not
* publish notifications on the feed.
*
* Note: a publisher is allowed to publish
* notifications feed after {@code publishStatus} is called
* with an up state and the publisher calls
* {@link IEPublishFeed#updateFeedState(EFeedState)} with an
* up state. There is no order for these two events and are
* independent of each other.
*
*
* Method {@link #publishStatus(EFeedState, IEPublishFeed)}
* has a {@code default} definition which throws an
* {@link UnsupportedOperationException}. The reason for this
* default method implementation is to allow users to define
* a separate method with the signature
* {@code void (EFeedState, IEPublishFeed)} and then use
* {@link EPublishFeed.Builder#statusCallback(FeedStatusCallback)}
* to use that defined method for {@code publishStatus}
* callbacks.
*
* @param feedState {@link EFeedState#UP up} to start the
* feed and {@link EFeedState#DOWN down} to stop the feed.
* @param feed start or stop publishing this feed.
* @throws UnsupportedOperationException
* if implementing class does not override this method nor
* uses a callback.
*/
default void publishStatus(EFeedState feedState,
IEPublishFeed feed)
{
throw (
new UnsupportedOperationException(
"publishStatus not implemented"));
} // end of publishStatus(EFeedState, IEPublishFeed)
} // end of EPublisher