View Javadoc

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  package org.apache.jsieve.mailet;
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.Enumeration;
26  import java.util.HashMap;
27  import java.util.HashSet;
28  import java.util.Iterator;
29  import java.util.List;
30  import java.util.ListIterator;
31  import java.util.Map;
32  import java.util.Set;
33  
34  import javax.mail.Header;
35  import javax.mail.MessagingException;
36  import javax.mail.internet.MimeMessage;
37  
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.apache.james.mime4j.field.address.AddressList;
41  import org.apache.james.mime4j.field.address.Mailbox;
42  import org.apache.james.mime4j.field.address.MailboxList;
43  import org.apache.james.mime4j.field.address.parser.ParseException;
44  import org.apache.jsieve.exception.InternetAddressException;
45  import org.apache.jsieve.exception.SieveException;
46  import org.apache.jsieve.mail.Action;
47  import org.apache.jsieve.mail.MailAdapter;
48  import org.apache.jsieve.mail.MailUtils;
49  import org.apache.jsieve.mail.SieveMailException;
50  import org.apache.jsieve.mail.optional.EnvelopeAccessors;
51  import org.apache.mailet.Mail;
52  import org.apache.mailet.MailAddress;
53  import org.apache.mailet.MailetContext;
54  /**
55   * <p>
56   * Class <code>SieveMailAdapter</code> implements a <code>MailAdapter</code>
57   * for use in a Mailet environment.
58   * </p>
59   */
60  public class SieveMailAdapter implements MailAdapter, EnvelopeAccessors, ActionContext
61  {
62      private static final Log LOG = LogFactory.getLog(SieveMailAdapter.class);
63      
64      private Log log = LOG;
65      
66      /**
67       * The Mail being adapted.
68       */
69      private Mail fieldMail;
70      /**
71       * The MailetContext.
72       */
73      private MailetContext fieldMailetContext;
74      /**
75       * List of Actions to perform.
76       */
77      private List fieldActions;
78      
79      private final ActionDispatcher dispatcher;
80      
81      private final Poster poster;
82      
83      /**
84       * Constructor for SieveMailAdapter.
85       * 
86       * @param aMail
87       * @param aMailetContext
88       */
89      public SieveMailAdapter(final Mail aMail, final MailetContext aMailetContext, final ActionDispatcher dispatcher, final Poster poster)
90      {
91          this.poster = poster;
92          this.dispatcher = dispatcher;
93          setMail(aMail);
94          setMailetContext(aMailetContext);
95      }
96      
97    
98      public void setLog(Log log) {
99          this.log = log;
100     }
101 
102     /**
103      * Returns the message.
104      * 
105      * @return MimeMessage
106      */
107     protected MimeMessage getMessage() throws MessagingException
108     {
109         return getMail().getMessage();
110     }
111     /**
112      * Returns the List of actions.
113      * 
114      * @return List
115      */
116     public List getActions()
117     {
118         List actions = null;
119         if (null == (actions = getActionsBasic()))
120         {
121             updateActions();
122             return getActions();
123         }
124         return actions;
125     }
126     /**
127      * Returns a new List of actions.
128      * 
129      * @return List
130      */
131     protected List computeActions()
132     {
133         return new ArrayList();
134     }
135     /**
136      * Returns the List of actions.
137      * 
138      * @return List
139      */
140     private List getActionsBasic()
141     {
142         return fieldActions;
143     }
144     /**
145      * Adds an Action.
146      * 
147      * @param action The action to set
148      */
149     public void addAction(Action action)
150     {
151         getActions().add(action);
152     }
153     /**
154      * @see org.apache.jsieve.mail.MailAdapter#executeActions()
155      */
156     public void executeActions() throws SieveException
157     {
158         ListIterator actionsIter = getActionsIterator();
159         while (actionsIter.hasNext())
160         {
161             Action action = (Action) actionsIter.next();
162             getMailetContext().log("Executing action: " + action.toString());
163             try
164             {
165                 dispatcher.execute(action, getMail(), this);
166             }
167             catch (MessagingException e)
168             {
169                 throw new SieveException(e);
170             }
171         }
172     }
173     /**
174      * Sets the actions.
175      * 
176      * @param actions The actions to set
177      */
178     protected void setActions(List actions)
179     {
180         fieldActions = actions;
181     }
182     /**
183      * Updates the actions.
184      */
185     protected void updateActions()
186     {
187         setActions(computeActions());
188     }
189     /**
190      * @see org.apache.jsieve.mail.MailAdapter#getActionsIterator()
191      */
192     public ListIterator getActionsIterator()
193     {
194         return getActions().listIterator();
195     }
196     /**
197      * @see org.apache.jsieve.mail.MailAdapter#getHeader(String)
198      */
199     public List getHeader(String name) throws SieveMailException
200     {
201         try
202         {
203             String[] headers = getMessage().getHeader(name);
204             return (headers == null ? new ArrayList(0) : Arrays.asList(headers));
205         }
206         catch (MessagingException ex)
207         {
208             throw new SieveMailException(ex);
209         }
210     }
211     /**
212      * @see org.apache.jsieve.mail.MailAdapter#getHeaderNames()
213      */
214     public List getHeaderNames() throws SieveMailException
215     {
216         Set headerNames = new HashSet();
217         try
218         {
219             Enumeration allHeaders = getMessage().getAllHeaders();
220             while (allHeaders.hasMoreElements())
221             {
222                 headerNames.add(((Header) allHeaders.nextElement()).getName());
223             }
224             return new ArrayList(headerNames);
225         }
226         catch (MessagingException ex)
227         {
228             throw new SieveMailException(ex);
229         }
230     }
231     /**
232      * @see org.apache.jsieve.mail.MailAdapter#getMatchingHeader(String)
233      */
234     public List getMatchingHeader(String name) throws SieveMailException
235     {
236         return MailUtils.getMatchingHeader(this, name);
237     }
238     /**
239      * @see org.apache.jsieve.mail.MailAdapter#getSize()
240      */
241     public int getSize() throws SieveMailException
242     {
243         try
244         {
245             return getMessage().getSize();
246         }
247         catch (MessagingException ex)
248         {
249             throw new SieveMailException(ex);
250         }
251     }
252     /**
253      * Method getEnvelopes.
254      * 
255      * @return Map
256      */
257     protected Map getEnvelopes()
258     {
259         Map envelopes = new HashMap(2);
260         if (null != getEnvelopeFrom())
261             envelopes.put("From", getEnvelopeFrom());
262         if (null != getEnvelopeTo())
263             envelopes.put("To", getEnvelopeTo());
264         return envelopes;
265     }
266     /**
267      * @see org.apache.jsieve.mail.optional.EnvelopeAccessors#getEnvelope(String)
268      */
269     public List getEnvelope(String name) throws SieveMailException
270     {
271         List values = new ArrayList(1);
272         Object value = getEnvelopes().get(name);
273         if (null != value)
274             values.add(value);
275         return values;
276     }
277     /**
278      * @see org.apache.jsieve.mail.optional.EnvelopeAccessors#getEnvelopeNames()
279      */
280     public List getEnvelopeNames() throws SieveMailException
281     {
282         return new ArrayList(getEnvelopes().keySet());
283     }
284     /**
285      * @see org.apache.jsieve.mail.optional.EnvelopeAccessors#getMatchingEnvelope(String)
286      */
287     public List getMatchingEnvelope(String name) throws SieveMailException
288     {
289         Iterator envelopeNamesIter = getEnvelopeNames().iterator();
290         List matchedEnvelopeValues = new ArrayList(32);
291         while (envelopeNamesIter.hasNext())
292         {
293             String envelopeName = (String) envelopeNamesIter.next();
294             if (envelopeName.trim().equalsIgnoreCase(name))
295                 matchedEnvelopeValues.addAll(getEnvelope(envelopeName));
296         }
297         return matchedEnvelopeValues;
298     }
299     /**
300      * Returns the from.
301      * 
302      * @return String
303      */
304     public String getEnvelopeFrom()
305     {
306         MailAddress sender = getMail().getSender(); 
307         return (null == sender ? "" : sender.toString());
308     }
309     /**
310      * Returns the sole recipient or null if there isn't one.
311      * 
312      * @return String
313      */
314     public String getEnvelopeTo()
315     {
316         String recipient = null;
317         Iterator recipientIter = getMail().getRecipients().iterator();
318         if (recipientIter.hasNext())
319             recipient = (String) recipientIter.next().toString();
320         return recipient;
321     }
322     /**
323      * Returns the mail.
324      * 
325      * @return Mail
326      */
327     public Mail getMail()
328     {
329         return fieldMail;
330     }
331     /**
332      * Sets the mail.
333      * 
334      * @param mail The mail to set
335      */
336     protected void setMail(Mail mail)
337     {
338         fieldMail = mail;
339     }
340     /**
341      * Returns the mailetContext.
342      * 
343      * @return MailetContext
344      */
345     public MailetContext getMailetContext()
346     {
347         return fieldMailetContext;
348     }
349     /**
350      * Sets the mailetContext.
351      * 
352      * @param mailetContext The mailetContext to set
353      */
354     protected void setMailetContext(MailetContext mailetContext)
355     {
356         fieldMailetContext = mailetContext;
357     }
358     /**
359      * @see java.lang.Object#toString()
360      */
361     public String toString()
362     {
363         String messageID = null;
364         try
365         {
366             messageID = getMail().getMessage().getMessageID();
367         }
368         catch (MessagingException e)
369         {
370             messageID = "<" + e.getMessage() + ">";
371         }
372         return getClass().getName() + " Envelope From: "
373                 + (null == getEnvelopeFrom() ? "null" : getEnvelopeFrom())
374                 + " Envelope To: "
375                 + (null == getEnvelopeTo() ? "null" : getEnvelopeTo())
376                 + " Message ID: " + (null == messageID ? "null" : messageID);
377     }
378     
379     public Object getContent() throws SieveMailException {
380         try {
381             return getMessage().getContent();
382         } catch (MessagingException e) {
383             throw new SieveMailException(e);
384         } catch (IOException e) {
385             throw new SieveMailException(e);
386         }
387     }
388     public String getContentType() throws SieveMailException {
389         try {
390             return getMessage().getContentType();
391         } catch (MessagingException e) {
392             throw new SieveMailException(e);
393         }
394     }
395     
396     public Address[] parseAddresses(String arg) throws SieveMailException, InternetAddressException {
397         try {
398             final MailboxList list = AddressList.parse(arg).flatten();
399             final int size = list.size();
400             final Address[] results = new Address[size];
401             for (int i=0;i<size;i++) {
402                 final Mailbox mailbox = list.get(i);
403                 results[i] = new AddressImpl(mailbox.getLocalPart(), mailbox.getDomain());
404             }
405             return null;
406         } catch (ParseException e) {
407             throw new InternetAddressException(e);
408         }
409     }
410     
411     /**
412      * Simple immutable address implementation.
413      * TODO: replace this with JSieve version
414      */
415     private static final class AddressImpl implements MailAdapter.Address {
416 
417         private final String localPart;
418         private final String domain;
419         
420         /**
421          * Constructs an address.
422          * @param localPart the local part of the address
423          * @param domain the domain part of the address
424          */
425         public AddressImpl(final String localPart, final String domain) {
426             super();
427             this.localPart = localPart;
428             this.domain = domain;
429         }
430 
431         /**
432          * Gets the domain of the address.
433          * @return domain
434          */
435         public String getDomain() {
436             return domain;
437         }
438 
439         /**
440          * Gets the local part of the address.
441          */
442         public String getLocalPart() {
443             return localPart;
444         }
445     }
446 
447     public Log getLog() {
448         return log;
449     }
450     
451     public String getServerInfo() {
452         return getMailetContext().getServerInfo();
453     }
454     public void post(String uri, MimeMessage mail) throws MessagingException {
455         poster.post(uri, mail);
456     }
457     
458     public void post(MailAddress sender, Collection recipients, MimeMessage mail) throws MessagingException {
459         getMailetContext().sendMail(sender, recipients, mail);
460     }
461 }