All Downloads are FREE. Search and download functionalities are using the official Maven repository.

almost.functional.reactive.BroadcastObserver Maven / Gradle / Ivy

Go to download

Almost Functional is very low impact functional classes inspired by guava, jdk 1.8 and various others.

There is a newer version: 1.8
Show newest version
/*
 * 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> nextConsumer, Optional> errorConsumer, Optional> 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);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy