View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2005 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  
18  package ch.elca.el4j.services.remoting;
19  
20  import java.lang.reflect.Proxy;
21  
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  import org.springframework.beans.factory.FactoryBean;
25  
26  import ch.elca.el4j.util.interfaceenrichment.EnrichmentDecorator;
27  import ch.elca.el4j.util.interfaceenrichment.InterfaceEnricher;
28  
29  /**
30   * This class is the global remote proxy bean.
31   *
32   * @svnLink $Revision: 3883 $;$Date: 2009-08-04 15:35:01 +0200 (Di, 04. Aug 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/remoting_core/src/main/java/ch/elca/el4j/services/remoting/RemotingProxyFactoryBean.java $
33   *
34   * @author Martin Zeltner (MZE)
35   */
36  public class RemotingProxyFactoryBean extends AbstractRemotingBase implements
37  		FactoryBean {
38  	/**
39  	 * Private logger.
40  	 */
41  	private static Logger s_logger = LoggerFactory
42  			.getLogger(RemotingProxyFactoryBean.class);
43  
44  	/**
45  	 * This is the service proxy to work with.
46  	 */
47  	private Object m_serviceProxy;
48  
49  	/** Whether the factory creates singleton beans or not. */
50  	private boolean m_singleton = true;
51  	
52  	/**
53  	 * {@inheritDoc}
54  	 */
55  	public void afterPropertiesSet() throws Exception {
56  		super.afterPropertiesSet();
57  		getRemoteProtocol().checkRemotingProxy(this);
58  	}
59  	
60  	/**
61  	 * @return Returns a freshly created service proxy.
62  	 */
63  	protected Object getFreshServiceProxy() {
64  		
65  		Object serviceProxy;
66  		
67  		boolean useImplicitContextPassing = getRemoteProtocol().
68  			getImplicitContextPassingRegistry() != null;
69  		
70  		if (useImplicitContextPassing
71  			&& !getRemoteProtocol().getProtocolSpecificContextPassing()) {
72  			s_logger.info("Implicit context passing enabled.");
73  			
74  			/**
75  			 * Get the context class loader from current thread.
76  			 */
77  			ClassLoader cl = Thread.currentThread().getContextClassLoader();
78  			
79  			/**
80  			 * Create the service interface to be able to send context
81  			 * information.
82  			 */
83  			InterfaceEnricher interfaceIndirector = new InterfaceEnricher();
84  			EnrichmentDecorator interfaceDecorator
85  				= new ContextEnrichmentDecorator();
86  			Class serviceInterfaceWithContext = interfaceIndirector
87  				.createShadowInterfaceAndLoadItDirectly(
88  					getServiceInterface(), interfaceDecorator, cl);
89  			
90  			/**
91  			 * Create the inner proxy bean.
92  			 */
93  			Object innerProxyBean = getRemoteProtocol().createProxyBean(this,
94  					serviceInterfaceWithContext);
95  			
96  			/**
97  			 * Generate the proxy.
98  			 */
99  			ClientContextInvocationHandler invocationHandler
100 				= getRemoteProtocol().getClientContextInvocationHandler(
101 					innerProxyBean, serviceInterfaceWithContext);
102 			
103 			Class[] proxyInterface = getRemoteProtocol().
104 					getProxyInterface(getServiceInterface());
105 			
106 			serviceProxy = Proxy.newProxyInstance(cl,
107 					proxyInterface, invocationHandler);
108 			
109 		} else {
110 			if (!getRemoteProtocol().getProtocolSpecificContextPassing()) {
111 				s_logger.warn("Implicit context passing disabled.");
112 			} else {
113 				s_logger.info(
114 					"Protocol specific implicit context passing enabled.");
115 			}
116 
117 			serviceProxy = getRemoteProtocol().createProxyBean(this,
118 					getServiceInterface());
119 		}
120 		
121 		return serviceProxy;
122 	}
123 	
124 	/**
125 	 * {@inheritDoc}
126 	 */
127 	public Object getObject() {
128 		Object serviceProxy;
129 		
130 		if (isSingleton()) {
131 			if (m_serviceProxy == null) {
132 				m_serviceProxy = getFreshServiceProxy();
133 			}
134 			serviceProxy = m_serviceProxy;
135 			
136 		} else {
137 			serviceProxy = getFreshServiceProxy();
138 		}
139 		return serviceProxy;
140 	}
141 
142 	/**
143 	 * {@inheritDoc}
144 	 */
145 	public Class getObjectType() {
146 		return (this.m_serviceProxy != null) ? this.m_serviceProxy.getClass()
147 				: getServiceInterface();
148 	}
149 
150 	/**
151 	 * {@inheritDoc}
152 	 */
153 	public boolean isSingleton() {
154 		return m_singleton;
155 	}
156 
157 	/**
158 	 * Defines whether the factory creates singleton bean instances or
159 	 * prototypes.
160 	 *
161 	 * @param singleton
162 	 *      <code>true</code> to crate singletons, <code>false</code> for
163 	 *      prototypes.
164 	 */
165 	public void setSingleton(boolean singleton) {
166 		m_singleton = singleton;
167 	}
168 }