KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > interop > rmi > iiop > client > Connection


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

18 package org.apache.geronimo.interop.rmi.iiop.client;
19
20 import java.io.IOException JavaDoc;
21 import java.lang.reflect.Constructor JavaDoc;
22 import java.net.Socket JavaDoc;
23
24 import org.apache.geronimo.interop.SystemException;
25 import org.apache.geronimo.interop.properties.BooleanProperty;
26 import org.apache.geronimo.interop.properties.IntProperty;
27 import org.apache.geronimo.interop.properties.PropertyMap;
28 import org.apache.geronimo.interop.properties.SystemProperties;
29 import org.apache.geronimo.interop.rmi.iiop.BadMagicException;
30 import org.apache.geronimo.interop.rmi.iiop.CdrInputStream;
31 import org.apache.geronimo.interop.rmi.iiop.CdrOutputStream;
32 import org.apache.geronimo.interop.rmi.iiop.GiopMessage;
33 import org.apache.geronimo.interop.rmi.iiop.ObjectRef;
34 import org.apache.geronimo.interop.rmi.iiop.SecurityInfo;
35 import org.apache.geronimo.interop.rmi.iiop.SimpleObjectInputStream;
36 import org.apache.geronimo.interop.rmi.iiop.UnsupportedProtocolVersionException;
37 import org.apache.geronimo.interop.util.ExceptionUtil;
38 import org.apache.geronimo.interop.util.InstancePool;
39 import org.apache.geronimo.interop.util.StringUtil;
40 import org.apache.geronimo.interop.util.ThreadContext;
41 import org.omg.GIOP.MsgType_1_1;
42 import org.omg.GIOP.ReplyHeader_1_2;
43 import org.omg.GIOP.ReplyStatusType_1_2;
44 import org.omg.GIOP.RequestHeader_1_2;
45 import org.omg.GIOP.SystemExceptionReplyBody;
46 import org.omg.GIOP.SystemExceptionReplyBodyHelper;
47 import org.omg.GIOP.TargetAddress;
48 import org.omg.IOP.ServiceContext JavaDoc;
49
50 public class Connection
51 {
52
53     private static final byte reservedBA[] = new byte[] { 0, 0, 0};
54     private int requestid_ = 0;
55
56     // http tunnelling related
57
private boolean httpTunnelled;
58     private String JavaDoc httpHeaders;
59     private String JavaDoc webProxyHost;
60     private int webProxyPort;
61
62     public Connection()
63     {
64     }
65
66     public static Connection getInstance(String JavaDoc endpoint, ObjectRef objectRef, PropertyMap connProps)
67     {
68         Connection conn = new Connection();
69         conn.init(endpoint, objectRef, connProps);
70         return conn;
71     }
72
73     public static final BooleanProperty simpleIDLProperty =
74             new BooleanProperty(SystemProperties.class, "org.apache.geronimo.interop.simpleIDL");
75
76     public static final IntProperty socketTimeoutProperty =
77             new IntProperty(Connection.class, "socketTimeout")
78             .defaultValue(600); // 10 minutes
79

80     private static final boolean SIMPLE_IDL = simpleIDLProperty.getBoolean();
81
82     private static final ServiceContext JavaDoc[] EMPTY_SERVICE_CONTEXT = {};
83
84     private static final byte[] CODE_SET_ENCAPSULATION =
85     {
86         (byte)0, // big endian
87
(byte)0, (byte)0, (byte)0, // padding
88
(byte)0x05, (byte)0x01, (byte)0x00, (byte)0x01, // 0x05010001 = CodeSet ID for UTF-8
89
(byte)0x00, (byte)0x01, (byte)0x01, (byte)0x09, // 0x00010109 = CodeSet ID for UTF-16
90
};
91
92     private static final ServiceContext JavaDoc CODE_SET_SERVICE_CONTEXT = new ServiceContext JavaDoc(1, CODE_SET_ENCAPSULATION);
93
94     private String JavaDoc url;
95
96     private boolean ok;
97
98     private InstancePool pool;
99
100     private Socket JavaDoc socket;
101
102     protected org.apache.geronimo.interop.rmi.iiop.ObjectInputStream input;
103
104     protected org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream output;
105
106     private CdrOutputStream parameters;
107
108     private CdrOutputStream requestOut;
109
110     private CdrInputStream results;
111
112     private String JavaDoc exceptionType;
113
114     private Exception JavaDoc exception;
115
116     private RequestHeader_1_2 requestHeader;
117
118     private int callForget;
119
120
121     protected java.io.InputStream JavaDoc socketIn;
122
123     protected java.io.OutputStream JavaDoc socketOut;
124
125     public String JavaDoc getInstanceName()
126     {
127         return url;
128     }
129
130     public void close()
131     {
132         parameters = null;
133         input = null;
134         output = null;
135         if (ok)
136         {
137             pool.put(this);
138         }
139         else
140         {
141             shutdown();
142         }
143     }
144
145     public void beforeInvoke() {
146         ok = false;
147         parameters = CdrOutputStream.getInstance();
148     }
149
150     public void forget(Object JavaDoc requestKey) {
151     }
152
153     public void invoke(ObjectRef object, String JavaDoc method, Object JavaDoc requestKey, int retryCount)
154     {
155         if(object.$getForwardingAddress() != null)
156         {
157             object = object.$getForwardingAddress();
158         }
159
160         RequestHeader_1_2 request = requestHeader;
161
162         request.request_id = requestid_++;
163         request.response_flags = 3;
164         request.target = new TargetAddress();
165         request.target.object_key(object.$getObjectKey());
166         request.operation = method;
167         request.service_context = getServiceContext(object, requestKey, retryCount);
168         request.reserved = reservedBA; // Sun's generated org.omg.GIOP.RequestHeader_1_2Helper wants this....
169

170         if (requestOut == null)
171         {
172             requestOut = CdrOutputStream.getInstance();
173         }
174         requestOut.write_request(request, parameters);
175
176
177         try
178         {
179             if(httpTunnelled)
180             {
181                 requestOut.send_http_request(socketOut, url, httpHeaders);
182             }
183             else
184             {
185                 requestOut.send_message(socketOut, url);
186             }
187         } catch (RuntimeException JavaDoc ex) {
188             throw ex;
189         }
190
191         requestOut.reset();
192
193         if (results == null)
194         {
195             results = CdrInputStream.getInstance();
196         }
197         else
198         {
199             results.reset();
200         }
201
202         results.setNamingContext(object.$getNamingContext());
203         GiopMessage message;
204         try
205         {
206             if(httpTunnelled)
207             {
208                 message = results.receive_http_response(socketIn, url);
209             }
210             else
211             {
212                 message = results.receive_message(socketIn, url);//_serverHost);
213
}
214         }
215         catch (BadMagicException ex)
216         {
217             throw new SystemException(ex);
218         }
219         catch (UnsupportedProtocolVersionException ex)
220         {
221             throw new SystemException(ex);
222         }
223         catch (RuntimeException JavaDoc ex)
224         {
225             throw new RetryInvokeException(ex);
226         }
227
228         switch (message.type)
229         {
230           case MsgType_1_1._Reply:
231                 processReply(message.reply, object);
232                 break;
233
234             default:
235                 throw new SystemException("TODO: message type = " + message.type);
236         }
237
238         ok = true;
239     }
240
241     public InstancePool getInstancePool() {
242         return pool;
243     }
244
245     public void setInstancePool(InstancePool pool) {
246         this.pool = pool;
247     }
248
249     public org.apache.geronimo.interop.rmi.iiop.ObjectInputStream getInputStream() {
250         if (SIMPLE_IDL) {
251             return getSimpleInputStream();
252         }
253         if (input == null) {
254             input = org.apache.geronimo.interop.rmi.iiop.ObjectInputStream.getInstance(results);
255         }
256         return input;
257     }
258
259     public org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream getOutputStream() {
260         if (SIMPLE_IDL) {
261             return getSimpleOutputStream();
262         }
263         if (output == null) {
264             output = org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream.getInstance(parameters);
265         }
266         return output;
267     }
268
269     public org.apache.geronimo.interop.rmi.iiop.ObjectInputStream getSimpleInputStream() {
270         if (input == null) {
271             input = org.apache.geronimo.interop.rmi.iiop.SimpleObjectInputStream.getInstance(results);
272         }
273         return input;
274     }
275
276     public org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream getSimpleOutputStream() {
277         if (output == null) {
278             output = org.apache.geronimo.interop.rmi.iiop.SimpleObjectOutputStream.getInstance(parameters);
279         }
280         return output;
281     }
282
283     public String JavaDoc getExceptionType() {
284         return exceptionType;
285     }
286
287     public Exception JavaDoc getException() {
288         if (exception == null) {
289             if (exceptionType != null) {
290                 return new SystemException(exceptionType, new org.omg.CORBA.UNKNOWN JavaDoc());
291             } else {
292                 throw new IllegalStateException JavaDoc("no exception");
293             }
294         } else {
295             return exception;
296         }
297     }
298
299     public void clearException()
300     {
301         exceptionType = null;
302         exception = null;
303     }
304
305     // TODO: check why we have 'objectRef' parameter???
306
protected void init(String JavaDoc endpoint, ObjectRef objectRef, PropertyMap connProps)
307     {
308         setHttpTunnelledPropsIfTrue(connProps);
309
310         if(httpTunnelled)
311         {
312             httpInit(endpoint, connProps);
313             return;
314         }
315
316         url = "iiop://" + endpoint;
317         UrlInfo urlInfo = UrlInfo.getInstance(url);
318         String JavaDoc host = urlInfo.getHost();
319         int port = urlInfo.getPort();
320         int socketTimeout = socketTimeoutProperty.getInt(endpoint, connProps);
321         try
322         {
323             socket = new Socket JavaDoc(host, port);
324             socketIn = socket.getInputStream();
325             socketOut = socket.getOutputStream();
326             socket.setSoTimeout(1000 * socketTimeout);
327         }
328         catch (Exception JavaDoc ex)
329         {
330             throw new SystemException(ex);
331         }
332         requestHeader = new RequestHeader_1_2();
333         requestHeader.reserved = reservedBA;
334     }
335
336     private void httpInit(String JavaDoc endpoint, PropertyMap connProps)
337     {
338         String JavaDoc host = null;
339         int port;
340         url = "iiop://" + endpoint;
341         int socketTimeout = socketTimeoutProperty.getInt(endpoint, connProps);
342
343         if(webProxyHost != null)
344         {
345             host = webProxyHost;
346             port = webProxyPort;
347         }
348         else
349         {
350             UrlInfo urlInfo = UrlInfo.getInstance(url);
351             host = urlInfo.getHost();
352             port = urlInfo.getPort();
353         }
354
355         try
356         {
357             socket = new Socket JavaDoc(host, port);
358             socketIn = socket.getInputStream();
359             socketOut = socket.getOutputStream();
360             socket.setSoTimeout(1000 * socketTimeout);
361         }
362         catch (IOException JavaDoc ex)
363         {
364             throw new SystemException(ex);
365         }
366         requestHeader = new RequestHeader_1_2();
367         requestHeader.reserved = reservedBA;
368     }
369
370     public ServiceContext JavaDoc[] getServiceContext(ObjectRef object, Object JavaDoc requestKey, int retryCount) {
371         String JavaDoc username;
372         String JavaDoc password;
373         SecurityInfo securityInfo = SecurityInfo.getCurrent();
374         if (securityInfo == null) {
375             ClientNamingContext namingContext = object.$getNamingContext();
376             if (namingContext != null) {
377                 username = namingContext.getUsername();
378                 password = namingContext.getPassword();
379             } else {
380                 username = null;
381                 password = null;
382             }
383         } else {
384             username = securityInfo.username;
385             password = securityInfo.password;
386         }
387         if (username != null && username.length() == 0) {
388             username = null; // Save network bandwidth in service context.
389
}
390         if (password != null && password.length() == 0) {
391             password = null; // Save network bandwidth in service context.
392
}
393         int count = 0;
394         if (username != null) {
395             count++;
396         }
397         if (password != null) {
398             count++;
399         }
400         if (requestKey != null) {
401             count++;
402         }
403         ServiceContext JavaDoc[] context = new ServiceContext JavaDoc[count];
404         int index = 0;
405         context[index++] = CODE_SET_SERVICE_CONTEXT;
406         if (username != null) {
407             context[index++] = new ServiceContext JavaDoc(SecurityInfo.TAG_USERNAME, SecurityInfo.encode(username));
408         }
409         if (password != null) {
410             context[index++] = new ServiceContext JavaDoc(SecurityInfo.TAG_PASSWORD, SecurityInfo.encode(password));
411         }
412         return context;
413     }
414
415     protected void processReply(ReplyHeader_1_2 reply, ObjectRef object)
416     {
417         processReplyServiceContext(reply);
418         int status = reply.reply_status.value();
419         switch (status)
420         {
421           case ReplyStatusType_1_2._NO_EXCEPTION:
422             processNormalReply(reply);
423             break;
424           case ReplyStatusType_1_2._USER_EXCEPTION:
425             processUserException(reply);
426             break;
427           case ReplyStatusType_1_2._SYSTEM_EXCEPTION:
428             processSystemException(reply);
429             break;
430           case ReplyStatusType_1_2._LOCATION_FORWARD:
431             processLocationForward(reply, object);
432             break;
433           case ReplyStatusType_1_2._LOCATION_FORWARD_PERM:
434             processLocationForward(reply, object);
435             break;
436           case ReplyStatusType_1_2._NEEDS_ADDRESSING_MODE:
437             throw new SystemException("TODO");
438           default:
439             throw new SystemException("reply status = " + status);
440         }
441     }
442
443     protected void processLocationForward(ReplyHeader_1_2 reply, ObjectRef object)
444     {
445         ObjectRef ref = (ObjectRef)results.read_Object();
446         object.$setForwardingAddress(ref);
447         throw new RetryInvokeException(new RuntimeException JavaDoc("LOCATION_FORWARD"));
448     }
449
450     protected void processReplyServiceContext(ReplyHeader_1_2 reply) {
451         ServiceContext JavaDoc[] list = reply.service_context;
452         int n = list.length;
453         for (int i = 0; i < n; i++) {
454             ServiceContext JavaDoc sc = list[i];
455             if (sc.context_id == 0xCFCFCFCF
456                 || sc.context_id == 0xDFDFDFDF) {
457                 // "CF..." indicates "Call Forget Request"
458
// "DF..." indicates "Call Forget Response"
459
callForget = sc.context_id;
460             }
461         }
462     }
463
464     protected void processNormalReply(ReplyHeader_1_2 reply) {
465         // Intentionally empty.
466
}
467
468     protected void processUserException(ReplyHeader_1_2 reply)
469     {
470         exception = null;
471         String JavaDoc type = results.read_string();
472         type = StringUtil.removePrefix(type, "IDL:");
473         type = StringUtil.removeSuffix(type, ":1.0");
474         if (! (input instanceof SimpleObjectInputStream))
475         {
476             if (type.endsWith("Ex"))
477             {
478                 type = StringUtil.removeSuffix(type, "Ex") + "Exception";
479             }
480         }
481         type = type.replace('/', '.');
482         exceptionType = type;
483         ok = true;
484     }
485
486     protected void processSystemException(ReplyHeader_1_2 reply)
487     {
488         exceptionType = "???";
489         SystemExceptionReplyBody replyBody = SystemExceptionReplyBodyHelper.read(results);
490         String JavaDoc id = replyBody.exception_id;
491         id = StringUtil.removePrefix(id, "IDL:CORBA/"); // ancient servers might send this!
492
id = StringUtil.removePrefix(id, "IDL:omg.org/CORBA/");
493         id = StringUtil.removeSuffix(id, ":1.0");
494         String JavaDoc causedBy = null;
495         if (results.hasMoreData())
496         {
497             // This is non-standard for IIOP, but if the data isn't present,
498
// we wont try to read it!
499
causedBy = ExceptionUtil.causedBy(results.read_string());
500         }
501         ok = true;
502         String JavaDoc exceptionClassName = "org.omg.CORBA." + id;
503         try
504         {
505             Class JavaDoc exceptionClass = ThreadContext.loadClass(exceptionClassName);
506             Constructor JavaDoc constructor = exceptionClass.getConstructor
507             (
508                 new Class JavaDoc[] { String JavaDoc.class }
509             );
510             org.omg.CORBA.SystemException JavaDoc corbaException;
511             corbaException = (org.omg.CORBA.SystemException JavaDoc)constructor.newInstance
512             (
513                 new Object JavaDoc[] { causedBy == null ? "" : causedBy }
514             );
515             corbaException.minor = replyBody.minor_code_value;
516             corbaException.completed = org.omg.CORBA.CompletionStatus.from_int(replyBody.completion_status);
517             exception = corbaException;
518         }
519         catch (Exception JavaDoc ex)
520         {
521             // Shouldn't happen, but just in case
522
ex.printStackTrace();
523             if (causedBy == null)
524             {
525                 causedBy = replyBody.exception_id;
526             }
527             else
528             {
529                 causedBy = replyBody.exception_id + "\nCaused by: " + causedBy;
530             }
531             exception = new org.omg.CORBA.UNKNOWN JavaDoc(causedBy,
532                 replyBody.minor_code_value,
533                 org.omg.CORBA.CompletionStatus.from_int(replyBody.completion_status));
534         }
535     }
536
537     private void setHttpTunnelledPropsIfTrue(PropertyMap connprops)
538     {
539         if(connprops.get("http") != null)
540         {
541             httpTunnelled = true;
542         }
543         else
544         {
545             httpTunnelled = false;
546         }
547
548         if(httpTunnelled)
549         {
550             // get http extra headers if present
551
httpHeaders = connprops.getProperty("HttpExtraHeader");
552
553             if(httpHeaders != null && httpHeaders.toLowerCase().indexOf("user-agent") == -1)
554             {
555                 httpHeaders += "User-Agent: Geronimo/1.0\r\n";
556             }
557
558             if(httpHeaders == null)
559             {
560                 httpHeaders = "User-Agent: Geronimo/1.0\r\n";
561             }
562
563             //get webproxy host/port if present:
564
webProxyHost = connprops.getProperty("WebProxyHost");
565             String JavaDoc port = connprops.getProperty("WebProxyPort");
566
567             if(port != null)
568             {
569                 try
570                 {
571                     webProxyPort = java.lang.Integer.parseInt(port);
572                 }
573                 catch(java.lang.NumberFormatException JavaDoc e)
574                 {
575                     throw new SystemException(org.apache.geronimo.interop.util.ExceptionUtil.causedBy(e));
576                 }
577             }
578
579             if(port == null && webProxyHost != null)
580             {
581                 webProxyPort = 80; //default
582
}
583         }
584         else
585         {
586             webProxyHost = null;
587             httpHeaders = null;
588         }
589     }
590
591     public void shutdown() {
592         if (socketOut != null) {
593             try {
594                 socketOut.close();
595             } catch (Exception JavaDoc ignore) {
596             }
597             socketOut = null;
598         }
599         if (socketIn != null) {
600             try {
601                 socketIn.close();
602             } catch (Exception JavaDoc ignore) {
603             }
604             socketIn = null;
605         }
606         if (socket != null) {
607             try {
608                 socket.close();
609             } catch (Exception JavaDoc ignore) {
610             }
611             socket = null;
612         }
613     }
614 }
615
Popular Tags