/* * Copyright 2008-2009 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 net.hasor.core.event; import net.hasor.core.*; import net.hasor.core.future.BasicFuture; import net.hasor.core.utils.StringUtils; import java.util.List; import java.util.concurrent.*; /** * 标准事件处理器接口的实现类 * @version : 2013-5-6 * @author 赵永春 (zyc@hasor.net) */ public class StandardEventManager implements EventContext { private static final EmptyEventCallBackHook EMPTY_CALLBACK = new EmptyEventCallBackHook(); private ScheduledExecutorService executorService = null; private ConcurrentMap<String, EventListenerPool> listenerMap = new ConcurrentHashMap<String, EventListenerPool>(); // // public StandardEventManager(int eventThreadPoolSize, String name, ClassLoader classLoader) { this.executorService = Executors.newScheduledThreadPool(eventThreadPoolSize, new NameThreadFactory(name + "-EventPool-%s", classLoader)); ThreadPoolExecutor threadPool = (ThreadPoolExecutor) this.executorService; threadPool.setCorePoolSize(eventThreadPoolSize); threadPool.setMaximumPoolSize(eventThreadPoolSize); } /**获取执行事件使用的{@link ScheduledExecutorService}接口对象。*/ protected ScheduledExecutorService getExecutorService() { return this.executorService; } // private EventListenerPool getListenerPool(String eventType) { EventListenerPool pool = listenerMap.get(eventType); if (pool == null) { EventListenerPool newPool = new EventListenerPool(); pool = listenerMap.putIfAbsent(eventType, newPool); if (pool == null) { pool = newPool; } } return pool; } // @Override public <T> void pushListener(final String eventType, final EventListener<T> eventListener) { if (StringUtils.isBlank(eventType) || eventListener == null) { return; } this.getListenerPool(eventType).pushOnceListener(eventListener); } @Override public <T> void addListener(final String eventType, final EventListener<T> eventListener) { if (StringUtils.isBlank(eventType) || eventListener == null) { return; } this.getListenerPool(eventType).addListener(eventListener); } @Override public <T> void removeListener(final String eventType, final EventListener<T> eventListener) { if (StringUtils.isBlank(eventType) || eventListener == null) { return; } this.getListenerPool(eventType).removeListener(eventListener); } // @Override public final <T> void fireSyncEvent(final String eventType, final T eventData) throws Throwable { try { this.fireEvent(eventType, FireType.Interrupt, null, true, eventData).get(); } catch (ExecutionException e) { throw e.getCause(); } } @Override public final <T> void fireSyncEventWithEspecial(final String eventType, final T eventData) throws Throwable { try { this.fireEvent(eventType, FireType.Interrupt, null, false, eventData).get(); } catch (ExecutionException e) { throw e.getCause(); } } @Override public final <T> void fireAsyncEvent(String eventType, T eventData) { this.fireEvent(eventType, FireType.Interrupt, null, false, eventData); } @Override public final <T> void fireAsyncEvent(String eventType, T eventData, FireType fireType) { this.fireEvent(eventType, fireType, null, false, eventData); } @Override public final <T> void fireAsyncEvent(String eventType, T eventData, FireType fireType, EventCallBackHook<T> callBack) { this.fireEvent(eventType, fireType, callBack, false, eventData); } // // private <T> Future<Boolean> fireEvent(String eventType, FireType fireType, EventCallBackHook<T> callBack, boolean atCurrentThread, T eventData) { EventObject<T> event = this.createEvent(eventType, Hasor.assertIsNotNull(fireType)); event.setCallBack(callBack); event.setEventData(eventData); return this.fireEvent(event, atCurrentThread); } /**创建事件对象*/ protected <T> EventObject<T> createEvent(String eventType, FireType fireType) { return new EventObject<T>(eventType, fireType); } /**引发事件,无论*/ protected <T> Future<Boolean> fireEvent(final EventObject<T> event, boolean atCurrentThread) { final BasicFuture<Boolean> future = new BasicFuture<Boolean>(); if (atCurrentThread) { this.executeEvent(event, future); } else { this.executorService.submit(new Runnable() { public void run() { StandardEventManager.this.executeEvent(event, future); } }); } // return future; } /**引发事件*/ protected <T> void executeEvent(final EventObject<T> eventObj, BasicFuture<Boolean> future) { String eventType = eventObj.getEventType(); T eventData = eventObj.getEventData(); EventCallBackHook<T> callBack = eventObj.getCallBack(); if (StringUtils.isBlank(eventType)) { future.failed(new NullPointerException("eventType is empty.")); return; } // //1.引发事件. EventListenerPool listenerPool = this.getListenerPool(eventType); if (listenerPool != null) { List<EventListener<?>> snapshot = listenerPool.getListenerSnapshot(); for (EventListener<?> listenerItem : snapshot) { Throwable doListener = doListener(eventObj, eventType, eventData, callBack, (EventListener<T>) listenerItem); if (doListener == null) { continue; } future.failed(doListener); return; } } // //2.处理Once事件. List<EventListener<?>> onceList = listenerPool.popOnceListener(); if (onceList != null) { for (EventListener<?> listenerItem : onceList) { Throwable doListener = doListener(eventObj, eventType, eventData, callBack, (EventListener<T>) listenerItem); if (doListener == null) { continue; } future.failed(doListener); return; } } // future.completed(true); return; } private <T> Throwable doListener(EventObject<T> eventObj, String eventType, T eventData, EventCallBackHook<T> callBack, EventListener<T> listener) { try { listener.onEvent(eventType, eventData); if (callBack != null) { callBack.handleComplete(eventType, eventData); } } catch (Throwable e) { if (callBack != null) { callBack.handleException(eventType, eventData, e); } if (FireType.Interrupt == eventObj.getFireType()) { return e; } } return null; } // public void release() { this.executorService.shutdownNow(); this.listenerMap.clear(); } }