KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openejb > webadmin > httpd > HttpRequestImpl


1 /**
2  * Redistribution and use of this software and associated documentation
3  * ("Software"), with or without modification, are permitted provided
4  * that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain copyright
7  * statements and notices. Redistributions must also contain a
8  * copy of this document.
9  *
10  * 2. Redistributions in binary form must reproduce the
11  * above copyright notice, this list of conditions and the
12  * following disclaimer in the documentation and/or other
13  * materials provided with the distribution.
14  *
15  * 3. The name "OpenEJB" must not be used to endorse or promote
16  * products derived from this Software without prior written
17  * permission of The OpenEJB Group. For written permission,
18  * please contact dev@openejb.org.
19  *
20  * 4. Products derived from this Software may not be called "OpenEJB"
21  * nor may "OpenEJB" appear in their names without prior written
22  * permission of The OpenEJB Group. OpenEJB is a registered
23  * trademark of The OpenEJB Group.
24  *
25  * 5. Due credit should be given to the OpenEJB Project
26  * (http://www.openejb.org/).
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39  * OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
42  *
43  * $Id: HttpRequestImpl.java 1912 2005-06-16 22:29:56Z jlaskowski $
44  */

45 package org.openejb.webadmin.httpd;
46
47 import java.io.ByteArrayInputStream JavaDoc;
48 import java.io.ByteArrayOutputStream JavaDoc;
49 import java.io.DataInput JavaDoc;
50 import java.io.DataInputStream JavaDoc;
51 import java.io.File JavaDoc;
52 import java.io.FileOutputStream JavaDoc;
53 import java.io.IOException JavaDoc;
54 import java.io.InputStream JavaDoc;
55 import java.net.URL JavaDoc;
56 import java.net.URLDecoder JavaDoc;
57 import java.rmi.RemoteException JavaDoc;
58 import java.util.HashMap JavaDoc;
59 import java.util.Hashtable JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.Map JavaDoc;
62 import java.util.StringTokenizer JavaDoc;
63
64 import javax.naming.InitialContext JavaDoc;
65 import javax.naming.NamingException JavaDoc;
66
67 import org.apache.commons.fileupload.MultipartStream;
68 import org.openejb.webadmin.HttpRequest;
69 import org.openejb.webadmin.HttpSession;
70 import org.openejb.core.stateful.StatefulEjbObjectHandler;
71 import org.openejb.util.FileUtils;
72
73 /** A class to take care of HTTP Requests. It parses headers, content, form and url
74  * parameters.
75  * @author <a HREF="mailto:david.blevins@visi.com">David Blevins</a>
76  * @author <a HREF="mailto:tim_urberg@yahoo.com">Tim Urberg</a>
77  */

