001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.fetchmail;
019:
020: import java.util.ArrayList;
021: import java.util.Collections;
022: import java.util.Enumeration;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Properties;
028:
029: import javax.mail.MessagingException;
030: import javax.mail.Session;
031:
032: import org.apache.avalon.cornerstone.services.scheduler.Target;
033: import org.apache.avalon.framework.configuration.Configurable;
034: import org.apache.avalon.framework.configuration.Configuration;
035: import org.apache.avalon.framework.configuration.ConfigurationException;
036: import org.apache.avalon.framework.logger.AbstractLogEnabled;
037: import org.apache.avalon.framework.service.ServiceException;
038: import org.apache.avalon.framework.service.ServiceManager;
039: import org.apache.avalon.framework.service.Serviceable;
040: import org.apache.james.services.MailServer;
041: import org.apache.james.services.UsersRepository;
042:
043: /**
044: * <p>Class <code>FetchMail</code> is an Avalon task that is periodically
045: * triggered to fetch mail from a JavaMail Message Store.</p>
046: *
047: * <p>The lifecycle of an instance of <code>FetchMail</code> is managed by
048: * Avalon. The <code>configure(Configuration)</code> method is invoked to parse
049: * and validate Configuration properties. The targetTriggered(String) method is
050: * invoked to execute the task.</p>
051: *
052: * <p>When triggered, a sorted list of Message Store Accounts to be processed is
053: * built. Each Message Store Account is processed by delegating to
054: * <code>StoreProcessor</code>.</p>
055: *
056: * <p>There are two kinds of Message Store Accounts, static and dynamic. Static
057: * accounts are expliciltly declared in the Configuration. Dynamic accounts are
058: * built each time the task is executed, one per each user defined to James,
059: * using the James user name with a configurable prefix and suffix to define
060: * the host user identity and recipient identity for each Account. Dynamic
061: * accounts allow <code>FetchMail</code> to fetch mail for all James users
062: * without modifying the Configuration parameters or restarting the Avalon
063: * server.</p>
064: *
065: * <p>To fully understand the operations supported by this task, read the Class
066: * documention for each Class in the delegation chain starting with this
067: * class' delegate, <code>StoreProcessor</code>. </p>
068: *
069: * <p>Creation Date: 24-May-03</p>
070: *
071: */
072: public class FetchMail extends AbstractLogEnabled implements
073: Configurable, Target, Serviceable {
074: /**
075: * Key fields for DynamicAccounts.
076: */
077: private class DynamicAccountKey {
078: /**
079: * The base user name without prfix or suffix
080: */
081: private String fieldUserName;
082:
083: /**
084: * The sequence number of the parameters used to construct the Account
085: */
086: private int fieldSequenceNumber;
087:
088: /**
089: * Constructor for DynamicAccountKey.
090: */
091: private DynamicAccountKey() {
092: super ();
093: }
094:
095: /**
096: * Constructor for DynamicAccountKey.
097: */
098: public DynamicAccountKey(String userName, int sequenceNumber) {
099: this ();
100: setUserName(userName);
101: setSequenceNumber(sequenceNumber);
102: }
103:
104: /**
105: * @see java.lang.Object#equals(Object)
106: */
107: public boolean equals(Object obj) {
108: if (null == obj)
109: return false;
110: if (!(obj.getClass() == getClass()))
111: return false;
112: return (getUserName().equals(
113: ((DynamicAccountKey) obj).getUserName()) && getSequenceNumber() == ((DynamicAccountKey) obj)
114: .getSequenceNumber());
115: }
116:
117: /**
118: * @see java.lang.Object#hashCode()
119: */
120: public int hashCode() {
121: return getUserName().hashCode() ^ getSequenceNumber();
122: }
123:
124: /**
125: * Returns the sequenceNumber.
126: * @return int
127: */
128: public int getSequenceNumber() {
129: return fieldSequenceNumber;
130: }
131:
132: /**
133: * Returns the userName.
134: * @return String
135: */
136: public String getUserName() {
137: return fieldUserName;
138: }
139:
140: /**
141: * Sets the sequenceNumber.
142: * @param sequenceNumber The sequenceNumber to set
143: */
144: protected void setSequenceNumber(int sequenceNumber) {
145: fieldSequenceNumber = sequenceNumber;
146: }
147:
148: /**
149: * Sets the userName.
150: * @param userName The userName to set
151: */
152: protected void setUserName(String userName) {
153: fieldUserName = userName;
154: }
155:
156: }
157:
158: /**
159: * Creation Date: 06-Jun-03
160: */
161: private class ParsedDynamicAccountParameters {
162: private String fieldUserPrefix;
163: private String fieldUserSuffix;
164:
165: private String fieldPassword;
166:
167: private int fieldSequenceNumber;
168:
169: private boolean fieldIgnoreRecipientHeader;
170: private String fieldRecipientPrefix;
171: private String fieldRecipientSuffix;
172: private String customRecipientHeader;
173:
174: /**
175: * Constructor for ParsedDynamicAccountParameters.
176: */
177: private ParsedDynamicAccountParameters() {
178: super ();
179: }
180:
181: /**
182: * Constructor for ParsedDynamicAccountParameters.
183: */
184: public ParsedDynamicAccountParameters(int sequenceNumber,
185: Configuration configuration)
186: throws ConfigurationException {
187: this ();
188: setSequenceNumber(sequenceNumber);
189: setUserPrefix(configuration.getAttribute("userprefix", ""));
190: setUserSuffix(configuration.getAttribute("usersuffix", ""));
191: setRecipientPrefix(configuration.getAttribute(
192: "recipientprefix", ""));
193: setRecipientSuffix(configuration.getAttribute(
194: "recipientsuffix", ""));
195: setPassword(configuration.getAttribute("password"));
196: setIgnoreRecipientHeader(configuration
197: .getAttributeAsBoolean("ignorercpt-header"));
198: setCustomRecipientHeader(configuration.getAttribute(
199: "customrcpt-header", ""));
200: }
201:
202: /**
203: * Returns the custom recipient header.
204: * @return String
205: */
206: public String getCustomRecipientHeader() {
207: return this .customRecipientHeader;
208: }
209:
210: /**
211: * Returns the recipientprefix.
212: * @return String
213: */
214: public String getRecipientPrefix() {
215: return fieldRecipientPrefix;
216: }
217:
218: /**
219: * Returns the recipientsuffix.
220: * @return String
221: */
222: public String getRecipientSuffix() {
223: return fieldRecipientSuffix;
224: }
225:
226: /**
227: * Returns the userprefix.
228: * @return String
229: */
230: public String getUserPrefix() {
231: return fieldUserPrefix;
232: }
233:
234: /**
235: * Returns the userSuffix.
236: * @return String
237: */
238: public String getUserSuffix() {
239: return fieldUserSuffix;
240: }
241:
242: /**
243: * Sets the custom recipient header.
244: * @param customRecipientHeader The header to be used
245: */
246: public void setCustomRecipientHeader(
247: String customRecipientHeader) {
248: this .customRecipientHeader = customRecipientHeader;
249: }
250:
251: /**
252: * Sets the recipientprefix.
253: * @param recipientprefix The recipientprefix to set
254: */
255: protected void setRecipientPrefix(String recipientprefix) {
256: fieldRecipientPrefix = recipientprefix;
257: }
258:
259: /**
260: * Sets the recipientsuffix.
261: * @param recipientsuffix The recipientsuffix to set
262: */
263: protected void setRecipientSuffix(String recipientsuffix) {
264: fieldRecipientSuffix = recipientsuffix;
265: }
266:
267: /**
268: * Sets the userprefix.
269: * @param userprefix The userprefix to set
270: */
271: protected void setUserPrefix(String userprefix) {
272: fieldUserPrefix = userprefix;
273: }
274:
275: /**
276: * Sets the userSuffix.
277: * @param userSuffix The userSuffix to set
278: */
279: protected void setUserSuffix(String userSuffix) {
280: fieldUserSuffix = userSuffix;
281: }
282:
283: /**
284: * Returns the password.
285: * @return String
286: */
287: public String getPassword() {
288: return fieldPassword;
289: }
290:
291: /**
292: * Sets the ignoreRecipientHeader.
293: * @param ignoreRecipientHeader The ignoreRecipientHeader to set
294: */
295: protected void setIgnoreRecipientHeader(
296: boolean ignoreRecipientHeader) {
297: fieldIgnoreRecipientHeader = ignoreRecipientHeader;
298: }
299:
300: /**
301: * Sets the password.
302: * @param password The password to set
303: */
304: protected void setPassword(String password) {
305: fieldPassword = password;
306: }
307:
308: /**
309: * Returns the ignoreRecipientHeader.
310: * @return boolean
311: */
312: public boolean isIgnoreRecipientHeader() {
313: return fieldIgnoreRecipientHeader;
314: }
315:
316: /**
317: * Returns the sequenceNumber.
318: * @return int
319: */
320: public int getSequenceNumber() {
321: return fieldSequenceNumber;
322: }
323:
324: /**
325: * Sets the sequenceNumber.
326: * @param sequenceNumber The sequenceNumber to set
327: */
328: protected void setSequenceNumber(int sequenceNumber) {
329: fieldSequenceNumber = sequenceNumber;
330: }
331:
332: }
333:
334: /**
335: * @see org.apache.avalon.cornerstone.services.scheduler.Target#targetTriggered(String)
336: */
337: private boolean fieldFetching = false;
338:
339: /**
340: * The Configuration for this task
341: */
342: private ParsedConfiguration fieldConfiguration;
343:
344: /**
345: * A List of ParsedDynamicAccountParameters, one for every <alllocal> entry
346: * in the configuration.
347: */
348: private List fieldParsedDynamicAccountParameters;
349:
350: /**
351: * The Static Accounts for this task.
352: * These are setup when the task is configured.
353: */
354: private List fieldStaticAccounts;
355:
356: /**
357: * The JavaMail Session for this fetch task.
358: */
359:
360: private Session fieldSession;
361:
362: /**
363: * The Dynamic Accounts for this task.
364: * These are setup each time the fetchtask is run.
365: */
366: private Map fieldDynamicAccounts;
367:
368: /**
369: * The MailServer service
370: */
371: private MailServer fieldServer;
372:
373: /**
374: * The Local Users repository
375: */
376: private UsersRepository fieldLocalUsers;
377:
378: /**
379: * Constructor for POP3mail.
380: */
381: public FetchMail() {
382: super ();
383: }
384:
385: /**
386: * Method configure parses and validates the Configuration data and creates
387: * a new <code>ParsedConfiguration</code>, an <code>Account</code> for each
388: * configured static account and a <code>ParsedDynamicAccountParameters</code>
389: * for each dynamic account.
390: *
391: * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
392: */
393: public void configure(Configuration configuration)
394: throws ConfigurationException {
395: // Set any Session parameters passed in the Configuration
396: setSessionParameters(configuration);
397:
398: // Create the ParsedConfiguration used in the delegation chain
399: ParsedConfiguration parsedConfiguration = new ParsedConfiguration(
400: configuration, getLogger(), getServer(),
401: getLocalUsers());
402: setConfiguration(parsedConfiguration);
403:
404: // Setup the Accounts
405: Configuration[] allAccounts = configuration
406: .getChildren("accounts");
407: if (allAccounts.length < 1)
408: throw new ConfigurationException(
409: "Missing <accounts> section.");
410: if (allAccounts.length > 1)
411: throw new ConfigurationException(
412: "Too many <accounts> sections, there must be exactly one");
413: Configuration accounts = allAccounts[0];
414:
415: // Create an Account for every configured account
416: Configuration[] accountsChildren = accounts.getChildren();
417: if (accountsChildren.length < 1)
418: throw new ConfigurationException(
419: "Missing <account> section.");
420:
421: for (int i = 0; i < accountsChildren.length; i++) {
422: Configuration accountsChild = accountsChildren[i];
423:
424: if ("alllocal".equals(accountsChild.getName())) {
425: // <allLocal> is dynamic, save the parameters for accounts to
426: // be created when the task is triggered
427: getParsedDynamicAccountParameters().add(
428: new ParsedDynamicAccountParameters(i,
429: accountsChild));
430: continue;
431: }
432:
433: if ("account".equals(accountsChild.getName())) {
434: // Create an Account for the named user and
435: // add it to the list of static accounts
436: getStaticAccounts()
437: .add(
438: new Account(
439: i,
440: parsedConfiguration,
441: accountsChild
442: .getAttribute("user"),
443: accountsChild
444: .getAttribute("password"),
445: accountsChild
446: .getAttribute("recipient"),
447: accountsChild
448: .getAttributeAsBoolean("ignorercpt-header"),
449: accountsChild
450: .getAttribute(
451: "customrcpt-header",
452: ""),
453: getSession()));
454: continue;
455: }
456:
457: throw new ConfigurationException("Illegal token: <"
458: + accountsChild.getName() + "> in <accounts>");
459: }
460: }
461:
462: /**
463: * Method target triggered fetches mail for each configured account.
464: *
465: * @see org.apache.avalon.cornerstone.services.scheduler.Target#targetTriggered(String)
466: */
467: public void targetTriggered(String arg0) {
468: // if we are already fetching then just return
469: if (isFetching()) {
470: getLogger()
471: .info(
472: "Triggered fetch cancelled. A fetch is already in progress.");
473: return;
474: }
475:
476: // Enter Fetching State
477: try {
478: setFetching(true);
479: getLogger().info("Fetcher starting fetches");
480:
481: // if debugging, list the JavaMail property key/value pairs
482: // for this Session
483: if (getLogger().isDebugEnabled()) {
484: getLogger().debug("Session properties:");
485: Properties properties = getSession().getProperties();
486: Enumeration e = properties.keys();
487: while (e.hasMoreElements()) {
488: String key = (String) e.nextElement();
489: String val = (String) properties.get(key);
490: if (val.length() > 40) {
491: val = val.substring(0, 37) + "...";
492: }
493: getLogger().debug(key + "=" + val);
494:
495: }
496: }
497:
498: // Update the dynamic accounts,
499: // merge with the static accounts and
500: // sort the accounts so they are in the order
501: // they were entered in config.xml
502: updateDynamicAccounts();
503: ArrayList mergedAccounts = new ArrayList(
504: getDynamicAccounts().size()
505: + getStaticAccounts().size());
506: mergedAccounts.addAll(getDynamicAccounts().values());
507: mergedAccounts.addAll(getStaticAccounts());
508: Collections.sort(mergedAccounts);
509:
510: StringBuffer logMessage = new StringBuffer(64);
511: logMessage.append("Processing ");
512: logMessage.append(getStaticAccounts().size());
513: logMessage.append(" static accounts and ");
514: logMessage.append(getDynamicAccounts().size());
515: logMessage.append(" dynamic accounts.");
516: getLogger().info(logMessage.toString());
517:
518: // Fetch each account
519: Iterator accounts = mergedAccounts.iterator();
520: while (accounts.hasNext()) {
521: try {
522: new StoreProcessor((Account) accounts.next())
523: .process();
524: } catch (MessagingException ex) {
525: getLogger()
526: .error(
527: "A MessagingException has terminated processing of this Account",
528: ex);
529: }
530: }
531: } catch (Exception ex) {
532: getLogger().error(
533: "An Exception has terminated this fetch.", ex);
534: } finally {
535: getLogger().info("Fetcher completed fetches");
536:
537: // Exit Fetching State
538: setFetching(false);
539: }
540: }
541:
542: /**
543: * Returns the fetching.
544: * @return boolean
545: */
546: protected boolean isFetching() {
547: return fieldFetching;
548: }
549:
550: /**
551: * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
552: */
553: public void service(final ServiceManager manager)
554: throws ServiceException {
555: try {
556: setServer((MailServer) manager.lookup(MailServer.ROLE));
557: } catch (ClassCastException cce) {
558: StringBuffer errorBuffer = new StringBuffer(128).append(
559: "Component ").append(MailServer.ROLE).append(
560: "does not implement the required interface.");
561: throw new ServiceException("", errorBuffer.toString());
562: }
563:
564: UsersRepository usersRepository = (UsersRepository) manager
565: .lookup(UsersRepository.ROLE);
566: setLocalUsers(usersRepository);
567: }
568:
569: /**
570: * Sets the fetching.
571: * @param fetching The fetching to set
572: */
573: protected void setFetching(boolean fetching) {
574: fieldFetching = fetching;
575: }
576:
577: /**
578: * Returns the server.
579: * @return MailServer
580: */
581: protected MailServer getServer() {
582: return fieldServer;
583: }
584:
585: /**
586: * Returns the configuration.
587: * @return ParsedConfiguration
588: */
589: protected ParsedConfiguration getConfiguration() {
590: return fieldConfiguration;
591: }
592:
593: /**
594: * Sets the configuration.
595: * @param configuration The configuration to set
596: */
597: protected void setConfiguration(ParsedConfiguration configuration) {
598: fieldConfiguration = configuration;
599: }
600:
601: /**
602: * Sets the server.
603: * @param server The server to set
604: */
605: protected void setServer(MailServer server) {
606: fieldServer = server;
607: }
608:
609: /**
610: * Returns the localUsers.
611: * @return UsersRepository
612: */
613: protected UsersRepository getLocalUsers() {
614: return fieldLocalUsers;
615: }
616:
617: /**
618: * Sets the localUsers.
619: * @param localUsers The localUsers to set
620: */
621: protected void setLocalUsers(UsersRepository localUsers) {
622: fieldLocalUsers = localUsers;
623: }
624:
625: /**
626: * Returns the accounts. Initializes if required.
627: * @return List
628: */
629: protected List getStaticAccounts() {
630: if (null == getStaticAccountsBasic()) {
631: updateStaticAccounts();
632: return getStaticAccounts();
633: }
634: return fieldStaticAccounts;
635: }
636:
637: /**
638: * Returns the staticAccounts.
639: * @return List
640: */
641: private List getStaticAccountsBasic() {
642: return fieldStaticAccounts;
643: }
644:
645: /**
646: * Sets the accounts.
647: * @param accounts The accounts to set
648: */
649: protected void setStaticAccounts(List accounts) {
650: fieldStaticAccounts = accounts;
651: }
652:
653: /**
654: * Updates the staticAccounts.
655: */
656: protected void updateStaticAccounts() {
657: setStaticAccounts(computeStaticAccounts());
658: }
659:
660: /**
661: * Updates the ParsedDynamicAccountParameters.
662: */
663: protected void updateParsedDynamicAccountParameters() {
664: setParsedDynamicAccountParameters(computeParsedDynamicAccountParameters());
665: }
666:
667: /**
668: * Updates the dynamicAccounts.
669: */
670: protected void updateDynamicAccounts()
671: throws ConfigurationException {
672: setDynamicAccounts(computeDynamicAccounts());
673: }
674:
675: /**
676: * Computes the staticAccounts.
677: */
678: protected List computeStaticAccounts() {
679: return new ArrayList();
680: }
681:
682: /**
683: * Computes the ParsedDynamicAccountParameters.
684: */
685: protected List computeParsedDynamicAccountParameters() {
686: return new ArrayList();
687: }
688:
689: /**
690: * Computes the dynamicAccounts.
691: */
692: protected Map computeDynamicAccounts()
693: throws ConfigurationException {
694: Map newAccounts = new HashMap(getLocalUsers().countUsers()
695: * getParsedDynamicAccountParameters().size());
696: Map oldAccounts = getDynamicAccountsBasic();
697: if (null == oldAccounts)
698: oldAccounts = new HashMap(0);
699:
700: Iterator parameterIterator = getParsedDynamicAccountParameters()
701: .iterator();
702:
703: // Process each ParsedDynamicParameters
704: while (parameterIterator.hasNext()) {
705: Map accounts = computeDynamicAccounts(oldAccounts,
706: (ParsedDynamicAccountParameters) parameterIterator
707: .next());
708: // Remove accounts from oldAccounts.
709: // This avoids an average 2*N increase in heapspace used as the
710: // newAccounts are created.
711: Iterator oldAccountsIterator = oldAccounts.keySet()
712: .iterator();
713: while (oldAccountsIterator.hasNext()) {
714: if (accounts.containsKey(oldAccountsIterator.next()))
715: oldAccountsIterator.remove();
716: }
717: // Add this parameter's accounts to newAccounts
718: newAccounts.putAll(accounts);
719: }
720: return newAccounts;
721: }
722:
723: /**
724: * Returns the dynamicAccounts. Initializes if required.
725: * @return Map
726: */
727: protected Map getDynamicAccounts() throws ConfigurationException {
728: if (null == getDynamicAccountsBasic()) {
729: updateDynamicAccounts();
730: return getDynamicAccounts();
731: }
732: return fieldDynamicAccounts;
733: }
734:
735: /**
736: * Returns the dynamicAccounts.
737: * @return Map
738: */
739: private Map getDynamicAccountsBasic() {
740: return fieldDynamicAccounts;
741: }
742:
743: /**
744: * Sets the dynamicAccounts.
745: * @param dynamicAccounts The dynamicAccounts to set
746: */
747: protected void setDynamicAccounts(Map dynamicAccounts) {
748: fieldDynamicAccounts = dynamicAccounts;
749: }
750:
751: /**
752: * Compute the dynamicAccounts for the passed parameters.
753: * Accounts for existing users are copied and accounts for new users are
754: * created.
755: * @param oldAccounts
756: * @param parameters
757: * @return Map - The current Accounts
758: * @throws ConfigurationException
759: */
760: protected Map computeDynamicAccounts(Map oldAccounts,
761: ParsedDynamicAccountParameters parameters)
762: throws ConfigurationException {
763: Map accounts = new HashMap(getLocalUsers().countUsers());
764: Iterator usersIterator = getLocalUsers().list();
765: while (usersIterator.hasNext()) {
766: String userName = (String) usersIterator.next();
767: DynamicAccountKey key = new DynamicAccountKey(userName,
768: parameters.getSequenceNumber());
769: Account account = (Account) oldAccounts.get(key);
770: if (null == account) {
771: // Create a new DynamicAccount
772: account = new DynamicAccount(parameters
773: .getSequenceNumber(), getConfiguration(),
774: userName, parameters.getUserPrefix(),
775: parameters.getUserSuffix(), parameters
776: .getPassword(), parameters
777: .getRecipientPrefix(), parameters
778: .getRecipientSuffix(), parameters
779: .isIgnoreRecipientHeader(), parameters
780: .getCustomRecipientHeader(),
781: getSession());
782: }
783: accounts.put(key, account);
784: }
785: return accounts;
786: }
787:
788: /**
789: * Resets the dynamicAccounts.
790: */
791: protected void resetDynamicAccounts() {
792: setDynamicAccounts(null);
793: }
794:
795: /**
796: * Returns the ParsedDynamicAccountParameters.
797: * @return List
798: */
799: protected List getParsedDynamicAccountParameters() {
800: if (null == getParsedDynamicAccountParametersBasic()) {
801: updateParsedDynamicAccountParameters();
802: return getParsedDynamicAccountParameters();
803: }
804: return fieldParsedDynamicAccountParameters;
805: }
806:
807: /**
808: * Returns the ParsedDynamicAccountParameters.
809: * @return List
810: */
811: private List getParsedDynamicAccountParametersBasic() {
812: return fieldParsedDynamicAccountParameters;
813: }
814:
815: /**
816: * Sets the ParsedDynamicAccountParameters.
817: * @param ParsedDynamicAccountParameters The ParsedDynamicAccountParametersto set
818: */
819: protected void setParsedDynamicAccountParameters(
820: List parsedDynamicAccountParameters) {
821: fieldParsedDynamicAccountParameters = parsedDynamicAccountParameters;
822: }
823:
824: /**
825: * Returns the session, lazily initialized if required.
826: * @return Session
827: */
828: protected Session getSession() {
829: Session session = null;
830: if (null == (session = getSessionBasic())) {
831: updateSession();
832: return getSession();
833: }
834: return session;
835: }
836:
837: /**
838: * Returns the session.
839: * @return Session
840: */
841: private Session getSessionBasic() {
842: return fieldSession;
843: }
844:
845: /**
846: * Answers a new Session.
847: * @return Session
848: */
849: protected Session computeSession() {
850: return Session.getInstance(System.getProperties());
851: }
852:
853: /**
854: * Updates the current Session.
855: */
856: protected void updateSession() {
857: setSession(computeSession());
858: }
859:
860: /**
861: * Sets the session.
862: * @param session The session to set
863: */
864: protected void setSession(Session session) {
865: fieldSession = session;
866: }
867:
868: /**
869: * Propogate any Session parameters in the configuration to the Session.
870: * @param configuration The configuration containing the parameters
871: * @throws ConfigurationException
872: */
873: protected void setSessionParameters(Configuration configuration)
874: throws ConfigurationException {
875: Configuration javaMailProperties = configuration.getChild(
876: "javaMailProperties", false);
877: if (null != javaMailProperties) {
878: Properties properties = getSession().getProperties();
879: Configuration[] allProperties = javaMailProperties
880: .getChildren("property");
881: for (int i = 0; i < allProperties.length; i++) {
882: properties.setProperty(allProperties[i]
883: .getAttribute("name"), allProperties[i]
884: .getAttribute("value"));
885: if (getLogger().isDebugEnabled()) {
886: StringBuffer messageBuffer = new StringBuffer(
887: "Set property name: ");
888: messageBuffer.append(allProperties[i]
889: .getAttribute("name"));
890: messageBuffer.append(" to: ");
891: messageBuffer.append(allProperties[i]
892: .getAttribute("value"));
893: getLogger().debug(messageBuffer.toString());
894: }
895: }
896: }
897: }
898:
899: }
|