View Javadoc

1   /*
2    * Copyright 2007 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.transport.mail;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.ByteArrayOutputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.net.URI;
25  import java.net.URISyntaxException;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.Enumeration;
29  import java.util.Iterator;
30  import java.util.List;
31  import javax.activation.DataHandler;
32  import javax.activation.DataSource;
33  import javax.mail.Address;
34  import javax.mail.Header;
35  import javax.mail.Message;
36  import javax.mail.MessagingException;
37  import javax.mail.Session;
38  import javax.mail.Transport;
39  import javax.mail.URLName;
40  import javax.mail.internet.InternetAddress;
41  
42  import org.springframework.util.Assert;
43  import org.springframework.util.ObjectUtils;
44  import org.springframework.ws.WebServiceMessage;
45  import org.springframework.ws.transport.AbstractReceiverConnection;
46  import org.springframework.ws.transport.TransportConstants;
47  import org.springframework.ws.transport.WebServiceConnection;
48  import org.springframework.ws.transport.mail.support.MailTransportUtils;
49  
50  /**
51   * Implementation of {@link WebServiceConnection} that is used for server-side Mail access. Exposes a {@link Message}
52   * request and response message.
53   *
54   * @author Arjen Poutsma
55   * @since 1.5.0
56   */
57  public class MailReceiverConnection extends AbstractReceiverConnection {
58  
59      private final Message requestMessage;
60  
61      private final Session session;
62  
63      private Message responseMessage;
64  
65      private ByteArrayOutputStream responseBuffer;
66  
67      private String responseContentType;
68  
69      private URLName transportUri;
70  
71      private InternetAddress from;
72  
73      /** Constructs a new Mail connection with the given parameters. */
74      protected MailReceiverConnection(Message requestMessage, Session session) {
75          Assert.notNull(requestMessage, "'requestMessage' must not be null");
76          Assert.notNull(session, "'session' must not be null");
77          this.requestMessage = requestMessage;
78          this.session = session;
79      }
80  
81      /** Returns the request message for this connection. */
82      public Message getRequestMessage() {
83          return requestMessage;
84      }
85  
86      /** Returns the response message, if any, for this connection. */
87      public Message getResponseMessage() {
88          return responseMessage;
89      }
90  
91      /*
92       * Package-friendly setters
93       */
94      void setTransportUri(URLName transportUri) {
95          this.transportUri = transportUri;
96      }
97  
98      void setFrom(InternetAddress from) {
99          this.from = from;
100     }
101 
102     /*
103      * URI
104      */
105 
106     public URI getUri() throws URISyntaxException {
107         try {
108             Address[] recipients = requestMessage.getRecipients(Message.RecipientType.TO);
109             if (!ObjectUtils.isEmpty(recipients) && recipients[0] instanceof InternetAddress) {
110                 return MailTransportUtils.toUri((InternetAddress) recipients[0], requestMessage.getSubject());
111             }
112             else {
113                 throw new URISyntaxException("", "Could not determine To header");
114             }
115         }
116         catch (MessagingException ex) {
117             throw new URISyntaxException("", ex.getMessage());
118         }
119     }
120 /*
121      * Errors
122      */
123 
124     public String getErrorMessage() throws IOException {
125         return null;
126     }
127 
128     public boolean hasError() throws IOException {
129         return false;
130     }
131 
132     /*
133     * Receiving
134     */
135 
136     protected Iterator getRequestHeaderNames() throws IOException {
137         try {
138             List headers = new ArrayList();
139             Enumeration enumeration = requestMessage.getAllHeaders();
140             while (enumeration.hasMoreElements()) {
141                 Header header = (Header) enumeration.nextElement();
142                 headers.add(header.getName());
143             }
144             return headers.iterator();
145         }
146         catch (MessagingException ex) {
147             throw new IOException(ex.getMessage());
148         }
149     }
150 
151     protected Iterator getRequestHeaders(String name) throws IOException {
152         try {
153             String[] headers = requestMessage.getHeader(name);
154             return Arrays.asList(headers).iterator();
155         }
156         catch (MessagingException ex) {
157             throw new MailTransportException(ex);
158         }
159     }
160 
161     protected InputStream getRequestInputStream() throws IOException {
162         try {
163             return requestMessage.getInputStream();
164         }
165         catch (MessagingException ex) {
166             throw new MailTransportException(ex);
167         }
168     }
169 
170     protected void addResponseHeader(String name, String value) throws IOException {
171         try {
172             responseMessage.addHeader(name, value);
173             if (TransportConstants.HEADER_CONTENT_TYPE.equals(name)) {
174                 responseContentType = value;
175             }
176         }
177         catch (MessagingException ex) {
178             throw new MailTransportException(ex);
179         }
180     }
181 
182     protected OutputStream getResponseOutputStream() throws IOException {
183         return responseBuffer;
184     }
185 
186     /*
187      * Sending
188      */
189 
190     protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
191         try {
192             responseMessage = requestMessage.reply(false);
193             responseMessage.setFrom(from);
194 
195             responseBuffer = new ByteArrayOutputStream();
196         }
197         catch (MessagingException ex) {
198             throw new MailTransportException(ex);
199         }
200     }
201 
202     protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
203         Transport transport = null;
204         try {
205             responseMessage.setDataHandler(
206                     new DataHandler(new ByteArrayDataSource(responseContentType, responseBuffer.toByteArray())));
207             transport = session.getTransport(transportUri);
208             transport.connect();
209             responseMessage.saveChanges();
210             transport.sendMessage(responseMessage, responseMessage.getAllRecipients());
211         }
212         catch (MessagingException ex) {
213             throw new MailTransportException(ex);
214         }
215         finally {
216             MailTransportUtils.closeService(transport);
217         }
218     }
219 
220     private class ByteArrayDataSource implements DataSource {
221 
222         private byte[] data;
223 
224         private String contentType;
225 
226         public ByteArrayDataSource(String contentType, byte[] data) {
227             this.data = data;
228             this.contentType = contentType;
229         }
230 
231         public String getContentType() {
232             return contentType;
233         }
234 
235         public InputStream getInputStream() throws IOException {
236             return new ByteArrayInputStream(data);
237         }
238 
239         public String getName() {
240             return "ByteArrayDataSource";
241         }
242 
243         public OutputStream getOutputStream() throws IOException {
244             throw new UnsupportedOperationException();
245         }
246     }
247 }