Source Code Cross Referenced for XMLMessage.java in  » 6.0-JDK-Modules-com.sun » xml » com » sun » xml » internal » ws » encoding » xml » 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 » 6.0 JDK Modules com.sun » xml » com.sun.xml.internal.ws.encoding.xml 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Portions Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package com.sun.xml.internal.ws.encoding.xml;
0027:
0028:        import com.sun.xml.internal.messaging.saaj.packaging.mime.MessagingException;
0029:        import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.ContentType;
0030:        import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.InternetHeaders;
0031:        import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeBodyPart;
0032:        import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeMultipart;
0033:        import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
0034:        import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
0035:        import com.sun.xml.internal.ws.encoding.jaxb.JAXBTypeSerializer;
0036:        import com.sun.xml.internal.ws.protocol.xml.XMLMessageException;
0037:        import com.sun.xml.internal.ws.spi.runtime.WSConnection;
0038:        import com.sun.xml.internal.ws.streaming.XMLStreamWriterFactory;
0039:        import com.sun.xml.internal.ws.util.ByteArrayBuffer;
0040:        import com.sun.xml.internal.ws.util.FastInfosetReflection;
0041:        import com.sun.xml.internal.ws.util.FastInfosetUtil;
0042:        import com.sun.xml.internal.ws.util.xml.XmlUtil;
0043:        import java.io.BufferedInputStream;
0044:        import java.util.HashMap;
0045:        import java.util.Map;
0046:        import java.util.Properties;
0047:        import javax.activation.DataHandler;
0048:
0049:        import javax.activation.DataSource;
0050:        import javax.xml.bind.JAXBContext;
0051:        import javax.xml.soap.MimeHeaders;
0052:        import javax.xml.transform.OutputKeys;
0053:        import javax.xml.transform.Source;
0054:        import javax.xml.transform.Transformer;
0055:        import javax.xml.transform.dom.DOMSource;
0056:        import javax.xml.transform.stream.StreamResult;
0057:        import javax.xml.transform.stream.StreamSource;
0058:        import javax.xml.ws.WebServiceException;
0059:        import javax.xml.ws.http.HTTPException;
0060:        import java.io.ByteArrayInputStream;
0061:        import java.io.IOException;
0062:        import java.io.InputStream;
0063:        import java.io.OutputStream;
0064:        import java.util.logging.Logger;
0065:
0066:        /**
0067:         *
0068:         * @author WS Developement Team
0069:         */
0070:        public final class XMLMessage {
0071:
0072:            private static final Logger log = Logger
0073:                    .getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain
0074:                            + ".protocol.xml");
0075:
0076:            // So that SAAJ registers DCHs for MIME types
0077:            static {
0078:                new com.sun.xml.internal.messaging.saaj.soap.AttachmentPartImpl();
0079:            }
0080:
0081:            private static final int PLAIN_XML_FLAG = 1; // 00001
0082:            private static final int MIME_MULTIPART_FLAG = 2; // 00010
0083:            private static final int FI_ENCODED_FLAG = 16; // 10000
0084:
0085:            private final DataRepresentation data;
0086:
0087:            /**
0088:             * Indicates when Fast Infoset should be used to serialize
0089:             * this message.
0090:             */
0091:            protected boolean useFastInfoset = false;
0092:
0093:            /**
0094:             * Construct a message from an input stream. When messages are
0095:             * received, there's two parts -- the transport headers and the
0096:             * message content in a transport specific stream.
0097:             */
0098:            public XMLMessage(MimeHeaders headers, final InputStream in) {
0099:                String ct = null;
0100:                if (headers != null) {
0101:                    ct = getContentType(headers);
0102:                }
0103:                this .data = getData(ct, in);
0104:                // TODO should headers be set on the data?
0105:            }
0106:
0107:            /**
0108:             * Finds if the stream has some content or not
0109:             *
0110:             * @return null if there is no data
0111:             *         else stream to be used
0112:             */
0113:            private InputStream hasSomeData(InputStream in) throws IOException {
0114:                if (in != null) {
0115:                    if (in.available() < 1) {
0116:                        if (!in.markSupported()) {
0117:                            in = new BufferedInputStream(in);
0118:                        }
0119:                        in.mark(1);
0120:                        if (in.read() != -1) {
0121:                            in.reset();
0122:                        } else {
0123:                            in = null; // No data
0124:                        }
0125:                    }
0126:                }
0127:                return in;
0128:            }
0129:
0130:            private DataRepresentation getData(final String ct, InputStream in) {
0131:                DataRepresentation data;
0132:                try {
0133:                    in = hasSomeData(in);
0134:                    if (in == null) {
0135:                        return new NullContent();
0136:                    }
0137:                    if (ct != null) {
0138:                        ContentType contentType = new ContentType(ct);
0139:                        int contentTypeId = identifyContentType(contentType);
0140:                        boolean isFastInfoset = (contentTypeId & FI_ENCODED_FLAG) > 0;
0141:                        if ((contentTypeId & MIME_MULTIPART_FLAG) != 0) {
0142:                            data = new XMLMultiPart(ct, in, isFastInfoset);
0143:                        } else if ((contentTypeId & PLAIN_XML_FLAG) != 0
0144:                                || (contentTypeId & FI_ENCODED_FLAG) != 0) {
0145:                            data = new XMLSource(in, isFastInfoset);
0146:                        } else {
0147:                            data = new UnknownContent(ct, in);
0148:                        }
0149:                    } else {
0150:                        data = new NullContent();
0151:                    }
0152:                } catch (Exception ex) {
0153:                    throw new WebServiceException(ex);
0154:                }
0155:                return data;
0156:            }
0157:
0158:            public XMLMessage(Source source, boolean useFastInfoset) {
0159:                this .data = (source == null) ? new NullContent()
0160:                        : new XMLSource(source);
0161:                this .useFastInfoset = useFastInfoset;
0162:
0163:                this .data.getMimeHeaders()
0164:                        .addHeader(
0165:                                "Content-Type",
0166:                                useFastInfoset ? "application/fastinfoset"
0167:                                        : "text/xml");
0168:            }
0169:
0170:            public XMLMessage(Exception err, boolean useFastInfoset) {
0171:                this .data = new XMLErr(err);
0172:                this .useFastInfoset = useFastInfoset;
0173:
0174:                this .data.getMimeHeaders()
0175:                        .addHeader(
0176:                                "Content-Type",
0177:                                useFastInfoset ? "application/fastinfoset"
0178:                                        : "text/xml");
0179:            }
0180:
0181:            public XMLMessage(DataSource ds, boolean useFastInfoset) {
0182:                this .useFastInfoset = useFastInfoset;
0183:                try {
0184:                    this .data = (ds == null) ? new NullContent() : getData(ds
0185:                            .getContentType(), ds.getInputStream());
0186:                } catch (IOException ioe) {
0187:                    throw new WebServiceException(ioe);
0188:                }
0189:
0190:                String contentType = (ds != null) ? ds.getContentType() : null;
0191:                contentType = (contentType == null) ? contentType = "text/xml"
0192:                        : contentType;
0193:                this .data.getMimeHeaders().addHeader(
0194:                        "Content-Type",
0195:                        !useFastInfoset ? contentType : contentType
0196:                                .replaceFirst("text/xml",
0197:                                        "application/fastinfoset"));
0198:            }
0199:
0200:            public XMLMessage(Object object, JAXBContext context,
0201:                    boolean useFastInfoset) {
0202:                this .data = (object == null) ? new NullContent() : new XMLJaxb(
0203:                        object, context);
0204:                this .useFastInfoset = useFastInfoset;
0205:
0206:                this .data.getMimeHeaders()
0207:                        .addHeader(
0208:                                "Content-Type",
0209:                                useFastInfoset ? "application/fastinfoset"
0210:                                        : "text/xml");
0211:            }
0212:
0213:            public XMLMessage(Source source,
0214:                    Map<String, DataHandler> attachments, boolean useFastInfoset) {
0215:                if (attachments == null) {
0216:                    this .data = (source == null) ? new NullContent()
0217:                            : new XMLSource(source);
0218:                } else {
0219:                    if (source == null) {
0220:                        this .data = new UnknownContent(attachments);
0221:                    } else {
0222:                        this .data = new XMLMultiPart(source, attachments,
0223:                                useFastInfoset);
0224:                    }
0225:                }
0226:
0227:                this .useFastInfoset = useFastInfoset;
0228:                this .data.getMimeHeaders()
0229:                        .addHeader(
0230:                                "Content-Type",
0231:                                useFastInfoset ? "application/fastinfoset"
0232:                                        : "text/xml");
0233:            }
0234:
0235:            public XMLMessage(Object object, JAXBContext context,
0236:                    Map<String, DataHandler> attachments, boolean useFastInfoset) {
0237:                if (attachments == null) {
0238:                    this .data = (object == null) ? new NullContent()
0239:                            : new XMLJaxb(object, context);
0240:                } else {
0241:                    if (object == null) {
0242:                        this .data = new UnknownContent(attachments);
0243:                    } else {
0244:                        this .data = new XMLMultiPart(JAXBTypeSerializer
0245:                                .serialize(object, context), attachments,
0246:                                useFastInfoset);
0247:                    }
0248:                }
0249:
0250:                this .useFastInfoset = useFastInfoset;
0251:                this .data.getMimeHeaders()
0252:                        .addHeader(
0253:                                "Content-Type",
0254:                                useFastInfoset ? "application/fastinfoset"
0255:                                        : "text/xml");
0256:            }
0257:
0258:            /**
0259:             * Returns true if the underlying encoding of this message is FI.
0260:             */
0261:            public boolean isFastInfoset() {
0262:                return data.isFastInfoset();
0263:            }
0264:
0265:            /**
0266:             * Returns true if the FI encoding should be used.
0267:             */
0268:            public boolean useFastInfoset() {
0269:                return useFastInfoset;
0270:            }
0271:
0272:            /**
0273:             * Returns true if the sender of this message accepts FI. Slow, but
0274:             * should only be called once.
0275:             */
0276:            public boolean acceptFastInfoset() {
0277:                return FastInfosetUtil.isFastInfosetAccepted(getMimeHeaders()
0278:                        .getHeader("Accept"));
0279:            }
0280:
0281:            public Source getSource() {
0282:                return data.getSource();
0283:            }
0284:
0285:            public DataSource getDataSource() {
0286:                return data.getDataSource();
0287:            }
0288:
0289:            /**
0290:             * Verify a contentType.
0291:             *
0292:             * @return
0293:             * MIME_MULTIPART_FLAG | PLAIN_XML_FLAG
0294:             * MIME_MULTIPART_FLAG | FI_ENCODED_FLAG;
0295:             * PLAIN_XML_FLAG
0296:             * FI_ENCODED_FLAG
0297:             *
0298:             */
0299:            private static int identifyContentType(ContentType contentType) {
0300:                String primary = contentType.getPrimaryType();
0301:                String sub = contentType.getSubType();
0302:
0303:                if (primary.equalsIgnoreCase("multipart")
0304:                        && sub.equalsIgnoreCase("related")) {
0305:                    String type = contentType.getParameter("type");
0306:                    if (type != null) {
0307:                        if (isXMLType(type)) {
0308:                            return MIME_MULTIPART_FLAG | PLAIN_XML_FLAG;
0309:                        } else if (isFastInfosetType(type)) {
0310:                            return MIME_MULTIPART_FLAG | FI_ENCODED_FLAG;
0311:                        }
0312:                    }
0313:                    return 0;
0314:                } else if (isXMLType(primary, sub)) {
0315:                    return PLAIN_XML_FLAG;
0316:                } else if (isFastInfosetType(primary, sub)) {
0317:                    return FI_ENCODED_FLAG;
0318:                }
0319:                return 0;
0320:            }
0321:
0322:            protected static boolean isXMLType(String primary, String sub) {
0323:                return (primary.equalsIgnoreCase("text") || primary
0324:                        .equalsIgnoreCase("application"))
0325:                        && sub.equalsIgnoreCase("xml");
0326:            }
0327:
0328:            protected static boolean isXMLType(String type) {
0329:                return type.toLowerCase().startsWith("text/xml")
0330:                        || type.toLowerCase().startsWith("application/xml");
0331:            }
0332:
0333:            protected static boolean isFastInfosetType(String primary,
0334:                    String sub) {
0335:                return primary.equalsIgnoreCase("application")
0336:                        && sub.equalsIgnoreCase("fastinfoset");
0337:            }
0338:
0339:            protected static boolean isFastInfosetType(String type) {
0340:                return type.toLowerCase().startsWith("application/fastinfoset");
0341:            }
0342:
0343:            /**
0344:             * Ideally this should be called just before writing the message
0345:             */
0346:            public MimeHeaders getMimeHeaders() {
0347:                return data.getMimeHeaders();
0348:            }
0349:
0350:            private static String getContentType(MimeHeaders headers) {
0351:                String[] values = headers.getHeader("Content-Type");
0352:                return (values == null) ? null : values[0];
0353:            }
0354:
0355:            public int getStatus() {
0356:                return data.getStatus();
0357:            }
0358:
0359:            public void writeTo(OutputStream out) throws IOException {
0360:                data.writeTo(out, useFastInfoset);
0361:            }
0362:
0363:            public Source getPayload() {
0364:                return data.getPayload();
0365:            }
0366:
0367:            public Map<String, DataHandler> getAttachments() {
0368:                return data.getAttachments();
0369:            }
0370:
0371:            public Object getPayload(JAXBContext context) {
0372:                // Get a copy of Source using getPayload() and use it to deserialize
0373:                // to JAXB object
0374:                return JAXBTypeSerializer.deserialize(getPayload(), context);
0375:            }
0376:
0377:            /**
0378:             * Defines operations available regardless of the actual in-memory data representation.
0379:             */
0380:            private static abstract class DataRepresentation {
0381:                /**
0382:                 * Can be called multiple times. Typically from XMLLogicalMessageImpl
0383:                 */
0384:                abstract Source getPayload();
0385:
0386:                /**
0387:                 * Should be called only once. Once this is called, don't use this object anymore
0388:                 */
0389:                abstract void writeTo(OutputStream out, boolean useFastInfoset)
0390:                        throws IOException;
0391:
0392:                /**
0393:                 * Returns true whenever the underlying representation of this message
0394:                 * is a Fast Infoset stream.
0395:                 */
0396:                abstract boolean isFastInfoset();
0397:
0398:                /**
0399:                 * Should be called only once. Once this is called, don't use this object anymore
0400:                 */
0401:                abstract Source getSource();
0402:
0403:                /**
0404:                 * Should be called only once. Once this is called, don't use this object anymore
0405:                 */
0406:                abstract DataSource getDataSource();
0407:
0408:                /**
0409:                 * Should be called only once. Once this is called, don't use this object anymore
0410:                 */
0411:                abstract Map<String, DataHandler> getAttachments();
0412:
0413:                /**
0414:                 * Should contain Content-Type for this message.
0415:                 */
0416:                abstract MimeHeaders getMimeHeaders();
0417:
0418:                int getStatus() {
0419:                    return WSConnection.OK;
0420:                }
0421:            }
0422:
0423:            /**
0424:             * Data represented as a multi-part MIME message. It also has XML as
0425:             * root part
0426:             *
0427:             * This class parses {@link MimeMultipart} lazily.
0428:             */
0429:            private static final class XMLMultiPart extends DataRepresentation {
0430:                private DataSource dataSource;
0431:                private MimeMultipart multipart;
0432:                private XMLSource xmlSource;
0433:                private boolean isFastInfoset;
0434:                private final MimeHeaders headers = new MimeHeaders();
0435:
0436:                public XMLMultiPart(final String contentType,
0437:                        final InputStream is, boolean isFastInfoset) {
0438:                    this .isFastInfoset = isFastInfoset;
0439:                    dataSource = new DataSource() {
0440:                        public InputStream getInputStream() {
0441:                            return is;
0442:                        }
0443:
0444:                        public OutputStream getOutputStream() {
0445:                            return null;
0446:                        }
0447:
0448:                        public String getContentType() {
0449:                            return contentType;
0450:                        }
0451:
0452:                        public String getName() {
0453:                            return "";
0454:                        }
0455:                    };
0456:                }
0457:
0458:                public XMLMultiPart(Source source,
0459:                        final Map<String, DataHandler> atts,
0460:                        boolean isFastInfoset) {
0461:                    this .isFastInfoset = isFastInfoset;
0462:                    multipart = new MimeMultipart("related");
0463:                    multipart.getContentType().setParameter("type", "text/xml");
0464:
0465:                    // Creates Primary part
0466:                    ByteOutputStream bos = new ByteOutputStream();
0467:                    new XMLSource(source).writeTo(bos, isFastInfoset);
0468:                    InternetHeaders headers = new InternetHeaders();
0469:                    headers.addHeader("Content-Type",
0470:                            isFastInfoset ? "application/fastinfoset"
0471:                                    : "text/xml");
0472:                    MimeBodyPart rootPart = new MimeBodyPart(headers, bos
0473:                            .getBytes(), bos.getCount());
0474:                    multipart.addBodyPart(rootPart, 0);
0475:
0476:                    for (Map.Entry<String, DataHandler> e : atts.entrySet()) {
0477:                        MimeBodyPart part = new MimeBodyPart();
0478:                        part.setDataHandler(e.getValue());
0479:                        multipart.addBodyPart(part);
0480:                    }
0481:                }
0482:
0483:                public XMLMultiPart(DataSource dataSource, boolean isFastInfoset) {
0484:                    this .dataSource = dataSource;
0485:                    this .isFastInfoset = isFastInfoset;
0486:                }
0487:
0488:                public boolean isFastInfoset() {
0489:                    return isFastInfoset;
0490:                }
0491:
0492:                public DataSource getDataSource() {
0493:                    if (dataSource != null) {
0494:                        return dataSource;
0495:                    } else if (multipart != null) {
0496:                        return new DataSource() {
0497:                            public InputStream getInputStream() {
0498:                                try {
0499:                                    if (xmlSource != null) {
0500:                                        replaceRootPart(false);
0501:                                    }
0502:                                    ByteOutputStream bos = new ByteOutputStream();
0503:                                    multipart.writeTo(bos);
0504:                                    return bos.newInputStream();
0505:                                } catch (MessagingException me) {
0506:                                    throw new XMLMessageException(
0507:                                            "xml.get.ds.err", me);
0508:                                } catch (IOException ioe) {
0509:                                    throw new XMLMessageException(
0510:                                            "xml.get.ds.err", ioe);
0511:                                }
0512:                            }
0513:
0514:                            public OutputStream getOutputStream() {
0515:                                return null;
0516:                            }
0517:
0518:                            public String getContentType() {
0519:                                return multipart.getContentType().toString();
0520:                            }
0521:
0522:                            public String getName() {
0523:                                return "";
0524:                            }
0525:                        };
0526:                    }
0527:                    return null;
0528:                }
0529:
0530:                private MimeBodyPart getRootPart() {
0531:                    try {
0532:                        convertToMultipart();
0533:                        ContentType contentType = multipart.getContentType();
0534:                        String startParam = contentType.getParameter("start");
0535:                        MimeBodyPart sourcePart = (startParam == null) ? (MimeBodyPart) multipart
0536:                                .getBodyPart(0)
0537:                                : (MimeBodyPart) multipart
0538:                                        .getBodyPart(startParam);
0539:                        return sourcePart;
0540:                    } catch (MessagingException ex) {
0541:                        throw new XMLMessageException("xml.get.source.err", ex);
0542:                    }
0543:                }
0544:
0545:                private void replaceRootPart(boolean useFastInfoset) {
0546:                    if (xmlSource == null) {
0547:                        return;
0548:                    }
0549:                    try {
0550:                        MimeBodyPart sourcePart = getRootPart();
0551:                        String ctype = sourcePart.getContentType();
0552:                        multipart.removeBodyPart(sourcePart);
0553:
0554:                        ByteOutputStream bos = new ByteOutputStream();
0555:                        xmlSource.writeTo(bos, useFastInfoset);
0556:                        InternetHeaders headers = new InternetHeaders();
0557:                        headers.addHeader("Content-Type",
0558:                                useFastInfoset ? "application/fastinfoset"
0559:                                        : ctype);
0560:
0561:                        sourcePart = new MimeBodyPart(headers, bos.getBytes(),
0562:                                bos.getCount());
0563:                        multipart.addBodyPart(sourcePart, 0);
0564:                    } catch (MessagingException ex) {
0565:                        throw new XMLMessageException("xml.get.source.err", ex);
0566:                    }
0567:                }
0568:
0569:                private void convertToMultipart() {
0570:                    if (dataSource != null) {
0571:                        try {
0572:                            multipart = new MimeMultipart(dataSource, null);
0573:                            dataSource = null;
0574:                        } catch (MessagingException ex) {
0575:                            throw new XMLMessageException("xml.get.source.err",
0576:                                    ex);
0577:                        }
0578:                    }
0579:                }
0580:
0581:                /**
0582:                 * Returns root part of the MIME message
0583:                 */
0584:                public Source getSource() {
0585:                    try {
0586:                        // If there is an XMLSource, return that
0587:                        if (xmlSource != null) {
0588:                            return xmlSource.getPayload();
0589:                        }
0590:
0591:                        // Otherwise, parse MIME package and find root part
0592:                        convertToMultipart();
0593:                        MimeBodyPart sourcePart = getRootPart();
0594:                        ContentType ctype = new ContentType(sourcePart
0595:                                .getContentType());
0596:                        String baseType = ctype.getBaseType();
0597:
0598:                        // Return a StreamSource or FastInfosetSource depending on type
0599:                        if (isXMLType(baseType)) {
0600:                            return new StreamSource(sourcePart.getInputStream());
0601:                        } else if (isFastInfosetType(baseType)) {
0602:                            return FastInfosetReflection
0603:                                    .FastInfosetSource_new(sourcePart
0604:                                            .getInputStream());
0605:                        } else {
0606:                            throw new XMLMessageException(
0607:                                    "xml.root.part.invalid.Content-Type",
0608:                                    new Object[] { baseType });
0609:                        }
0610:                    } catch (MessagingException ex) {
0611:                        throw new XMLMessageException("xml.get.source.err", ex);
0612:                    } catch (Exception ioe) {
0613:                        throw new XMLMessageException("xml.get.source.err", ioe);
0614:                    }
0615:                }
0616:
0617:                public Source getPayload() {
0618:                    return getSource();
0619:                }
0620:
0621:                public void writeTo(OutputStream out, boolean useFastInfoset) {
0622:                    try {
0623:                        // If a source has been set, ensure MIME parsing
0624:                        if (xmlSource != null) {
0625:                            convertToMultipart();
0626:                        }
0627:
0628:                        // Try to use dataSource whenever possible
0629:                        if (dataSource != null) {
0630:                            // If already encoded correctly, just copy the bytes
0631:                            if (isFastInfoset == useFastInfoset) {
0632:                                InputStream is = dataSource.getInputStream();
0633:                                byte[] buf = new byte[1024];
0634:                                int len;
0635:                                while ((len = is.read(buf)) != -1) {
0636:                                    out.write(buf, 0, len);
0637:                                }
0638:                                return; // we're done
0639:                            } else {
0640:                                // Parse MIME and create source for root part
0641:                                xmlSource = new XMLSource(getSource());
0642:                            }
0643:                        }
0644:
0645:                        // Finally, possibly re-encode root part and write it out
0646:                        replaceRootPart(useFastInfoset);
0647:                        multipart.writeTo(out);
0648:                    } catch (Exception e) {
0649:                        throw new WebServiceException(e);
0650:                    }
0651:                }
0652:
0653:                public Map<String, DataHandler> getAttachments() {
0654:                    // If a source has been set, ensure MIME parsing
0655:                    if (xmlSource != null) {
0656:                        convertToMultipart();
0657:                    }
0658:                    try {
0659:                        MimeBodyPart rootPart = getRootPart();
0660:                        Map<String, DataHandler> map = new HashMap<String, DataHandler>();
0661:                        int count = multipart.getCount();
0662:                        for (int i = 0; i < count; i++) {
0663:                            MimeBodyPart part = multipart.getBodyPart(i);
0664:                            if (part != rootPart) {
0665:                                map.put(part.getContentID(), part
0666:                                        .getDataHandler());
0667:                            }
0668:                        }
0669:                        return map;
0670:                    } catch (MessagingException ex) {
0671:                        throw new XMLMessageException("xml.get.source.err", ex);
0672:                    }
0673:                }
0674:
0675:                MimeHeaders getMimeHeaders() {
0676:                    headers.removeHeader("Content-Type");
0677:                    if (dataSource != null) {
0678:                        headers.addHeader("Content-Type", dataSource
0679:                                .getContentType());
0680:                    } else {
0681:                        if (multipart != null) {
0682:                            headers.addHeader("Content-Type", multipart
0683:                                    .getContentType().toString());
0684:                        }
0685:                    }
0686:                    return headers;
0687:                }
0688:
0689:            }
0690:
0691:            /**
0692:             * Data represented as {@link Source}.
0693:             */
0694:            public static class XMLSource extends DataRepresentation {
0695:
0696:                private Source source;
0697:                private boolean isFastInfoset;
0698:                private final MimeHeaders headers = new MimeHeaders();
0699:
0700:                public XMLSource(InputStream in, boolean isFastInfoset)
0701:                        throws Exception {
0702:                    this .source = isFastInfoset ? FastInfosetReflection
0703:                            .FastInfosetSource_new(in) : new StreamSource(in);
0704:                    this .isFastInfoset = isFastInfoset;
0705:                }
0706:
0707:                public XMLSource(Source source) {
0708:                    this .source = source;
0709:                    this .isFastInfoset = ((source != null) ? (source.getClass() == FastInfosetReflection.fiFastInfosetSource)
0710:                            : false);
0711:                }
0712:
0713:                public boolean isFastInfoset() {
0714:                    return isFastInfoset;
0715:                }
0716:
0717:                /*
0718:                 * If there is a ByteInputStream available, then write it to the output
0719:                 * stream. Otherwise, use Transformer to write Source to output stream.
0720:                 */
0721:                public void writeTo(OutputStream out, boolean useFastInfoset) {
0722:                    try {
0723:                        InputStream is = null;
0724:                        boolean canAvoidTransform = false;
0725:                        if (source instanceof  StreamSource) {
0726:                            is = ((StreamSource) source).getInputStream();
0727:                            // If use of FI is requested, need to transcode
0728:                            canAvoidTransform = !useFastInfoset;
0729:                        } else if (source.getClass() == FastInfosetReflection.fiFastInfosetSource) {
0730:                            is = FastInfosetReflection
0731:                                    .FastInfosetSource_getInputStream(source);
0732:                            // If use of FI is not requested, need to transcode
0733:                            canAvoidTransform = useFastInfoset;
0734:                        }
0735:
0736:                        if (canAvoidTransform && is != null
0737:                                && is instanceof  ByteInputStream) {
0738:                            ByteInputStream bis = (ByteInputStream) is;
0739:                            // Reset the stream
0740:                            byte[] buf = bis.getBytes();
0741:                            out.write(buf);
0742:                            bis.close();
0743:                            return;
0744:                        }
0745:
0746:                        // TODO: Use an efficient transformer from SAAJ that knows how to optimally
0747:                        // write to FI results
0748:                        Transformer transformer = XmlUtil.newTransformer();
0749:                        transformer.transform(source,
0750:                                useFastInfoset ? FastInfosetReflection
0751:                                        .FastInfosetResult_new(out)
0752:                                        : new StreamResult(out));
0753:                    } catch (Exception e) {
0754:                        throw new WebServiceException(e);
0755:                    }
0756:                }
0757:
0758:                public Source getSource() {
0759:                    return source;
0760:                }
0761:
0762:                DataSource getDataSource() {
0763:                    return new DataSource() {
0764:                        public InputStream getInputStream() {
0765:                            try {
0766:                                InputStream is = null;
0767:                                if (source instanceof  StreamSource) {
0768:                                    is = ((StreamSource) source)
0769:                                            .getInputStream();
0770:                                } else if (source.getClass() == FastInfosetReflection.fiFastInfosetSource) {
0771:                                    is = FastInfosetReflection
0772:                                            .FastInfosetSource_getInputStream(source);
0773:                                }
0774:                                if (is != null) {
0775:                                    return is;
0776:                                }
0777:                                // Copy source to result respecting desired encoding
0778:                                ByteArrayBuffer bab = new ByteArrayBuffer();
0779:                                Transformer transformer = XmlUtil
0780:                                        .newTransformer();
0781:                                transformer.transform(source,
0782:                                        isFastInfoset() ? FastInfosetReflection
0783:                                                .FastInfosetResult_new(bab)
0784:                                                : new StreamResult(bab));
0785:                                bab.close();
0786:                                return bab.newInputStream();
0787:                            } catch (Exception e) {
0788:                                throw new WebServiceException(e);
0789:                            }
0790:                        }
0791:
0792:                        public OutputStream getOutputStream() {
0793:                            return null;
0794:                        }
0795:
0796:                        public String getContentType() {
0797:                            return isFastInfoset() ? "application/fastinfoset"
0798:                                    : "text/xml";
0799:                        }
0800:
0801:                        public String getName() {
0802:                            return "";
0803:                        }
0804:                    };
0805:
0806:                }
0807:
0808:                /*
0809:                 * Usually called from logical handler
0810:                 * If there is a DOMSource, return that. Otherwise, return a copy of
0811:                 * the existing source.
0812:                 */
0813:                public Source getPayload() {
0814:                    try {
0815:
0816:                        if (source instanceof  DOMSource) {
0817:                            return source;
0818:                        }
0819:
0820:                        InputStream is = null;
0821:
0822:                        if (source instanceof  StreamSource) {
0823:                            is = ((StreamSource) source).getInputStream();
0824:                        } else if (source.getClass() == FastInfosetReflection.fiFastInfosetSource) {
0825:                            is = FastInfosetReflection
0826:                                    .FastInfosetSource_getInputStream(source);
0827:                        }
0828:
0829:                        if (is != null && is instanceof  ByteInputStream) {
0830:                            ByteInputStream bis = (ByteInputStream) is;
0831:                            // Reset the stream
0832:                            byte[] buf = bis.getBytes();
0833:
0834:                            ByteArrayInputStream bais = new ByteArrayInputStream(
0835:                                    buf);
0836:                            bis.close();
0837:                            return isFastInfoset ? FastInfosetReflection
0838:                                    .FastInfosetSource_new(is)
0839:                                    : new StreamSource(bais);
0840:
0841:                        }
0842:
0843:                        // Copy source to result respecting desired encoding
0844:                        ByteArrayBuffer bab = new ByteArrayBuffer();
0845:                        Transformer transformer = XmlUtil.newTransformer();
0846:                        // Adding this to work with empty source. Is it JAXP bug ?
0847:                        Properties oprops = new Properties();
0848:                        oprops.put(OutputKeys.OMIT_XML_DECLARATION, "yes");
0849:                        transformer.setOutputProperties(oprops);
0850:                        transformer.transform(source,
0851:                                isFastInfoset ? FastInfosetReflection
0852:                                        .FastInfosetResult_new(bab)
0853:                                        : new StreamResult(bab));
0854:                        bab.close();
0855:
0856:                        // Set internal source
0857:                        InputStream bis = (bab.size() == 0) ? null : bab
0858:                                .newInputStream();
0859:                        source = isFastInfoset ? FastInfosetReflection
0860:                                .FastInfosetSource_new(bis) : new StreamSource(
0861:                                bis);
0862:
0863:                        // Return fresh source back to handler
0864:                        bis = bab.newInputStream();
0865:                        return isFastInfoset ? FastInfosetReflection
0866:                                .FastInfosetSource_new(bis) : new StreamSource(
0867:                                bis);
0868:                    } catch (Exception e) {
0869:                        throw new WebServiceException(e);
0870:                    }
0871:                }
0872:
0873:                public Map<String, DataHandler> getAttachments() {
0874:                    return null;
0875:                }
0876:
0877:                MimeHeaders getMimeHeaders() {
0878:                    return headers;
0879:                }
0880:
0881:            }
0882:
0883:            /**
0884:             * Data represented as a JAXB object.
0885:             */
0886:            public static class XMLJaxb extends DataRepresentation {
0887:                private final Object object;
0888:                private final JAXBContext jaxbContext;
0889:                private final MimeHeaders headers = new MimeHeaders();
0890:
0891:                public XMLJaxb(Object object, JAXBContext jaxbContext) {
0892:                    this .object = object;
0893:                    this .jaxbContext = jaxbContext;
0894:                }
0895:
0896:                public void writeTo(OutputStream out, boolean useFastInfoset) {
0897:                    if (useFastInfoset) {
0898:                        JAXBTypeSerializer
0899:                                .serializeDocument(object,
0900:                                        XMLStreamWriterFactory
0901:                                                .createFIStreamWriter(out),
0902:                                        jaxbContext);
0903:                    } else {
0904:                        JAXBTypeSerializer.serialize(object, out, jaxbContext);
0905:                    }
0906:                }
0907:
0908:                boolean isFastInfoset() {
0909:                    return false;
0910:                }
0911:
0912:                public Source getSource() {
0913:                    return JAXBTypeSerializer.serialize(object, jaxbContext);
0914:                }
0915:
0916:                DataSource getDataSource() {
0917:                    return new DataSource() {
0918:                        public InputStream getInputStream() {
0919:                            ByteOutputStream bos = new ByteOutputStream();
0920:                            JAXBTypeSerializer.serialize(object, bos,
0921:                                    jaxbContext);
0922:                            return bos.newInputStream();
0923:                        }
0924:
0925:                        public OutputStream getOutputStream() {
0926:                            return null;
0927:                        }
0928:
0929:                        public String getContentType() {
0930:                            return isFastInfoset() ? "application/fastinfoset"
0931:                                    : "text/xml";
0932:                        }
0933:
0934:                        public String getName() {
0935:                            return "";
0936:                        }
0937:                    };
0938:                }
0939:
0940:                /*
0941:                 * Usually called from logical handler
0942:                 * If there is a DOMSource, return that. Otherwise, return a copy of
0943:                 * the existing source.
0944:                 */
0945:                public Source getPayload() {
0946:                    return getSource();
0947:                }
0948:
0949:                public Map<String, DataHandler> getAttachments() {
0950:                    return null;
0951:                }
0952:
0953:                MimeHeaders getMimeHeaders() {
0954:                    return headers;
0955:                }
0956:
0957:            }
0958:
0959:            /**
0960:             * Don't know about this content. It's conent-type is NOT the XML types
0961:             * we recognize(text/xml, application/xml, multipart/related;text/xml etc).
0962:             *
0963:             * This could be used to represent image/jpeg etc
0964:             */
0965:            public static class UnknownContent extends DataRepresentation {
0966:                private final String ct;
0967:                private final InputStream in;
0968:                private final MimeMultipart multipart;
0969:                private final MimeHeaders headers = new MimeHeaders();
0970:
0971:                public UnknownContent(String ct, InputStream in) {
0972:                    this .ct = ct;
0973:                    this .in = in;
0974:                    this .multipart = null;
0975:                }
0976:
0977:                public UnknownContent(Map<String, DataHandler> atts) {
0978:                    this .in = null;
0979:                    multipart = new MimeMultipart("mixed");
0980:                    for (Map.Entry<String, DataHandler> e : atts.entrySet()) {
0981:                        MimeBodyPart part = new MimeBodyPart();
0982:                        part.setDataHandler(e.getValue());
0983:                        multipart.addBodyPart(part);
0984:                    }
0985:                    this .ct = multipart.getContentType().toString();
0986:                }
0987:
0988:                public void writeTo(OutputStream out, boolean useFastInfoset) {
0989:                    try {
0990:                        if (multipart != null) {
0991:                            multipart.writeTo(out);
0992:                        }
0993:                        byte[] buf = new byte[1024];
0994:                        int len;
0995:                        while ((len = in.read(buf)) != -1) {
0996:                            out.write(buf, 0, len);
0997:                        }
0998:                    } catch (Exception ex) {
0999:                        throw new WebServiceException(ex);
1000:                    }
1001:                }
1002:
1003:                boolean isFastInfoset() {
1004:                    return false;
1005:                }
1006:
1007:                /**
1008:                 * NO XML content so return null
1009:                 */
1010:                public Source getSource() {
1011:                    return null;
1012:                }
1013:
1014:                DataSource getDataSource() {
1015:                    return new DataSource() {
1016:                        public InputStream getInputStream() {
1017:                            if (multipart != null) {
1018:                                try {
1019:                                    ByteOutputStream bos = new ByteOutputStream();
1020:                                    multipart.writeTo(bos);
1021:                                    return bos.newInputStream();
1022:                                } catch (Exception ioe) {
1023:                                    throw new WebServiceException(ioe);
1024:                                }
1025:                            }
1026:                            return in;
1027:                        }
1028:
1029:                        public OutputStream getOutputStream() {
1030:                            return null;
1031:                        }
1032:
1033:                        public String getContentType() {
1034:                            assert ct != null;
1035:                            return ct;
1036:                        }
1037:
1038:                        public String getName() {
1039:                            return "";
1040:                        }
1041:                    };
1042:                }
1043:
1044:                /**
1045:                 * NO XML content so return null
1046:                 */
1047:                public Source getPayload() {
1048:                    return null;
1049:                }
1050:
1051:                /**
1052:                 * JAXWS doesn't know about this conent. So we treate the whole content
1053:                 * as one payload.
1054:                 */
1055:                public Map<String, DataHandler> getAttachments() {
1056:                    return null;
1057:                }
1058:
1059:                MimeHeaders getMimeHeaders() {
1060:                    headers.removeHeader("Content-Type");
1061:                    headers.addHeader("Content-Type", ct);
1062:                    return headers;
1063:                }
1064:
1065:            }
1066:
1067:            /**
1068:             * Represents HTTPException or anyother exception
1069:             */
1070:            private static final class XMLErr extends DataRepresentation {
1071:                private final Exception err;
1072:                private final MimeHeaders headers = new MimeHeaders();
1073:
1074:                XMLErr(Exception err) {
1075:                    this .err = err;
1076:                }
1077:
1078:                public Source getPayload() {
1079:                    return null;
1080:                }
1081:
1082:                public Map<String, DataHandler> getAttachments() {
1083:                    return null;
1084:                }
1085:
1086:                public void writeTo(OutputStream out, boolean useFastInfoset)
1087:                        throws IOException {
1088:                    String msg = err.getMessage();
1089:                    if (msg == null) {
1090:                        msg = err.toString();
1091:                    }
1092:                    msg = "<err>" + msg + "</err>";
1093:
1094:                    if (useFastInfoset) {
1095:                        FastInfosetUtil.transcodeXMLStringToFI(msg, out);
1096:                    } else {
1097:                        out.write(msg.getBytes());
1098:                    }
1099:                }
1100:
1101:                boolean isFastInfoset() {
1102:                    return false;
1103:                }
1104:
1105:                Source getSource() {
1106:                    return null;
1107:                }
1108:
1109:                DataSource getDataSource() {
1110:                    return null;
1111:                }
1112:
1113:                @Override
1114:                int getStatus() {
1115:                    if (err instanceof  HTTPException) {
1116:                        return ((HTTPException) err).getStatusCode();
1117:                    }
1118:                    return WSConnection.INTERNAL_ERR;
1119:                }
1120:
1121:                MimeHeaders getMimeHeaders() {
1122:                    return headers;
1123:                }
1124:            }
1125:
1126:            /**
1127:             * There is no content to write.
1128:             */
1129:            private static final class NullContent extends DataRepresentation {
1130:                private final MimeHeaders headers = new MimeHeaders();
1131:
1132:                public Source getPayload() {
1133:                    return null;
1134:                }
1135:
1136:                public Map<String, DataHandler> getAttachments() {
1137:                    return null;
1138:                }
1139:
1140:                public void writeTo(OutputStream out, boolean useFastInfoset)
1141:                        throws IOException {
1142:                    // Nothing to do
1143:                }
1144:
1145:                boolean isFastInfoset() {
1146:                    return false;
1147:                }
1148:
1149:                Source getSource() {
1150:                    return null;
1151:                }
1152:
1153:                DataSource getDataSource() {
1154:                    return null;
1155:                }
1156:
1157:                MimeHeaders getMimeHeaders() {
1158:                    return headers;
1159:                }
1160:            }
1161:        }
w_w_w.___j___av__a___2s__._c_o_m___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.