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

org.wamblee.observer.Observable Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2005-2010 the original author or authors.
 * 
 * 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 org.wamblee.observer;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Implements subscription and notification logic for an observer pattern. This
 * class is thread safe.
 */
public class Observable {
    /**
     * Observable.
     */
    private ObservableType observable;

    /**
     * Used to notify observers.
     */
    private ObserverNotifier notifier;

    /**
     * Map of subscription to observer.
     */
    private Map> observers;

    /**
     * Counter for subscriptions. Holds the next subscription.
     */
    private long counter;

    /**
     * Constructs the observable.
     * 
     * @param aObservable
     *            Observable this instance is used for.
     * @param aNotifier
     *            Object used for implementing notification of listeners.
     */
    public Observable(ObservableType aObservable,
        ObserverNotifier aNotifier) {
        observable = aObservable;
        notifier = aNotifier;
        observers = new TreeMap>();
        counter = 0;
    }

    /**
     * Subscribe an obvers.
     * 
     * @param aObserver
     *            Observer to subscribe.
     * @return Event Event to send.
     */
    public synchronized long subscribe(Observer aObserver) {
        long subscription = counter++; // integer rage is so large it will
        // never roll over.

        observers.put(subscription, aObserver);

        return subscription;
    }

    /**
     * Unsubscribe an observer.
     * 
     * @param aSubscription
     *            Subscription which is used
     * @throws IllegalArgumentException
     *             In case the subscription is not known.
     */
    public synchronized void unsubscribe(long aSubscription) {
        Object obj = observers.remove(aSubscription);

        if (obj == null) {
            throw new IllegalArgumentException("Subscription '" +
                aSubscription + "'");
        }
    }

    /**
     * Gets the number of subscribed observers.
     * 
     * @return Number of subscribed observers.
     */
    public int getObserverCount() {
        return observers.size();
    }

    /**
     * Notifies all subscribed observers.
     * 
     * @param aEvent
     *            Event to send.
     */
    public void send(Event aEvent) {
        // Make sure we do the notification while not holding the lock to avoid
        // potential deadlock
        // situations.
        List> myObservers = new ArrayList>();

        synchronized (this) {
            myObservers.addAll(observers.values());
        }

        for (Observer observer : myObservers) {
            notifier.update(observer, observable, aEvent);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy