KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > service > mail > JavaMailContainer


1 /*
2  * $Id: JavaMailContainer.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  * Copyright (c) 2001-2005 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  */

25 package org.ofbiz.service.mail;
26
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Properties JavaDoc;
31 import java.util.Timer JavaDoc;
32 import java.util.TimerTask JavaDoc;
33 import javax.mail.*;
34 import javax.mail.internet.MimeMessage JavaDoc;
35 import javax.mail.event.StoreEvent JavaDoc;
36 import javax.mail.event.StoreListener JavaDoc;
37
38 import org.ofbiz.base.container.Container;
39 import org.ofbiz.base.container.ContainerConfig;
40 import org.ofbiz.base.container.ContainerException;
41 import org.ofbiz.base.util.Debug;
42 import org.ofbiz.base.util.GeneralException;
43 import org.ofbiz.base.util.UtilValidate;
44 import org.ofbiz.base.util.UtilMisc;
45 import org.ofbiz.entity.GenericDelegator;
46 import org.ofbiz.entity.GenericValue;
47 import org.ofbiz.entity.GenericEntityException;
48 import org.ofbiz.service.GenericDispatcher;
49 import org.ofbiz.service.LocalDispatcher;
50 import org.ofbiz.service.GenericServiceException;
51
52 import org.apache.commons.collections.map.LinkedMap;
53
54 /**
55  *
56  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
57  * @version $Rev: 5462 $
58  * @since 3.3
59  */

