View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 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.Collection;
19  import java.util.HashMap;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.apache.log4j.Logger;
24  
25  import com.eviware.soapui.DefaultSoapUICore;
26  import com.eviware.soapui.SoapUI;
27  import com.eviware.soapui.config.SoapUIListenerConfig;
28  import com.eviware.soapui.config.SoapUIListenersConfig;
29  import com.eviware.soapui.config.SoapuiListenersDocumentConfig;
30  
31  public class SoapUIListenerRegistry
32  {
33  	private Map<Class<?>, List<Class<?>>> listeners = new HashMap<Class<?>, List<Class<?>>>();
34  	private Map<Class<?>, List<Object>> singletonListeners = new HashMap<Class<?>, List<Object>>();
35  	private Map<Class<?>, SoapUIListenerConfig> listenerConfigs = new HashMap<Class<?>, SoapUIListenerConfig>();
36  	private final static Logger log = Logger.getLogger( SoapUIListenerRegistry.class );
37  
38  	public void addListener( Class<?> listenerInterface, Class<?> listenerClass, SoapUIListenerConfig config )
39  	{
40  		List<Class<?>> classes = null;
41  		if( listeners.containsKey( listenerInterface ) )
42  		{
43  			classes = listeners.get( listenerInterface );
44  		}
45  		if( classes == null )
46  		{
47  			classes = new ArrayList<Class<?>>();
48  		}
49  		classes.add( listenerClass );
50  		listeners.put( listenerInterface, classes );
51  		
52  		if( config != null )
53  		{
54  			listenerConfigs.put( listenerClass, config );
55  		}
56  	}
57  
58  	public void removeListener( Class<?> listenerInterface, Class<?> listenerClass )
59  	{
60  		List<Class<?>> classes = null;
61  		if( listeners.containsKey( listenerInterface ) )
62  		{
63  			classes = listeners.get( listenerInterface );
64  		}
65  		if( classes != null )
66  		{
67  			classes.remove( listenerClass );
68  		}
69  		if( classes == null || classes.size() == 0 )
70  		{
71  			listeners.remove( listenerInterface );
72  		}
73  		
74  		listenerConfigs.remove( listenerClass );
75  	}
76  	
77  	public SoapUIListenerRegistry( InputStream config )
78  	{
79  		if( config != null )
80  			addConfig( config, getClass().getClassLoader() );
81  	}
82  
83  	public void addConfig( InputStream config, ClassLoader classLoader )
84  	{
85  		try
86  		{
87  			SoapuiListenersDocumentConfig configDocument = SoapuiListenersDocumentConfig.Factory.parse( config );
88  			SoapUIListenersConfig soapuiListeners = configDocument.getSoapuiListeners();
89  
90  			for( SoapUIListenerConfig listenerConfig : soapuiListeners.getListenerList() )
91  			{
92  				try
93  				{
94  					String listenerInterfaceName = listenerConfig.getListenerInterface();
95  					String listenerClassName = listenerConfig.getListenerClass();
96  
97  					Class<?> listenerInterface = Class.forName( listenerInterfaceName, true, classLoader );
98  					Class<?> listenerClass = Class.forName( listenerClassName, true, classLoader );
99  					if( !listenerInterface.isInterface() )
100 					{
101 						throw new RuntimeException( "Listener interface: " + listenerInterfaceName + " must be an interface" );
102 					}
103 					if( !listenerInterface.isAssignableFrom( listenerClass ) )
104 					{
105 						throw new RuntimeException( "Listener class: " + listenerClassName + " must implement interface: "
106 									+ listenerInterfaceName );
107 					}
108 					// make sure the class can be instantiated even if factory
109 					// will instantiate interfaces only on demand
110 					Object obj = listenerClass.newInstance();
111 					if( listenerConfig.getSingleton() )
112 					{
113 						if( obj instanceof InitializableListener )
114 						{
115 							((InitializableListener)obj).init( listenerConfig );
116 						}
117 						
118 						getLog().info( "Adding singleton listener [" + listenerClass + "]" );
119 						addSingletonListener( listenerInterface, obj );
120 					}
121 					else
122 					{
123 						// class can be instantiated, register it
124 						getLog().info( "Adding listener [" + listenerClass + "]" );
125 						addListener( listenerInterface, listenerClass, listenerConfig );
126 					}
127 				}
128 				catch( Exception e )
129 				{
130 					System.err.println( "Error initializing Listener: " + e );
131 				}
132 			}
133 		}
134 		catch( Exception e )
135 		{
136 			SoapUI.logError( e );
137 		}
138 		finally
139 		{
140 			try
141 			{
142 				config.close();
143 			}
144 			catch( IOException e )
145 			{
146 				SoapUI.logError( e );
147 			}
148 		}
149 	}
150 
151 	private Logger getLog()
152 	{
153 		return DefaultSoapUICore.log == null ? log  : DefaultSoapUICore.log;
154 	}
155 
156 	public void addSingletonListener( Class<?> listenerInterface, Object listener )
157 	{
158 		if( !singletonListeners.containsKey( listenerInterface ))
159 			singletonListeners.put( listenerInterface, new ArrayList<Object>() );
160 		
161 		singletonListeners.get( listenerInterface ).add( listener );
162 	}
163 	
164 	public void removeSingletonListener( Class<?> listenerInterface, Object listener )
165 	{
166 		if( singletonListeners.containsKey( listenerInterface ))
167 			singletonListeners.get( listenerInterface ).remove( listener );
168 	}
169 
170 	@SuppressWarnings("unchecked")
171 	public <T extends Object> List<T> getListeners( Class<T> listenerType )
172 	{
173 		List<T> result = new ArrayList<T>();
174 		if( listeners.containsKey( listenerType ) )
175 		{
176 			List<Class<?>> list = listeners.get( listenerType );
177 			for( Class<?> listenerClass : list )
178 			{
179 				try
180 				{
181 					T listener = ( T ) listenerClass.newInstance();
182 					if( listenerConfigs.containsKey( listenerClass ) && listener instanceof InitializableListener )
183 						((InitializableListener)listener).init( listenerConfigs.get( listenerClass ) );
184 					
185 					result.add( listener );
186 				}
187 				catch( Exception e )
188 				{
189 					SoapUI.logError( e );
190 				}
191 			}
192 		}
193 		
194 		if( singletonListeners.containsKey( listenerType ))
195 			result.addAll( ( Collection<? extends T> ) singletonListeners.get( listenerType) );
196 		
197 		return result;
198 	}
199 }