View Javadoc

1   /*
2    * Created on 29.04.2005 from Linke
3    *
4    */
5   package net.sf.crispy.impl;
6   
7   import java.util.HashMap;
8   import java.util.Iterator;
9   import java.util.Map;
10  import java.util.Properties;
11  
12  import net.sf.crispy.Executor;
13  import net.sf.crispy.ExecutorDecorator;
14  import net.sf.crispy.IServiceManager;
15  import net.sf.crispy.Interceptor;
16  import net.sf.crispy.InterceptorFilter;
17  import net.sf.crispy.InterceptorHandler;
18  import net.sf.crispy.InvocationException;
19  import net.sf.crispy.Modifier;
20  import net.sf.crispy.PropertiesLoader;
21  import net.sf.crispy.Property;
22  import net.sf.crispy.concurrent.AsynchronousCallback;
23  import net.sf.crispy.proxy.DynamicProxy;
24  import net.sf.crispy.proxy.DynamicProxyFactory;
25  import net.sf.crispy.proxy.Proxy;
26  import net.sf.crispy.proxy.ProxyDecorator;
27  import net.sf.crispy.proxy.StaticProxy;
28  import net.sf.crispy.proxy.StaticProxyDecorator;
29  import net.sf.crispy.util.Util;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  
34  
35  /**
36   * Create Services for different kind of Services, how XML-RPC, EJB (JNDI), ...
37   * or a simple local invocation from a Java-Object (Factory-Pattern).
38   * It is the central class (it is a start point).
39   * 
40   * @author Linke
41   *
42   */
43  public class ServiceManager implements IServiceManager {
44  	
45      /** extra debug mode for more information by problems */
46      public static boolean DEBUG_MODE_ON = false;
47  
48  
49      private static Log log = LogFactory.getLog (ServiceManager.class);
50      
51      private Properties properties = null;
52  	private InterceptorHandler interceptorHandler = new InterceptorHandler();
53  	/** Map service-interface to ProxyDecorator. Every service-interface required your one ProxyDecorator. */
54  	private Map proxyDecoratorMap = new HashMap();
55  		
56      public ServiceManager (PropertiesLoader pvPropertiesLoader) {
57      	properties = pvPropertiesLoader.load();
58      	init(properties);
59      }
60      
61      public ServiceManager (Class pvServiceInterface, Class pvServiceClass) { 
62          properties = new Properties();
63          properties.put(pvServiceInterface.getName(), pvServiceClass.getName());
64          init(properties);
65      }
66      
67      public ServiceManager (Properties pvProperties) { 
68          init(pvProperties);
69      }
70      
71      public ServiceManager () {
72  //    	init(new Properties());
73      }
74          
75      protected final void init(Properties pvProperties) {
76      	properties = pvProperties;
77      	
78          if ((properties == null) || (properties.size() == 0)) {
79          	log.warn("No properties are available! The ServiceManager can't correct work!");
80          }
81          
82          // if is set true, than can NOT overwrite this value with properties
83          if (DEBUG_MODE_ON == false) {
84          	String lvDebugOnStr = properties.getProperty(Property.DEBUG_MODE_ON, "false");
85          	DEBUG_MODE_ON = Boolean.valueOf(lvDebugOnStr).booleanValue();
86          }
87                      	        
88          // --- Proxy-Interceptoren finden und hinzufuegen (sortieren) ---
89      	Map lvSorterMap = Util.getAllPropertiesByPrefixAndSort(properties, Property.INTERCEPTOR_CLASS);
90          
91          // --- Proxy-Interceptoren hinzufuegen (sortieren) ---
92          Iterator it = lvSorterMap.values().iterator();
93          while (it.hasNext()) {		
94          	String lvProxyInterceptorStr = (String) it.next();
95          	try {
96          		Interceptor lvProxyInterceptor = (Interceptor) Class.forName(lvProxyInterceptorStr).newInstance(); 
97          		addInterceptor(lvProxyInterceptor);
98          		if (log.isDebugEnabled()) { log.debug("Proxy-Interceptor created: " + lvProxyInterceptor); }
99          	} catch (Exception e) {
100         		handleObjectCreationException(e, "Proxy-Interceptor", lvProxyInterceptorStr);
101         	}            		
102         }
103     	
104     	// --- create modifier ---
105     	String lvModifierClass = properties.getProperty(Property.MODIFIER_CLASS);
106     	if (lvModifierClass != null) {
107     		try {
108     			Modifier lvModifier = (Modifier) Class.forName(lvModifierClass).newInstance();
109     			setModifier(lvModifier);
110     			if (log.isDebugEnabled()) { log.debug("Modifier created: " + lvModifierClass); }
111 			} catch (Exception e) {
112 				handleObjectCreationException(e, "Modifier", lvModifierClass);
113 			}            		    		
114     	}
115     }
116     
117     /** create static proxy */
118     private StaticProxy createStaticProxy(final Object pvStaticProxyObject) {
119     	StaticProxy lvStaticProxyDecorator = null;
120 		StaticProxy lvStaticProxy = (StaticProxy) pvStaticProxyObject;
121 		lvStaticProxyDecorator = new StaticProxyDecorator(lvStaticProxy);
122 		lvStaticProxyDecorator.setProperties(properties);
123 		if (log.isDebugEnabled()) { log.debug("Static-Proxy created: " + pvStaticProxyObject + " with Properties: " + properties); }
124     	return lvStaticProxyDecorator;
125     }
126     
127     /** create executor */
128     private Executor createExecutor(final Object pvExecutorObject) {
129     	Executor lvExecutor = null;
130    		lvExecutor = (Executor) pvExecutorObject;
131    		lvExecutor.setProperties(properties);
132    		lvExecutor = new ExecutorDecorator(lvExecutor);
133    		if (log.isDebugEnabled()) { log.debug("Executor created: " + pvExecutorObject + " with Properties: " + properties); }
134     	return lvExecutor;
135     }
136     
137     
138     
139     private ProxyDecorator createProxyDecorator() {
140     	ProxyDecorator lvProxyDecorator = null;
141 
142     	String lvStaticProxyClassString = properties.getProperty(Property.STATIC_PROXY_CLASS);
143     	String lvExcutorClassString = properties.getProperty(Property.EXECUTOR_CLASS);
144 
145     	StaticProxy lvStaticProxy = null;
146     	Executor lvExecutor = null;
147     	
148     	try {
149     		Object lvPropertyObject = Util.createObject(lvStaticProxyClassString);
150     		
151     		if (lvPropertyObject != null && ( ! (lvPropertyObject instanceof Executor)) && ( ! (lvPropertyObject instanceof StaticProxy))) {
152     			handleObjectCreationException(null, "StaticProxy/Executor", lvPropertyObject.toString());
153     		}
154     		else if (lvPropertyObject != null && lvPropertyObject instanceof StaticProxy) {
155 				lvStaticProxy = createStaticProxy(lvPropertyObject);
156 			} 
157 			else if (lvPropertyObject != null && lvPropertyObject instanceof Executor) {
158 				lvExecutor = createExecutor(lvPropertyObject);
159 			}
160 		} catch (Exception e) {
161 			handleObjectCreationException(e, "StaticProxy", lvStaticProxyClassString);
162 		}
163 
164     	try {
165     		Object lvPropertyObject = Util.createObject(lvExcutorClassString);
166     		if (lvPropertyObject != null && ( ! (lvPropertyObject instanceof Executor)) && ( ! (lvPropertyObject instanceof StaticProxy))) {
167     			handleObjectCreationException(null, "StaticProxy/Executor", lvPropertyObject.toString());
168     		}
169     		else if (lvStaticProxy == null && lvPropertyObject != null && lvPropertyObject instanceof StaticProxy) {
170 				lvStaticProxy = createStaticProxy(lvPropertyObject);
171 			} 
172 			else if (lvPropertyObject != null && lvPropertyObject instanceof Executor) {
173 				lvExecutor = createExecutor(lvPropertyObject);
174 			}
175 		} catch (Exception e) {
176 			handleObjectCreationException(e, "Executor", lvExcutorClassString);
177 		}
178 		
179 		
180 
181     	// --- create DynamicProxy ---
182 		DynamicProxy lvDynamicProxy = null;
183 		String lvDynamicProxyClass = properties.getProperty(Property.DYNAMIC_PROXY_CLASS);
184     	if (lvDynamicProxyClass != null) {
185    			lvDynamicProxy = DynamicProxyFactory.createDynamicProxy(lvDynamicProxyClass, properties);
186    			lvDynamicProxy.setProperties(properties);
187    			lvDynamicProxy.setStaticProxy(lvStaticProxy);
188    			if (log.isDebugEnabled()) { log.debug("Dynamic-Proxy created: " + lvDynamicProxyClass + " with Properties: " + properties); }
189     	}
190 		
191     	// --- create Executer (optional) ---
192     	// wenn KEIN DynamicProxy angegeben, dann wird der DynamicJdkyProxy geladen
193         if (lvExecutor != null) {
194 			if (lvDynamicProxy != null) {
195 				lvDynamicProxy.setStaticProxy(lvStaticProxy);
196 				lvDynamicProxy.setExecutor(lvExecutor);
197 			} else {
198 				// wenn KEIN DynamicProxy gesetzt, wird Standardmaessig der JdkDelegateProxy genommen
199 				lvDynamicProxy = DynamicProxyFactory.getDefaultDynamicProxy(properties);
200 				lvDynamicProxy.setProperties(properties);
201 				lvDynamicProxy.setStaticProxy(lvStaticProxy);
202 				((DynamicProxy) lvDynamicProxy).setExecutor(lvExecutor);
203 			}				
204         }
205 
206         // --- wenn kein Proxy gefunden wurde, wird der StaticBeanProxy erzeugt ---
207         if (lvDynamicProxy == null) {
208         	lvProxyDecorator = new ProxyDecorator(lvStaticProxy, interceptorHandler);
209         	if (lvStaticProxy == null) {
210         		// wenn kein Proxy angegeben, dann wird der Bean-Proxy genommen
211         		lvProxyDecorator = new ProxyDecorator(new StaticLocalObjectProxy (properties), interceptorHandler);        		
212         	}
213         } else {
214         	lvDynamicProxy.setInterceptorHandler(interceptorHandler);
215         	lvProxyDecorator = new ProxyDecorator(lvDynamicProxy, interceptorHandler);
216         	if ((lvExecutor == null) && (lvStaticProxy == null)) {
217         		lvDynamicProxy.setStaticProxy(new StaticLocalObjectProxy (properties));
218         	}
219         }
220     	
221     	return lvProxyDecorator;
222     }
223     
224     private void handleObjectCreationException(Throwable pvThrowable, String pvMessage, String pvClassString) {
225 		String lvErrorTxt = "Exception by creating " + pvMessage + " - Instance. No valid " 
226 		 							+ pvMessage + " class: " + pvClassString;
227 		log.error(lvErrorTxt + ": " + pvThrowable);
228 		throw new InvocationException(lvErrorTxt, pvThrowable);    	
229     }
230       
231     private void handleAddDynamicProxy (ProxyDecorator pvProxyDecorator) {
232 		Proxy lvProxy = pvProxyDecorator.getProxy();
233 		if (lvProxy instanceof StaticProxy) {
234 			DynamicProxy lvDynamicProxy = DynamicProxyFactory.getDefaultDynamicProxy();
235 			lvDynamicProxy.setStaticProxy((StaticProxy) lvProxy);
236 			lvDynamicProxy.setProperties(properties);
237 			lvDynamicProxy.setInterceptorHandler(interceptorHandler);
238 			pvProxyDecorator.setProxy(lvDynamicProxy);
239 		}
240     }
241     
242     private void handleRemoveDynamicProxy () {
243     	Iterator it = proxyDecoratorMap.values().iterator();
244     	while (it.hasNext()) {
245     		ProxyDecorator lvProxyDecorator = (ProxyDecorator) it.next();    	
246 	    	if ((lvProxyDecorator != null) && (getInterceptorSize() == 0)) {
247 				Proxy lvProxy = lvProxyDecorator.getProxy();
248 				if (lvProxy instanceof DynamicProxy) {
249 					DynamicProxy lvDynamicProxy = (DynamicProxy) lvProxy;
250 					StaticProxy lvStaticProxy = lvDynamicProxy.getStaticProxy();
251 					if (lvStaticProxy != null) {
252 						lvProxyDecorator.setProxy(lvStaticProxy);
253 					}
254 				}
255 	    	}
256     	}
257     }
258     
259 	public final Iterator getInterceptorIterator () { return interceptorHandler.getInterceptorIterator(); }
260 	public final Interceptor getInterceptorByPos (int pvPos) { return interceptorHandler.getInterceptorByPos(pvPos); }
261 	public final int getInterceptorSize () { return interceptorHandler.getInterceptorSize(); }
262 	public final Interceptor removeInterceptorByPos (int pvPos) {
263 		Interceptor lvInterceptor = interceptorHandler.removeInterceptorByPos(pvPos);
264 		handleRemoveDynamicProxy();
265 		return lvInterceptor;
266 	}
267 	public final void removeAllInterceptors () {
268 		interceptorHandler.removeAllInterceptors();
269 		handleRemoveDynamicProxy();
270 	}	
271 	public final void addInterceptor (Interceptor pvInterceptor) { 
272 		interceptorHandler.addInterceptor(pvInterceptor); 
273 	} 
274 	
275 	
276 	public final int getInterceptorFilterSize () { return interceptorHandler.getInterceptorFilterSize(); }
277 	public final InterceptorFilter removeInterceptorFilterByPos (int pvPos) {
278 		return interceptorHandler.removeInterceptorFilter(pvPos);
279 	}
280 	public final void addInterceptorFilter (InterceptorFilter pvInterceptorFilter) {
281 		interceptorHandler.addInterceptorFilter(pvInterceptorFilter);
282 	}
283     
284 	public final Modifier getModifier() { return interceptorHandler.getModifier(); }
285 	public final void setModifier(Modifier pvModifier) { interceptorHandler.setModifier(pvModifier); }
286 	
287 	public final String getProperty(String pvKey) { return (String) properties.get(pvKey); }
288 	public final Iterator getPropertyKeys () { return properties.keySet().iterator(); }
289 	
290 	
291     /**
292      * Create a Proxy-Instance to the Service-Interface for <b>synchronous</b> invocation.
293      * 
294      * @param pvServiceInterface Service-Interface
295      * 
296      * @return Proxy-Object.
297      * 
298 	 * @see net.sf.crispy.IServiceManager#createService(java.lang.Class)
299 	 */
300     public Object createService(Class pvServiceInterface) {
301     	if (pvServiceInterface == null) {
302     		throw new IllegalArgumentException ("The service interface must be unequal NULL");
303     	}
304 
305 
306     	
307     	// Test, ob mit diesem Service-Interface bereits ein synchroner Aufruf verbunden ist
308     	DynamicProxy lvDynamicProxy = getDynamicProxyByServiceInterface(pvServiceInterface);
309     	if (lvDynamicProxy != null && lvDynamicProxy.isInvocationAsynchronous() == true) {
310     		throw new InvocationException("With the Service-Interface: " + pvServiceInterface.getName()
311     											+ " is already a asynchrounus service associated!");
312     	}
313 
314     	
315     	ProxyDecorator lvProxyDecorator = (ProxyDecorator) proxyDecoratorMap.get(pvServiceInterface);    	
316     	if (lvProxyDecorator == null) {
317     		lvProxyDecorator = createProxyDecorator();
318     		proxyDecoratorMap.put(pvServiceInterface, lvProxyDecorator);
319     		if (interceptorHandler.getInterceptorSize() > 0) {
320     			handleAddDynamicProxy (lvProxyDecorator);
321     		}
322     		
323     	}
324     	
325     	return lvProxyDecorator.newInstance(pvServiceInterface);    	    	
326     }
327     
328     /**
329      * Create a Proxy-Object for invocation and do invocation asynchronous.
330      *  
331      * @param pvServiceInterface For this Interface is created a Proxy-Object. 
332      * @param pvAsynchronousCallback Hanlder for asynchronous execution.
333      * @param pvMethodFilter Only for method-names in this array are asynchronous execution
334      * @param pvMaxSizeOfThreads Max size of keeping Threads.
335      * 
336      * @return Proxy-Object.
337      * 
338      * @see net.sf.crispy.IServiceManager#createService(java.lang.Class, net.sf.crispy.concurrent.AsynchronousCallback, java.lang.String[], int)
339      */
340     public Object createService(Class pvServiceInterface, AsynchronousCallback pvAsynchronousCallback, String[] pvMethodFilter, int pvMaxSizeOfThreads) {
341        	if (pvServiceInterface == null) {
342     		throw new IllegalArgumentException ("The service interface must be unequal NULL");
343     	}
344        	
345     	// Test, ob mit diesem Service-Interface bereits ein synchroner Aufruf verbunden ist
346     	DynamicProxy lvDynamicProxy = getDynamicProxyByServiceInterface(pvServiceInterface);
347     	if (lvDynamicProxy != null && lvDynamicProxy.isInvocationAsynchronous() == false) {
348     		throw new InvocationException("With the Service-Interface: " + pvServiceInterface.getName()
349     											+ " is already a synchrounus service associated!");
350     	}
351     	
352     	Object lvServiceProxy = createService(pvServiceInterface);
353 
354     	lvDynamicProxy = getDynamicProxyByServiceInterface(pvServiceInterface);
355     	if (lvDynamicProxy != null) {
356     		lvDynamicProxy.setAsynchronousCallback(pvAsynchronousCallback, pvMethodFilter, pvMaxSizeOfThreads);
357     	} else {
358     		System.err.println("---> For the interface: " + pvServiceInterface 
359     								+ " is don't set a DynamicProxy."
360     								+ " All calls are synchronous!!!");
361     	}
362 
363     	return lvServiceProxy;
364     }
365     
366     /**
367      * 
368      * @param pvServiceInterface Search Service-Interface.
369      * @return 
370      */
371     private DynamicProxy getDynamicProxyByServiceInterface (Class pvServiceInterface) {
372     	DynamicProxy lvDynamicProxy = null;
373     	ProxyDecorator pd = (ProxyDecorator) proxyDecoratorMap.get(pvServiceInterface);
374     	if (pd != null) {
375 	    	Proxy lvProxy = pd.getProxy();
376 	    	if (lvProxy instanceof DynamicProxy) {
377 	    		lvDynamicProxy = (DynamicProxy) lvProxy;
378 	    	} 
379     	}
380     	return lvDynamicProxy;
381     }
382     
383     /**
384      * @param pvServiceInterface Search Service-Interface. 
385      * @return Get the class from StaticProxy or Executor or null.  
386      */
387     public Class getTransporterClassByServiceInterface (Class pvServiceInterface) {
388     	ProxyDecorator pd = (ProxyDecorator) proxyDecoratorMap.get(pvServiceInterface);
389     	if (pd != null) {
390 	    	Object o = pd.getProxy();
391 	    	if (o instanceof DynamicProxy) {
392 	    		StaticProxy lvStaticProxy = ((DynamicProxy) o).getStaticProxy();
393 	    		if (lvStaticProxy == null) {
394 	    			ExecutorDecorator lvExecutorDecorator = (ExecutorDecorator) ((DynamicProxy) o).getExecutor();
395 	    			o = lvExecutorDecorator.getExecutor();
396 	    		} else {
397 	    			o = ((StaticProxyDecorator) lvStaticProxy).getStaticProxy();
398 	    		}
399 	    	}
400 	    	else if (o instanceof StaticProxyDecorator) {
401 	    		o = ((StaticProxyDecorator) o).getStaticProxy();
402 	    	}
403 	   		return o.getClass();
404     	} else {
405     		return null;
406     	}
407     }
408     
409     public void removeAsynchronousCallback(Class pvServiceInterface) {
410     	DynamicProxy lvDynamicProxy = getDynamicProxyByServiceInterface(pvServiceInterface);
411     	if (lvDynamicProxy != null) {
412     		lvDynamicProxy.setAsynchronousCallback(null, null, 0);
413     	}
414     }
415     
416     public AsynchronousCallback getAsynchronousCallback(Class pvServiceInterface) {
417     	AsynchronousCallback lvAsynchronousCallback = null;
418     	
419     	DynamicProxy lvDynamicProxy = getDynamicProxyByServiceInterface(pvServiceInterface);
420     	if (lvDynamicProxy != null) {
421     		lvAsynchronousCallback = lvDynamicProxy.getAsynchronousCallback();
422     	}
423     	return lvAsynchronousCallback;
424     }
425     
426     public boolean isInvocationAsynchronous(Class pvServiceInterface) {
427     	return (getAsynchronousCallback(pvServiceInterface) != null);
428     }
429 
430 }