001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.jaxws.message.attachments;
020:
021: import org.apache.axiom.om.OMText;
022: import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
023: import org.apache.axiom.om.impl.llom.OMTextImpl;
024: import org.apache.axis2.jaxws.ExceptionFactory;
025: import org.apache.axis2.jaxws.message.Message;
026: import org.apache.axis2.transport.http.HTTPConstants;
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029:
030: import javax.activation.DataHandler;
031: import javax.mail.internet.InternetHeaders;
032: import javax.mail.internet.MimeBodyPart;
033: import javax.mail.internet.MimePartDataSource;
034: import javax.xml.bind.attachment.AttachmentMarshaller;
035: import javax.xml.stream.XMLStreamWriter;
036:
037: /**
038: * An implementation of the JAXB AttachmentMarshaller that is used to handle binary data from JAXB
039: * and create populate the appropriate constructs within the JAX-WS Message Model.
040: */
041: public class JAXBAttachmentMarshaller extends AttachmentMarshaller {
042:
043: private static final Log log = LogFactory
044: .getLog(JAXBAttachmentMarshaller.class);
045:
046: private Message message;
047: private XMLStreamWriter writer;
048: private final String APPLICATION_OCTET = "application/octet-stream";
049:
050: public JAXBAttachmentMarshaller(Message message,
051: XMLStreamWriter writer) {
052: this .message = message;
053: this .writer = writer;
054: }
055:
056: @Override
057: public boolean isXOPPackage() {
058: boolean value = false;
059:
060: // For outbound messages, only trigger MTOM if
061: // the message is mtom enabled (which indicates that
062: // the api dispatch/provider/proxy/impl has an MTOM binding)
063: if (message != null) {
064: value = message.isMTOMEnabled();
065: }
066:
067: // If the writer is not an MTOM XMLStreamWriter then we don't have
068: // any place to store the attachment
069: if (!(writer instanceof MTOMXMLStreamWriter)) {
070: if (log.isDebugEnabled()) {
071: log.debug("The writer is not enabled for MTOM. "
072: + "MTOM values will not be optimized");
073: }
074: value = false;
075: }
076:
077: if (log.isDebugEnabled()) {
078: log.debug("isXOPPackage returns " + value);
079: }
080: return value;
081:
082: }
083:
084: @Override
085: public String addMtomAttachment(byte[] data, int offset,
086: int length, String mimeType, String namespace,
087: String localPart) {
088:
089: if (offset != 0 || length != data.length) {
090: int len = length - offset;
091: byte[] newData = new byte[len];
092: System.arraycopy(data, offset, newData, 0, len);
093: data = newData;
094: }
095:
096: if (mimeType == null || mimeType.length() == 0) {
097: mimeType = APPLICATION_OCTET;
098: }
099:
100: if (log.isDebugEnabled()) {
101: log
102: .debug("Adding MTOM/XOP byte array attachment for element: "
103: + "{" + namespace + "}" + localPart);
104: }
105:
106: String cid;
107: try {
108: // Create MIME Body Part
109: InternetHeaders ih = new InternetHeaders();
110: ih.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, mimeType);
111: MimeBodyPart mbp = new MimeBodyPart(ih, data);
112:
113: //Create a data source for the MIME Body Part
114: MimePartDataSource mpds = new MimePartDataSource(mbp);
115:
116: DataHandler dataHandler = new DataHandler(mpds);
117: cid = addDataHandler(dataHandler);
118:
119: // Add the content id to the mime body part
120: mbp.setHeader(HTTPConstants.HEADER_CONTENT_ID, cid);
121: } catch (Throwable t) {
122: throw ExceptionFactory.makeWebServiceException(t);
123: }
124: return cid == null ? null : "cid:" + cid;
125: }
126:
127: @Override
128: public String addMtomAttachment(DataHandler data, String namespace,
129: String localPart) {
130: if (log.isDebugEnabled()) {
131: log
132: .debug("Adding MTOM/XOP datahandler attachment for element: "
133: + "{" + namespace + "}" + localPart);
134: }
135: String cid = addDataHandler(data);
136: return cid == null ? null : "cid:" + cid;
137: }
138:
139: @Override
140: public String addSwaRefAttachment(DataHandler data) {
141: if (log.isDebugEnabled()) {
142: log.debug("Adding SWAREF attachment");
143: }
144:
145: String cid = addDataHandler(data);
146: message.setDoingSWA(true);
147: return "cid:" + cid;
148: }
149:
150: private String addDataHandler(DataHandler dh) {
151: String cid = null;
152: OMText textNode = null;
153:
154: // If this is an MTOMXMLStreamWriter then inform the writer
155: // that it must write out this attchment (I guess we should do this
156: // even if the attachment is SWAREF ?)
157: if (writer instanceof MTOMXMLStreamWriter) {
158: textNode = new OMTextImpl(dh, null);
159: cid = textNode.getContentID();
160: ((MTOMXMLStreamWriter) writer).writeOptimized(textNode);
161: // Remember the attachment on the message.
162: message.addDataHandler(dh, cid);
163: }
164:
165: if (log.isDebugEnabled()) {
166: log.debug(" content id=" + cid);
167: log.debug(" dataHandler =" + dh);
168: }
169: return cid;
170: }
171:
172: }
|