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 }