KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jms > services > HessianListener


1 /*
2  * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
3  *
4  * The Apache Software License, Version 1.1
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution, if
19  * any, must include the following acknowlegement:
20  * "This product includes software developed by the
21  * Caucho Technology (http://www.caucho.com/)."
22  * Alternately, this acknowlegement may appear in the software itself,
23  * if and wherever such third-party acknowlegements normally appear.
24  *
25  * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * info@caucho.com.
29  *
30  * 5. Products derived from this software may not be called "Resin"
31  * nor may "Resin" appear in their names without prior written
32  * permission of Caucho Technology.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * @author Emil Ong
47  */

48
49 package com.caucho.jms.services;
50
51 import com.caucho.hessian.io.AbstractHessianOutput;
52 import com.caucho.hessian.io.Hessian2Input;
53 import com.caucho.hessian.io.Hessian2Output;
54 import com.caucho.hessian.io.HessianOutput;
55 import com.caucho.hessian.io.SerializerFactory;
56 import com.caucho.hessian.server.HessianSkeleton;
57 import com.caucho.jms.util.BytesMessageInputStream;
58 import com.caucho.services.server.GenericService;
59 import com.caucho.util.NullOutputStream;
60
61 import javax.jms.*;
62 import java.io.IOException JavaDoc;
63 import java.util.logging.Logger JavaDoc;
64
65 /**
66  * MessageListener for serving Hessian services.
67  */

