/** * Copyright 2010-2011 Voxeo Corporation * * 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 com.voxeo.moho.common.event; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Future; import com.voxeo.moho.ApplicationContext; import com.voxeo.moho.common.AttributeStoreImpl; import com.voxeo.moho.common.util.Utils; import com.voxeo.moho.event.Event; import com.voxeo.moho.event.EventSource; import com.voxeo.moho.event.Observer; import com.voxeo.moho.spi.ExecutionContext; import com.voxeo.moho.utils.EventListener; /** * DispatchableEventSource supports dispatching events to different targets on a * single threaded event queue The target can be either an EventListener or a * event method in an Observer. The event method in an Observer is a public * method with a single parameter whose type is one of the event. */ public class DispatchableEventSource extends AttributeStoreImpl implements EventSource { protected String _id; protected Map<String, String> _states = new ConcurrentHashMap<String, String>(); protected ExecutionContext _context; protected EventDispatcher _dispatcher = new EventDispatcher(); protected ConcurrentHashMap<Observer, AutowiredEventListener> _observers = new ConcurrentHashMap<Observer, AutowiredEventListener>(); protected DispatchableEventSource() { } public DispatchableEventSource(final ExecutionContext applicationContext) { this(applicationContext, true); } public DispatchableEventSource(final ExecutionContext applicationContext, boolean orderedDispatch) { this(); _context = applicationContext; _dispatcher.setExecutor(getThreadPool(), orderedDispatch); _id = UUID.randomUUID().toString(); } // Event Handling // ================================================================= public void addListener(final EventListener<?> listener) { if (listener != null) { _dispatcher.addListener(MohoEvent.class, listener); } } public void addListeners(final EventListener<?>... listeners) { if (listeners != null) { for (final EventListener<?> listener : listeners) { this.addListener(listener); } } } public <E extends MohoEvent<?>, T extends EventListener<E>> void addListener(final Class<E> type, final T listener) { if (listener != null) { _dispatcher.addListener(type, listener); } } public <E extends MohoEvent<?>, T extends EventListener<E>> void addListeners(final Class<E> type, final T... listeners) { if (listeners != null) { for (final T listener : listeners) { this.addListener(type, listener); } } } @SuppressWarnings("rawtypes") public void addObserver(final Observer observer) { if (observer != null) { if (observer instanceof EventListener) { EventListener<?> l = (EventListener<?>) observer; Class claz = Utils.getGenericType(observer); if (claz == null) { claz = Event.class; } _dispatcher.addListener(claz, l); } else { final AutowiredEventListener autowire = new AutowiredEventListener(observer); if (_observers.putIfAbsent(observer, autowire) == null) { _dispatcher.addListener(Event.class, autowire); } } } } @Override public void addObserver(final Observer... observers) { if (observers != null) { for (final Observer o : observers) { addObserver(o); } } } public void removeListener(final EventListener<?> listener) { _dispatcher.removeListener(listener); } @Override public void removeObserver(final Observer listener) { if (listener instanceof EventListener) { _dispatcher.removeListener((EventListener<?>) listener); } else { final AutowiredEventListener autowiredEventListener = _observers.remove(listener); if (autowiredEventListener != null) { _dispatcher.removeListener(autowiredEventListener); } } } @Override public <S extends EventSource, T extends Event<S>> Future<T> dispatch(final T event) { return _dispatcher.fire(event, true, null); } @Override public <S extends EventSource, T extends Event<S>> Future<T> dispatch(final T event, final Runnable afterExec) { return _dispatcher.fire(event, true, afterExec); } // PROPERTIES // ================================================================= public String getId() { return _id; } public ApplicationContext getApplicationContext() { return _context; } // States // ================================================================== @Override public String getApplicationState() { return _states.get(AutowiredEventTarget.DEFAULT_FSM); } @Override public void setApplicationState(final String state) { _states.put(AutowiredEventTarget.DEFAULT_FSM, state); } public String getApplicationState(final String FSM) { return _states.get(FSM); } @Override public void setApplicationState(final String FSM, final String state) { _states.put(FSM, state); } protected Executor getThreadPool() { return _context.getExecutor(); } }