KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > james > fetchmail > FolderProcessor


1 /***********************************************************************
2  * Copyright (c) 2003-2004 The Apache Software Foundation. *
3  * All rights reserved. *
4  * ------------------------------------------------------------------- *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you *
6  * may not use this file except in compliance with the License. You *
7  * may obtain a copy of the License at: *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14  * implied. See the License for the specific language governing *
15  * permissions and limitations under the License. *
16  ***********************************************************************/

17  
18 package org.apache.james.fetchmail;
19
20 import javax.mail.FetchProfile JavaDoc;
21 import javax.mail.Flags JavaDoc;
22 import javax.mail.Folder JavaDoc;
23 import javax.mail.Message JavaDoc;
24 import javax.mail.MessagingException JavaDoc;
25 import javax.mail.internet.MimeMessage JavaDoc;
26
27 /**
28  * <p>Class <code>FolderProcessor</code> opens a Folder and iterates over all
29  * of the Messages, delegating their processing to
30  * <code>MessageProcessor</code>.</p>
31  *
32  * <p>If isRecurse(), all subfolders are fetched recursively.</p>
33  *
34  * <p>Creation Date: 25-May-03</p>
35  *
36  */

37 public class FolderProcessor extends ProcessorAbstract
38 {
39     /**
40      * The fetched folder
41      */

42     private Folder JavaDoc fieldFolder;
43     
44     private Boolean JavaDoc fieldMarkSeenPermanent;
45
46     /**
47      * Constructor for FolderProcessor.
48      * @param folder The folder to be fetched
49      * @param account The account being processed
50      */

51     protected FolderProcessor(Folder JavaDoc folder, Account account)
52     {
53         super(account);
54         setFolder(folder);
55     }
56     
57     /**
58      * Method process opens a Folder, fetches the Envelopes for all of its
59      * Messages, creates a <code>MessageProcessor</code> and runs it to process
60      * each message.
61      *
62      * @see org.apache.james.fetchmail.ProcessorAbstract#process()
63      */

64     public void process() throws MessagingException JavaDoc
65     {
66         int messagesProcessed = 0;
67         int messageCount = 0;
68         try
69         {
70             // open the folder
71
try
72             {
73                 open();
74             }
75             catch (MessagingException JavaDoc ex)
76             {
77                 getLogger().error(
78                     getFetchTaskName() + " Failed to open folder!");
79                 throw ex;
80             }
81
82             // Lock the folder while processing each message
83
synchronized (getFolder())
84             {
85                 messageCount = getFolder().getMessageCount();
86                 for (int i = 1; i <= messageCount; i++)
87                 {
88                     MimeMessage JavaDoc message =
89                         (MimeMessage JavaDoc) getFolder().getMessage(i);
90                     if (isFetchAll() || !isSeen(message))
91                     {
92                         try
93                         {
94                             new MessageProcessor(message, getAccount())
95                                 .process();
96                             messagesProcessed++;
97                         }
98                         // Catch and report an exception but don't rethrow it,
99
// allowing subsequent messages to be processed.
100
catch (Exception JavaDoc ex)
101                         {
102                             StringBuffer JavaDoc logMessageBuffer =
103                                 new StringBuffer JavaDoc("Exception processing message ID: ");
104                             logMessageBuffer.append(message.getMessageID());
105                             getLogger().error(logMessageBuffer.toString(), ex);
106                         }
107                     }
108                 }
109             }
110         }
111         catch (MessagingException JavaDoc mex)
112         {
113             getLogger().error(
114                 "A MessagingException has terminated fetching messages for this folder",
115                 mex);
116         }
117         finally
118         {
119             // Close the folder
120
try
121             {
122                 close();
123             }
124             catch (MessagingException JavaDoc ex)
125             {
126                 // No-op
127
}
128             StringBuffer JavaDoc logMessageBuffer = new StringBuffer JavaDoc("Processed ");
129             logMessageBuffer.append(messagesProcessed);
130             logMessageBuffer.append(" messages of ");
131             logMessageBuffer.append(messageCount);
132             logMessageBuffer.append(" in folder '");
133             logMessageBuffer.append(getFolder().getName());
134             logMessageBuffer.append("'");
135             getLogger().info(logMessageBuffer.toString());
136         }
137
138         // Recurse through sub-folders if required
139
try
140         {
141             if (isRecurse())
142                 recurse();
143         }
144         catch (MessagingException JavaDoc mex)
145         {
146             getLogger().error(
147                 "A MessagingException has terminated recursing through sub-folders",
148                 mex);
149         }
150
151         return;
152     }
153     
154     /**
155      * Method close.
156      * @throws MessagingException
157      */

158     protected void close() throws MessagingException JavaDoc
159     {
160         if (null != getFolder() && getFolder().isOpen())
161             getFolder().close(true);
162     }
163     
164     /**
165      * Method recurse.
166      * @throws MessagingException
167      */

168     protected void recurse() throws MessagingException JavaDoc
169     {
170         if ((getFolder().getType() & Folder.HOLDS_FOLDERS)
171             == Folder.HOLDS_FOLDERS)
172         {
173             // folder contains subfolders...
174
Folder JavaDoc folders[] = getFolder().list();
175
176             for (int i = 0; i < folders.length; i++)
177             {
178                 new FolderProcessor(folders[i], getAccount()).process();
179             }
180
181         }
182     }
183     
184     /**
185      * Method open.
186      * @throws MessagingException
187      */

188     protected void open() throws MessagingException JavaDoc
189     {
190         int openFlag = Folder.READ_WRITE;
191         
192         if (isOpenReadOnly())
193             openFlag = Folder.READ_ONLY;
194
195         getFolder().open(openFlag);
196     }
197
198     /**
199      * Returns the folder.
200      * @return Folder
201      */

202     protected Folder JavaDoc getFolder()
203     {
204         return fieldFolder;
205     }
206     
207     /**
208      * Answer if <code>aMessage</code> has been SEEN.
209      * @param aMessage
210      * @return boolean
211      * @throws MessagingException
212      */

213     protected boolean isSeen(MimeMessage JavaDoc aMessage) throws MessagingException JavaDoc
214     {
215         boolean isSeen = false;
216         if (isMarkSeenPermanent().booleanValue())
217             isSeen = aMessage.isSet(Flags.Flag.SEEN);
218         else
219             isSeen = handleMarkSeenNotPermanent(aMessage);
220         return isSeen;
221     }
222
223     /**
224      * Answer the result of computing markSeenPermanent.
225      * @return Boolean
226      */

227     protected Boolean JavaDoc computeMarkSeenPermanent()
228     {
229         return new Boolean JavaDoc(
230             getFolder().getPermanentFlags().contains(Flags.Flag.SEEN));
231     }
232
233     /**
234      * <p>Handler for when the folder does not support the SEEN flag.
235      * The default behaviour implemented here is to answer the value of the
236      * SEEN flag anyway.</p>
237      *
238      * <p>Subclasses may choose to override this method and implement their own
239      * solutions.</p>
240      *
241      * @param aMessage
242      * @return boolean
243      * @throws MessagingException
244      */

245     protected boolean handleMarkSeenNotPermanent(MimeMessage JavaDoc aMessage)
246         throws MessagingException JavaDoc
247     {
248         return aMessage.isSet(Flags.Flag.SEEN);
249     }
250
251     /**
252      * Sets the folder.
253      * @param folder The folder to set
254      */

255     protected void setFolder(Folder JavaDoc folder)
256     {
257         fieldFolder = folder;
258     }
259     
260     /**
261      * Returns the isMarkSeenPermanent.
262      * @return Boolean
263      */

264     protected Boolean JavaDoc isMarkSeenPermanent()
265     {
266         Boolean JavaDoc markSeenPermanent = null;
267         if (null == (markSeenPermanent = isMarkSeenPermanentBasic()))
268         {
269             updateMarkSeenPermanent();
270             return isMarkSeenPermanent();
271         }
272         return markSeenPermanent;
273     }
274     
275     /**
276      * Returns the markSeenPermanent.
277      * @return Boolean
278      */

279     private Boolean JavaDoc isMarkSeenPermanentBasic()
280     {
281         return fieldMarkSeenPermanent;
282     }
283
284     /**
285      * Sets the markSeenPermanent.
286      * @param markSeenPermanent The isMarkSeenPermanent to set
287      */

288     protected void setMarkSeenPermanent(Boolean JavaDoc markSeenPermanent)
289     {
290         fieldMarkSeenPermanent = markSeenPermanent;
291     }
292     
293     /**
294      * Updates the markSeenPermanent.
295      */

296     protected void updateMarkSeenPermanent()
297     {
298         setMarkSeenPermanent(computeMarkSeenPermanent());
299     }
300
301 }
302
Popular Tags