68 public class HessianListener {
69   protected static Logger JavaDoc log
70     = Logger.getLogger(HessianListener.class.getName());
71
72   private Class JavaDoc _homeAPI;
73   private Object JavaDoc _homeImpl;
74   
75   private Class JavaDoc _objectAPI;
76   private Object JavaDoc _objectImpl;
77   
78   private HessianSkeleton _homeSkeleton;
79   private HessianSkeleton _objectSkeleton;
80
81   private SerializerFactory _serializerFactory;
82
83   private int _listenerMax = 5;
84   private Connection _jmsConnection;
85   private ConnectionFactory _connectionFactory;
86   private Destination _destination;
87   private Session _jmsSession;
88
89   /**
90    * Sets the home api.
91    */

92   public void setHomeAPI(Class JavaDoc api)
93   {
94     _homeAPI = api;
95   }
96
97   /**
98    * Sets the home implementation
99    */

100   public void setHome(Object JavaDoc home)
101   {
102     _homeImpl = home;
103   }
104
105   /**
106    * Sets the object api.
107    */

108   public void setObjectAPI(Class JavaDoc api)
109   {
110     _objectAPI = api;
111   }
112
113   /**
114    * Sets the object implementation
115    */

116   public void setObject(Object JavaDoc object)
117   {
118     _objectImpl = object;
119   }
120
121   /**
122    * Sets the service class.
123    */

124   public void setService(Object JavaDoc service)
125   {
126     setHome(service);
127   }
128
129   /**
130    * Sets the api-class.
131    */

132   public void setAPIClass(Class JavaDoc api)
133   {
134     setHomeAPI(api);
135   }
136
137   /**
138    * Gets the api-class.
139    */

140   public Class JavaDoc getAPIClass()
141   {
142     return _homeAPI;
143   }
144
145   /**
146    * Sets the name of the connection factory.
147    */

148   public void setConnectionFactory(ConnectionFactory connectionFactory)
149   {
150     _connectionFactory = connectionFactory;
151   }
152
153   /**
154    * Sets the name of the input queue.
155    */

156   public void setDestination(Destination destination)
157   {
158     _destination = destination;
159   }
160
161   /**
162    * Sets the serializer factory.
163    */

164   public void setSerializerFactory(SerializerFactory factory)
165   {
166     _serializerFactory = factory;
167   }
168
169   /**
170    * Gets the serializer factory.
171    */

172   public SerializerFactory getSerializerFactory()
173   {
174     if (_serializerFactory == null)
175       _serializerFactory = new SerializerFactory();
176
177     return _serializerFactory;
178   }
179
180   /**
181    * Sets the serializer send collection java type.
182    */

183   public void setSendCollectionType(boolean sendType)
184   {
185     getSerializerFactory().setSendCollectionType(sendType);
186   }
187
188   public void init()
189   {
190     if (_homeImpl == null)
191       _homeImpl = this;
192
193     if (_homeImpl != null) {
194       _homeAPI = findRemoteAPI(_homeImpl.getClass());
195
196       if (_homeAPI == null)
197         _homeAPI = _homeImpl.getClass();
198     }
199
200     if (_objectAPI == null && _objectImpl != null)
201       _objectAPI = _objectImpl.getClass();
202
203     _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI);
204     if (_objectAPI != null)
205       _homeSkeleton.setObjectClass(_objectAPI);
206
207     if (_objectImpl != null) {
208       _objectSkeleton = new HessianSkeleton(_objectImpl, _objectAPI);
209       _objectSkeleton.setHomeClass(_homeAPI);
210     }
211     else
212       _objectSkeleton = _homeSkeleton;
213   }
214   
215   public void start() throws Throwable JavaDoc
216   {
217     _jmsConnection = _connectionFactory.createConnection();
218
219     if (_destination instanceof Topic)
220       _listenerMax = 1;
221
222     for (int i = 0; i < _listenerMax; i++) {
223       Session session =
224         _jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
225
226       MessageConsumer consumer = session.createConsumer(_destination);
227
228       consumer.setMessageListener(new HessianListenerMDB());
229     }
230
231     _jmsConnection.start();
232   }
233
234   public void stop() throws JMSException
235   {
236     _jmsConnection.stop();
237   }
238
239   private Class JavaDoc findRemoteAPI(Class JavaDoc implClass)
240   {
241     if (implClass == null || implClass.equals(GenericService.class))
242       return null;
243     
244     Class JavaDoc []interfaces = implClass.getInterfaces();
245
246     if (interfaces.length == 1)
247       return interfaces[0];
248
249     return findRemoteAPI(implClass.getSuperclass());
250   }
251
252   private class HessianListenerMDB implements MessageListener {
253     /**
254      * Execute a request. The "id" property of the request selects the
255      * bean. Once the bean's selected, it will be applied.
256      */

257     public void onMessage(Message message)
258     {
259       try {
260         String JavaDoc objectId = message.getStringProperty("id");
261
262         // XXX ??? ServiceContext.begin(req, serviceId, objectId);
263

264         if (! (message instanceof BytesMessage)) {
265           log.info("HessianListener expects only BytesMessages");
266           return;
267         }
268
269         BytesMessageInputStream is =
270           new BytesMessageInputStream((BytesMessage) message);
271
272         NullOutputStream os = new NullOutputStream();
273
274         Hessian2Input in = new Hessian2Input(is);
275         AbstractHessianOutput out;
276
277         SerializerFactory serializerFactory = getSerializerFactory();
278
279         in.setSerializerFactory(serializerFactory);
280
281         int code = in.read();
282
283         if (code != 'c') {
284           // XXX: deflate
285
throw new IOException JavaDoc("expected 'c' in hessian input at " + code);
286         }
287
288         int major = in.read();
289         int minor = in.read();
290
291         if (major >= 2)
292           out = new Hessian2Output(os);
293         else
294           out = new HessianOutput(os);
295
296         out.setSerializerFactory(serializerFactory);
297
298         if (objectId != null)
299           _objectSkeleton.invoke(in, out);
300         else
301           _homeSkeleton.invoke(in, out);
302
303         out.close();
304       } catch (JMSException e) {
305         log.warning("Unable to process request: " + e);
306       } catch (IOException JavaDoc e) {
307         log.warning("Unable to process request: " + e);
308       } catch (Throwable JavaDoc e) {
309         log.warning("Unable to process request: " + e);
310       }
311       /* XXX
312          finally {
313          ServiceContext.end();
314          }*/

315     }
316   }
317 }
318
Popular Tags