Source Code Cross Referenced for HessianInput.java in  » EJB-Server-resin-3.1.5 » hessian » com » caucho » hessian » io » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server resin 3.1.5 » hessian » com.caucho.hessian.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
0003:         *
0004:         * The Apache Software License, Version 1.1
0005:         *
0006:         * Redistribution and use in source and binary forms, with or without
0007:         * modification, are permitted provided that the following conditions
0008:         * are met:
0009:         *
0010:         * 1. Redistributions of source code must retain the above copyright
0011:         *    notice, this list of conditions and the following disclaimer.
0012:         *
0013:         * 2. Redistributions in binary form must reproduce the above copyright
0014:         *    notice, this list of conditions and the following disclaimer in
0015:         *    the documentation and/or other materials provided with the
0016:         *    distribution.
0017:         *
0018:         * 3. The end-user documentation included with the redistribution, if
0019:         *    any, must include the following acknowlegement:
0020:         *       "This product includes software developed by the
0021:         *        Caucho Technology (http://www.caucho.com/)."
0022:         *    Alternately, this acknowlegement may appear in the software itself,
0023:         *    if and wherever such third-party acknowlegements normally appear.
0024:         *
0025:         * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
0026:         *    endorse or promote products derived from this software without prior
0027:         *    written permission. For written permission, please contact
0028:         *    info@caucho.com.
0029:         *
0030:         * 5. Products derived from this software may not be called "Resin"
0031:         *    nor may "Resin" appear in their names without prior written
0032:         *    permission of Caucho Technology.
0033:         *
0034:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0035:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0036:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0037:         * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
0038:         * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
0039:         * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
0040:         * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
0041:         * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
0042:         * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
0043:         * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
0044:         * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0045:         *
0046:         * @author Scott Ferguson
0047:         */
0048:
0049:        package com.caucho.hessian.io;
0050:
0051:        import java.io.ByteArrayOutputStream;
0052:        import java.io.IOException;
0053:        import java.io.InputStream;
0054:        import java.io.Reader;
0055:        import java.lang.reflect.Field;
0056:        import java.util.ArrayList;
0057:        import java.util.Date;
0058:        import java.util.HashMap;
0059:
0060:        /**
0061:         * Input stream for Hessian requests.
0062:         *
0063:         * <p>HessianInput is unbuffered, so any client needs to provide
0064:         * its own buffering.
0065:         *
0066:         * <pre>
0067:         * InputStream is = ...; // from http connection
0068:         * HessianInput in = new HessianInput(is);
0069:         * String value;
0070:         *
0071:         * in.startReply();         // read reply header
0072:         * value = in.readString(); // read string value
0073:         * in.completeReply();      // read reply footer
0074:         * </pre>
0075:         */
0076:        public class HessianInput extends AbstractHessianInput {
0077:            private static int END_OF_DATA = -2;
0078:
0079:            private static Field _detailMessageField;
0080:
0081:            // factory for deserializing objects in the input stream
0082:            protected SerializerFactory _serializerFactory;
0083:
0084:            protected ArrayList _refs;
0085:
0086:            // the underlying input stream
0087:            private InputStream _is;
0088:            // a peek character
0089:            protected int _peek = -1;
0090:
0091:            // the method for a call
0092:            private String _method;
0093:
0094:            private Reader _chunkReader;
0095:            private InputStream _chunkInputStream;
0096:
0097:            private Throwable _replyFault;
0098:
0099:            private StringBuffer _sbuf = new StringBuffer();
0100:
0101:            // true if this is the last chunk
0102:            private boolean _isLastChunk;
0103:            // the chunk length
0104:            private int _chunkLength;
0105:
0106:            /**
0107:             * Creates an uninitialized Hessian input stream.
0108:             */
0109:            public HessianInput() {
0110:            }
0111:
0112:            /**
0113:             * Creates a new Hessian input stream, initialized with an
0114:             * underlying input stream.
0115:             *
0116:             * @param is the underlying input stream.
0117:             */
0118:            public HessianInput(InputStream is) {
0119:                init(is);
0120:            }
0121:
0122:            /**
0123:             * Sets the serializer factory.
0124:             */
0125:            public void setSerializerFactory(SerializerFactory factory) {
0126:                _serializerFactory = factory;
0127:            }
0128:
0129:            /**
0130:             * Gets the serializer factory.
0131:             */
0132:            public SerializerFactory getSerializerFactory() {
0133:                return _serializerFactory;
0134:            }
0135:
0136:            /**
0137:             * Initialize the hessian stream with the underlying input stream.
0138:             */
0139:            public void init(InputStream is) {
0140:                _is = is;
0141:                _method = null;
0142:                _isLastChunk = true;
0143:                _chunkLength = 0;
0144:                _peek = -1;
0145:                _refs = null;
0146:                _replyFault = null;
0147:
0148:                if (_serializerFactory == null)
0149:                    _serializerFactory = new SerializerFactory();
0150:            }
0151:
0152:            /**
0153:             * Returns the calls method
0154:             */
0155:            public String getMethod() {
0156:                return _method;
0157:            }
0158:
0159:            /**
0160:             * Returns any reply fault.
0161:             */
0162:            public Throwable getReplyFault() {
0163:                return _replyFault;
0164:            }
0165:
0166:            /**
0167:             * Starts reading the call
0168:             *
0169:             * <pre>
0170:             * c major minor
0171:             * </pre>
0172:             */
0173:            public int readCall() throws IOException {
0174:                int tag = read();
0175:
0176:                if (tag != 'c')
0177:                    throw error("expected hessian call ('c') at "
0178:                            + codeName(tag));
0179:
0180:                int major = read();
0181:                int minor = read();
0182:
0183:                return (major << 16) + minor;
0184:            }
0185:
0186:            /**
0187:             * For backward compatibility with HessianSkeleton
0188:             */
0189:            public void skipOptionalCall() throws IOException {
0190:                int tag = read();
0191:
0192:                if (tag == 'c') {
0193:                    read();
0194:                    read();
0195:                } else
0196:                    _peek = tag;
0197:            }
0198:
0199:            /**
0200:             * Starts reading the call
0201:             *
0202:             * <p>A successful completion will have a single value:
0203:             *
0204:             * <pre>
0205:             * m b16 b8 method
0206:             * </pre>
0207:             */
0208:            public String readMethod() throws IOException {
0209:                int tag = read();
0210:
0211:                if (tag != 'm')
0212:                    throw error("expected hessian method ('m') at "
0213:                            + codeName(tag));
0214:                int d1 = read();
0215:                int d2 = read();
0216:
0217:                _isLastChunk = true;
0218:                _chunkLength = d1 * 256 + d2;
0219:                _sbuf.setLength(0);
0220:                int ch;
0221:                while ((ch = parseChar()) >= 0)
0222:                    _sbuf.append((char) ch);
0223:
0224:                _method = _sbuf.toString();
0225:
0226:                return _method;
0227:            }
0228:
0229:            /**
0230:             * Starts reading the call, including the headers.
0231:             *
0232:             * <p>The call expects the following protocol data
0233:             *
0234:             * <pre>
0235:             * c major minor
0236:             * m b16 b8 method
0237:             * </pre>
0238:             */
0239:            public void startCall() throws IOException {
0240:                readCall();
0241:
0242:                while (readHeader() != null) {
0243:                    readObject();
0244:                }
0245:
0246:                readMethod();
0247:            }
0248:
0249:            /**
0250:             * Completes reading the call
0251:             *
0252:             * <p>A successful completion will have a single value:
0253:             *
0254:             * <pre>
0255:             * z
0256:             * </pre>
0257:             */
0258:            public void completeCall() throws IOException {
0259:                int tag = read();
0260:
0261:                if (tag == 'z') {
0262:                } else
0263:                    throw error("expected end of call ('z') at "
0264:                            + codeName(tag)
0265:                            + ".  Check method arguments and ensure method overloading is enabled if necessary");
0266:            }
0267:
0268:            /**
0269:             * Reads a reply as an object.
0270:             * If the reply has a fault, throws the exception.
0271:             */
0272:            public Object readReply(Class expectedClass) throws Throwable {
0273:                int tag = read();
0274:
0275:                if (tag != 'r')
0276:                    error("expected hessian reply at " + codeName(tag));
0277:
0278:                int major = read();
0279:                int minor = read();
0280:
0281:                tag = read();
0282:                if (tag == 'f')
0283:                    throw prepareFault();
0284:                else {
0285:                    _peek = tag;
0286:
0287:                    Object value = readObject(expectedClass);
0288:
0289:                    completeValueReply();
0290:
0291:                    return value;
0292:                }
0293:            }
0294:
0295:            /**
0296:             * Starts reading the reply
0297:             *
0298:             * <p>A successful completion will have a single value:
0299:             *
0300:             * <pre>
0301:             * r
0302:             * </pre>
0303:             */
0304:            public void startReply() throws Throwable {
0305:                int tag = read();
0306:
0307:                if (tag != 'r')
0308:                    error("expected hessian reply at " + codeName(tag));
0309:
0310:                int major = read();
0311:                int minor = read();
0312:
0313:                tag = read();
0314:                if (tag == 'f')
0315:                    throw prepareFault();
0316:                else
0317:                    _peek = tag;
0318:            }
0319:
0320:            /**
0321:             * Prepares the fault.
0322:             */
0323:            private Throwable prepareFault() throws IOException {
0324:                HashMap fault = readFault();
0325:
0326:                Object detail = fault.get("detail");
0327:                String message = (String) fault.get("message");
0328:
0329:                if (detail instanceof  Throwable) {
0330:                    _replyFault = (Throwable) detail;
0331:
0332:                    if (message != null && _detailMessageField != null) {
0333:                        try {
0334:                            _detailMessageField.set(_replyFault, message);
0335:                        } catch (Throwable e) {
0336:                        }
0337:                    }
0338:
0339:                    return _replyFault;
0340:                }
0341:
0342:                else {
0343:                    String code = (String) fault.get("code");
0344:
0345:                    _replyFault = new HessianServiceException(message, code,
0346:                            detail);
0347:
0348:                    return _replyFault;
0349:                }
0350:            }
0351:
0352:            /**
0353:             * Completes reading the call
0354:             *
0355:             * <p>A successful completion will have a single value:
0356:             *
0357:             * <pre>
0358:             * z
0359:             * </pre>
0360:             */
0361:            public void completeReply() throws IOException {
0362:                int tag = read();
0363:
0364:                if (tag != 'z')
0365:                    error("expected end of reply at " + codeName(tag));
0366:            }
0367:
0368:            /**
0369:             * Completes reading the call
0370:             *
0371:             * <p>A successful completion will have a single value:
0372:             *
0373:             * <pre>
0374:             * z
0375:             * </pre>
0376:             */
0377:            public void completeValueReply() throws IOException {
0378:                int tag = read();
0379:
0380:                if (tag != 'z')
0381:                    error("expected end of reply at " + codeName(tag));
0382:            }
0383:
0384:            /**
0385:             * Reads a header, returning null if there are no headers.
0386:             *
0387:             * <pre>
0388:             * H b16 b8 value
0389:             * </pre>
0390:             */
0391:            public String readHeader() throws IOException {
0392:                int tag = read();
0393:
0394:                if (tag == 'H') {
0395:                    _isLastChunk = true;
0396:                    _chunkLength = (read() << 8) + read();
0397:
0398:                    _sbuf.setLength(0);
0399:                    int ch;
0400:                    while ((ch = parseChar()) >= 0)
0401:                        _sbuf.append((char) ch);
0402:
0403:                    return _sbuf.toString();
0404:                }
0405:
0406:                _peek = tag;
0407:
0408:                return null;
0409:            }
0410:
0411:            /**
0412:             * Reads a null
0413:             *
0414:             * <pre>
0415:             * N
0416:             * </pre>
0417:             */
0418:            public void readNull() throws IOException {
0419:                int tag = read();
0420:
0421:                switch (tag) {
0422:                case 'N':
0423:                    return;
0424:
0425:                default:
0426:                    throw expect("null", tag);
0427:                }
0428:            }
0429:
0430:            /**
0431:             * Reads a boolean
0432:             *
0433:             * <pre>
0434:             * T
0435:             * F
0436:             * </pre>
0437:             */
0438:            public boolean readBoolean() throws IOException {
0439:                int tag = read();
0440:
0441:                switch (tag) {
0442:                case 'T':
0443:                    return true;
0444:                case 'F':
0445:                    return false;
0446:                case 'I':
0447:                    return parseInt() == 0;
0448:                case 'L':
0449:                    return parseLong() == 0;
0450:                case 'D':
0451:                    return parseDouble() == 0.0;
0452:                case 'N':
0453:                    return false;
0454:
0455:                default:
0456:                    throw expect("boolean", tag);
0457:                }
0458:            }
0459:
0460:            /**
0461:             * Reads a byte
0462:             *
0463:             * <pre>
0464:             * I b32 b24 b16 b8
0465:             * </pre>
0466:             */
0467:            /*
0468:            public byte readByte()
0469:              throws IOException
0470:            {
0471:              return (byte) readInt();
0472:            }
0473:             */
0474:
0475:            /**
0476:             * Reads a short
0477:             *
0478:             * <pre>
0479:             * I b32 b24 b16 b8
0480:             * </pre>
0481:             */
0482:            public short readShort() throws IOException {
0483:                return (short) readInt();
0484:            }
0485:
0486:            /**
0487:             * Reads an integer
0488:             *
0489:             * <pre>
0490:             * I b32 b24 b16 b8
0491:             * </pre>
0492:             */
0493:            public int readInt() throws IOException {
0494:                int tag = read();
0495:
0496:                switch (tag) {
0497:                case 'T':
0498:                    return 1;
0499:                case 'F':
0500:                    return 0;
0501:                case 'I':
0502:                    return parseInt();
0503:                case 'L':
0504:                    return (int) parseLong();
0505:                case 'D':
0506:                    return (int) parseDouble();
0507:
0508:                default:
0509:                    throw expect("int", tag);
0510:                }
0511:            }
0512:
0513:            /**
0514:             * Reads a long
0515:             *
0516:             * <pre>
0517:             * L b64 b56 b48 b40 b32 b24 b16 b8
0518:             * </pre>
0519:             */
0520:            public long readLong() throws IOException {
0521:                int tag = read();
0522:
0523:                switch (tag) {
0524:                case 'T':
0525:                    return 1;
0526:                case 'F':
0527:                    return 0;
0528:                case 'I':
0529:                    return parseInt();
0530:                case 'L':
0531:                    return parseLong();
0532:                case 'D':
0533:                    return (long) parseDouble();
0534:
0535:                default:
0536:                    throw expect("long", tag);
0537:                }
0538:            }
0539:
0540:            /**
0541:             * Reads a float
0542:             *
0543:             * <pre>
0544:             * D b64 b56 b48 b40 b32 b24 b16 b8
0545:             * </pre>
0546:             */
0547:            public float readFloat() throws IOException {
0548:                return (float) readDouble();
0549:            }
0550:
0551:            /**
0552:             * Reads a double
0553:             *
0554:             * <pre>
0555:             * D b64 b56 b48 b40 b32 b24 b16 b8
0556:             * </pre>
0557:             */
0558:            public double readDouble() throws IOException {
0559:                int tag = read();
0560:
0561:                switch (tag) {
0562:                case 'T':
0563:                    return 1;
0564:                case 'F':
0565:                    return 0;
0566:                case 'I':
0567:                    return parseInt();
0568:                case 'L':
0569:                    return (double) parseLong();
0570:                case 'D':
0571:                    return parseDouble();
0572:
0573:                default:
0574:                    throw expect("long", tag);
0575:                }
0576:            }
0577:
0578:            /**
0579:             * Reads a date.
0580:             *
0581:             * <pre>
0582:             * T b64 b56 b48 b40 b32 b24 b16 b8
0583:             * </pre>
0584:             */
0585:            public long readUTCDate() throws IOException {
0586:                int tag = read();
0587:
0588:                if (tag != 'd')
0589:                    throw error("expected date at " + codeName(tag));
0590:
0591:                long b64 = read();
0592:                long b56 = read();
0593:                long b48 = read();
0594:                long b40 = read();
0595:                long b32 = read();
0596:                long b24 = read();
0597:                long b16 = read();
0598:                long b8 = read();
0599:
0600:                return ((b64 << 56) + (b56 << 48) + (b48 << 40) + (b40 << 32)
0601:                        + (b32 << 24) + (b24 << 16) + (b16 << 8) + b8);
0602:            }
0603:
0604:            /**
0605:             * Reads a byte from the stream.
0606:             */
0607:            public int readChar() throws IOException {
0608:                if (_chunkLength > 0) {
0609:                    _chunkLength--;
0610:                    if (_chunkLength == 0 && _isLastChunk)
0611:                        _chunkLength = END_OF_DATA;
0612:
0613:                    int ch = parseUTF8Char();
0614:                    return ch;
0615:                } else if (_chunkLength == END_OF_DATA) {
0616:                    _chunkLength = 0;
0617:                    return -1;
0618:                }
0619:
0620:                int tag = read();
0621:
0622:                switch (tag) {
0623:                case 'N':
0624:                    return -1;
0625:
0626:                case 'S':
0627:                case 's':
0628:                case 'X':
0629:                case 'x':
0630:                    _isLastChunk = tag == 'S' || tag == 'X';
0631:                    _chunkLength = (read() << 8) + read();
0632:
0633:                    _chunkLength--;
0634:                    int value = parseUTF8Char();
0635:
0636:                    // special code so successive read byte won't
0637:                    // be read as a single object.
0638:                    if (_chunkLength == 0 && _isLastChunk)
0639:                        _chunkLength = END_OF_DATA;
0640:
0641:                    return value;
0642:
0643:                default:
0644:                    throw new IOException("expected 'S' at " + (char) tag);
0645:                }
0646:            }
0647:
0648:            /**
0649:             * Reads a byte array from the stream.
0650:             */
0651:            public int readString(char[] buffer, int offset, int length)
0652:                    throws IOException {
0653:                int readLength = 0;
0654:
0655:                if (_chunkLength == END_OF_DATA) {
0656:                    _chunkLength = 0;
0657:                    return -1;
0658:                } else if (_chunkLength == 0) {
0659:                    int tag = read();
0660:
0661:                    switch (tag) {
0662:                    case 'N':
0663:                        return -1;
0664:
0665:                    case 'S':
0666:                    case 's':
0667:                    case 'X':
0668:                    case 'x':
0669:                        _isLastChunk = tag == 'S' || tag == 'X';
0670:                        _chunkLength = (read() << 8) + read();
0671:                        break;
0672:
0673:                    default:
0674:                        throw new IOException("expected 'S' at " + (char) tag);
0675:                    }
0676:                }
0677:
0678:                while (length > 0) {
0679:                    if (_chunkLength > 0) {
0680:                        buffer[offset++] = (char) parseUTF8Char();
0681:                        _chunkLength--;
0682:                        length--;
0683:                        readLength++;
0684:                    } else if (_isLastChunk) {
0685:                        if (readLength == 0)
0686:                            return -1;
0687:                        else {
0688:                            _chunkLength = END_OF_DATA;
0689:                            return readLength;
0690:                        }
0691:                    } else {
0692:                        int tag = read();
0693:
0694:                        switch (tag) {
0695:                        case 'S':
0696:                        case 's':
0697:                        case 'X':
0698:                        case 'x':
0699:                            _isLastChunk = tag == 'S' || tag == 'X';
0700:                            _chunkLength = (read() << 8) + read();
0701:                            break;
0702:
0703:                        default:
0704:                            throw new IOException("expected 'S' at "
0705:                                    + (char) tag);
0706:                        }
0707:                    }
0708:                }
0709:
0710:                if (readLength == 0)
0711:                    return -1;
0712:                else if (_chunkLength > 0 || !_isLastChunk)
0713:                    return readLength;
0714:                else {
0715:                    _chunkLength = END_OF_DATA;
0716:                    return readLength;
0717:                }
0718:            }
0719:
0720:            /**
0721:             * Reads a string
0722:             *
0723:             * <pre>
0724:             * S b16 b8 string value
0725:             * </pre>
0726:             */
0727:            public String readString() throws IOException {
0728:                int tag = read();
0729:
0730:                switch (tag) {
0731:                case 'N':
0732:                    return null;
0733:
0734:                case 'I':
0735:                    return String.valueOf(parseInt());
0736:                case 'L':
0737:                    return String.valueOf(parseLong());
0738:                case 'D':
0739:                    return String.valueOf(parseDouble());
0740:
0741:                case 'S':
0742:                case 's':
0743:                case 'X':
0744:                case 'x':
0745:                    _isLastChunk = tag == 'S' || tag == 'X';
0746:                    _chunkLength = (read() << 8) + read();
0747:
0748:                    _sbuf.setLength(0);
0749:                    int ch;
0750:
0751:                    while ((ch = parseChar()) >= 0)
0752:                        _sbuf.append((char) ch);
0753:
0754:                    return _sbuf.toString();
0755:
0756:                default:
0757:                    throw expect("string", tag);
0758:                }
0759:            }
0760:
0761:            /**
0762:             * Reads an XML node.
0763:             *
0764:             * <pre>
0765:             * S b16 b8 string value
0766:             * </pre>
0767:             */
0768:            public org.w3c.dom.Node readNode() throws IOException {
0769:                int tag = read();
0770:
0771:                switch (tag) {
0772:                case 'N':
0773:                    return null;
0774:
0775:                case 'S':
0776:                case 's':
0777:                case 'X':
0778:                case 'x':
0779:                    _isLastChunk = tag == 'S' || tag == 'X';
0780:                    _chunkLength = (read() << 8) + read();
0781:
0782:                    throw error("Can't handle string in this context");
0783:
0784:                default:
0785:                    throw expect("string", tag);
0786:                }
0787:            }
0788:
0789:            /**
0790:             * Reads a byte array
0791:             *
0792:             * <pre>
0793:             * B b16 b8 data value
0794:             * </pre>
0795:             */
0796:            public byte[] readBytes() throws IOException {
0797:                int tag = read();
0798:
0799:                switch (tag) {
0800:                case 'N':
0801:                    return null;
0802:
0803:                case 'B':
0804:                case 'b':
0805:                    _isLastChunk = tag == 'B';
0806:                    _chunkLength = (read() << 8) + read();
0807:
0808:                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
0809:
0810:                    int data;
0811:                    while ((data = parseByte()) >= 0)
0812:                        bos.write(data);
0813:
0814:                    return bos.toByteArray();
0815:
0816:                default:
0817:                    throw expect("bytes", tag);
0818:                }
0819:            }
0820:
0821:            /**
0822:             * Reads a byte from the stream.
0823:             */
0824:            public int readByte() throws IOException {
0825:                if (_chunkLength > 0) {
0826:                    _chunkLength--;
0827:                    if (_chunkLength == 0 && _isLastChunk)
0828:                        _chunkLength = END_OF_DATA;
0829:
0830:                    return read();
0831:                } else if (_chunkLength == END_OF_DATA) {
0832:                    _chunkLength = 0;
0833:                    return -1;
0834:                }
0835:
0836:                int tag = read();
0837:
0838:                switch (tag) {
0839:                case 'N':
0840:                    return -1;
0841:
0842:                case 'B':
0843:                case 'b':
0844:                    _isLastChunk = tag == 'B';
0845:                    _chunkLength = (read() << 8) + read();
0846:
0847:                    int value = parseByte();
0848:
0849:                    // special code so successive read byte won't
0850:                    // be read as a single object.
0851:                    if (_chunkLength == 0 && _isLastChunk)
0852:                        _chunkLength = END_OF_DATA;
0853:
0854:                    return value;
0855:
0856:                default:
0857:                    throw new IOException("expected 'B' at " + (char) tag);
0858:                }
0859:            }
0860:
0861:            /**
0862:             * Reads a byte array from the stream.
0863:             */
0864:            public int readBytes(byte[] buffer, int offset, int length)
0865:                    throws IOException {
0866:                int readLength = 0;
0867:
0868:                if (_chunkLength == END_OF_DATA) {
0869:                    _chunkLength = 0;
0870:                    return -1;
0871:                } else if (_chunkLength == 0) {
0872:                    int tag = read();
0873:
0874:                    switch (tag) {
0875:                    case 'N':
0876:                        return -1;
0877:
0878:                    case 'B':
0879:                    case 'b':
0880:                        _isLastChunk = tag == 'B';
0881:                        _chunkLength = (read() << 8) + read();
0882:                        break;
0883:
0884:                    default:
0885:                        throw new IOException("expected 'B' at " + (char) tag);
0886:                    }
0887:                }
0888:
0889:                while (length > 0) {
0890:                    if (_chunkLength > 0) {
0891:                        buffer[offset++] = (byte) read();
0892:                        _chunkLength--;
0893:                        length--;
0894:                        readLength++;
0895:                    } else if (_isLastChunk) {
0896:                        if (readLength == 0)
0897:                            return -1;
0898:                        else {
0899:                            _chunkLength = END_OF_DATA;
0900:                            return readLength;
0901:                        }
0902:                    } else {
0903:                        int tag = read();
0904:
0905:                        switch (tag) {
0906:                        case 'B':
0907:                        case 'b':
0908:                            _isLastChunk = tag == 'B';
0909:                            _chunkLength = (read() << 8) + read();
0910:                            break;
0911:
0912:                        default:
0913:                            throw new IOException("expected 'B' at "
0914:                                    + (char) tag);
0915:                        }
0916:                    }
0917:                }
0918:
0919:                if (readLength == 0)
0920:                    return -1;
0921:                else if (_chunkLength > 0 || !_isLastChunk)
0922:                    return readLength;
0923:                else {
0924:                    _chunkLength = END_OF_DATA;
0925:                    return readLength;
0926:                }
0927:            }
0928:
0929:            /**
0930:             * Reads a fault.
0931:             */
0932:            private HashMap readFault() throws IOException {
0933:                HashMap map = new HashMap();
0934:
0935:                int code = read();
0936:                for (; code > 0 && code != 'z'; code = read()) {
0937:                    _peek = code;
0938:
0939:                    Object key = readObject();
0940:                    Object value = readObject();
0941:
0942:                    if (key != null && value != null)
0943:                        map.put(key, value);
0944:                }
0945:
0946:                if (code != 'z')
0947:                    throw expect("fault", code);
0948:
0949:                return map;
0950:            }
0951:
0952:            /**
0953:             * Reads an object from the input stream with an expected type.
0954:             */
0955:            public Object readObject(Class cl) throws IOException {
0956:                if (cl == null || cl == Object.class)
0957:                    return readObject();
0958:
0959:                int tag = read();
0960:
0961:                switch (tag) {
0962:                case 'N':
0963:                    return null;
0964:
0965:                case 'M': {
0966:                    String type = readType();
0967:
0968:                    // hessian/3386
0969:                    if ("".equals(type)) {
0970:                        Deserializer reader;
0971:                        reader = _serializerFactory.getDeserializer(cl);
0972:
0973:                        return reader.readMap(this );
0974:                    } else {
0975:                        Deserializer reader;
0976:                        reader = _serializerFactory.getObjectDeserializer(type);
0977:
0978:                        return reader.readMap(this );
0979:                    }
0980:                }
0981:
0982:                case 'V': {
0983:                    String type = readType();
0984:                    int length = readLength();
0985:
0986:                    Deserializer reader;
0987:                    reader = _serializerFactory.getObjectDeserializer(type);
0988:
0989:                    if (cl != reader.getType()
0990:                            && cl.isAssignableFrom(reader.getType()))
0991:                        return reader.readList(this , length);
0992:
0993:                    reader = _serializerFactory.getDeserializer(cl);
0994:
0995:                    Object v = reader.readList(this , length);
0996:
0997:                    return v;
0998:                }
0999:
1000:                case 'R': {
1001:                    int ref = parseInt();
1002:
1003:                    return _refs.get(ref);
1004:                }
1005:
1006:                case 'r': {
1007:                    String type = readType();
1008:                    String url = readString();
1009:
1010:                    return resolveRemote(type, url);
1011:                }
1012:                }
1013:
1014:                _peek = tag;
1015:
1016:                // hessian/332i vs hessian/3406
1017:                //return readObject();
1018:
1019:                Object value = _serializerFactory.getDeserializer(cl)
1020:                        .readObject(this );
1021:
1022:                return value;
1023:            }
1024:
1025:            /**
1026:             * Reads an arbitrary object from the input stream when the type
1027:             * is unknown.
1028:             */
1029:            public Object readObject() throws IOException {
1030:                int tag = read();
1031:
1032:                switch (tag) {
1033:                case 'N':
1034:                    return null;
1035:
1036:                case 'T':
1037:                    return Boolean.valueOf(true);
1038:
1039:                case 'F':
1040:                    return Boolean.valueOf(false);
1041:
1042:                case 'I':
1043:                    return Integer.valueOf(parseInt());
1044:
1045:                case 'L':
1046:                    return Long.valueOf(parseLong());
1047:
1048:                case 'D':
1049:                    return Double.valueOf(parseDouble());
1050:
1051:                case 'd':
1052:                    return new Date(parseLong());
1053:
1054:                case 'x':
1055:                case 'X': {
1056:                    _isLastChunk = tag == 'X';
1057:                    _chunkLength = (read() << 8) + read();
1058:
1059:                    return parseXML();
1060:                }
1061:
1062:                case 's':
1063:                case 'S': {
1064:                    _isLastChunk = tag == 'S';
1065:                    _chunkLength = (read() << 8) + read();
1066:
1067:                    int data;
1068:                    _sbuf.setLength(0);
1069:
1070:                    while ((data = parseChar()) >= 0)
1071:                        _sbuf.append((char) data);
1072:
1073:                    return _sbuf.toString();
1074:                }
1075:
1076:                case 'b':
1077:                case 'B': {
1078:                    _isLastChunk = tag == 'B';
1079:                    _chunkLength = (read() << 8) + read();
1080:
1081:                    int data;
1082:                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
1083:
1084:                    while ((data = parseByte()) >= 0)
1085:                        bos.write(data);
1086:
1087:                    return bos.toByteArray();
1088:                }
1089:
1090:                case 'V': {
1091:                    String type = readType();
1092:                    int length = readLength();
1093:
1094:                    return _serializerFactory.readList(this , length, type);
1095:                }
1096:
1097:                case 'M': {
1098:                    String type = readType();
1099:
1100:                    return _serializerFactory.readMap(this , type);
1101:                }
1102:
1103:                case 'R': {
1104:                    int ref = parseInt();
1105:
1106:                    return _refs.get(ref);
1107:                }
1108:
1109:                case 'r': {
1110:                    String type = readType();
1111:                    String url = readString();
1112:
1113:                    return resolveRemote(type, url);
1114:                }
1115:
1116:                default:
1117:                    throw error("unknown code for readObject at "
1118:                            + codeName(tag));
1119:                }
1120:            }
1121:
1122:            /**
1123:             * Reads a remote object.
1124:             */
1125:            public Object readRemote() throws IOException {
1126:                String type = readType();
1127:                String url = readString();
1128:
1129:                return resolveRemote(type, url);
1130:            }
1131:
1132:            /**
1133:             * Reads a reference.
1134:             */
1135:            public Object readRef() throws IOException {
1136:                return _refs.get(parseInt());
1137:            }
1138:
1139:            /**
1140:             * Reads the start of a list.
1141:             */
1142:            public int readListStart() throws IOException {
1143:                return read();
1144:            }
1145:
1146:            /**
1147:             * Reads the start of a list.
1148:             */
1149:            public int readMapStart() throws IOException {
1150:                return read();
1151:            }
1152:
1153:            /**
1154:             * Returns true if this is the end of a list or a map.
1155:             */
1156:            public boolean isEnd() throws IOException {
1157:                int code = read();
1158:
1159:                _peek = code;
1160:
1161:                return (code < 0 || code == 'z');
1162:            }
1163:
1164:            /**
1165:             * Reads the end byte.
1166:             */
1167:            public void readEnd() throws IOException {
1168:                int code = read();
1169:
1170:                if (code != 'z')
1171:                    throw error("unknown code at " + codeName(code));
1172:            }
1173:
1174:            /**
1175:             * Reads the end byte.
1176:             */
1177:            public void readMapEnd() throws IOException {
1178:                int code = read();
1179:
1180:                if (code != 'z')
1181:                    throw error("expected end of map ('z') at "
1182:                            + codeName(code));
1183:            }
1184:
1185:            /**
1186:             * Reads the end byte.
1187:             */
1188:            public void readListEnd() throws IOException {
1189:                int code = read();
1190:
1191:                if (code != 'z')
1192:                    throw error("expected end of list ('z') at "
1193:                            + codeName(code));
1194:            }
1195:
1196:            /**
1197:             * Adds a list/map reference.
1198:             */
1199:            public int addRef(Object ref) {
1200:                if (_refs == null)
1201:                    _refs = new ArrayList();
1202:
1203:                _refs.add(ref);
1204:
1205:                return _refs.size() - 1;
1206:            }
1207:
1208:            /**
1209:             * Adds a list/map reference.
1210:             */
1211:            public void setRef(int i, Object ref) {
1212:                _refs.set(i, ref);
1213:            }
1214:
1215:            /**
1216:             * Resets the references for streaming.
1217:             */
1218:            public void resetReferences() {
1219:                if (_refs != null)
1220:                    _refs.clear();
1221:            }
1222:
1223:            /**
1224:             * Resolves a remote object.
1225:             */
1226:            public Object resolveRemote(String type, String url)
1227:                    throws IOException {
1228:                HessianRemoteResolver resolver = getRemoteResolver();
1229:
1230:                if (resolver != null)
1231:                    return resolver.lookup(type, url);
1232:                else
1233:                    return new HessianRemote(type, url);
1234:            }
1235:
1236:            /**
1237:             * Parses a type from the stream.
1238:             *
1239:             * <pre>
1240:             * t b16 b8
1241:             * </pre>
1242:             */
1243:            public String readType() throws IOException {
1244:                int code = read();
1245:
1246:                if (code != 't') {
1247:                    _peek = code;
1248:                    return "";
1249:                }
1250:
1251:                _isLastChunk = true;
1252:                _chunkLength = (read() << 8) + read();
1253:
1254:                _sbuf.setLength(0);
1255:                int ch;
1256:                while ((ch = parseChar()) >= 0)
1257:                    _sbuf.append((char) ch);
1258:
1259:                return _sbuf.toString();
1260:            }
1261:
1262:            /**
1263:             * Parses the length for an array
1264:             *
1265:             * <pre>
1266:             * l b32 b24 b16 b8
1267:             * </pre>
1268:             */
1269:            public int readLength() throws IOException {
1270:                int code = read();
1271:
1272:                if (code != 'l') {
1273:                    _peek = code;
1274:                    return -1;
1275:                }
1276:
1277:                return parseInt();
1278:            }
1279:
1280:            /**
1281:             * Parses a 32-bit integer value from the stream.
1282:             *
1283:             * <pre>
1284:             * b32 b24 b16 b8
1285:             * </pre>
1286:             */
1287:            private int parseInt() throws IOException {
1288:                int b32 = read();
1289:                int b24 = read();
1290:                int b16 = read();
1291:                int b8 = read();
1292:
1293:                return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
1294:            }
1295:
1296:            /**
1297:             * Parses a 64-bit long value from the stream.
1298:             *
1299:             * <pre>
1300:             * b64 b56 b48 b40 b32 b24 b16 b8
1301:             * </pre>
1302:             */
1303:            private long parseLong() throws IOException {
1304:                long b64 = read();
1305:                long b56 = read();
1306:                long b48 = read();
1307:                long b40 = read();
1308:                long b32 = read();
1309:                long b24 = read();
1310:                long b16 = read();
1311:                long b8 = read();
1312:
1313:                return ((b64 << 56) + (b56 << 48) + (b48 << 40) + (b40 << 32)
1314:                        + (b32 << 24) + (b24 << 16) + (b16 << 8) + b8);
1315:            }
1316:
1317:            /**
1318:             * Parses a 64-bit double value from the stream.
1319:             *
1320:             * <pre>
1321:             * b64 b56 b48 b40 b32 b24 b16 b8
1322:             * </pre>
1323:             */
1324:            private double parseDouble() throws IOException {
1325:                long b64 = read();
1326:                long b56 = read();
1327:                long b48 = read();
1328:                long b40 = read();
1329:                long b32 = read();
1330:                long b24 = read();
1331:                long b16 = read();
1332:                long b8 = read();
1333:
1334:                long bits = ((b64 << 56) + (b56 << 48) + (b48 << 40)
1335:                        + (b40 << 32) + (b32 << 24) + (b24 << 16) + (b16 << 8) + b8);
1336:
1337:                return Double.longBitsToDouble(bits);
1338:            }
1339:
1340:            org.w3c.dom.Node parseXML() throws IOException {
1341:                throw new UnsupportedOperationException();
1342:            }
1343:
1344:            /**
1345:             * Reads a character from the underlying stream.
1346:             */
1347:            private int parseChar() throws IOException {
1348:                while (_chunkLength <= 0) {
1349:                    if (_isLastChunk)
1350:                        return -1;
1351:
1352:                    int code = read();
1353:
1354:                    switch (code) {
1355:                    case 's':
1356:                    case 'x':
1357:                        _isLastChunk = false;
1358:
1359:                        _chunkLength = (read() << 8) + read();
1360:                        break;
1361:
1362:                    case 'S':
1363:                    case 'X':
1364:                        _isLastChunk = true;
1365:
1366:                        _chunkLength = (read() << 8) + read();
1367:                        break;
1368:
1369:                    default:
1370:                        throw expect("string", code);
1371:                    }
1372:
1373:                }
1374:
1375:                _chunkLength--;
1376:
1377:                return parseUTF8Char();
1378:            }
1379:
1380:            /**
1381:             * Parses a single UTF8 character.
1382:             */
1383:            private int parseUTF8Char() throws IOException {
1384:                int ch = read();
1385:
1386:                if (ch < 0x80)
1387:                    return ch;
1388:                else if ((ch & 0xe0) == 0xc0) {
1389:                    int ch1 = read();
1390:                    int v = ((ch & 0x1f) << 6) + (ch1 & 0x3f);
1391:
1392:                    return v;
1393:                } else if ((ch & 0xf0) == 0xe0) {
1394:                    int ch1 = read();
1395:                    int ch2 = read();
1396:                    int v = ((ch & 0x0f) << 12) + ((ch1 & 0x3f) << 6)
1397:                            + (ch2 & 0x3f);
1398:
1399:                    return v;
1400:                } else
1401:                    throw error("bad utf-8 encoding at " + codeName(ch));
1402:            }
1403:
1404:            /**
1405:             * Reads a byte from the underlying stream.
1406:             */
1407:            private int parseByte() throws IOException {
1408:                while (_chunkLength <= 0) {
1409:                    if (_isLastChunk) {
1410:                        return -1;
1411:                    }
1412:
1413:                    int code = read();
1414:
1415:                    switch (code) {
1416:                    case 'b':
1417:                        _isLastChunk = false;
1418:
1419:                        _chunkLength = (read() << 8) + read();
1420:                        break;
1421:
1422:                    case 'B':
1423:                        _isLastChunk = true;
1424:
1425:                        _chunkLength = (read() << 8) + read();
1426:                        break;
1427:
1428:                    default:
1429:                        throw expect("byte[]", code);
1430:                    }
1431:                }
1432:
1433:                _chunkLength--;
1434:
1435:                return read();
1436:            }
1437:
1438:            /**
1439:             * Reads bytes based on an input stream.
1440:             */
1441:            public InputStream readInputStream() throws IOException {
1442:                int tag = read();
1443:
1444:                switch (tag) {
1445:                case 'N':
1446:                    return null;
1447:
1448:                case 'B':
1449:                case 'b':
1450:                    _isLastChunk = tag == 'B';
1451:                    _chunkLength = (read() << 8) + read();
1452:                    break;
1453:
1454:                default:
1455:                    throw expect("inputStream", tag);
1456:                }
1457:
1458:                return new InputStream() {
1459:                    boolean _isClosed = false;
1460:
1461:                    public int read() throws IOException {
1462:                        if (_isClosed || _is == null)
1463:                            return -1;
1464:
1465:                        int ch = parseByte();
1466:                        if (ch < 0)
1467:                            _isClosed = true;
1468:
1469:                        return ch;
1470:                    }
1471:
1472:                    public int read(byte[] buffer, int offset, int length)
1473:                            throws IOException {
1474:                        if (_isClosed || _is == null)
1475:                            return -1;
1476:
1477:                        int len = HessianInput.this 
1478:                                .read(buffer, offset, length);
1479:                        if (len < 0)
1480:                            _isClosed = true;
1481:
1482:                        return len;
1483:                    }
1484:
1485:                    public void close() throws IOException {
1486:                        while (read() >= 0) {
1487:                        }
1488:
1489:                        _isClosed = true;
1490:                    }
1491:                };
1492:            }
1493:
1494:            /**
1495:             * Reads bytes from the underlying stream.
1496:             */
1497:            int read(byte[] buffer, int offset, int length) throws IOException {
1498:                int readLength = 0;
1499:
1500:                while (length > 0) {
1501:                    while (_chunkLength <= 0) {
1502:                        if (_isLastChunk)
1503:                            return readLength == 0 ? -1 : readLength;
1504:
1505:                        int code = read();
1506:
1507:                        switch (code) {
1508:                        case 'b':
1509:                            _isLastChunk = false;
1510:
1511:                            _chunkLength = (read() << 8) + read();
1512:                            break;
1513:
1514:                        case 'B':
1515:                            _isLastChunk = true;
1516:
1517:                            _chunkLength = (read() << 8) + read();
1518:                            break;
1519:
1520:                        default:
1521:                            throw expect("byte[]", code);
1522:                        }
1523:                    }
1524:
1525:                    int sublen = _chunkLength;
1526:                    if (length < sublen)
1527:                        sublen = length;
1528:
1529:                    sublen = _is.read(buffer, offset, sublen);
1530:                    offset += sublen;
1531:                    readLength += sublen;
1532:                    length -= sublen;
1533:                    _chunkLength -= sublen;
1534:                }
1535:
1536:                return readLength;
1537:            }
1538:
1539:            final int read() throws IOException {
1540:                if (_peek >= 0) {
1541:                    int value = _peek;
1542:                    _peek = -1;
1543:                    return value;
1544:                }
1545:
1546:                int ch = _is.read();
1547:
1548:                return ch;
1549:            }
1550:
1551:            public void close() {
1552:                _is = null;
1553:            }
1554:
1555:            public Reader getReader() {
1556:                return null;
1557:            }
1558:
1559:            protected IOException expect(String expect, int ch) {
1560:                return error("expected " + expect + " at " + codeName(ch));
1561:            }
1562:
1563:            protected String codeName(int ch) {
1564:                if (ch < 0)
1565:                    return "end of file";
1566:                else
1567:                    return "0x" + Integer.toHexString(ch & 0xff) + " ("
1568:                            + (char) +ch + ")";
1569:            }
1570:
1571:            protected IOException error(String message) {
1572:                if (_method != null)
1573:                    return new HessianProtocolException(_method + ": "
1574:                            + message);
1575:                else
1576:                    return new HessianProtocolException(message);
1577:            }
1578:
1579:            static {
1580:                try {
1581:                    _detailMessageField = Throwable.class
1582:                            .getDeclaredField("detailMessage");
1583:                    _detailMessageField.setAccessible(true);
1584:                } catch (Throwable e) {
1585:                }
1586:            }
1587:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.