+++ /dev/null
-/*
- * Copyright 2005 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.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.log4j.Logger;
-
-
-/**
- * Implements subscription and notification logic for an observer pattern.
- * This class is thread safe.
- */
-public class Observable<ObservableType, Event> {
-
- private static final Logger LOGGER = Logger.getLogger(Observable.class);
-
- /**
- * Observable.
- */
- private ObservableType _observable;
-
- /**
- * Used to notify observers.
- */
- private ObserverNotifier<ObservableType,Event> _notifier;
-
- /**
- * Map of subscription to observer.
- */
- private Map<Long, Observer<ObservableType,Event>> _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<ObservableType,Event> aNotifier) {
- _observable = aObservable;
- _notifier = aNotifier;
- _observers = new TreeMap<Long, Observer<ObservableType, Event>>();
- _counter = 0;
- }
-
- /**
- * Subscribe an obvers.
- * @param aObserver Observer to subscribe.
- * @return Event Event to send.
- */
- public synchronized long subscribe(Observer<ObservableType, Event> 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.
- */
- 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<Observer<ObservableType,Event>> observers = new ArrayList<Observer<ObservableType, Event>>();
- synchronized (this) {
- observers.addAll(_observers.values());
- }
- for (Observer<ObservableType,Event> observer: observers) {
- _notifier.update(observer, _observable, aEvent);
- }
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable {
- if ( _observers.size() > 0 ) {
- LOGGER.error("Still observers registered at finalization of observer!");
- for (Observer observer: _observers.values()) {
- LOGGER.error(" observer: " + observer);
- }
- }
-
- super.finalize();
- }
-
-}