001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package core.tut.pori.context; 017 018import java.util.Collection; 019import java.util.Date; 020import java.util.concurrent.ExecutorService; 021 022import org.apache.log4j.Logger; 023import org.springframework.beans.BeansException; 024import org.springframework.context.ApplicationEvent; 025import org.springframework.context.ApplicationListener; 026import org.springframework.context.event.SimpleApplicationEventMulticaster; 027import org.springframework.context.support.ClassPathXmlApplicationContext; 028import org.springframework.core.ResolvableType; 029 030import core.tut.pori.utils.StringUtils; 031 032/** 033 * This class can be used to submit application events to the defined listeners. 034 * 035 * Listeners are defined by event context configuration and the defined annotations. 036 * 037 * One should not initialize this handler directly, as an instantiated version is available from ServiceInitializer. 038 * 039 */ 040public class EventHandler { 041 private static final Logger LOGGER = Logger.getLogger(EventHandler.class); 042 private static final String SERVLET_CONFIGURATION_FILE = "event-context.xml"; 043 private ClassPathXmlApplicationContext _context = null; 044 045 /** 046 * 047 * @throws BeansException 048 */ 049 public EventHandler() throws BeansException{ 050 initialize(); 051 } 052 053 /** 054 * 055 * @throws BeansException on failure 056 */ 057 private void initialize() throws BeansException{ 058 LOGGER.debug("Initializing handler..."); 059 Date started = new Date(); 060 _context = new ClassPathXmlApplicationContext(core.tut.pori.properties.SystemProperty.CONFIGURATION_FILE_PATH+SERVLET_CONFIGURATION_FILE); 061 062 LOGGER.debug("Event Handler initialized in "+StringUtils.getDurationString(started, new Date())); 063 } 064 065 /** 066 * close this Service handler and release are resources associated with it 067 */ 068 public void close(){ 069 _context.close(); 070 _context = null; 071 } 072 073 /** 074 * 075 * @param event 076 */ 077 public void publishEvent(ApplicationEvent event){ 078 _context.publishEvent(event); 079 } 080 081 /** 082 * Implementation of an asynchronous event multicaster. 083 * 084 * The default event delivery system will block whilst each event listener is in progress. 085 * This class sends all events simultaneously to all receivers, though in practice the performance of this method is limited by the current load of the scheduler service. 086 */ 087 public static class EventMulticaster extends SimpleApplicationEventMulticaster { 088 089 @Override 090 public void multicastEvent(final ApplicationEvent event) { 091 multicastEvent(event, null); 092 } 093 094 @SuppressWarnings("rawtypes") 095 @Override 096 public void multicastEvent(final ApplicationEvent event, ResolvableType type) { 097 Collection<ApplicationListener<?>> listeners = getApplicationListeners(event, (type == null ? ResolvableType.forClass(event.getClass()) : type)); 098 if(listeners.isEmpty()){ 099 LOGGER.debug("No listeners for event "+event.getClass().toString()); 100 return; 101 } 102 103 ExecutorService executor = ServiceInitializer.getExecutorHandler().getExecutor(); 104 if(executor == null){ 105 LOGGER.warn("No executor available. Ignoring multicast."); 106 return; 107 } 108 for(final ApplicationListener listener : listeners){ 109 executor.execute(new Runnable() { 110 @SuppressWarnings("unchecked") 111 @Override 112 public void run() { 113 try { 114 listener.onApplicationEvent(event); 115 } catch (Throwable ex){ 116 LOGGER.error(ex, ex); 117 } 118 } 119 }); 120 } 121 } 122 } // class EventMulticaster 123}