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.util.LinkedHashSet;
21  import java.util.Set;
22  
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  import org.springframework.beans.factory.DisposableBean;
26  import org.springframework.beans.factory.InitializingBean;
27  import org.springframework.context.ApplicationContext;
28  import org.springframework.context.ApplicationContextAware;
29  
30  import ch.elca.el4j.core.contextpassing.ImplicitContextPassingRegistry;
31  
32  /**
33   * This abstract class defines a base for remote protocols. It contains
34   * basically the host name and port number.
35   *
36   * @svnLink $Revision: 4204 $;$Date: 2010-11-02 11:44:37 +0100 (Di, 02. Nov 2010) $;$Author: swisswheel $;$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/AbstractRemotingProtocol.java $
37   *
38   * @author Martin Zeltner (MZE)
39   */
40  public abstract class AbstractRemotingProtocol implements
41  		ApplicationContextAware, InitializingBean, DisposableBean {
42  	/**
43  	 * Private logger.
44  	 */
45  	private static Logger s_logger
46  		= LoggerFactory.getLogger(AbstractRemotingProtocol.class);
47  
48  	/**
49  	 * With this ApplicationContext the current bean has been created.
50  	 */
51  	protected ApplicationContext m_parentApplicationContext;
52  
53  	/**
54  	 * This is the registry to implicit pass the context.
55  	 */
56  	private ImplicitContextPassingRegistry m_implicitContextPassingRegistry;
57  
58  	/**
59  	 * This member contains protocol specific configuration. This will only be
60  	 * used if it is really necessary.
61  	 */
62  	private ProtocolSpecificConfiguration m_protocolSpecificConfiguration;
63  	
64  	/**
65  	 * Set of child application contexts.
66  	 */
67  	private Set<ApplicationContext> m_chlidApplicationContexts
68  		= new LinkedHashSet<ApplicationContext>();
69  	
70  	/**
71  	 * State whether the protocol can candle the context on its own.
72  	 * Per default not.
73  	 */
74  	private boolean m_protocolSpecificContextPassing = false;
75  	
76  	/**
77  	 * If it is set to <code>true</code>, the exporter object (if singleton),
78  	 * will not be pre-instantiated. By default singleton exporter objects
79  	 * will be pre-instantiated.
80  	 */
81  	private boolean m_doNotForcePreInstantiationOfExporterObject = false;
82  	
83  	/**
84  	 * Does this protocol handle context passing on its own?
85  	 * @return Whether this protocol handles the context
86  	 */
87  	public boolean getProtocolSpecificContextPassing() {
88  		return m_protocolSpecificContextPassing;
89  	}
90  	
91  	/**
92  	 * Set if this protocol should handle the context passing on its own.
93  	 * Enabling this will disable generic context passing, therefore only
94  	 * use this if the protocol handles the context.
95  	 * @param protocolSpecificContextPassing Should the context be handled?
96  	 */
97  	public void setProtocolSpecificContextPassing(
98  		boolean protocolSpecificContextPassing) {
99  		m_protocolSpecificContextPassing = protocolSpecificContextPassing;
100 	}
101 	
102 	/**
103 	 * @return Returns the implicitContextPassingRegistry.
104 	 */
105 	public ImplicitContextPassingRegistry getImplicitContextPassingRegistry() {
106 		return m_implicitContextPassingRegistry;
107 	}
108 
109 	/**
110 	 * @param implicitContextPassingRegistry
111 	 *            The implicitContextPassingRegistry to set.
112 	 */
113 	public void setImplicitContextPassingRegistry(
114 			ImplicitContextPassingRegistry implicitContextPassingRegistry) {
115 		m_implicitContextPassingRegistry = implicitContextPassingRegistry;
116 	}
117 
118 	/**
119 	 * @return Returns the protocolSpecificConfiguration.
120 	 */
121 	public ProtocolSpecificConfiguration getProtocolSpecificConfiguration() {
122 		return m_protocolSpecificConfiguration;
123 	}
124 
125 	/**
126 	 * @param protocolSpecificConfiguration
127 	 *            The protocolSpecificConfiguration to set.
128 	 */
129 	public void setProtocolSpecificConfiguration(
130 		ProtocolSpecificConfiguration protocolSpecificConfiguration) {
131 		m_protocolSpecificConfiguration = protocolSpecificConfiguration;
132 	}
133 	
134 	/**
135 	 * Method to create the proxy bean.
136 	 *
137 	 * @param proxyBean
138 	 *            Is the bean where the method gets information about the proxy
139 	 *            bean.
140 	 * @param serviceInterfaceWithContext
141 	 *            Is the modified interface.
142 	 * @return Returns the created proxy bean.
143 	 */
144 	public abstract Object createProxyBean(RemotingProxyFactoryBean proxyBean,
145 			Class serviceInterfaceWithContext);
146 
147 	/**
148 	 * Method to create the exporter bean.
149 	 *
150 	 * @param exporterBean
151 	 *            Is the bean where the method gets information about the
152 	 *            exporter bean.
153 	 * @param serviceInterfaceWithContext
154 	 *            Is the modified interface.
155 	 * @param serviceProxy
156 	 *            Is the bean which has to wrapped.
157 	 * @return Returns the generated exporter bean.
158 	 */
159 	public abstract Object createExporterBean(
160 			RemotingServiceExporter exporterBean,
161 			Class serviceInterfaceWithContext, Object serviceProxy);
162 
163 	/**
164 	 * Method to get the class type of the proxy object.
165 	 *
166 	 * @return Returns the class type.
167 	 */
168 	public abstract Class getProxyObjectType();
169 
170 	/**
171 	 * Method to get the class type of the exporter object.
172 	 *
173 	 * @return Returns the class type.
174 	 */
175 	public abstract Class getExporterObjectType();
176 
177 	/**
178 	 * This method will be called to preinstantiate beans, which depends on the
179 	 * exporter bean.
180 	 *
181 	 * @param exporterBean
182 	 *            Is the reference to the dependent bean.
183 	 */
184 	public void prepareExporterDependentBeans(
185 			RemotingServiceExporter exporterBean) {
186 		// Per default, do nothing.
187 	}
188 
189 	/**
190 	 * This method will be used to finalize the preinstantiated beans, which
191 	 * depends on the exporter bean.
192 	 *
193 	 * @param exporterBean
194 	 *            Is the reference to the dependent bean.
195 	 */
196 	public void finalizeExporterDependentBeans(
197 			RemotingServiceExporter exporterBean) {
198 		// Per default, do nothing.
199 	}
200 
201 	/**
202 	 * {@inheritDoc}
203 	 */
204 	public void setApplicationContext(ApplicationContext applicationContext) {
205 		m_parentApplicationContext = applicationContext;
206 	}
207 	
208 	/**
209 	 * Defines the interface implemented by the Proxy that wraps the  enriched
210 	 * service interface. Subclasses can override this method to supply protocol
211 	 * specific interfaces.
212 	 *
213 	 * @param serviceInterface The service interface to wrap.
214 	 * @return Returns the interfaces implemented by the proxy.
215 	 */
216 	public Class[] getProxyInterface(Class serviceInterface) {
217 		return new Class[] {serviceInterface};
218 	}
219 	
220 	/**
221 	 * Creates a invocation handler used on the client proxy. Subclasses can
222 	 * override this method to supply protocol specific behaviour.
223 	 *
224 	 * @param innerProxyBean The inner proxy to wrap.
225 	 * @param serviceInterfaceWithContext The inner proxy's interface.
226 	 * @return Returns an invocation handler for the given inner proxy and its
227 	 *      interface.
228 	 */
229 	public ClientContextInvocationHandler getClientContextInvocationHandler(
230 			Object innerProxyBean, Class serviceInterfaceWithContext) {
231 		
232 		return new ClientContextInvocationHandler(
233 				innerProxyBean, serviceInterfaceWithContext,
234 				getImplicitContextPassingRegistry());
235 	}
236 	
237 	/**
238 	 * Checks whether the service exporter is configured properly to be used
239 	 * with this protocol. Pre-instantiates the object of the given exporter
240 	 * if it is singleton. This was the default behaviour in SPring 1.2.x.
241 	 * Subclasses may override this behaviour.
242 	 *
243 	 * @param serviceExporter
244 	 *      The remoting service exporter that is using this protocol.
245 	 *
246 	 * @throws Exception
247 	 *      Whenever something goes wrong.
248 	 */
249 	public void checkRemotingExporter(RemotingServiceExporter serviceExporter)
250 		throws Exception {
251 		if (!isDoNotForcePreInstantiationOfExporterObject() && serviceExporter.isSingleton()) {
252 			s_logger.info("Service exporter bean '"
253 				+ serviceExporter.getBeanName() + "' is a singleton. Will now "
254 				+ "pre-instantiate exporter object like it was done in "
255 				+ "Spring 1.2.x.");
256 			serviceExporter.getObject();
257 		}
258 	}
259 	
260 	/**
261 	 * Checks whether the proxy factory is configured properly to be used
262 	 * with this protocol. Does nothing by default.
263 	 * Subclasses may override this behaviour.
264 	 *
265 	 * @param proxyFactory
266 	 *      The remoting proxy factory that is using this protocol.
267 	 *
268 	 * @throws Exception
269 	 *      Whenever something goes wrong.
270 	 */
271 	public void checkRemotingProxy(RemotingProxyFactoryBean proxyFactory)
272 		throws Exception {
273 		// do nothing
274 	}
275 	
276 	/**
277 	 * Destroys the child app contexts if they are disposable.
278 	 *
279 	 * {@inheritDoc}
280 	 */
281 	public void destroy() throws Exception {
282 		Set<ApplicationContext> contexts = getChlidApplicationContexts();
283 		for (ApplicationContext context : contexts) {
284 			if (context instanceof DisposableBean) {
285 				DisposableBean disposableBean = (DisposableBean) context;
286 				disposableBean.destroy();
287 			}
288 		}
289 	}
290 	
291 	/**
292 	 * Registers the given app context as child.
293 	 *
294 	 * @param applicationContext To register.
295 	 * @return Returns <code>true</code> if registration was successfully.
296 	 */
297 	protected boolean registerChildApplicationContext(
298 		ApplicationContext applicationContext) {
299 		return m_chlidApplicationContexts.add(applicationContext);
300 	}
301 	
302 	/**
303 	 * Unregisters the given app context as child.
304 	 *
305 	 * @param applicationContext To unregister.
306 	 * @return Returns <code>true</code> if unregistration was successfully.
307 	 */
308 	protected boolean unregisterChildApplicationContext(
309 		ApplicationContext applicationContext) {
310 		return m_chlidApplicationContexts.remove(applicationContext);
311 	}
312 	
313 	/**
314 	 * @return Returns the set of the registered child app contexts.
315 	 */
316 	public Set<ApplicationContext> getChlidApplicationContexts() {
317 		return new LinkedHashSet<ApplicationContext>(
318 			m_chlidApplicationContexts);
319 	}
320 
321 	/**
322 	 * @return Returns the doNotForcePreInstantiationOfExporterObject.
323 	 */
324 	public boolean isDoNotForcePreInstantiationOfExporterObject() {
325 		return m_doNotForcePreInstantiationOfExporterObject;
326 	}
327 
328 	/**
329 	 * If it is set to <code>true</code>, the exporter object (if singleton),
330 	 * will not be pre-instantiated. By default singleton exporter objects
331 	 * will be pre-instantiated.
332 	 * 
333 	 * @param doNotForcePreInstantiationOfExporterObject Is the doNotForcePreInstantiationOfExporterObject to set.
334 	 */
335 	public void setDoNotForcePreInstantiationOfExporterObject(boolean doNotForcePreInstantiationOfExporterObject) {
336 		m_doNotForcePreInstantiationOfExporterObject = doNotForcePreInstantiationOfExporterObject;
337 	}
338 }