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:
020: package org.apache.axis2.transport.mail;
021:
022: import org.apache.axiom.om.OMOutputFormat;
023: import org.apache.axis2.AxisFault;
024: import org.apache.axis2.addressing.EndpointReference;
025: import org.apache.axis2.context.ConfigurationContext;
026: import org.apache.axis2.context.MessageContext;
027: import org.apache.axis2.description.HandlerDescription;
028: import org.apache.axis2.description.Parameter;
029: import org.apache.axis2.description.TransportOutDescription;
030: import org.apache.axis2.handlers.AbstractHandler;
031: import org.apache.axis2.i18n.Messages;
032: import org.apache.axis2.transport.MessageFormatter;
033: import org.apache.axis2.transport.OutTransportInfo;
034: import org.apache.axis2.transport.TransportSender;
035: import org.apache.axis2.transport.TransportUtils;
036: import org.apache.axis2.transport.http.HTTPTransportUtils;
037: import org.apache.axis2.transport.http.HttpTransportProperties;
038: import org.apache.axis2.util.Utils;
039:
040: import javax.mail.PasswordAuthentication;
041: import java.io.ByteArrayOutputStream;
042: import java.io.IOException;
043: import java.io.OutputStream;
044: import java.util.ArrayList;
045: import java.util.Iterator;
046:
047: /**
048: * 0. For this profile we only care about SOAP 1.2
049: * 1. There should be no mime text body in this case
050: * 2. The SOAP envelope should be base64 encoded and marked with the following headers
051: * SOAP 1.2
052: * Content-Type: application/soap+xml; charset=UTF-8 ; action="soap-action-goes-here"
053: * Content-Transfer-Encoding: base64
054: * Content-Description: "/serviceName"
055: * 3. The content-description is the logical name of the service. It should be quoted.
056: * 4. The subject can be anything. Perhaps something like "SOAP Message" might be useful to people looking at the mail in a normal mail browser.
057: * 5. If there are attachments the there will be a mime multipart. There should only be one part with content-type: application/soap+xml.
058: * 6. The service URL will be created as mailto:paul@wso2.com?X-Service-Path=/axis2/services/MyService
059: * or paul@wso2.com?/axis2/services/MyService
060: * <p/>
061: * <p/>
062: * Example without attachments
063: * ========================
064: * From: rm_client@lenio.dk
065: * To: lenioserver@oiositest.dk
066: * Message-ID: <8868170.01165394158287.JavaMail.hgk@hans-guldager-knudsens-computer.local>
067: * Subject: ANYTHING
068: * MIME-Version: 1.0
069: * Content-Type: application/soap+xml; charset=UTF-8 ; action="http://rep.oio.dk/oiosi/IMessageHandler/RequestRespondRequest"
070: * Content-Transfer-Encoding: base64
071: * Content-Description: /my/service/urlpath
072: * <p/>
073: * PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0ndXRmLTgnPz48c29hcGVudjpFbnZlbG9wZSB4
074: * Y3VtZW50YXRpb24uPC9EZXNjcmlwdGlvbj48L05vdGlmaWNhdGlvbj48L3NvYXBlbnY6Qm9keT48
075: * L3NvYXBlbnY6RW52ZWxvcGU+
076: * <p/>
077: * ========================
078: * <p/>
079: * Example with attachments
080: * <p/>
081: * ========================
082: * From: rm_client@lenio.dk
083: * To: lenioserver@oiositest.dk
084: * Message-ID: <8868170.01165394158287.JavaMail.hgk@hans-guldager-knudsens-computer.local>
085: * Subject: ANYTHING
086: * MIME-Version: 1.0
087: * content-type: multipart/mixed; boundary=--boundary_0_9fdec710-2336-4dc9-8bcd-45f2c06cf605
088: * <p/>
089: * ----boundary_0_9fdec710-2336-4dc9-8bcd-45f2c06cf605
090: * Content-Type: application/soap+xml; charset=UTF-8 ; action="http://rep.oio.dk/oiosi/IMessageHandler/RequestRespondRequest"
091: * Content-Transfer-Encoding: base64
092: * Content-Description: /my/service/urlpath
093: * <p/>
094: * PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0ndXRmLTgnPz48c29hcGVudjpFbnZlbG9wZSB4
095: * Y3VtZW50YXRpb24uPC9EZXNjcmlwdGlvbj48L05vdGlmaWNhdGlvbj48L3NvYXBlbnY6Qm9keT48
096: * L3NvYXBlbnY6RW52ZWxvcGU+
097: * <p/>
098: * ----boundary_0_9fdec710-2336-4dc9-8bcd-45f2c06cf605
099: * ----boundary_0_9fdec710-2336-4dc9-8bcd-45f2c06cf605
100: * content-type: application/octet-stream
101: * content-transfer-encoding: base64
102: * <p/>
103: * PHM6RW52ZWxvcGUgeG1sbnM6cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMy8wNS9zb2FwLWVu
104: * dmVsb3BlIiB4bWxuczphPSJodHRwOi8vd3d3LnczLm9yZy8yMDA1LzA4L2FkZHJlc3Npbmci
105: * IHhtbG5zOnU9Imh0dHA6Ly9kb2NzLm9hc2lzLW9wZW4ub3JnL3dzcy8yMDA0LzAxL29hc2lz
106: * LTIwMDQwMS13c3Mtd3NzZWN1cml0eS11dGlsaXR5LTEuMC54c2QiPjxzOkhlYWRlcj48YTpB
107: * Y3Rpb24gczptdXN0VW5kZXJzdGFuZD0iMSI+aHR0cDovL3JlcC5vaW8uZGsvb2lvc2kvSU1l
108: * c3NhZ2VIYW5kbGVyL1JlcXVlc3RSZXNwb25kUmVxdWVzdDwvYTpBY3Rpb24+PGE6TWVzc2Fn
109: */
110: public class MailTransportSender extends AbstractHandler implements
111: TransportSender {
112:
113: /* smtpProperties holds all the parameters needed to Java Mail. This will be filled either from Axis2.xml or
114: from runtime.
115: */
116: private final java.util.Properties smtpProperties = new java.util.Properties();
117:
118: private PasswordAuthentication passwordAuthentication;
119:
120: private ByteArrayOutputStream byteArrayOutputStream;
121:
122: private final static String NAME = "MailTransportSender";
123:
124: public MailTransportSender() {
125: init(new HandlerDescription(NAME));
126: }
127:
128: public void init(ConfigurationContext configurationContext,
129: TransportOutDescription transportOut) throws AxisFault {
130:
131: ArrayList mailParameters = transportOut.getParameters();
132:
133: String password = "";
134: String username = "";
135:
136: for (Iterator iterator = mailParameters.iterator(); iterator
137: .hasNext();) {
138: Parameter param = (Parameter) iterator.next();
139: String paramKey = param.getName();
140: String paramValue = Utils.getParameterValue(param);
141: if (paramKey == null || paramValue == null) {
142: throw new AxisFault(Messages.getMessage("canNotBeNull",
143: "Parameter name and value"));
144:
145: }
146: smtpProperties.setProperty(paramKey, paramValue);
147: if (paramKey.equals(Constants.SMTP_USER)) {
148: username = paramValue;
149: }
150: if (paramKey.equals(Constants.SMTP_USER_PASSWORD)) {
151: password = paramValue;
152: }
153:
154: }
155: passwordAuthentication = new PasswordAuthentication(username,
156: password);
157: }
158:
159: public void cleanup(MessageContext msgContext) throws AxisFault {
160: }
161:
162: private void mailProperties(MessageContext msgContext) {
163: Object obj = msgContext.getProperty(Constants.MAIL_SMTP);
164: if (obj != null) {
165: // Overide the axis2.xml cofiguration setting
166: if (obj instanceof HttpTransportProperties.MailProperties) {
167: HttpTransportProperties.MailProperties props = (HttpTransportProperties.MailProperties) obj;
168: smtpProperties.clear();
169: smtpProperties.putAll(props.getProperties());
170: String username = (String) smtpProperties
171: .get(Constants.SMTP_USER);
172: String passwd = props.getPassword();
173: passwordAuthentication = new PasswordAuthentication(
174: username, passwd);
175: } else if (obj instanceof java.util.Properties) {
176: smtpProperties.clear();
177: java.util.Properties props = (java.util.Properties) obj;
178: smtpProperties.putAll(props);
179: }
180: }
181:
182: }
183:
184: public void sendMimeMessage(MessageContext msgContext)
185: throws AxisFault {
186: try {
187: // Override with runtime settings
188: mailProperties(msgContext);
189:
190: EMailSender sender = new EMailSender();
191: sender.setOutputStream(byteArrayOutputStream);
192: sender.setMessageContext(msgContext);
193: sender.setProperties(smtpProperties);
194: sender.setPasswordAuthentication(passwordAuthentication);
195:
196: // In mail char set is what is being used. Charset encoding is not what is expected here.
197: String charSet = (String) msgContext
198: .getProperty(org.apache.axis2.Constants.Configuration.CHARACTER_SET_ENCODING);
199: if (charSet == null) {
200: charSet = MessageContext.DEFAULT_CHAR_SET_ENCODING;
201: }
202:
203: OMOutputFormat format = new OMOutputFormat();
204:
205: format.setSOAP11(msgContext.isSOAP11());
206: format.setCharSetEncoding(charSet);
207: // Check if msg is 'In-Reply-To' received message
208: OutTransportInfo transportInfo = (OutTransportInfo) msgContext
209: .getProperty(org.apache.axis2.Constants.OUT_TRANSPORT_INFO);
210:
211: if (transportInfo != null
212: && transportInfo instanceof MailBasedOutTransportInfo) {
213: MailBasedOutTransportInfo mailTransportInfo = (MailBasedOutTransportInfo) transportInfo;
214:
215: sender.setInReplyTo(mailTransportInfo.getInReplyTo());
216: sender.setFrom(mailTransportInfo.getFrom());
217: }
218: sender.setFormat(format);
219:
220: sender.send();
221:
222: } catch (IOException e) {
223: throw new AxisFault(e.getMessage(), e);
224: }
225: }
226:
227: public void writeMimeMessage(MessageContext msgContext,
228: OutputStream out) throws AxisFault {
229: try {
230: OMOutputFormat format = new OMOutputFormat();
231: MessageFormatter messageFormatter = TransportUtils
232: .getMessageFormatter(msgContext);
233: format.setDoOptimize(msgContext.isDoingMTOM());
234: //Set to null so that the code will not fail on 7bit.
235: format.setCharSetEncoding(null);
236: messageFormatter.writeTo(msgContext, format, out, false);
237: out.flush();
238: } catch (Exception e) {
239: throw new AxisFault(e.getMessage(), e);
240: }
241: }
242:
243: public void stop() {
244: }
245:
246: /**
247: * @param msgContext
248: * @return
249: * @throws AxisFault
250: */
251: public InvocationResponse invoke(MessageContext msgContext)
252: throws AxisFault {
253:
254: msgContext.setDoingMTOM(HTTPTransportUtils
255: .doWriteMTOM(msgContext));
256: msgContext.setDoingSwA(HTTPTransportUtils
257: .doWriteSwA(msgContext));
258:
259: byteArrayOutputStream = new ByteArrayOutputStream();
260: writeMimeMessage(msgContext, byteArrayOutputStream);
261:
262: sendMimeMessage(msgContext);
263:
264: return InvocationResponse.CONTINUE;
265: }
266: }
|