1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  
21  
22  package org.apache.mailet.base.test;
23  
24  import org.apache.mailet.base.RFC2822Headers;
25  
26  import javax.mail.internet.MimeMessage;
27  import javax.mail.internet.InternetHeaders;
28  import javax.mail.internet.InternetAddress;
29  import javax.mail.*;
30  import javax.mail.search.SearchTerm;
31  import javax.activation.DataHandler;
32  import java.util.*;
33  import java.io.ByteArrayInputStream;
34  import java.io.InputStream;
35  import java.io.IOException;
36  import java.io.OutputStream;
37  import java.io.UnsupportedEncodingException;
38  
39  public class FakeMimeMessage extends MimeMessage {
40  
41      private final List m_fromAddresses = new ArrayList();
42      private Address m_senderAddress;
43      private final List m_toRecepients = new ArrayList();
44      private final List m_ccRecepients = new ArrayList();
45      private final List m_bccRecepients = new ArrayList();
46      private final List m_replyToAddresses = new ArrayList();
47      private String m_subject;
48      private int m_iMessageNumber;
49      private boolean m_bIsExpunged;
50      private Object m_content;
51      private Date m_sentDate;
52      private String[] m_contentLanguage;
53      private String m_fileName;
54      private DataHandler m_dataHandler;
55      private HashMap m_contentHeaders = new HashMap();
56      private Flags m_setFlags = new Flags();
57      private boolean m_doMatch;
58  
59      public FakeMimeMessage() throws MessagingException {
60          super((Session)null);
61      }
62  
63      public FakeMimeMessage(int messageNumber) throws MessagingException {
64          super((Session)null);
65          m_iMessageNumber = messageNumber;
66      }
67  
68      public FakeMimeMessage(MimeMessage mimeMessage) throws MessagingException {
69          super(mimeMessage); // trivial implementation
70      }
71  
72      public Address[] getFrom() throws MessagingException {
73          return (Address[])m_fromAddresses.toArray(new Address[m_fromAddresses.size()]);
74      }
75      
76      public void setFrom(Address address) throws MessagingException {
77          m_fromAddresses.clear();
78          m_fromAddresses.add(address);
79      }
80  
81      public void setFrom() throws MessagingException {
82          m_fromAddresses.clear();
83          m_fromAddresses.add(InternetAddress.getLocalAddress(null));
84      }
85  
86      public void addFrom(Address[] addresses) throws MessagingException {
87          m_fromAddresses.add(addresses);
88      }
89  
90      public Address getSender() throws MessagingException {
91          return m_senderAddress;
92      }
93  
94      public void setSender(Address address) throws MessagingException {
95          m_senderAddress = address;
96      }
97  
98      public Address[] getRecipients(Message.RecipientType recipientType) throws MessagingException {
99          List recipientsList = getRecipientsList(recipientType);
100         List recipientAddresses = new ArrayList();
101         for (Iterator iterator = recipientsList.iterator(); iterator.hasNext();) {
102             String recipient = (String) iterator.next();
103             recipientAddresses.add(new InternetAddress(recipient));
104         }
105         return (Address[]) (recipientAddresses.toArray(new Address[]{}));
106     }
107 
108     private List getRecipientsList(Message.RecipientType recipientType) {
109         if (Message.RecipientType.TO.equals(recipientType)) return m_toRecepients; 
110         if (Message.RecipientType.CC.equals(recipientType)) return m_ccRecepients; 
111         if (Message.RecipientType.BCC.equals(recipientType)) return m_bccRecepients;
112         return null;
113     }
114     
115     public Address[] getAllRecipients() throws MessagingException {
116         List allRecipients = new ArrayList();
117         allRecipients.addAll(m_toRecepients);
118         allRecipients.addAll(m_ccRecepients);
119         allRecipients.addAll(m_bccRecepients);
120         return (Address[]) allRecipients.toArray();
121     }
122 
123     public void setRecipients(Message.RecipientType recipientType, Address[] addresses) throws MessagingException {
124         getRecipientsList(recipientType).addAll(Arrays.asList(addresses));
125     }
126 
127     public void setRecipients(Message.RecipientType recipientType, String recipient) throws MessagingException {
128         getRecipientsList(recipientType).add(recipient);
129     }
130 
131     public void addRecipients(Message.RecipientType recipientType, Address[] addresses) throws MessagingException {
132         getRecipientsList(recipientType).addAll(Arrays.asList(addresses));
133     }
134 
135     public void addRecipients(Message.RecipientType recipientType, String recipient) throws MessagingException {
136         getRecipientsList(recipientType).add(recipient);
137     }
138 
139     public Address[] getReplyTo() throws MessagingException {
140         return (Address[]) m_replyToAddresses.toArray();
141     }
142 
143     public void setReplyTo(Address[] addresses) throws MessagingException {
144         m_replyToAddresses.addAll(Arrays.asList(addresses));
145     }
146 
147     public String getSubject() throws MessagingException {
148         return m_subject;
149     }
150 
151     public void setSubject(String subject) throws MessagingException {
152         m_subject = subject;
153     }
154 
155     public void setSubject(String subject, String charset) throws MessagingException {
156         if (subject == null)
157         {
158             m_subject = null;
159             return;
160         }
161         try {
162             m_subject = new String(subject.getBytes(charset));
163         } catch (UnsupportedEncodingException e) {
164             throw new MessagingException("setting subject failed", e);
165         }
166     }
167 
168     public Date getSentDate() throws MessagingException {
169         return m_sentDate;
170     }
171 
172     public void setSentDate(Date date) throws MessagingException {
173         m_sentDate = date;
174     }
175 
176     public Date getReceivedDate() throws MessagingException {
177         return null; // trivial implementation
178     }
179 
180     public int getSize() throws MessagingException {
181         return -1; // trivial implementation
182     }
183 
184     public int getLineCount() throws MessagingException {
185         return -1; // trivial implementation
186     }
187 
188     public String getContentType() throws MessagingException {
189         return getHeader("Content-Type", null);
190     }
191 
192     public boolean isMimeType(String mimeType) throws MessagingException {
193         return mimeType.startsWith(getContentType());
194     }
195 
196     public String getDisposition() throws MessagingException {
197         return getHeader("Content-Disposition", null);
198     }
199 
200     public void setDisposition(String disposition) throws MessagingException {
201         setHeader("Content-Disposition", disposition);
202     }
203 
204     public String getEncoding() throws MessagingException {
205         return getHeader("Content-Transfer-Encoding", null);
206     }
207 
208     public String getContentID() throws MessagingException {
209         return getHeader("Content-ID", null);
210     }
211 
212     public void setContentID(String contentID) throws MessagingException {
213         setHeader("Content-ID", contentID);
214     }
215 
216     public String getContentMD5() throws MessagingException {
217         return getHeader("Content-MD5", null);
218     }
219 
220     public void setContentMD5(String value) throws MessagingException {
221         setHeader("Content-MD5", value);
222     }
223 
224     public String getDescription() throws MessagingException {
225         return getHeader("Content-Description", null);
226     }
227 
228     public void setDescription(String description) throws MessagingException { 
229         setHeader("Content-Description", description);
230     }
231 
232     public void setDescription(String description, String charset) throws MessagingException {
233         try {
234             setDescription(new String(description.getBytes(charset)));
235         } catch (UnsupportedEncodingException e) {
236             throw new MessagingException("setting description failed", e);
237         }
238     }
239 
240     public String[] getContentLanguage() throws MessagingException {
241         return m_contentLanguage;
242     }
243 
244     public void setContentLanguage(String[] contentLanguage) throws MessagingException {
245         m_contentLanguage = contentLanguage;
246     }
247 
248     public String getMessageID() throws MessagingException {
249         return "ID-" + m_iMessageNumber; // trivial implementation
250     }
251 
252     public String getFileName() throws MessagingException {
253         return m_fileName;
254     }
255 
256     public void setFileName(String fileName) throws MessagingException {
257         m_fileName = fileName;
258     }
259 
260     public InputStream getInputStream() throws IOException, MessagingException {
261         return null; // trivial implementation
262     }
263 
264     protected InputStream getContentStream() throws MessagingException {
265         return null; // trivial implementation
266     }
267 
268     public InputStream getRawInputStream() throws MessagingException {
269         if (m_content instanceof String) {
270             return new ByteArrayInputStream(m_content.toString().getBytes());
271         }
272         throw new UnsupportedOperationException("Unimplementated method");
273     }
274 
275     public synchronized DataHandler getDataHandler() throws MessagingException {
276         return m_dataHandler;
277     }
278 
279     public synchronized void setDataHandler(DataHandler dataHandler) throws MessagingException {
280         m_dataHandler = dataHandler;
281     }
282 
283     public Object getContent() throws IOException, MessagingException {
284         return m_content;
285     }
286 
287     public void setContent(Object object, String mimeType) throws MessagingException {
288         m_content = object;  // trivial implementation
289         addHeader(RFC2822Headers.CONTENT_TYPE, mimeType);
290     }
291 
292     public void setText(String string) throws MessagingException {
293         setContent(string, "text/plain");
294     }
295 
296     public void setText(String string, String charset) throws MessagingException {
297         try {
298             setContent(new String(string.getBytes(charset)) , "text/plain");
299         } catch (UnsupportedEncodingException e) {
300             throw new MessagingException("setting text content failed", e);
301         }
302     }
303 
304     public void setContent(Multipart multipart) throws MessagingException {
305         m_content = multipart;
306     }
307 
308     public Message reply(boolean b) throws MessagingException {
309         return new FakeMimeMessage(this); // trivial implementation
310     }
311 
312     public void writeTo(OutputStream outputStream) throws IOException, MessagingException {
313         ; // trivial implementation
314     }
315 
316     public void writeTo(OutputStream outputStream, String[] strings) throws IOException, MessagingException {
317         ; // trivial implementation
318     }
319 
320     public String[] getHeader(String name) throws MessagingException {
321         String value = (String) m_contentHeaders.get(name);
322         if (value == null) return null;
323         return new String[] {value};
324     }
325 
326     public String getHeader(String name, String delimiter) throws MessagingException {
327         String[] header = getHeader(name);
328         if (header == null || header.length == 0) return null;
329         return header[0];
330     }
331 
332     public void setHeader(String name, String value) throws MessagingException {
333         addHeader(name, value);
334     }
335 
336     public void addHeader(String name, String value) throws MessagingException {
337         m_contentHeaders.put(name, value);
338     }
339 
340     public void removeHeader(String name) throws MessagingException {
341         m_contentHeaders.remove(name);
342     }
343 
344     public Enumeration getAllHeaders() throws MessagingException {
345         return Collections.enumeration(m_contentHeaders.values());
346     }
347 
348     public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
349         ArrayList matchingHeaders = new ArrayList();
350         for (int i = 0; i < names.length; i++) {
351             String name = names[i];
352             String value = getHeader(name, null);
353             if (value == null) continue;
354             matchingHeaders.add(value);
355         }
356         return Collections.enumeration(matchingHeaders); 
357     }
358 
359     public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
360         List existingHeaders = Arrays.asList(names);
361 
362         ArrayList nonMatchingHeaders = new ArrayList();
363         
364         Iterator iterator = m_contentHeaders.keySet().iterator();
365         while (iterator.hasNext()) {
366             String name = (String) iterator.next();
367             if (existingHeaders.contains(name)) continue;
368             String value = getHeader(name, null);
369             if (value == null) continue;
370             nonMatchingHeaders.add(value);
371         }
372         return Collections.enumeration(nonMatchingHeaders); 
373     }
374 
375     public void addHeaderLine(String headerLine) throws MessagingException {
376         int separatorIndex = headerLine.indexOf(":");
377         if (separatorIndex < 0) throw new MessagingException("header line does not conform to standard");
378         
379         addHeader(headerLine.substring(0,separatorIndex), headerLine.substring(separatorIndex,headerLine.length()));
380     }
381 
382     public Enumeration getAllHeaderLines() throws MessagingException {
383         return Collections.enumeration(getHeadersAsStrings(m_contentHeaders));
384     }
385 
386     private ArrayList getHeadersAsStrings(HashMap contentHeaders) {
387         ArrayList headerLines = new ArrayList();
388         Iterator iterator = contentHeaders.keySet().iterator();
389         while (iterator.hasNext()) {
390             String key = (String) iterator.next();
391             String value = (String) contentHeaders.get(key);
392             headerLines.add(key + ":" + value);
393         }
394         return headerLines;
395     }
396 
397     public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
398         ArrayList matchingHeaders = new ArrayList();
399         for (int i = 0; i < names.length; i++) {
400             String name = names[i];
401             String value = getHeader(name, null);
402             if (value == null) continue;
403             matchingHeaders.add(name + ":" + value);
404         }
405         return Collections.enumeration(matchingHeaders); 
406     }
407 
408     public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
409         List existingHeaders = names != null ? Arrays.asList(names) : null;
410 
411         ArrayList nonMatchingHeaders = new ArrayList();
412         
413         Iterator iterator = m_contentHeaders.keySet().iterator();
414         while (iterator.hasNext()) {
415             String name = (String) iterator.next();
416             if (existingHeaders!=null && existingHeaders.contains(name)) continue;
417             String value = getHeader(name, null);
418             if (value == null) continue;
419             nonMatchingHeaders.add(name + ":" + value);
420         }
421         return Collections.enumeration(nonMatchingHeaders); 
422     }
423 
424     public synchronized Flags getFlags() throws MessagingException {
425         return new Flags(m_setFlags);
426     }
427 
428     public synchronized boolean isSet(Flags.Flag flag) throws MessagingException {
429         return m_setFlags.contains(flag);
430     }
431 
432     public synchronized void setFlags(Flags flags, boolean set) throws MessagingException {
433         if (set) m_setFlags.add(flags);
434         else m_setFlags.remove(flags);
435     }
436 
437     public void saveChanges() throws MessagingException {
438         ; // trivial implementation
439     }
440 
441     protected void updateHeaders() throws MessagingException {
442         ; // trivial implementation 
443     }
444 
445     protected InternetHeaders createInternetHeaders(InputStream inputStream) throws MessagingException {
446         return new InternetHeaders();
447     }
448 
449     public void setRecipient(Message.RecipientType recipientType, Address address) throws MessagingException {
450         setRecipients(recipientType, new Address[]{address});
451     }
452 
453     public void addRecipient(Message.RecipientType recipientType, Address address) throws MessagingException {
454         setRecipients(recipientType, new Address[]{address});
455     }
456 
457     public void setFlag(Flags.Flag flag, boolean set) throws MessagingException {
458         if (set) m_setFlags.add(flag);
459         else m_setFlags.remove(flag);
460     }
461 
462     public int getMessageNumber() {
463         return m_iMessageNumber;
464     }
465 
466     protected void setMessageNumber(int i) {
467         m_iMessageNumber = i;
468     }
469 
470     public Folder getFolder() {
471         return null;
472     }
473 
474     public boolean isExpunged() {
475         return m_bIsExpunged;
476     }
477 
478     protected void setExpunged(boolean b) {
479         m_bIsExpunged = b;
480     }
481 
482     public void setShouldMatch(boolean doMatch) {
483         m_doMatch = doMatch;
484     }
485     
486     public boolean match(SearchTerm searchTerm) throws MessagingException {
487         return m_doMatch; 
488     }
489 }