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