almost.functional.reactive.BroadcastObserver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of almost-functional Show documentation
Show all versions of almost-functional Show documentation
Almost Functional is very low impact functional classes inspired by guava, jdk 1.8 and various others.
/*
* Copyright (c) 2014, [email protected]
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with or
* without fee is hereby granted, provided that the above copyright notice and this permission
* notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
* OR PERFORMANCE OF THIS SOFTWARE.
*/
package almost.functional.reactive;
import almost.functional.Consumer;
import almost.functional.Optional;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;
import static almost.functional.utils.ArrayIterable.newIterable;
import static almost.functional.utils.Iterables.forEach;
import static almost.functional.utils.LogFactory.getLogger;
/**
* A single Observer that allow for multiple Observers to observe a single event. Once this Observer
* is completed all the various consumers are released.
* @see almost.functional.reactive.Observer
* @see almost.functional.Consumer
* @param type being observed
*/
public class BroadcastObserver implements Observer {
private static final Logger LOGGER = getLogger();
private final List> nextConsumers = new CopyOnWriteArrayList>();
private final List> errorConsumers = new CopyOnWriteArrayList>();
private final List> completedConsumers = new CopyOnWriteArrayList>();
public BroadcastObserver() {
this(Optional.>empty(), Optional.>empty(), Optional.>empty());
}
public BroadcastObserver(Optional extends Consumer> nextConsumer, Optional extends Consumer> errorConsumer, Optional extends Consumer> completedConsumer) {
if (nextConsumer.isPresent()) {
nextConsumers.add(nextConsumer.get());
}
if (errorConsumer.isPresent()) {
errorConsumers.add(errorConsumer.get());
}
if (completedConsumer.isPresent()) {
completedConsumers.add(completedConsumer.get());
}
}
@Override
public void completed(Boolean withoutError) {
inform(withoutError, completedConsumers);
nextConsumers.clear();
errorConsumers.clear();
completedConsumers.clear();
}
@Override
public void next(T t) {
inform(t, nextConsumers);
}
@Override
public void error(Throwable e) {
inform(e, errorConsumers);
}
/**
* Add multiple next Consumers to this observer.
* @param consumers a number of next Consumers.
* @return this Observer
*/
public Observer addNextConsumer(Consumer ... consumers) {
addAll(nextConsumers, consumers);
return this;
}
/**
* Add multiple error Consumers to this observer.
* @param consumers a number or error Consumers
* @return this Observer
*/
public Observer addErrorConsumer(Consumer ... consumers) {
addAll(errorConsumers, consumers);
return this;
}
/**
* Add multiple completed Consumers to this observer.
* @param consumers a number of completed Consumers
* @return this Observer
*/
public Observer addCompletedConsumer(Consumer ... consumers) {
addAll(completedConsumers, consumers);
return this;
}
private static void addAll(final List> consumerList, Consumer ... additions) {
forEach(newIterable(additions), new Consumer>() {
@Override
public void accept(Consumer vConsumer) {
consumerList.add(vConsumer);
}
});
}
private static void inform(V value, List> consumers) {
for (Consumer consumer : consumers) {
try {
consumer.accept(value);
} catch (Exception e) {
LOGGER.warning("Failed informing of " + value);
}
}
}
}