1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
52
53
54
55
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
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
82 public Message getRequestMessage() {
83 return requestMessage;
84 }
85
86
87 public Message getResponseMessage() {
88 return responseMessage;
89 }
90
91
92
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
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
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
134
135
136 @Override
137 protected Iterator<String> getRequestHeaderNames() throws IOException {
138 try {
139 List<String> headers = new ArrayList<String>();
140 Enumeration<?> enumeration = requestMessage.getAllHeaders();
141 while (enumeration.hasMoreElements()) {
142 Header header = (Header) enumeration.nextElement();
143 headers.add(header.getName());
144 }
145 return headers.iterator();
146 }
147 catch (MessagingException ex) {
148 throw new IOException(ex.getMessage());
149 }
150 }
151
152 @Override
153 protected Iterator<String> getRequestHeaders(String name) throws IOException {
154 try {
155 String[] headers = requestMessage.getHeader(name);
156 return Arrays.asList(headers).iterator();
157 }
158 catch (MessagingException ex) {
159 throw new MailTransportException(ex);
160 }
161 }
162
163 @Override
164 protected InputStream getRequestInputStream() throws IOException {
165 try {
166 return requestMessage.getInputStream();
167 }
168 catch (MessagingException ex) {
169 throw new MailTransportException(ex);
170 }
171 }
172
173 @Override
174 protected void addResponseHeader(String name, String value) throws IOException {
175 try {
176 responseMessage.addHeader(name, value);
177 if (TransportConstants.HEADER_CONTENT_TYPE.equals(name)) {
178 responseContentType = value;
179 }
180 }
181 catch (MessagingException ex) {
182 throw new MailTransportException(ex);
183 }
184 }
185
186 @Override
187 protected OutputStream getResponseOutputStream() throws IOException {
188 return responseBuffer;
189 }
190
191
192
193
194
195 @Override
196 protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
197 try {
198 responseMessage = requestMessage.reply(false);
199 responseMessage.setFrom(from);
200
201 responseBuffer = new ByteArrayOutputStream();
202 }
203 catch (MessagingException ex) {
204 throw new MailTransportException(ex);
205 }
206 }
207
208 @Override
209 protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
210 Transport transport = null;
211 try {
212 responseMessage.setDataHandler(
213 new DataHandler(new ByteArrayDataSource(responseContentType, responseBuffer.toByteArray())));
214 transport = session.getTransport(transportUri);
215 transport.connect();
216 responseMessage.saveChanges();
217 transport.sendMessage(responseMessage, responseMessage.getAllRecipients());
218 }
219 catch (MessagingException ex) {
220 throw new MailTransportException(ex);
221 }
222 finally {
223 MailTransportUtils.closeService(transport);
224 }
225 }
226
227 private class ByteArrayDataSource implements DataSource {
228
229 private byte[] data;
230
231 private String contentType;
232
233 public ByteArrayDataSource(String contentType, byte[] data) {
234 this.data = data;
235 this.contentType = contentType;
236 }
237
238 public String getContentType() {
239 return contentType;
240 }
241
242 public InputStream getInputStream() throws IOException {
243 return new ByteArrayInputStream(data);
244 }
245
246 public String getName() {
247 return "ByteArrayDataSource";
248 }
249
250 public OutputStream getOutputStream() throws IOException {
251 throw new UnsupportedOperationException();
252 }
253 }
254 }