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);
}
}
}