View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.support.listener;
14  
15  import java.io.IOException;
16  import java.io.InputStream;
17  import java.util.ArrayList;
18  import java.util.Arrays;
19  import java.util.Collection;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  
24  import org.apache.log4j.Logger;
25  
26  import com.eviware.soapui.DefaultSoapUICore;
27  import com.eviware.soapui.SoapUI;
28  import com.eviware.soapui.config.SoapUIListenerConfig;
29  import com.eviware.soapui.config.SoapUIListenersConfig;
30  import com.eviware.soapui.config.SoapuiListenersDocumentConfig;
31  
32  public class SoapUIListenerRegistry
33  {
34  	private Map<Class<?>, List<Class<?>>> listeners = new HashMap<Class<?>, List<Class<?>>>();
35  	private Map<Class<?>, List<Object>> singletonListeners = new HashMap<Class<?>, List<Object>>();
36  	private Map<Class<?>, SoapUIListenerConfig> listenerConfigs = new HashMap<Class<?>, SoapUIListenerConfig>();
37  	private final static Logger log = Logger.getLogger( SoapUIListenerRegistry.class );
38  
39  	public void addListener( Class<?> listenerInterface, Class<?> listenerClass, SoapUIListenerConfig config )
40  	{
41  		List<Class<?>> classes = null;
42  		if( listeners.containsKey( listenerInterface ) )
43  		{
44  			classes = listeners.get( listenerInterface );
45  		}
46  		if( classes == null )
47  		{
48  			classes = new ArrayList<Class<?>>();
49  		}
50  		classes.add( listenerClass );
51  		listeners.put( listenerInterface, classes );
52  
53  		if( config != null )
54  		{
55  			listenerConfigs.put( listenerClass, config );
56  		}
57  	}
58  
59  	public void removeListener( Class<?> listenerInterface, Class<?> listenerClass )
60  	{
61  		List<Class<?>> classes = null;
62  		if( listeners.containsKey( listenerInterface ) )
63  		{
64  			classes = listeners.get( listenerInterface );
65  		}
66  		if( classes != null )
67  		{
68  			classes.remove( listenerClass );
69  		}
70  		if( classes == null || classes.size() == 0 )
71  		{
72  			listeners.remove( listenerInterface );
73  		}
74  
75  		listenerConfigs.remove( listenerClass );
76  	}
77  
78  	public SoapUIListenerRegistry( InputStream config )
79  	{
80  		if( config != null )
81  			addConfig( config, getClass().getClassLoader() );
82  	}
83  
84  	public void addConfig( InputStream config, ClassLoader classLoader )
85  	{
86  		try
87  		{
88  			SoapuiListenersDocumentConfig configDocument = SoapuiListenersDocumentConfig.Factory.parse( config );
89  			SoapUIListenersConfig soapuiListeners = configDocument.getSoapuiListeners();
90  
91  			for( SoapUIListenerConfig listenerConfig : soapuiListeners.getListenerList() )
92  			{
93  				try
94  				{
95  					String listenerInterfaceName = listenerConfig.getListenerInterface();
96  					String listenerClassName = listenerConfig.getListenerClass();
97  
98  					Class<?> listenerInterface = Class.forName( listenerInterfaceName, true, classLoader );
99  					Class<?> listenerClass = Class.forName( listenerClassName, true, classLoader );
100 					if( !listenerInterface.isInterface() )
101 					{
102 						throw new RuntimeException( "Listener interface: " + listenerInterfaceName + " must be an interface" );
103 					}
104 					if( !listenerInterface.isAssignableFrom( listenerClass ) )
105 					{
106 						throw new RuntimeException( "Listener class: " + listenerClassName + " must implement interface: "
107 								+ listenerInterfaceName );
108 					}
109 					// make sure the class can be instantiated even if factory
110 					// will instantiate interfaces only on demand
111 					Object obj = listenerClass.newInstance();
112 					if( listenerConfig.getSingleton() )
113 					{
114 						if( obj instanceof InitializableListener )
115 						{
116 							( ( InitializableListener )obj ).init( listenerConfig );
117 						}
118 
119 						getLog().info( "Adding singleton listener [" + listenerClass + "]" );
120 						addSingletonListener( listenerInterface, obj );
121 					}
122 					else
123 					{
124 						// class can be instantiated, register it
125 						getLog().info( "Adding listener [" + listenerClass + "]" );
126 						addListener( listenerInterface, listenerClass, listenerConfig );
127 					}
128 				}
129 				catch( Exception e )
130 				{
131 					System.err.println( "Error initializing Listener: " + e );
132 				}
133 			}
134 		}
135 		catch( Exception e )
136 		{
137 			SoapUI.logError( e );
138 		}
139 		finally
140 		{
141 			try
142 			{
143 				config.close();
144 			}
145 			catch( IOException e )
146 			{
147 				SoapUI.logError( e );
148 			}
149 		}
150 	}
151 
152 	private Logger getLog()
153 	{
154 		return DefaultSoapUICore.log == null ? log : DefaultSoapUICore.log;
155 	}
156 
157 	public void addSingletonListener( Class<?> listenerInterface, Object listener )
158 	{
159 		if( !singletonListeners.containsKey( listenerInterface ) )
160 			singletonListeners.put( listenerInterface, new ArrayList<Object>() );
161 
162 		singletonListeners.get( listenerInterface ).add( listener );
163 	}
164 
165 	public void removeSingletonListener( Class<?> listenerInterface, Object listener )
166 	{
167 		if( singletonListeners.containsKey( listenerInterface ) )
168 			singletonListeners.get( listenerInterface ).remove( listener );
169 	}
170 
171 	@SuppressWarnings( "unchecked" )
172 	public <T extends Object> List<T> getListeners( Class<T> listenerType )
173 	{
174 		List<T> result = new ArrayList<T>();
175 		if( listeners.containsKey( listenerType ) )
176 		{
177 			List<Class<?>> list = listeners.get( listenerType );
178 			for( Class<?> listenerClass : list )
179 			{
180 				try
181 				{
182 					T listener = ( T )listenerClass.newInstance();
183 					if( listenerConfigs.containsKey( listenerClass ) && listener instanceof InitializableListener )
184 						( ( InitializableListener )listener ).init( listenerConfigs.get( listenerClass ) );
185 
186 					result.add( listener );
187 				}
188 				catch( Exception e )
189 				{
190 					SoapUI.logError( e );
191 				}
192 			}
193 		}
194 
195 		if( singletonListeners.containsKey( listenerType ) )
196 			result.addAll( ( Collection<? extends T> )singletonListeners.get( listenerType ) );
197 
198 		return result;
199 	}
200 
201 	@SuppressWarnings("unchecked")
202 	public <T extends Object> List<T> joinListeners( Class<T> listenerType, Collection<T> existing )
203 	{
204 		List<T> result = new ArrayList<T>();
205 		if( listeners.containsKey( listenerType ) )
206 		{
207 			List<Class<?>> list = listeners.get( listenerType );
208 			for( Class<?> listenerClass : list )
209 			{
210 				try
211 				{
212 					T listener = ( T )listenerClass.newInstance();
213 					if( listenerConfigs.containsKey( listenerClass ) && listener instanceof InitializableListener )
214 						( ( InitializableListener )listener ).init( listenerConfigs.get( listenerClass ) );
215 
216 					result.add( listener );
217 				}
218 				catch( Exception e )
219 				{
220 					SoapUI.logError( e );
221 				}
222 			}
223 		}
224 
225 		if( singletonListeners.containsKey( listenerType ) )
226 			result.addAll( ( Collection<? extends T> )singletonListeners.get( listenerType ) );
227 		
228 		result.addAll( existing );
229 
230 		return result;
231 	}
232 }