60 public class JavaMailContainer implements Container {
61
62     public static final String JavaDoc module = JavaMailContainer.class.getName();
63     public static final String JavaDoc INBOX = "INBOX";
64
65     protected GenericDelegator delegator = null;
66     protected LocalDispatcher dispatcher = null;
67     protected GenericValue userLogin = null;
68     protected long timerDelay = 300000;
69     protected Timer JavaDoc pollTimer = null;
70     protected boolean deleteMail = false; // whether to delete emails after fetching them.
71

72     protected String JavaDoc configFile = null;
73     protected Map JavaDoc stores = null;
74
75     /**
76      * Initialize the container
77      *
78      * @param args args from calling class
79      * @param configFile Location of master OFBiz configuration file
80      * @throws org.ofbiz.base.container.ContainerException
81      *
82      */

83     public void init(String JavaDoc[] args, String JavaDoc configFile) throws ContainerException {
84         this.configFile = configFile;
85         this.stores = new LinkedMap();
86         this.pollTimer = new Timer JavaDoc();
87     }
88
89     /**
90      * Start the container
91      *
92      * @return true if server started
93      * @throws org.ofbiz.base.container.ContainerException
94      *
95      */

96     public boolean start() throws ContainerException {
97         ContainerConfig.Container cfg = ContainerConfig.getContainer("javamail-container", configFile);
98         String JavaDoc dispatcherName = ContainerConfig.getPropertyValue(cfg, "dispatcher-name", "JavaMailDispatcher");
99         String JavaDoc delegatorName = ContainerConfig.getPropertyValue(cfg, "delegator-name", "default");
100         if ("true".equals(ContainerConfig.getPropertyValue(cfg, "delete-mail", "false"))) {
101             this.deleteMail = true;
102         } else {
103             this.deleteMail = false;
104         }
105         
106         this.delegator = GenericDelegator.getGenericDelegator(delegatorName);
107         this.dispatcher = new GenericDispatcher(dispatcherName, delegator);
108         this.timerDelay = (long) ContainerConfig.getPropertyValue(cfg, "poll-delay", 300000);
109
110         // load the userLogin object
111
String JavaDoc runAsUser = ContainerConfig.getPropertyValue(cfg, "run-as-user", "system");
112         try {
113             this.userLogin = delegator.findByPrimaryKey("UserLogin", UtilMisc.toMap("userLoginId", runAsUser));
114         } catch (GenericEntityException e) {
115             Debug.logError(e, "Unable to load run-as-user UserLogin; cannot start container", module);
116             return false;
117         }
118
119         // load the MCA configuration
120
ServiceMcaUtil.readConfig();
121
122         // load the listeners
123
List JavaDoc configs = cfg.getPropertiesWithValue("store-listener");
124         Iterator JavaDoc i = configs.iterator();
125         while (i.hasNext()) {
126             ContainerConfig.Container.Property prop = (ContainerConfig.Container.Property) i.next();
127             Session session = this.makeSession(prop);
128             Store store = this.getStore(session);
129             if (store != null) {
130                 stores.put(store, session);
131             }
132         }
133
134         // start the polling timer
135
if (stores != null && stores.size() > 0) {
136             pollTimer.schedule(new PollerTask(dispatcher, userLogin), timerDelay, timerDelay);
137         } else {
138             Debug.logWarning("No JavaMail Store(s) configured; poller disabled.", module);
139         }
140
141         return true;
142     }
143
144     /**
145      * Stop the container
146      *
147      * @throws org.ofbiz.base.container.ContainerException
148      *
149      */

150     public void stop() throws ContainerException {
151         // stop the poller
152
this.pollTimer.cancel();
153         Debug.logInfo("stop JavaMail poller", module);
154     }
155
156     // java-mail methods
157
protected Session makeSession(ContainerConfig.Container.Property client) {
158         Properties JavaDoc props = new Properties JavaDoc();
159         Map JavaDoc clientProps = client.properties;
160         if (clientProps != null) {
161             Iterator JavaDoc i = clientProps.entrySet().iterator();
162             while (i.hasNext()) {
163                 Map.Entry JavaDoc e = (Map.Entry JavaDoc) i.next();
164                 ContainerConfig.Container.Property p = (ContainerConfig.Container.Property) e.getValue();
165                 props.setProperty(p.name.toLowerCase(), p.value.toLowerCase());
166             }
167         }
168         return Session.getInstance(props);
169     }
170
171     protected Store getStore(Session session) throws ContainerException {
172         // create the store object
173
Store store = null;
174         try {
175             store = session.getStore();
176         } catch (NoSuchProviderException e) {
177             throw new ContainerException(e);
178         }
179
180         // re-write the URLName including the password for this store
181
if (store != null) {
182             URLName urlName = this.updateUrlName(store.getURLName(), session.getProperties());
183             Debug.log("URLName - " + urlName.toString(), module);
184             try {
185                 store = session.getStore(urlName);
186             } catch (NoSuchProviderException e) {
187                 throw new ContainerException(e);
188             }
189         }
190
191         // test the store
192
try {
193             store.connect();
194             store.close();
195         } catch (MessagingException e) {
196             Debug.logError("Unable to connect to mail store : " + store.getURLName().toString(), module);
197         }
198
199         return store;
200     }
201
202     protected URLName updateUrlName(URLName urlName, Properties JavaDoc props) {
203         String JavaDoc protocol = urlName.getProtocol();
204         String JavaDoc userName = urlName.getUsername();
205         String JavaDoc password = urlName.getPassword();
206         String JavaDoc host = urlName.getHost();
207         String JavaDoc file = urlName.getFile();
208         int port = urlName.getPort();
209
210         // check the username
211
if (UtilValidate.isEmpty(userName)) {
212             userName = props.getProperty("mail." + protocol + ".user");
213             if (UtilValidate.isEmpty(userName)) {
214                 userName = props.getProperty("mail.user");
215             }
216         }
217
218         // check the password; update with the non-standard property
219
if (UtilValidate.isEmpty(password)) {
220             password = props.getProperty("mail." + protocol + ".pass");
221             if (UtilValidate.isEmpty(password)) {
222                 password = props.getProperty("mail.pass");
223             }
224         }
225
226         // check the host
227
if (UtilValidate.isEmpty(host)) {
228             host = props.getProperty("mail." + protocol + ".host");
229             if (UtilValidate.isEmpty(host)) {
230                 host = props.getProperty("mail.host");
231             }
232         }
233
234         Debug.logInfo("Update URL - " + protocol + "://" + userName + "@" + host + ":" + port + "!" + password + ";" + file, module);
235         return new URLName(protocol, host, port, file, userName, password);
236     }
237
238     class LoggingStoreListener implements StoreListener JavaDoc {
239
240         public void notification(StoreEvent JavaDoc event) {
241             String JavaDoc typeString = "";
242             switch(event.getMessageType()) {
243                 case StoreEvent.ALERT:
244                     typeString = "ALERT: ";
245                     break;
246                 case StoreEvent.NOTICE:
247                     typeString = "NOTICE: ";
248                     break;
249             }
250
251             Debug.log("JavaMail " + typeString + event.getMessage(), module);
252         }
253     }
254
255     class PollerTask extends TimerTask JavaDoc {
256
257         LocalDispatcher dispatcher;
258         GenericValue userLogin;
259
260         public PollerTask(LocalDispatcher dispatcher, GenericValue userLogin) {
261             this.dispatcher = dispatcher;
262             this.userLogin = userLogin;
263         }
264
265         public void run() {
266             if (stores != null && stores.size() > 0) {
267                 Iterator JavaDoc i = stores.keySet().iterator();
268                 while (i.hasNext()) {
269                     Store store = (Store) i.next();
270                     Session session = (Session) stores.get(store);
271                     try {
272                         checkMessages(store, session);
273                     } catch (GeneralException e) {
274                         Debug.logError(e, "Mail service invocation error", module);
275                     } catch (MessagingException e) {
276                         Debug.logError(e, "Mail message error", module);
277                     }
278                 }
279             }
280         }
281
282         protected void checkMessages(Store store, Session session) throws MessagingException, GeneralException {
283             store.addStoreListener(new LoggingStoreListener());
284             store.connect();
285
286             // open the default folder
287
Folder folder = store.getDefaultFolder();
288             if (folder == null) {
289                 throw new MessagingException("No default folder available");
290             }
291
292             // open the inbox
293
folder = folder.getFolder(INBOX);
294             if (folder == null) {
295                 throw new MessagingException("No INBOX folder available");
296             }
297
298             // get the message count; stop if nothing to do
299
folder.open(Folder.READ_WRITE);
300             int totalMessages = folder.getMessageCount();
301             if (totalMessages == 0) {
302                 folder.close(false);
303                 store.close();
304                 return;
305             }
306
307             // get all messages
308
Message JavaDoc[] messages = folder.getMessages();
309             FetchProfile profile = new FetchProfile();
310             profile.add(FetchProfile.Item.ENVELOPE);
311             profile.add(FetchProfile.Item.FLAGS);
312             profile.add("X-Mailer");
313             folder.fetch(messages, profile);
314
315             // process each message
316
for (int i = 0; i < messages.length; i++) {
317                 // process each un-read message
318
if (!messages[i].isSet(Flags.Flag.SEEN)) {
319                     this.processMessage(messages[i], session);
320                     Debug.logVerbose("Message from " + UtilMisc.toListArray(messages[i].getFrom()) + " with subject [" + messages[i].getSubject() + "] has been processed." , module);
321                     messages[i].setFlag(Flags.Flag.SEEN, true);
322                     Debug.logVerbose("Message [" + messages[i].getSubject() + "] is marked seen", module);
323                 }
324                 if (deleteMail) {
325                     Debug.logVerbose("Message [" + messages[i].getSubject() + "] is being deleted", module);
326                     messages[i].setFlag(Flags.Flag.DELETED, true);
327                 }
328             }
329
330             // expunge and close the folder
331
folder.close(true);
332             store.close();
333         }
334
335         protected void processMessage(Message JavaDoc message, Session session) {
336             if (message instanceof MimeMessage JavaDoc) {
337                 MimeMessageWrapper wrapper = new MimeMessageWrapper(session, (MimeMessage JavaDoc) message);
338                 try {
339                     ServiceMcaUtil.evalRules(dispatcher, wrapper, userLogin);
340                 } catch (GenericServiceException e) {
341                     Debug.logError(e, "Problem processing message", module);
342                 }
343             }
344         }
345     }
346 }
347
Popular Tags