/* * Copyright (C) 2012, Katy Hilgenberg. * Special acknowledgments to: Knowledge & Data Engineering Group, University of Kassel (http://www.kde.cs.uni-kassel.de). * Contact: sdcf@cs.uni-kassel.de * * This file is part of the SDCFramework (Sensor Data Collection Framework) project. * * The SDCFramework is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The SDCFramework is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the SDCFramework. If not, see <http://www.gnu.org/licenses/>. */ package de.unikassel.android.sdcframework.util; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedQueue; import de.unikassel.android.sdcframework.util.facade.EventObserver; import de.unikassel.android.sdcframework.util.facade.ObservableEvent; import de.unikassel.android.sdcframework.util.facade.ObservableEventSource; /** * Generic implementation for an observable event source. <br/> * <br/> * This class is implementing the {@link ObservableEventSource * ObservableEventSource} interface. <br/> * <br/> * A class extending this type can notify it's registered observers about the * observed events by invoking the * {@link ObservableEventSourceImpl#notify(ObservableEvent) notify} method. * * @author Katy Hilgenberg * @param <T> * the observed event type extending {@linkplain ObservableEvent * ObservableEvent} * */ public class ObservableEventSourceImpl< T extends ObservableEvent > implements ObservableEventSource< T > { /** * The observer collection */ private final ConcurrentLinkedQueue< EventObserver< T > > observers; /** * Constructor */ public ObservableEventSourceImpl() { super(); observers = new ConcurrentLinkedQueue< EventObserver< T > >(); } /** * Getter for the observers * * @return the observers */ public final Collection< EventObserver< T > > getObservers() { return Collections.unmodifiableCollection( observers ); } /* * (non-Javadoc) * * @see de.unikassel.android.sdcframework.util.ObservableEventCreator# * registerEventObserver * (de.unikassel.android.sdcframework.util.AbstractEventObserver) */ @SuppressWarnings( "unchecked" ) @Override public final void registerEventObserver( EventObserver< ? extends T > observer ) { if ( !observers.contains( observer ) ) { if ( observers.add( (EventObserver< T >) observer ) ) { onObserverRegistration( observer ); } } } /** * Handler for registered observers ( to be overloaded by extending classes if * necessary ) * * @param observer * the registered observer */ protected void onObserverRegistration( EventObserver< ? extends T > observer ) { // default do nothing } /* * (non-Javadoc) * * @see de.unikassel.android.sdcframework.util.ObservableEventCreator# * unregisterEventObserver * (de.unikassel.android.sdcframework.util.AbstractEventObserver) */ @Override public final void unregisterEventObserver( EventObserver< ? extends T > observer ) { if ( observers.remove( observer ) ) { onObserverUnregistration( observer ); } } /** * Handler for unregistered observers ( to be overloaded by extending classes * if necessary ) * * @param observer * the unregistered observer */ protected void onObserverUnregistration( EventObserver< ? extends T > observer ) { // default do nothing } /* * (non-Javadoc) * * @see * de.unikassel.android.sdcframework.util.ObservableEventCreator#notify(T) */ @Override public final void notify( T data ) { if ( data == null ) return; Iterator< EventObserver< T >> it = observers.iterator(); while ( it.hasNext() ) { EventObserver< T > observer = it.next(); try { observer.onEvent( this, data ); } catch ( Exception e ) { Logger.getInstance().error( this, "Exception during observer notification: " + e.getMessage() ); } } } /* * (non-Javadoc) * * @see de.unikassel.android.sdcframework.util.facade.ObservableEventSource# * removeAllObservers() */ @Override public final void removeAllObservers() { observers.clear(); } /* * (non-Javadoc) * * @see de.unikassel.android.sdcframework.util.facade.ObservableEventSource# * hasObservers() */ @Override public final boolean hasObservers() { return !observers.isEmpty(); } }