78 public class HttpRequestImpl implements HttpRequest {
79     public static final String JavaDoc FORM_URL_ENCODED = "application/x-www-form-urlencoded";
80     public static final String JavaDoc MULITPART_FORM_DATA = "multipart/form-data";
81     public static final String JavaDoc FILENAME = "filename";
82     public static final String JavaDoc NAME = "name";
83
84     /** 5.1 Request-Line */
85     private String JavaDoc line;
86     /** 5.1.1 Method */
87     private int method;
88     /** 5.1.2 Request-URI */
89     private URL JavaDoc uri;
90     /** the headers for this page */
91     private HashMap JavaDoc headers;
92     /** the form parameters for this page */
93     private HashMap JavaDoc formParams = new HashMap JavaDoc();
94     /** the URL (or query) parameters for this page */
95     private HashMap JavaDoc queryParams = new HashMap JavaDoc();
96     /** the content of the body of this page */
97     private byte[] body;
98     private String JavaDoc[][] formParamsArray;
99
100
101     private String JavaDoc methodString;
102     private String JavaDoc pathString;
103     
104     
105     /**
106      * @return Returns the methodString.
107      */

108     public String JavaDoc getMethodString() {
109         return methodString;
110     }
111
112     /**
113      * @return Returns the pathString.
114      */

115     public String JavaDoc getPathString() {
116         return pathString;
117     }
118
119     /** Gets a header based the header name passed in.
120      * @param name The name of the header to get
121      * @return The value of the header
122      */

123     public String JavaDoc getHeader(String JavaDoc name) {
124         return (String JavaDoc) headers.get(name);
125     }
126
127     /** Gets a form parameter based on the name passed in.
128      * @param name The name of the form parameter to get
129      * @return The value of the parameter
130      */

131     public String JavaDoc getFormParameter(String JavaDoc name) {
132         return (String JavaDoc) formParams.get(name);
133     }
134
135     /** Gets all the form parameters in the form of a two-dimentional array
136      * The second dimention has two indexes which contain the key and value
137      * for example:
138      * <code>
139      * for(int i=0; i<formParams.length; i++) {
140      * key = formParams[i][0];
141      * value = formParams[i][1];
142      * }
143      * </code>
144      *
145      * All values are strings
146      * @return All the form parameters
147      */

148     public String JavaDoc[][] getFormParameters() {
149         Iterator JavaDoc keys = formParams.keySet().iterator();
150         String JavaDoc[][] returnValue = new String JavaDoc[formParams.size()][2];
151
152         String JavaDoc temp;
153         int i = 0;
154         while (keys.hasNext()) {
155             temp = (String JavaDoc) keys.next();
156             returnValue[i][0] = temp;
157             returnValue[i++][1] = (String JavaDoc) formParams.get(temp);
158         }
159
160         return returnValue;
161     }
162
163     /** Gets a URL (or query) parameter based on the name passed in.
164      * @param name The name of the URL (or query) parameter
165      * @return The value of the URL (or query) parameter
166      */

167     public String JavaDoc getQueryParameter(String JavaDoc name) {
168         return (String JavaDoc) queryParams.get(name);
169     }
170
171     /** Gets an integer value of the request method. These values are:
172      *
173      * OPTIONS = 0
174      * GET = 1
175      * HEAD = 2
176      * POST = 3
177      * PUT = 4
178      * DELETE = 5
179      * TRACE = 6
180      * CONNECT = 7
181      * UNSUPPORTED = 8
182      * @return The integer value of the method
183      */

184     public int getMethod() {
185         return method;
186     }
187
188     /** Gets the URI for the current URL page.
189      * @return The URI
190      */

191     public URL JavaDoc getURI() {
192         return uri;
193     }
194
195     /*------------------------------------------------------------*/
196     /* Methods for reading in and parsing a request */
197     /*------------------------------------------------------------*/
198     /** parses the request into the 3 different parts, request, headers, and body
199      * @param input the data input for this page
200      * @throws IOException if an exception is thrown
201      */

202     protected void readMessage(InputStream JavaDoc input) throws IOException JavaDoc {
203         DataInput JavaDoc in = new DataInputStream JavaDoc(input);
204
205         readRequestLine(in);
206         readHeaders(in);
207         readBody(in);
208     }
209
210     private String JavaDoc requestLine;
211     
212     protected String JavaDoc getRequestLine(){
213         return requestLine;
214     }
215     /** reads and parses the request line
216      * @param in the input to be read
217      * @throws IOException if an exception is thrown
218      */

219     private void readRequestLine(DataInput JavaDoc in) throws IOException JavaDoc {
220         
221         try {
222             line = in.readLine();
223             requestLine = line;
224 // System.out.println(line);
225
} catch (Exception JavaDoc e) {
226             throw new IOException JavaDoc(
227                 "Could not read the HTTP Request Line :"
228                     + e.getClass().getName()
229                     + " : "
230                     + e.getMessage());
231         }
232
233         StringTokenizer JavaDoc lineParts = new StringTokenizer JavaDoc(line, " ");
234         /* [1] Parse the method */
235         parseMethod(lineParts);
236         /* [2] Parse the URI */
237         parseURI(lineParts);
238     }
239
240     /** parses the method for this page
241      * @param lineParts a StringTokenizer of the request line
242      * @throws IOException if an exeption is thrown
243      */

244     private void parseMethod(StringTokenizer JavaDoc lineParts) throws IOException JavaDoc {
245         String JavaDoc token = null;
246         try {
247             token = lineParts.nextToken();
248         } catch (Exception JavaDoc e) {
249             throw new IOException JavaDoc(
250                 "Could not parse the HTTP Request Method :"
251                     + e.getClass().getName()
252                     + " : "
253                     + e.getMessage());
254         }
255
256         if (token.equalsIgnoreCase("GET")) {
257             method = GET;
258         } else if (token.equalsIgnoreCase("POST")) {
259             method = POST;
260         } else {
261             method = UNSUPPORTED;
262             throw new IOException JavaDoc("Unsupported HTTP Request Method :" + token);
263         }
264     }
265
266     /** parses the URI into the different parts
267      * @param lineParts a StringTokenizer of the URI
268      * @throws IOException if an exeption is thrown
269      */

270     private void parseURI(StringTokenizer JavaDoc lineParts) throws IOException JavaDoc {
271         String JavaDoc token = null;
272         try {
273             token = lineParts.nextToken();
274         } catch (Exception JavaDoc e) {
275             throw new IOException JavaDoc(
276                 "Could not parse the HTTP Request Method :"
277                     + e.getClass().getName()
278                     + " : "
279                     + e.getMessage());
280         }
281
282         try {
283             uri = new URL JavaDoc("http", "localhost", token);
284         } catch (java.net.MalformedURLException JavaDoc e) {
285             throw new IOException JavaDoc("Malformed URL :" + token + " Exception: " + e.getMessage());
286         }
287
288         parseQueryParams(uri.getQuery());
289     }
290
291     /** parses the URL (or query) parameters
292      * @param query the URL (or query) parameters to be parsed
293      * @throws IOException if an exception is thrown
294      */

295     private void parseQueryParams(String JavaDoc query) throws IOException JavaDoc {
296         if (query == null)
297             return;
298         StringTokenizer JavaDoc parameters = new StringTokenizer JavaDoc(query, "&");
299
300         while (parameters.hasMoreTokens()) {
301             StringTokenizer JavaDoc param = new StringTokenizer JavaDoc(parameters.nextToken(), "=");
302
303             /* [1] Parse the Name */
304             if (!param.hasMoreTokens())
305                 continue;
306             String JavaDoc name = URLDecoder.decode(param.nextToken());
307             if (name == null)
308                 continue;
309
310             /* [2] Parse the Value */
311             if (!param.hasMoreTokens())
312                 continue;
313             String JavaDoc value = URLDecoder.decode(param.nextToken());
314             if (value == null)
315                 continue;
316
317             //System.out.println("[] "+name+" = "+value);
318
queryParams.put(name, value);
319         }
320     }
321
322     /** reads the headers from the data input sent from the browser
323      * @param in the data input sent from the browser
324      * @throws IOException if an exeption is thrown
325      */

326     private void readHeaders(DataInput JavaDoc in) throws IOException JavaDoc {
327 // System.out.println("\nREQUEST");
328
headers = new HashMap JavaDoc();
329         while (true) {
330             // Header Field
331
String JavaDoc hf = null;
332
333             try {
334                 hf = in.readLine();
335                 //System.out.println(hf);
336
} catch (Exception JavaDoc e) {
337                 throw new IOException JavaDoc(
338                     "Could not read the HTTP Request Header Field :"
339                         + e.getClass().getName()
340                         + " : "
341                         + e.getMessage());
342             }
343
344             if (hf == null || hf.equals("")) {
345                 break;
346             }
347
348             /* [1] parse the name */
349             int colonIndex = hf.indexOf((int) ':');
350             String JavaDoc name = hf.substring(0, colonIndex);
351             if (name == null)
352                 break;
353
354             /* [2] Parse the Value */
355             String JavaDoc value = hf.substring(colonIndex + 1, hf.length());
356             if (value == null)
357                 break;
358             value = value.trim();
359             headers.put(name, value);
360         }
361
362         //temp-debug-------------------------------------------
363
//java.util.Iterator myKeys = headers.keySet().iterator();
364
//String temp = null;
365
//while(myKeys.hasNext()) {
366
// temp = (String)myKeys.next();
367
// System.out.println("Test: " + temp + "=" + headers.get(temp));
368
//}
369
//end temp-debug---------------------------------------
370
}
371
372     /** reads the body from the data input passed in
373      * @param in the data input with the body of the page
374      * @throws IOException if an exception is thrown
375      */

376     private void readBody(DataInput JavaDoc in) throws IOException JavaDoc {
377         readRequestBody(in);
378         //System.out.println("Body Length: " + body.length);
379
// Content-type: application/x-www-form-urlencoded
380
// or multipart/form-data
381
String JavaDoc type = getHeader(HttpRequest.HEADER_CONTENT_TYPE);
382         if (FORM_URL_ENCODED.equals(type)) {
383             parseFormParams();
384         } else if (type != null && type.startsWith(MULITPART_FORM_DATA)) {
385             parseMultiPartFormParams();
386         }
387     }
388
389     /** reads the request line of the data input
390      * @param in the data input that contains the request line
391      * @throws IOException if an exception is thrown
392      */

393     private void readRequestBody(DataInput JavaDoc in) throws IOException JavaDoc {
394         // Content-length: 384
395
String JavaDoc len = getHeader(HttpRequest.HEADER_CONTENT_LENGTH);
396         //System.out.println("readRequestBody Content-Length: " + len);
397

398         int length = -1;
399         if (len != null) {
400             try {
401                 length = Integer.parseInt(len);
402             } catch (Exception JavaDoc e) {
403                 //don't care
404
}
405         }
406
407         if (length < 1) {
408             this.body = new byte[0];
409         } else if (length > 0) {
410             this.body = new byte[length];
411
412             try {
413                 in.readFully(body);
414             } catch (Exception JavaDoc e) {
415                 throw new IOException JavaDoc(
416                     "Could not read the HTTP Request Body :"
417                         + e.getClass().getName()
418                         + " : "
419                         + e.getMessage());
420             }
421         }
422     }
423
424     /** parses form parameters into the formParams variable
425      * @throws IOException if an exeption is thrown
426      */

427     private void parseFormParams() throws IOException JavaDoc {
428         String JavaDoc rawParams = new String JavaDoc(body);
429         //System.out.println("rawParams: " + rawParams);
430
StringTokenizer JavaDoc parameters = new StringTokenizer JavaDoc(rawParams, "&");
431         String JavaDoc name = null;
432         String JavaDoc value = null;
433
434         while (parameters.hasMoreTokens()) {
435             StringTokenizer JavaDoc param = new StringTokenizer JavaDoc(parameters.nextToken(), "=");
436
437             /* [1] Parse the Name */
438             name = URLDecoder.decode(param.nextToken());
439             if (name == null)
440                 break;
441
442             /* [2] Parse the Value */
443             if (param.hasMoreTokens()) {
444                 value = URLDecoder.decode(param.nextToken());
445             } else {
446                 value = ""; //if there is no token set value to blank string
447
}
448
449             if (value == null)
450                 value = "";
451
452             formParams.put(name, value);
453             //System.out.println(name + ": " + value);
454
}
455     }
456
457     /**
458      * A method which parses form parameters that are multipart/form-data
459      * according to <a HREF="http://www.ietf.org/rfc/rfc1867.txt" target="_blank">
460      * RFC 1867</a>. Currently multipart/mixed is not implemented.
461      */

462     private void parseMultiPartFormParams() throws IOException JavaDoc {
463         /* see http://www.ietf.org/rfc/rfc1867.txt */
464         ByteArrayOutputStream JavaDoc output;
465         StringBuffer JavaDoc multiPartBuffer;
466         int j;
467         Map JavaDoc headerMap;
468         boolean isFile;
469         String JavaDoc fileName = null;
470         byte[] outputArray;
471         FileOutputStream JavaDoc fos;
472
473         String JavaDoc contentType = getHeader(HttpRequest.HEADER_CONTENT_TYPE);
474         int boundaryIndex = contentType.indexOf("boundary=");
475         if (boundaryIndex < 0) {
476             throw new IOException JavaDoc("the request was rejected because no multipart boundary was found");
477         }
478         byte[] boundary = contentType.substring(boundaryIndex + 9).getBytes();
479
480         ByteArrayInputStream JavaDoc input = new ByteArrayInputStream JavaDoc(body);
481         MultipartStream multi = new MultipartStream(input, boundary);
482
483         boolean nextPart = multi.skipPreamble();
484         while (nextPart) {
485             try {
486                 output = new ByteArrayOutputStream JavaDoc();
487                 multi.readBodyData(output);
488                 outputArray = output.toByteArray();
489                 multiPartBuffer = new StringBuffer JavaDoc(50);
490                 isFile = false;
491                 File JavaDoc jarFileInTempDir;
492                 j = 0;
493
494                 for (int i = 0; i < outputArray.length; i++) {
495                     //first check for \r\n end of line
496
if (outputArray[i] == 13 && outputArray[i + 1] == 10) {
497                         //we've come to the end of a line
498
headerMap = parseMultiPartHeader(multiPartBuffer);
499                         if (headerMap.get(NAME) != null) {
500                             fileName = (String JavaDoc) headerMap.get(NAME);
501                         }
502
503                         //add the filename if there is one
504
if (fileName != null && headerMap.get(FILENAME) != null) {
505                             this.formParams.put(fileName, headerMap.get(FILENAME));
506                             isFile = true;
507                         }
508
509                         if (outputArray[i + 2] == 13 && outputArray[i + 3] == 10) {
510                             //we've reached the blank line
511
i+=4;
512                             j = i;
513                             break;
514                         } else {
515                             i++;
516                         }
517                         
518                         multiPartBuffer = new StringBuffer JavaDoc(50);
519                     } else {
520                         multiPartBuffer.append((char) outputArray[i]);
521                     }
522                 }
523
524                 //here we know that we have a file and that we need to write it
525
if (isFile) {
526                     //create file
527
jarFileInTempDir = new File JavaDoc((String JavaDoc) this.formParams.get(fileName));
528                     if (!jarFileInTempDir.exists()) {
529                         jarFileInTempDir.createNewFile();
530                     }
531
532                     //write the byte array to the file
533
fos = new FileOutputStream JavaDoc(jarFileInTempDir);
534                     fos.write(outputArray, j, outputArray.length-j);
535                     fos.close();
536                 } else { //form data, not a file
537
multiPartBuffer = new StringBuffer JavaDoc(outputArray.length-j);
538                     for (int i = j; i < outputArray.length; i++) {
539                         multiPartBuffer.append((char)outputArray[i]);
540                     }
541                     
542                     this.formParams.put(
543                         fileName,
544                         multiPartBuffer.toString());
545                 }
546
547                 nextPart = multi.readBoundary();
548             } catch (MultipartStream.MalformedStreamException mse) {
549                 throw new IOException JavaDoc(mse.getMessage());
550             }
551         }
552     }
553
554     /**
555      * Parses the first one or two lines of a multipart. The usual headers are
556      * Content-Dispostion or Content-Type.
557      *
558      * @param header - the header string to be parsed
559      * @return a map of of header info and their values
560      */

561     private Map JavaDoc parseMultiPartHeader(StringBuffer JavaDoc headerBuffer) throws IOException JavaDoc {
562         Map JavaDoc headerMap = new HashMap JavaDoc();
563         int colonIndex = headerBuffer.toString().indexOf(":");
564         String JavaDoc headerName = headerBuffer.substring(0, colonIndex);
565         StringTokenizer JavaDoc headerValueToken =
566             new StringTokenizer JavaDoc(headerBuffer.substring(colonIndex + 1, headerBuffer.length()), ";");
567
568         String JavaDoc currentToken;
569         //loop through the tokens of semi-colon
570
while (headerValueToken.hasMoreTokens()) {
571             currentToken = headerValueToken.nextToken();
572             if (currentToken.indexOf("=") > -1) {
573                 headerMap.put(
574                     currentToken.substring(0, currentToken.indexOf("=")).trim(),
575                     currentToken
576                         .substring(currentToken.indexOf("=") + 2, currentToken.length() - 1)
577                         .trim());
578             } else {
579                 headerMap.put(headerName, currentToken.trim());
580             }
581         }
582
583         //first get rid of any path that might already be there then
584
//change the path of the file name to a temp directory
585
String JavaDoc fileName = (String JavaDoc) headerMap.get(FILENAME);
586         if (fileName != null) {
587             StringBuffer JavaDoc temp;
588             if (fileName.indexOf("\\") > -1) {
589                 temp = new StringBuffer JavaDoc(fileName).reverse();
590                 fileName = temp.delete(temp.toString().indexOf("\\"), temp.length()).reverse().toString();
591             }
592
593             temp = new StringBuffer JavaDoc();
594             temp.append(FileUtils.createTempDirectory().getAbsolutePath());
595             temp.append(System.getProperty("file.separator"));
596             temp.append(fileName);
597             headerMap.put(FILENAME, temp.toString());
598         }
599
600         return headerMap;
601     }
602
603     private HashMap JavaDoc cookies;
604     
605     protected HashMap JavaDoc getCookies(){
606         if (cookies != null) return cookies;
607         
608         cookies = new HashMap JavaDoc();
609
610         String JavaDoc cookieHeader = getHeader(HEADER_COOKIE);
611         if (cookieHeader == null ) return cookies;
612
613         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(cookieHeader, ";");
614         while (tokens.hasMoreTokens()){
615             StringTokenizer JavaDoc token = new StringTokenizer JavaDoc(tokens.nextToken(),"=");
616             String JavaDoc name = token.nextToken();
617             String JavaDoc value = token.nextToken();
618             cookies.put(name, value);
619         }
620         return cookies;
621     }
622
623     protected static final String JavaDoc EJBSESSIONID = "EJBSESSIONID";
624
625     protected String JavaDoc getCookie(String JavaDoc name){
626         return (String JavaDoc) getCookies().get(name);
627     }
628
629     public HttpSession getSession() {
630         return getSession(true);
631     }
632     
633     private WebSession session;
634     
635     public HttpSession getSession(boolean create) {
636         if (session != null) return session;
637         
638         String JavaDoc id = getCookie(EJBSESSIONID);
639         
640         if (id != null) {
641             session = (WebSession)sessions.get(id);
642         }
643         
644         if (session == null && create){
645             session = createSession();
646             sessions.put(session.getId(), session);
647         }
648         return session;
649     }
650     
651     private static final Hashtable JavaDoc sessions = new Hashtable JavaDoc();
652
653     private WebSession createSession(){
654         // Lookup/create sessions
655
WebSessionHome home = null;
656
657         try {
658             home = (WebSessionHome)new InitialContext JavaDoc().lookup("java:openejb/ejb/httpd/session");
659         } catch (NamingException JavaDoc e) {
660             // TODO Auto-generated catch block
661
throw new IllegalStateException JavaDoc("The WebSessionBean has not been deployed. "+
662                     " This is required for the HTTPd service to provide HttpSession support. "+
663                     e.getClass().getName()+": "+e.getMessage());
664         }
665
666         
667         WebSession session = null;
668         try {
669             session = home.create();
670         } catch (RemoteException JavaDoc e) {
671             // TODO Auto-generated catch block
672
e.printStackTrace();
673         }
674         // mark them as nocopy
675
Object JavaDoc obj = org.openejb.util.proxy.ProxyManager.getInvocationHandler(session);
676         StatefulEjbObjectHandler handler = (StatefulEjbObjectHandler) obj;
677         handler.setIntraVmCopyMode(false);
678         return session;
679     }
680 }
Popular Tags