1 /************************************************************************
2 * Copyright (c) 2003-2006 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 java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.Enumeration;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Properties;
28
29 import javax.mail.MessagingException;
30 import javax.mail.Session;
31
32 import org.apache.avalon.cornerstone.services.scheduler.Target;
33 import org.apache.avalon.framework.configuration.Configurable;
34 import org.apache.avalon.framework.configuration.Configuration;
35 import org.apache.avalon.framework.configuration.ConfigurationException;
36 import org.apache.avalon.framework.logger.AbstractLogEnabled;
37 import org.apache.avalon.framework.service.ServiceException;
38 import org.apache.avalon.framework.service.ServiceManager;
39 import org.apache.avalon.framework.service.Serviceable;
40 import org.apache.james.services.MailServer;
41 import org.apache.james.services.UsersRepository;
42
43 /***
44 * <p>Class <code>FetchMail</code> is an Avalon task that is periodically
45 * triggered to fetch mail from a JavaMail Message Store.</p>
46 *
47 * <p>The lifecycle of an instance of <code>FetchMail</code> is managed by
48 * Avalon. The <code>configure(Configuration)</code> method is invoked to parse
49 * and validate Configuration properties. The targetTriggered(String) method is
50 * invoked to execute the task.</p>
51 *
52 * <p>When triggered, a sorted list of Message Store Accounts to be processed is
53 * built. Each Message Store Account is processed by delegating to
54 * <code>StoreProcessor</code>.</p>
55 *
56 * <p>There are two kinds of Message Store Accounts, static and dynamic. Static
57 * accounts are expliciltly declared in the Configuration. Dynamic accounts are
58 * built each time the task is executed, one per each user defined to James,
59 * using the James user name with a configurable prefix and suffix to define
60 * the host user identity and recipient identity for each Account. Dynamic
61 * accounts allow <code>FetchMail</code> to fetch mail for all James users
62 * without modifying the Configuration parameters or restarting the Avalon
63 * server.</p>
64 *
65 * <p>To fully understand the operations supported by this task, read the Class
66 * documention for each Class in the delegation chain starting with this
67 * class' delegate, <code>StoreProcessor</code>. </p>
68 *
69 * <p>Creation Date: 24-May-03</p>
70 *
71 */
72 public class FetchMail extends AbstractLogEnabled implements Configurable, Target, Serviceable
73 {
74 /***
75 * Key fields for DynamicAccounts.
76 */
77 private class DynamicAccountKey
78 {
79 /***
80 * The base user name without prfix or suffix
81 */
82 private String fieldUserName;
83
84 /***
85 * The sequence number of the parameters used to construct the Account
86 */
87 private int fieldSequenceNumber;
88
89 /***
90 * Constructor for DynamicAccountKey.
91 */
92 private DynamicAccountKey()
93 {
94 super();
95 }
96
97 /***
98 * Constructor for DynamicAccountKey.
99 */
100 public DynamicAccountKey(String userName, int sequenceNumber)
101 {
102 this();
103 setUserName(userName);
104 setSequenceNumber(sequenceNumber);
105 }
106
107 /***
108 * @see java.lang.Object#equals(Object)
109 */
110 public boolean equals(Object obj)
111 {
112 if (null == obj)
113 return false;
114 if (!(obj.getClass() == getClass()))
115 return false;
116 return (
117 getUserName().equals(((DynamicAccountKey) obj).getUserName())
118 && getSequenceNumber()
119 == ((DynamicAccountKey) obj).getSequenceNumber());
120 }
121
122 /***
123 * @see java.lang.Object#hashCode()
124 */
125 public int hashCode()
126 {
127 return getUserName().hashCode() ^ getSequenceNumber();
128 }
129
130 /***
131 * Returns the sequenceNumber.
132 * @return int
133 */
134 public int getSequenceNumber()
135 {
136 return fieldSequenceNumber;
137 }
138
139 /***
140 * Returns the userName.
141 * @return String
142 */
143 public String getUserName()
144 {
145 return fieldUserName;
146 }
147
148 /***
149 * Sets the sequenceNumber.
150 * @param sequenceNumber The sequenceNumber to set
151 */
152 protected void setSequenceNumber(int sequenceNumber)
153 {
154 fieldSequenceNumber = sequenceNumber;
155 }
156
157 /***
158 * Sets the userName.
159 * @param userName The userName to set
160 */
161 protected void setUserName(String userName)
162 {
163 fieldUserName = userName;
164 }
165
166 }
167 /***
168 * Creation Date: 06-Jun-03
169 */
170 private class ParsedDynamicAccountParameters
171 {
172 private String fieldUserPrefix;
173 private String fieldUserSuffix;
174
175 private String fieldPassword;
176
177 private int fieldSequenceNumber;
178
179 private boolean fieldIgnoreRecipientHeader;
180 private String fieldRecipientPrefix;
181 private String fieldRecipientSuffix;
182 private String customRecipientHeader;
183
184 /***
185 * Constructor for ParsedDynamicAccountParameters.
186 */
187 private ParsedDynamicAccountParameters()
188 {
189 super();
190 }
191
192 /***
193 * Constructor for ParsedDynamicAccountParameters.
194 */
195 public ParsedDynamicAccountParameters(
196 int sequenceNumber,
197 Configuration configuration)
198 throws ConfigurationException
199 {
200 this();
201 setSequenceNumber(sequenceNumber);
202 setUserPrefix(configuration.getAttribute("userprefix", ""));
203 setUserSuffix(configuration.getAttribute("usersuffix", ""));
204 setRecipientPrefix(configuration.getAttribute("recipientprefix", ""));
205 setRecipientSuffix(configuration.getAttribute("recipientsuffix", ""));
206 setPassword(configuration.getAttribute("password"));
207 setIgnoreRecipientHeader(
208 configuration.getAttributeAsBoolean("ignorercpt-header"));
209 setCustomRecipientHeader(configuration.getAttribute("customrcpt-header", ""));
210 }
211
212 /***
213 * Returns the custom recipient header.
214 * @return String
215 */
216 public String getCustomRecipientHeader() {
217 return this.customRecipientHeader;
218 }
219
220 /***
221 * Returns the recipientprefix.
222 * @return String
223 */
224 public String getRecipientPrefix()
225 {
226 return fieldRecipientPrefix;
227 }
228
229 /***
230 * Returns the recipientsuffix.
231 * @return String
232 */
233 public String getRecipientSuffix()
234 {
235 return fieldRecipientSuffix;
236 }
237
238 /***
239 * Returns the userprefix.
240 * @return String
241 */
242 public String getUserPrefix()
243 {
244 return fieldUserPrefix;
245 }
246
247 /***
248 * Returns the userSuffix.
249 * @return String
250 */
251 public String getUserSuffix()
252 {
253 return fieldUserSuffix;
254 }
255
256 /***
257 * Sets the custom recipient header.
258 * @param customRecipientHeader The header to be used
259 */
260 public void setCustomRecipientHeader(String customRecipientHeader) {
261 this.customRecipientHeader = customRecipientHeader;
262 }
263
264 /***
265 * Sets the recipientprefix.
266 * @param recipientprefix The recipientprefix to set
267 */
268 protected void setRecipientPrefix(String recipientprefix)
269 {
270 fieldRecipientPrefix = recipientprefix;
271 }
272
273 /***
274 * Sets the recipientsuffix.
275 * @param recipientsuffix The recipientsuffix to set
276 */
277 protected void setRecipientSuffix(String recipientsuffix)
278 {
279 fieldRecipientSuffix = recipientsuffix;
280 }
281
282 /***
283 * Sets the userprefix.
284 * @param userprefix The userprefix to set
285 */
286 protected void setUserPrefix(String userprefix)
287 {
288 fieldUserPrefix = userprefix;
289 }
290
291 /***
292 * Sets the userSuffix.
293 * @param userSuffix The userSuffix to set
294 */
295 protected void setUserSuffix(String userSuffix)
296 {
297 fieldUserSuffix = userSuffix;
298 }
299
300 /***
301 * Returns the password.
302 * @return String
303 */
304 public String getPassword()
305 {
306 return fieldPassword;
307 }
308
309 /***
310 * Sets the ignoreRecipientHeader.
311 * @param ignoreRecipientHeader The ignoreRecipientHeader to set
312 */
313 protected void setIgnoreRecipientHeader(boolean ignoreRecipientHeader)
314 {
315 fieldIgnoreRecipientHeader = ignoreRecipientHeader;
316 }
317
318 /***
319 * Sets the password.
320 * @param password The password to set
321 */
322 protected void setPassword(String password)
323 {
324 fieldPassword = password;
325 }
326
327 /***
328 * Returns the ignoreRecipientHeader.
329 * @return boolean
330 */
331 public boolean isIgnoreRecipientHeader()
332 {
333 return fieldIgnoreRecipientHeader;
334 }
335
336 /***
337 * Returns the sequenceNumber.
338 * @return int
339 */
340 public int getSequenceNumber()
341 {
342 return fieldSequenceNumber;
343 }
344
345 /***
346 * Sets the sequenceNumber.
347 * @param sequenceNumber The sequenceNumber to set
348 */
349 protected void setSequenceNumber(int sequenceNumber)
350 {
351 fieldSequenceNumber = sequenceNumber;
352 }
353
354 }
355 /***
356 * @see org.apache.avalon.cornerstone.services.scheduler.Target#targetTriggered(String)
357 */
358 private boolean fieldFetching = false;
359
360 /***
361 * The Configuration for this task
362 */
363 private ParsedConfiguration fieldConfiguration;
364
365 /***
366 * A List of ParsedDynamicAccountParameters, one for every <alllocal> entry
367 * in the configuration.
368 */
369 private List fieldParsedDynamicAccountParameters;
370
371 /***
372 * The Static Accounts for this task.
373 * These are setup when the task is configured.
374 */
375 private List fieldStaticAccounts;
376
377 /***
378 * The JavaMail Session for this fetch task.
379 */
380
381 private Session fieldSession;
382
383 /***
384 * The Dynamic Accounts for this task.
385 * These are setup each time the fetchtask is run.
386 */
387 private Map fieldDynamicAccounts;
388
389 /***
390 * The MailServer service
391 */
392 private MailServer fieldServer;
393
394 /***
395 * The Local Users repository
396 */
397 private UsersRepository fieldLocalUsers;
398
399 /***
400 * Constructor for POP3mail.
401 */
402 public FetchMail()
403 {
404 super();
405 }
406
407 /***
408 * Method configure parses and validates the Configuration data and creates
409 * a new <code>ParsedConfiguration</code>, an <code>Account</code> for each
410 * configured static account and a <code>ParsedDynamicAccountParameters</code>
411 * for each dynamic account.
412 *
413 * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
414 */
415 public void configure(Configuration configuration)
416 throws ConfigurationException
417 {
418
419 setSessionParameters(configuration);
420
421
422 ParsedConfiguration parsedConfiguration =
423 new ParsedConfiguration(
424 configuration,
425 getLogger(),
426 getServer(),
427 getLocalUsers());
428 setConfiguration(parsedConfiguration);
429
430
431 Configuration[] allAccounts = configuration.getChildren("accounts");
432 if (allAccounts.length < 1)
433 throw new ConfigurationException("Missing <accounts> section.");
434 if (allAccounts.length > 1)
435 throw new ConfigurationException("Too many <accounts> sections, there must be exactly one");
436 Configuration accounts = allAccounts[0];
437
438
439 Configuration[] accountsChildren = accounts.getChildren();
440 if (accountsChildren.length < 1)
441 throw new ConfigurationException("Missing <account> section.");
442
443 for (int i = 0; i < accountsChildren.length; i++)
444 {
445 Configuration accountsChild = accountsChildren[i];
446
447 if ("alllocal".equals(accountsChild.getName()))
448 {
449
450
451 getParsedDynamicAccountParameters().add(
452 new ParsedDynamicAccountParameters(i, accountsChild));
453 continue;
454 }
455
456 if ("account".equals(accountsChild.getName()))
457 {
458
459
460 getStaticAccounts().add(
461 new Account(
462 i,
463 parsedConfiguration,
464 accountsChild.getAttribute("user"),
465 accountsChild.getAttribute("password"),
466 accountsChild.getAttribute("recipient"),
467 accountsChild.getAttributeAsBoolean(
468 "ignorercpt-header"),
469 accountsChild.getAttribute("customrcpt-header",""),
470 getSession()));
471 continue;
472 }
473
474 throw new ConfigurationException(
475 "Illegal token: <"
476 + accountsChild.getName()
477 + "> in <accounts>");
478 }
479 }
480
481 /***
482 * Method target triggered fetches mail for each configured account.
483 *
484 * @see org.apache.avalon.cornerstone.services.scheduler.Target#targetTriggered(String)
485 */
486 public void targetTriggered(String arg0)
487 {
488
489 if (isFetching())
490 {
491 getLogger().info(
492 "Triggered fetch cancelled. A fetch is already in progress.");
493 return;
494 }
495
496
497 try
498 {
499 setFetching(true);
500 getLogger().info("Fetcher starting fetches");
501
502
503
504 if (getLogger().isDebugEnabled())
505 {
506 getLogger().debug("Session properties:");
507 Properties properties = getSession().getProperties();
508 Enumeration e = properties.keys();
509 while (e.hasMoreElements())
510 {
511 String key = (String) e.nextElement();
512 String val = (String) properties.get(key);
513 if (val.length() > 40)
514 {
515 val = val.substring(0, 37) + "...";
516 }
517 getLogger().debug(key + "=" + val);
518
519 }
520 }
521
522
523
524
525
526 updateDynamicAccounts();
527 ArrayList mergedAccounts =
528 new ArrayList(
529 getDynamicAccounts().size() + getStaticAccounts().size());
530 mergedAccounts.addAll(getDynamicAccounts().values());
531 mergedAccounts.addAll(getStaticAccounts());
532 Collections.sort(mergedAccounts);
533
534 StringBuffer logMessage = new StringBuffer(64);
535 logMessage.append("Processing ");
536 logMessage.append(getStaticAccounts().size());
537 logMessage.append(" static accounts and ");
538 logMessage.append(getDynamicAccounts().size());
539 logMessage.append(" dynamic accounts.");
540 getLogger().info(logMessage.toString());
541
542
543 Iterator accounts = mergedAccounts.iterator();
544 while (accounts.hasNext())
545 {
546 try
547 {
548 new StoreProcessor((Account) accounts.next()).process();
549 }
550 catch (MessagingException ex)
551 {
552 getLogger().error(
553 "A MessagingException has terminated processing of this Account",
554 ex);
555 }
556 }
557 }
558 catch (Exception ex)
559 {
560 getLogger().error("An Exception has terminated this fetch.", ex);
561 }
562 finally
563 {
564 getLogger().info("Fetcher completed fetches");
565
566
567 setFetching(false);
568 }
569 }
570
571 /***
572 * Returns the fetching.
573 * @return boolean
574 */
575 protected boolean isFetching()
576 {
577 return fieldFetching;
578 }
579
580 /***
581 * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
582 */
583 public void service(final ServiceManager manager) throws ServiceException
584 {
585 try
586 {
587 setServer((MailServer) manager.lookup(MailServer.ROLE));
588 }
589 catch (ClassCastException cce)
590 {
591 StringBuffer errorBuffer =
592 new StringBuffer(128).append("Component ").append(
593 MailServer.ROLE).append(
594 "does not implement the required interface.");
595 throw new ServiceException("", errorBuffer.toString());
596 }
597
598 UsersRepository usersRepository =
599 (UsersRepository) manager.lookup(UsersRepository.ROLE);
600 setLocalUsers(usersRepository);
601 }
602
603
604
605
606
607
608 /***
609 * Sets the fetching.
610 * @param fetching The fetching to set
611 */
612 protected void setFetching(boolean fetching)
613 {
614 fieldFetching = fetching;
615 }
616
617 /***
618 * Returns the server.
619 * @return MailServer
620 */
621 protected MailServer getServer()
622 {
623 return fieldServer;
624 }
625
626 /***
627 * Returns the configuration.
628 * @return ParsedConfiguration
629 */
630 protected ParsedConfiguration getConfiguration()
631 {
632 return fieldConfiguration;
633 }
634
635 /***
636 * Sets the configuration.
637 * @param configuration The configuration to set
638 */
639 protected void setConfiguration(ParsedConfiguration configuration)
640 {
641 fieldConfiguration = configuration;
642 }
643
644 /***
645 * Sets the server.
646 * @param server The server to set
647 */
648 protected void setServer(MailServer server)
649 {
650 fieldServer = server;
651 }
652
653 /***
654 * Returns the localUsers.
655 * @return UsersRepository
656 */
657 protected UsersRepository getLocalUsers()
658 {
659 return fieldLocalUsers;
660 }
661
662 /***
663 * Sets the localUsers.
664 * @param localUsers The localUsers to set
665 */
666 protected void setLocalUsers(UsersRepository localUsers)
667 {
668 fieldLocalUsers = localUsers;
669 }
670
671 /***
672 * Returns the accounts. Initializes if required.
673 * @return List
674 */
675 protected List getStaticAccounts()
676 {
677 if (null == getStaticAccountsBasic())
678 {
679 updateStaticAccounts();
680 return getStaticAccounts();
681 }
682 return fieldStaticAccounts;
683 }
684
685 /***
686 * Returns the staticAccounts.
687 * @return List
688 */
689 private List getStaticAccountsBasic()
690 {
691 return fieldStaticAccounts;
692 }
693
694 /***
695 * Sets the accounts.
696 * @param accounts The accounts to set
697 */
698 protected void setStaticAccounts(List accounts)
699 {
700 fieldStaticAccounts = accounts;
701 }
702
703 /***
704 * Updates the staticAccounts.
705 */
706 protected void updateStaticAccounts()
707 {
708 setStaticAccounts(computeStaticAccounts());
709 }
710
711 /***
712 * Updates the ParsedDynamicAccountParameters.
713 */
714 protected void updateParsedDynamicAccountParameters()
715 {
716 setParsedDynamicAccountParameters(computeParsedDynamicAccountParameters());
717 }
718
719 /***
720 * Updates the dynamicAccounts.
721 */
722 protected void updateDynamicAccounts() throws ConfigurationException
723 {
724 setDynamicAccounts(computeDynamicAccounts());
725 }
726
727 /***
728 * Computes the staticAccounts.
729 */
730 protected List computeStaticAccounts()
731 {
732 return new ArrayList();
733 }
734
735 /***
736 * Computes the ParsedDynamicAccountParameters.
737 */
738 protected List computeParsedDynamicAccountParameters()
739 {
740 return new ArrayList();
741 }
742
743 /***
744 * Computes the dynamicAccounts.
745 */
746 protected Map computeDynamicAccounts() throws ConfigurationException
747 {
748 Map newAccounts =
749 new HashMap(
750 getLocalUsers().countUsers()
751 * getParsedDynamicAccountParameters().size());
752 Map oldAccounts = getDynamicAccountsBasic();
753 if (null == oldAccounts)
754 oldAccounts = new HashMap(0);
755
756 Iterator parameterIterator =
757 getParsedDynamicAccountParameters().iterator();
758
759
760 while (parameterIterator.hasNext())
761 {
762 Map accounts =
763 computeDynamicAccounts(
764 oldAccounts,
765 (ParsedDynamicAccountParameters) parameterIterator.next());
766
767
768
769 Iterator oldAccountsIterator = oldAccounts.keySet().iterator();
770 while (oldAccountsIterator.hasNext())
771 {
772 if (accounts.containsKey(oldAccountsIterator.next()))
773 oldAccountsIterator.remove();
774 }
775
776 newAccounts.putAll(accounts);
777 }
778 return newAccounts;
779 }
780
781 /***
782 * Returns the dynamicAccounts. Initializes if required.
783 * @return Map
784 */
785 protected Map getDynamicAccounts() throws ConfigurationException
786 {
787 if (null == getDynamicAccountsBasic())
788 {
789 updateDynamicAccounts();
790 return getDynamicAccounts();
791 }
792 return fieldDynamicAccounts;
793 }
794
795 /***
796 * Returns the dynamicAccounts.
797 * @return Map
798 */
799 private Map getDynamicAccountsBasic()
800 {
801 return fieldDynamicAccounts;
802 }
803
804 /***
805 * Sets the dynamicAccounts.
806 * @param dynamicAccounts The dynamicAccounts to set
807 */
808 protected void setDynamicAccounts(Map dynamicAccounts)
809 {
810 fieldDynamicAccounts = dynamicAccounts;
811 }
812
813 /***
814 * Compute the dynamicAccounts for the passed parameters.
815 * Accounts for existing users are copied and accounts for new users are
816 * created.
817 * @param oldAccounts
818 * @param parameters
819 * @return Map - The current Accounts
820 * @throws ConfigurationException
821 */
822 protected Map computeDynamicAccounts(
823 Map oldAccounts,
824 ParsedDynamicAccountParameters parameters)
825 throws ConfigurationException
826 {
827 Map accounts = new HashMap(getLocalUsers().countUsers());
828 Iterator usersIterator = getLocalUsers().list();
829 while (usersIterator.hasNext())
830 {
831 String userName = (String) usersIterator.next();
832 DynamicAccountKey key =
833 new DynamicAccountKey(userName, parameters.getSequenceNumber());
834 Account account = (Account) oldAccounts.get(key);
835 if (null == account)
836 {
837
838 account =
839 new DynamicAccount(
840 parameters.getSequenceNumber(),
841 getConfiguration(),
842 userName,
843 parameters.getUserPrefix(),
844 parameters.getUserSuffix(),
845 parameters.getPassword(),
846 parameters.getRecipientPrefix(),
847 parameters.getRecipientSuffix(),
848 parameters.isIgnoreRecipientHeader(),
849 parameters.getCustomRecipientHeader(),
850 getSession());
851 }
852 accounts.put(key, account);
853 }
854 return accounts;
855 }
856
857 /***
858 * Resets the dynamicAccounts.
859 */
860 protected void resetDynamicAccounts()
861 {
862 setDynamicAccounts(null);
863 }
864
865 /***
866 * Returns the ParsedDynamicAccountParameters.
867 * @return List
868 */
869 protected List getParsedDynamicAccountParameters()
870 {
871 if (null == getParsedDynamicAccountParametersBasic())
872 {
873 updateParsedDynamicAccountParameters();
874 return getParsedDynamicAccountParameters();
875 }
876 return fieldParsedDynamicAccountParameters;
877 }
878
879 /***
880 * Returns the ParsedDynamicAccountParameters.
881 * @return List
882 */
883 private List getParsedDynamicAccountParametersBasic()
884 {
885 return fieldParsedDynamicAccountParameters;
886 }
887
888 /***
889 * Sets the ParsedDynamicAccountParameters.
890 * @param ParsedDynamicAccountParameters The ParsedDynamicAccountParametersto set
891 */
892 protected void setParsedDynamicAccountParameters(List parsedDynamicAccountParameters)
893 {
894 fieldParsedDynamicAccountParameters = parsedDynamicAccountParameters;
895 }
896
897 /***
898 * Returns the session, lazily initialized if required.
899 * @return Session
900 */
901 protected Session getSession()
902 {
903 Session session = null;
904 if (null == (session = getSessionBasic()))
905 {
906 updateSession();
907 return getSession();
908 }
909 return session;
910 }
911
912 /***
913 * Returns the session.
914 * @return Session
915 */
916 private Session getSessionBasic()
917 {
918 return fieldSession;
919 }
920
921 /***
922 * Answers a new Session.
923 * @return Session
924 */
925 protected Session computeSession()
926 {
927 return Session.getInstance(System.getProperties());
928 }
929
930 /***
931 * Updates the current Session.
932 */
933 protected void updateSession()
934 {
935 setSession(computeSession());
936 }
937
938 /***
939 * Sets the session.
940 * @param session The session to set
941 */
942 protected void setSession(Session session)
943 {
944 fieldSession = session;
945 }
946
947
948 /***
949 * Propogate any Session parameters in the configuration to the Session.
950 * @param configuration The configuration containing the parameters
951 * @throws ConfigurationException
952 */
953 protected void setSessionParameters(Configuration configuration)
954 throws ConfigurationException
955 {
956 Configuration javaMailProperties =
957 configuration.getChild("javaMailProperties", false);
958 if (null != javaMailProperties)
959 {
960 Properties properties = getSession().getProperties();
961 Configuration[] allProperties =
962 javaMailProperties.getChildren("property");
963 for (int i = 0; i < allProperties.length; i++)
964 {
965 properties.setProperty(
966 allProperties[i].getAttribute("name"),
967 allProperties[i].getAttribute("value"));
968 if (getLogger().isDebugEnabled())
969 {
970 StringBuffer messageBuffer =
971 new StringBuffer("Set property name: ");
972 messageBuffer.append(allProperties[i].getAttribute("name"));
973 messageBuffer.append(" to: ");
974 messageBuffer.append(
975 allProperties[i].getAttribute("value"));
976 getLogger().debug(messageBuffer.toString());
977 }
978 }
979 }
980 }
981
982 }