KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > remote > hessian > HessianConnection


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.remote.hessian;
21
22 import org.apache.cayenne.CayenneRuntimeException;
23 import org.apache.cayenne.event.EventBridge;
24 import org.apache.cayenne.remote.BaseConnection;
25 import org.apache.cayenne.remote.ClientMessage;
26 import org.apache.cayenne.remote.RemoteService;
27 import org.apache.cayenne.remote.RemoteSession;
28 import org.apache.cayenne.util.Util;
29
30 import com.caucho.hessian.client.HessianRuntimeException;
31 import com.caucho.hessian.io.HessianProtocolException;
32
33 /**
34  * An ClientConnection that passes messages to a remotely deployed HessianService. It
35  * supports HTTP BASIC authentication. HessianConnection serializes messages using Hessian
36  * binary web service protocol over HTTP. For more info on Hessian see Caucho site at <a
37  * HREF="http://www.caucho.com/resin-3.0/protocols/hessian.xtp">http://www.caucho.com/resin-3.0/protocols/hessian.xtp</a>.
38  * HessianConnection supports logging of message traffic via Jakarta commons-logging API.
39  *
40  * @since 1.2
41  * @author Andrus Adamchik
42  */

43 public class HessianConnection extends BaseConnection {
44
45     public static final String JavaDoc[] CLIENT_SERIALIZER_FACTORIES = new String JavaDoc[] {
46             ClientSerializerFactory.class.getName(), EnumSerializerProxy.class.getName()
47     };
48
49     protected String JavaDoc url;
50     protected String JavaDoc userName;
51     protected String JavaDoc password;
52     protected String JavaDoc sharedSessionName;
53
54     protected RemoteSession session;
55     protected RemoteService service;
56
57     /**
58      * Creates HessianConnection that will establish dedicated session and will not use
59      * HTTP basic authentication.
60      */

61     public HessianConnection(String JavaDoc url) {
62         this(url, null, null, null);
63     }
64
65     /**
66      * Creates a HessianConnection. This constructor can optionally setup basic
67      * authentication credentials and configure shared session. <code>url</code> is the
68      * only required parameter.
69      */

70     public HessianConnection(String JavaDoc url, String JavaDoc userName, String JavaDoc password,
71             String JavaDoc sharedSessionName) {
72         if (url == null) {
73             throw new IllegalArgumentException JavaDoc("URL of Cayenne service is null.");
74         }
75
76         this.url = url;
77         this.userName = userName;
78         this.password = password;
79         this.sharedSessionName = sharedSessionName;
80     }
81
82     /**
83      * Returns a URL of Cayenne service used by this connector.
84      */

85     public String JavaDoc getUrl() {
86         return url;
87     }
88
89     /**
90      * Returns user name that is used for basic authentication when connecting to the
91      * cayenne server.
92      */

93     public String JavaDoc getUserName() {
94         return userName;
95     }
96
97     /**
98      * Returns password that is used for basic authentication when connecting to the
99      * cayenne server.
100      */

101     public String JavaDoc getPassword() {
102         return password;
103     }
104
105     public String JavaDoc getSharedSessionName() {
106         return sharedSessionName;
107     }
108
109     public EventBridge getServerEventBridge() throws CayenneRuntimeException {
110         if (session == null) {
111             connect();
112         }
113
114         return session.isServerEventsEnabled() ? session.createServerEventBridge() : null;
115     }
116
117     /**
118      * Retunrs internal RemoteSession instance.
119      */

120     RemoteSession getSession() {
121         return session;
122     }
123
124     /**
125      * Establishes server session if needed.
126      */

127     protected void beforeSendMessage(ClientMessage message)
128             throws CayenneRuntimeException {
129         // for now only support session-based communications...
130
if (session == null) {
131             connect();
132         }
133     }
134
135     /**
136      * Sends a message to remote Cayenne Hessian service.
137      */

138     protected Object JavaDoc doSendMessage(ClientMessage message) throws CayenneRuntimeException {
139         try {
140             return service.processMessage(message);
141         }
142         catch (Throwable JavaDoc th) {
143             th = unwindThrowable(th);
144             String JavaDoc errorMessage = buildExceptionMessage("Remote error", th);
145             throw new CayenneRuntimeException(errorMessage, th);
146         }
147     }
148
149     /**
150      * Establishes a session with remote service.
151      */

152     protected synchronized void connect() throws CayenneRuntimeException {
153         if (session != null) {
154             return;
155         }
156
157         long t0 = 0;
158         if (logger.isInfoEnabled()) {
159             t0 = System.currentTimeMillis();
160             StringBuffer JavaDoc log = new StringBuffer JavaDoc("Connecting to [");
161             if (userName != null) {
162                 log.append(userName);
163
164                 if (password != null) {
165                     log.append(":*******");
166                 }
167
168                 log.append("@");
169             }
170
171             log.append(url);
172             log.append("]");
173
174             if (sharedSessionName != null) {
175                 log.append(" - shared session '").append(sharedSessionName).append("'");
176             }
177             else {
178                 log.append(" - dedicated session.");
179             }
180
181             logger.info(log.toString());
182         }
183
184         // init service proxy...
185
HessianProxyFactory factory = new HessianProxyFactory(this);
186         factory.setSerializerFactory(HessianConfig.createFactory(
187                 CLIENT_SERIALIZER_FACTORIES,
188                 null));
189         factory.setUser(userName);
190         factory.setPassword(password);
191         try {
192             this.service = (RemoteService) factory.create(RemoteService.class, url);
193         }
194         catch (Throwable JavaDoc th) {
195             th = unwindThrowable(th);
196             String JavaDoc message = buildExceptionMessage("URL error", th);
197             throw new CayenneRuntimeException(message, th);
198         }
199
200         // create server session...
201
try {
202             session = (sharedSessionName != null) ? service
203                     .establishSharedSession(sharedSessionName) : service
204                     .establishSession();
205
206             if (logger.isInfoEnabled()) {
207                 long time = System.currentTimeMillis() - t0;
208                 logger.info("=== Connected, session: "
209                         + session
210                         + " - took "
211                         + time
212                         + " ms.");
213             }
214         }
215         catch (Throwable JavaDoc th) {
216             th = unwindThrowable(th);
217             th.printStackTrace();
218             String JavaDoc message = buildExceptionMessage(
219                     "Error establishing remote session",
220                     th);
221             throw new CayenneRuntimeException(message, th);
222         }
223
224         // TODO: send a connect event...
225
}
226
227     String JavaDoc buildExceptionMessage(String JavaDoc message, Throwable JavaDoc th) {
228
229         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(message);
230         buffer.append(". URL - ").append(url);
231
232         String JavaDoc thMessage = th.getMessage();
233         if (!Util.isEmptyString(thMessage)) {
234             buffer.append("; CAUSE - ").append(thMessage);
235         }
236
237         return buffer.toString();
238     }
239
240     /**
241      * Utility method to get exception cause. Implements special handling of Hessian
242      * exceptions.
243      */

244     Throwable JavaDoc unwindThrowable(Throwable JavaDoc th) {
245         if (th instanceof HessianProtocolException) {
246             Throwable JavaDoc cause = ((HessianProtocolException) th).getRootCause();
247
248             if (cause != null) {
249                 return unwindThrowable(cause);
250             }
251         }
252         else if (th instanceof HessianRuntimeException) {
253             Throwable JavaDoc cause = ((HessianRuntimeException) th).getRootCause();
254
255             if (cause != null) {
256                 return unwindThrowable(cause);
257             }
258         }
259
260         return Util.unwindException(th);
261     }
262 }
263
Popular Tags