PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Frameworks/Core/ERJavaMail/Sources/er/javamail/ERJavaMail.java

https://bitbucket.org/molequedeideias/wonder
Java | 870 lines | 334 code | 80 blank | 456 comment | 92 complexity | 7c5a36273ee11dbff09a79eeb270b5f7 MD5 | raw file
  1. package er.javamail;
  2. import java.util.Map;
  3. import java.util.Properties;
  4. import java.util.concurrent.ConcurrentHashMap;
  5. import java.util.regex.Pattern;
  6. import java.util.regex.PatternSyntaxException;
  7. import com.webobjects.eocontrol.EOEnterpriseObject;
  8. import com.webobjects.eocontrol.EOOrQualifier;
  9. import com.webobjects.eocontrol.EOQualifier;
  10. import com.webobjects.foundation.NSArray;
  11. import com.webobjects.foundation.NSMutableArray;
  12. import er.extensions.ERXExtensions;
  13. import er.extensions.ERXFrameworkPrincipal;
  14. import er.extensions.foundation.ERXProperties;
  15. import er.extensions.validation.ERXValidationFactory;
  16. /**
  17. * ERJavaMail is the principal class for the ERJavaMail framework.
  18. *
  19. * @property er.javamail.centralize
  20. * @property er.javamail.adminEmail
  21. * @property er.javamail.debugEnabled
  22. * @property er.javamail.senderQueue.size
  23. * @property er.javamail.milliSecondsWaitIfSenderOverflowed
  24. * @property er.javamail.XMailerHeader
  25. * @property er.javamail.smtpProtocol
  26. * @property er.javamail.smtpHost
  27. * @property mail.[smtpProtocol].host
  28. * @property WOSMTPHost
  29. * @property er.javamail.smtpPort
  30. * @property mail.[smtpProtocol].port
  31. * @property er.javamail.smtpAuth
  32. * @property mail.[smtpProtocol].auth
  33. * @property er.javamail.smtpUser
  34. * @property mail.[smtpProtocol].user
  35. * @property er.javamail.smtpPassword
  36. * @property mail.[smtpProtocol].password
  37. * @property mail.smtps.socketFactory.fallback
  38. * @property er.javamail.emailPattern
  39. * @property er.javamail.WhiteListEmailAddressPatterns
  40. * @property er.javamail.BlackListEmailAddressPatterns
  41. *
  42. * @author <a href="mailto:tuscland@mac.com">Camille Troillard</a>
  43. * @author <a href="mailto:maxmuller@mac.com">Max Muller</a>
  44. */
  45. public class ERJavaMail extends ERXFrameworkPrincipal {
  46. public final static Class<?> REQUIRES[] = new Class[] { ERXExtensions.class };
  47. static {
  48. setUpFrameworkPrincipalClass(ERJavaMail.class);
  49. }
  50. /**
  51. * <span class="en"> ERJavaMail class singleton. </span>
  52. *
  53. * <span class="ja"> シングルトン・クラス </span>
  54. */
  55. protected static ERJavaMail sharedInstance;
  56. /**
  57. * <span class="en"> Accessor to the ERJavaMail singleton.
  58. *
  59. * @return the one <code>ERJavaMail</code> instance </span>
  60. *
  61. * <span class="ja"> ERJavaMail シングルトン・アクセス・メソッド
  62. *
  63. * @return <code>ERJavaMail</code> インスタンス </span>
  64. */
  65. public static synchronized ERJavaMail sharedInstance() {
  66. if (sharedInstance == null) {
  67. sharedInstance = ERXFrameworkPrincipal.sharedInstance(ERJavaMail.class);
  68. }
  69. return sharedInstance;
  70. }
  71. /**
  72. * <span class="en"> <code>EMAIL_VALIDATION_PATTERN</code> is a regexp pattern that is used to validate emails.
  73. * </span>
  74. *
  75. * <span class="ja"> <code>EMAIL_VALIDATION_PATTERN</code> はメールアドレスの検証のための Regex パタン </span>
  76. */
  77. // RFC 2822 token definitions for valid email - only used together to form a java Pattern object:
  78. private static final String sp = "!#$%&'*+\\-/=?^_`{|}~";
  79. private static final String atext = "[a-zA-Z0-9" + sp + "]";
  80. private static final String atom = atext + "+"; // one or more atext chars
  81. private static final String dotAtom = "\\." + atom;
  82. private static final String localPart = atom + "(" + dotAtom + ")*"; // one atom followed by 0 or more dotAtoms.
  83. // RFC 1035 tokens for domain names:
  84. private static final String letter = "[a-zA-Z]";
  85. private static final String letDig = "[a-zA-Z0-9]";
  86. private static final String letDigHyp = "[a-zA-Z0-9\\-]";
  87. private static final String rfcLabel = letDig + "(" + letDigHyp + "{0,61}" + letDig + "){0,1}";
  88. private static final String domain = rfcLabel + "((\\." + rfcLabel + ")*\\." + letter + "{2,6}){0,1}";
  89. // Combined together, these form the allowed email regexp allowed by RFC 2822:
  90. private static final String EMAIL_VALIDATION_PATTERN = "^" + localPart + "@" + domain + "$";
  91. /**
  92. * The compiled form of the <code>EMAIL_VALIDATION_PATTERN</code> pattern.
  93. */
  94. protected Pattern _pattern = null;
  95. private Delegate _delegate;
  96. public void setDelegate(Delegate delegate) {
  97. _delegate = delegate;
  98. }
  99. /**
  100. * Specialized implementation of the method from ERXPrincipalClass.
  101. */
  102. @Override
  103. public void finishInitialization() {
  104. initializeFrameworkFromSystemProperties();
  105. log.debug("ERJavaMail loaded");
  106. }
  107. /**
  108. * <span class="en"> This method is used to initialize ERJavaMail from System properties. Later, we will implement a
  109. * way to initialize those properties everytime the propertis are changed. The observer will call this method
  110. * whenever appropriate. </span>
  111. *
  112. * <span class="ja"> このメソッドは ERJavaMail をシステム・プロパティより初期化するためにあります。 後でプロパティが変更される度にこのメソッドが実行される処理を追加実装します。 </span>
  113. */
  114. public void initializeFrameworkFromSystemProperties() {
  115. // Centralize mails ?
  116. boolean centralize = ERXProperties.booleanForKey("er.javamail.centralize");
  117. setCentralize(centralize);
  118. log.debug("er.javamail.centralize: " + centralize);
  119. String adminEmail = System.getProperty("er.javamail.adminEmail");
  120. if (isValidEmail(adminEmail)) {
  121. setAdminEmail(adminEmail);
  122. log.debug("er.javamail.adminEmail: " + _adminEmail);
  123. }
  124. else if (centralize) {
  125. throw new IllegalArgumentException("When 'er.javamail.centralize' is true (default)," + " all outgoing mails will get sent to 'er.javamail.adminEmail'" + " instead of the normal TO addresses, but you did not provide a valid email for that property.");
  126. }
  127. // JavaMail Debug Enabled ?
  128. boolean debug = ERXProperties.booleanForKey("er.javamail.debugEnabled");
  129. setDebugEnabled(debug);
  130. log.debug("er.javamail.debugEnabled: " + debug);
  131. // Number of messages that the sender queue can hold at a time
  132. int queueSize = ERXProperties.intForKey("er.javamail.senderQueue.size");
  133. if (queueSize >= 1)
  134. setSenderQueueSize(queueSize);
  135. log.debug("er.javamail.senderQueue.size: " + queueSize);
  136. // Time to wait when sender if overflowed
  137. int milliswait = ERXProperties.intForKey("er.javamail.milliSecondsWaitIfSenderOverflowed");
  138. if (milliswait > 1000)
  139. setMilliSecondsWaitIfSenderOverflowed(milliswait);
  140. log.debug("er.javamail.milliSecondsWaitIfSenderOverflowed: " + milliswait);
  141. // Smtp host
  142. setupSmtpHostSafely();
  143. setDefaultSession(newSession());
  144. if (defaultSession() == null)
  145. log.warn("Unable to create default mail session!");
  146. // Default X-Mailer header
  147. setDefaultXMailerHeader(System.getProperty("er.javamail.XMailerHeader"));
  148. log.debug("er.javamail.XMailHeader: " + defaultXMailerHeader());
  149. }
  150. /**
  151. * <span class="en"> Helper method to init the smtpHost property. This method first check is
  152. * <code>er.javamail.smtpHost</code> is set. If it is not set, then it looks for <code>mail.smtp.host</code>
  153. * (standard JavaMail property) and finally the <code>WOSMTPHost</code> property. When a correct property is found,
  154. * then it sets both properties to the found value. If no properties are found, a RuntimeException is thrown.
  155. *
  156. * @throws RuntimeException
  157. * if neither one of <code>er.javamail.smtpHost</code>, <code>mail.smtp.host</code> or
  158. * <code>WOSMTPHost</code> is set. </span>
  159. *
  160. * <span class="ja"> smtpHost プロパティを初期化するヘルプ・メソッドです。 最初には <code>er.javamail.smtpHost</code>
  161. * がセットされているかどうかをチェックします。 セットされていなければ、<code>mail.smtp.host</code> (標準 JavaMail プロパティ) をチェックし、最終的には
  162. * <code>WOSMTPHost</code> プロパティ。 正しいプロパティが見つかると結果値を両方のプロパティにセットします。見つからない場合には RuntimeException が発生します。
  163. *
  164. * @throws RuntimeException
  165. * - <code>er.javamail.smtpHost</code>, <code>mail.smtp.host</code> 又は <code>WOSMTPHost</code>
  166. * がセットされていなければ </span>
  167. */
  168. protected void setupSmtpHostSafely() {
  169. setupSmtpProperties(System.getProperties(), null);
  170. }
  171. protected void setupSmtpProperties(Properties properties, String contextString) {
  172. String contextSuffix = contextString == null ? "" : ("." + contextString);
  173. // Smtp host
  174. String smtpProtocol = smtpProtocolForContext(contextString);
  175. String smtpHost = ERXProperties.stringForKeyWithDefault("er.javamail.smtpHost" + contextSuffix, ERXProperties.stringForKey("er.javamail.smtpHost"));
  176. if ((smtpHost == null) || (smtpHost.length() == 0)) {
  177. // Try to fail back to default java config
  178. smtpHost = ERXProperties.stringForKey("mail." + smtpProtocol + ".host");
  179. if ((smtpHost == null) || (smtpHost.length() == 0)) {
  180. // use the standard WO host
  181. smtpHost = ERXProperties.stringForKey("WOSMTPHost");
  182. if ((smtpHost == null) || (smtpHost.length() == 0)) {
  183. throw new RuntimeException("ERJavaMail: You must specify a SMTP host for outgoing mail with the property 'er.javamail.smtpHost'");
  184. }
  185. // ... and then maybe actually do what the docs say this method is supposed to do
  186. properties.setProperty("mail." + smtpProtocol + ".host", smtpHost);
  187. properties.setProperty("er.javamail.smtpHost", smtpHost);
  188. }
  189. else {
  190. properties.setProperty("er.javamail.smtpHost", smtpHost);
  191. }
  192. }
  193. else {
  194. properties.setProperty("mail." + smtpProtocol + ".host", smtpHost);
  195. }
  196. log.debug("er.javamail.smtpHost: " + smtpHost);
  197. String port = ERXProperties.stringForKeyWithDefault("er.javamail.smtpPort" + contextSuffix, ERXProperties.stringForKey("er.javamail.smtpPort"));
  198. if (port != null && port.length() > 0) {
  199. properties.setProperty("mail." + smtpProtocol + ".port", port);
  200. log.debug("ERJavaMail will use smtp port: " + port);
  201. }
  202. boolean smtpAuth = ERXProperties.booleanForKeyWithDefault("er.javamail.smtpAuth" + contextSuffix, ERXProperties.booleanForKey("er.javamail.smtpAuth"));
  203. log.debug("ERJavaMail will use authenticated SMTP connections.");
  204. if (smtpAuth) {
  205. properties.setProperty("mail." + smtpProtocol + ".auth", String.valueOf(smtpAuth));
  206. String user = ERXProperties.stringForKeyWithDefault("er.javamail.smtpUser" + contextSuffix, ERXProperties.stringForKey("er.javamail.smtpUser"));
  207. if (user == null || user.length() == 0) {
  208. throw new RuntimeException("You specified er.javamail.smtpAuth=true, but you didn't specify an er.javamail.smtpUser to use as the login name.");
  209. }
  210. properties.setProperty("mail." + smtpProtocol + ".user", user);
  211. String password = ERXProperties.stringForKeyWithDefault("er.javamail.smtpPassword" + contextSuffix, ERXProperties.stringForKey("er.javamail.smtpPassword"));
  212. if (password == null || password.length() == 0) {
  213. log.warn("You specified er.javamail.smtpAuth=true, but you didn't set er.javamail.smtpPassword for the " + user + " mail user.");
  214. }
  215. if (password != null) {
  216. properties.setProperty("mail." + smtpProtocol + ".password", password);
  217. }
  218. }
  219. if ("smtps".equals(smtpProtocol)) {
  220. properties.setProperty("mail.smtps.socketFactory.fallback", "false");
  221. }
  222. }
  223. /**
  224. * <span class="en"> This is the default JavaMail Session. It is shared among all deliverers for immediate
  225. * deliveries. Deferred deliverers, use their own JavaMail session. </span>
  226. *
  227. * <span class="ja"> JavaMail のデフォルト・セッションです。 即時配信処理より共有されています。 延期配信は独自の JavaMail セッションを使用しています。 </span>
  228. */
  229. protected javax.mail.Session _defaultSession;
  230. private final Map<String, javax.mail.Session> _sessions = new ConcurrentHashMap<String, javax.mail.Session>();
  231. /**
  232. * <span class="en"> Sets the default JavaMail session to a particular value. This value is set by default at
  233. * initialization of the framework but you can specify a custom one by using this method. Note that a new deliverer
  234. * need to be instanciated for changes to be taken in account.
  235. *
  236. * @param session
  237. * the default <code>javax.mail.Session</code> </span>
  238. *
  239. * <span class="ja"> JavaMail のデフォルト・セッションをセットします。 フレームワークの初期化時に設定されのですが、独自で設定する時には ここを実行するといいのです。
  240. *
  241. * @param session
  242. * - デフォルト <code>javax.mail.Session</code> </span>
  243. */
  244. public void setDefaultSession(javax.mail.Session session) {
  245. session.setDebug(debugEnabled());
  246. _defaultSession = session;
  247. }
  248. /**
  249. * <span class="en"> This is the deafult JavaMail Session accessor. It is shared among all deliverers for immediate
  250. * deliveries. Deferred deliverers, use their own JavaMail session.
  251. *
  252. * @return the default <code>javax.mail.Session</code> instance </span>
  253. *
  254. * <span class="ja"> JavaMail のデフォルト・セッション・アクセス方法です。 即時配信処理のために共有されています。 延期配信は独自の JavaMail セッションを使用しています。
  255. *
  256. * @return デフォルト <code>javax.mail.Session</code> インスタンス </span>
  257. */
  258. public javax.mail.Session defaultSession() {
  259. return _defaultSession;
  260. }
  261. /**
  262. * <span class="en"> Returns a newly allocated Session object from the given Properties
  263. *
  264. * @param props
  265. * a <code>Properties</code> value
  266. * @return a <code>javax.mail.Session</code> value initialized from the given properties </span>
  267. *
  268. * <span class="ja"> 指定プロパティを使った新規セッションを戻します。
  269. *
  270. * @param props
  271. * - <code>Properties</code> 値
  272. *
  273. * @return 指定プロパティで初期化されている <code>javax.mail.Session</code> 値 </span>
  274. */
  275. public javax.mail.Session newSession(Properties props) {
  276. return newSessionForContext(props, null);
  277. }
  278. /**
  279. * <span class="en"> Returns a newly allocated Session object from the System Properties
  280. *
  281. * @return a <code>javax.mail.Session</code> value </span>
  282. *
  283. * <span class="ja"> システム・プロパティを使った新規セッションを戻します。
  284. *
  285. * @return <code>javax.mail.Session</code> 値 </span>
  286. */
  287. public javax.mail.Session newSession() {
  288. return newSession(System.getProperties());
  289. }
  290. /**
  291. * Returns a newly allocated Session object for the given message.
  292. *
  293. * @param message
  294. * the message
  295. * @return a new <code>javax.mail.Session</code> value
  296. */
  297. public javax.mail.Session newSessionForMessage(ERMessage message) {
  298. return newSessionForContext(message.contextString());
  299. }
  300. /**
  301. * Returns the Session object that is appropriate for the given message.
  302. *
  303. * @return a <code>javax.mail.Session</code> value
  304. */
  305. public javax.mail.Session sessionForMessage(ERMessage message) {
  306. return sessionForContext(message.contextString());
  307. }
  308. /**
  309. * Returns a new Session object that is appropriate for the given context.
  310. *
  311. * @param contextString
  312. * the message context
  313. * @return a new <code>javax.mail.Session</code> value
  314. */
  315. protected javax.mail.Session newSessionForContext(String contextString) {
  316. javax.mail.Session session;
  317. if (contextString == null || contextString.length() == 0) {
  318. session = newSessionForContext(System.getProperties(), contextString);
  319. }
  320. else {
  321. Properties sessionProperties = new Properties();
  322. sessionProperties.putAll(System.getProperties());
  323. setupSmtpProperties(sessionProperties, contextString);
  324. session = newSessionForContext(sessionProperties, contextString);
  325. }
  326. return session;
  327. }
  328. /**
  329. * Returns a newly allocated Session object from the given Properties
  330. *
  331. * @param properties
  332. * a <code>Properties</code> value
  333. * @return a <code>javax.mail.Session</code> value initialized from the given properties
  334. */
  335. public javax.mail.Session newSessionForContext(Properties properties, String contextString) {
  336. if (_delegate != null) {
  337. _delegate.willCreateSessionWithPropertiesForContext(properties, contextString);
  338. }
  339. javax.mail.Session session = javax.mail.Session.getInstance(properties);
  340. if (_delegate != null) {
  341. _delegate.didCreateSession(session);
  342. }
  343. session.setDebug(debugEnabled());
  344. return session;
  345. }
  346. /**
  347. * Returns the Session object that is appropriate for the given context.
  348. *
  349. * @param contextString
  350. * the message context
  351. * @return a <code>javax.mail.Session</code> value
  352. */
  353. protected javax.mail.Session sessionForContext(String contextString) {
  354. javax.mail.Session session;
  355. if (contextString == null || contextString.length() == 0) {
  356. session = defaultSession();
  357. }
  358. else {
  359. session = _sessions.get(contextString);
  360. if (session == null) {
  361. session = newSessionForContext(contextString);
  362. _sessions.put(contextString, session);
  363. }
  364. }
  365. return session;
  366. }
  367. /**
  368. * email address used when centralizeMails == true <BR>
  369. * Needed when debugging application so that mails are always sent to only one destination.
  370. */
  371. protected String _adminEmail;
  372. /**
  373. * <span class="en"> admin email accessor. The admin email is the email address where centralized mail go to.
  374. *
  375. * @return a <code>String</code> value </span>
  376. *
  377. * <span class="ja"> centralizeMails == true の場合で使用されるメール・アドレス<br>
  378. * デバッグ中にすべてのメールが一つのターゲットに送信されます。
  379. *
  380. * @return メール・アドレス </span>
  381. */
  382. public String adminEmail() {
  383. return _adminEmail;
  384. }
  385. /**
  386. * <span class="en"> Sets the admin email to another value. This value is set at initialization from the
  387. * <code>er.javamail.adminEmail</code> Property.
  388. *
  389. * @param adminEmail
  390. * a <code>String</code> value </span>
  391. *
  392. * <span class="ja"> この値は初期化中で <code>er.javamail.adminEmail</code> プロパティより設定されますが、 このコマンドでオーバライドが可能です。
  393. *
  394. * @param adminEmail
  395. * - メール・アドレス </span>
  396. */
  397. public void setAdminEmail(String adminEmail) {
  398. if (!(isValidEmail(adminEmail) || (adminEmail != null && adminEmail.trim().length() > 0))) {
  399. throw new IllegalArgumentException("You specified an invalid admin email address '" + adminEmail + "'.");
  400. }
  401. _adminEmail = adminEmail;
  402. }
  403. /** This property specify wether JavaMail is debug enabled or not. */
  404. protected boolean _debugEnabled = true;
  405. /**
  406. * <span class="en"> Returns <code>true</code> if JavaMail is debug enabled.
  407. *
  408. * @return a <code>boolean</code> value </span>
  409. *
  410. * <span class="ja"> JavaMail がデバッグ中の場合には <code>true</code> が戻ります。
  411. *
  412. * @return <code>boolean</code> 値 </span>
  413. */
  414. public boolean debugEnabled() {
  415. return _debugEnabled;
  416. }
  417. /**
  418. * <span class="en"> Sets the debug mode of JavaMail.
  419. *
  420. * @param debug
  421. * a <code>boolean</code> value sets JavaMail in debug mode </span>
  422. *
  423. * <span class="ja"> JavaMail のデバッグ・モードをセットします。
  424. *
  425. * @param debug
  426. * - <code>boolean</code> でデバッグ・モードを On / Off できます </span>
  427. */
  428. public void setDebugEnabled(boolean debug) {
  429. _debugEnabled = debug;
  430. }
  431. /** This property sets the default header for the X-Mailer property */
  432. protected String _defaultXMailerHeader = null;
  433. /**
  434. * <span class="en"> Gets the default X-Mailer header to use for sending mails. Pulls the value out of the property:
  435. * er.javamail.XMailerHeader
  436. *
  437. * @return default X-Mailer header </span>
  438. *
  439. * <span class="ja"> 送信時の XMailer ヘッダーのデフォルト値を取得します。 プロパティの er.javamail.XMailerHeader を参照!
  440. *
  441. * @return デフォルト X-Mailer ヘッダー </span>
  442. */
  443. public String defaultXMailerHeader() {
  444. return _defaultXMailerHeader;
  445. }
  446. /**
  447. * <span class="en"> Sets the default value of the XMailer header used when sending mails.
  448. *
  449. * @param header
  450. * a <code>String</code> value </span>
  451. *
  452. * <span class="ja"> 送信時の XMailer ヘッダーのデフォルト値をセットします。
  453. *
  454. * @param header
  455. * - <code>String</code> 値 </span>
  456. */
  457. public void setDefaultXMailerHeader(String header) {
  458. _defaultXMailerHeader = header;
  459. }
  460. /** Used to send mail to adminEmail only. Useful for debugging issues */
  461. protected boolean _centralize = true;
  462. /**
  463. * <span class="en"> Centralize is used to send all the outbound email to a single address which is useful when
  464. * debugging.
  465. *
  466. * @return a <code>boolean</code> value </span>
  467. *
  468. * <span class="ja"> すべてのメールを er.javamail.adminEmail ユーザに送信します。(デバッグ中に便利)
  469. *
  470. * @return <code>boolean</code> 値 </span>
  471. */
  472. public boolean centralize() {
  473. return _centralize;
  474. }
  475. /**
  476. * <span class="en"> Sets the value of the <code>er.javamail.centralize</code> Property.
  477. *
  478. * @param centralize
  479. * if the boolean value is true, then all the outbound mails will be sent to <code>adminEmail</code>
  480. * email address. </span>
  481. *
  482. * <span class="ja"> <code>er.javamail.centralize</code> プロパティの値をセットします。
  483. *
  484. * @param centralize
  485. * - true の場合にはすべてのメールが <code>adminEmail</code> へ送信されます。 </span>
  486. */
  487. public void setCentralize(boolean centralize) {
  488. _centralize = centralize;
  489. }
  490. /**
  491. * <span class="en"> Returns the SMTP protocol to use for connections. </span>
  492. *
  493. * <span class="ja"> 接続の為の SMTP プロトコールを設定します。 (smtp or smtps)
  494. *
  495. * @param contextString
  496. * - SMTP プロトコール名 </span>
  497. */
  498. public String smtpProtocolForContext(String contextString) {
  499. String contextSuffix = (contextString == null) ? "" : ("." + contextString);
  500. return ERXProperties.stringForKeyWithDefault("er.javamail.smtpProtocol" + contextSuffix, ERXProperties.stringForKeyWithDefault("er.javamail.smtpProtocol", ERXProperties.stringForKeyWithDefault("mail.smtp.protocol", "smtp")));
  501. }
  502. /**
  503. * Number of messages that the sender queue can hold at a time; default to 50 messages and can be configured by
  504. * <code>er.javamail.senderQueue.size</code> system property.
  505. */
  506. protected int _senderQueueSize = 50;
  507. public int senderQueueSize() {
  508. return _senderQueueSize;
  509. }
  510. /**
  511. * <span class="ja"> 送信キューが一回で保持できるメッセージ数です。 デフォルトでは 50 メッセージで、システム・プロパティの <code>er.javamail.senderQueue.size</code>
  512. * で変更可能です。 </span>
  513. */
  514. public void setSenderQueueSize(int value) {
  515. _senderQueueSize = value;
  516. }
  517. /**
  518. * <span class="en"> Wait n milliseconds (by default this value is 6000) if the mail sender is overflowed </span>
  519. *
  520. * <span class="ja"> メール・キューがオーバフローされている時に待つ時間。 (デフォルトでは 6000) </span>
  521. */
  522. protected int _milliSecondsWaitIfSenderOverflowed = 6000;
  523. /**
  524. * <span class="en"> This method return the time spent waiting if the mail queue if overflowed. During that time,
  525. * mails are sent and the queue lowers. When the duration is spent, and the queue is under the overflow limit, the
  526. * mails are being sent again.
  527. *
  528. * @return an <code>int</code> value </span>
  529. *
  530. * <span class="ja"> メール・キューがオーバフローされている時に待つ時間を設定します。この時間内ではメールが送信され、キューが減ります。
  531. * 期間が過ぎるとキューがオーバフロー制限より以下であれば、メールが再度に送信されます。
  532. *
  533. * @return <code>int</code> 値 </span>
  534. */
  535. public int milliSecondsWaitIfSenderOverflowed() {
  536. return _milliSecondsWaitIfSenderOverflowed;
  537. }
  538. /**
  539. * <span class="en"> Sets the value of the <code>er.javamail.milliSecondsWaitIfSenderOverflowed</code> Property.
  540. *
  541. * @param value
  542. * an <code>int</code> value in milli-seconds. </span>
  543. *
  544. * <span class="ja"> <code>er.javamail.milliSecondsWaitIfSenderOverflowed</code> プロパティをセットします。
  545. *
  546. * @param value
  547. * - <code>int</code> ミリ秒 </span>
  548. */
  549. public void setMilliSecondsWaitIfSenderOverflowed(int value) {
  550. _milliSecondsWaitIfSenderOverflowed = value;
  551. }
  552. /**
  553. * <span class="en"> Validates an enterprise object's email attribute (accessed via key).
  554. *
  555. * @param object
  556. * the object to be validated
  557. * @param key
  558. * the attribute's name
  559. * @param email
  560. * the email value
  561. * @return the email if the validation didn't failed </span>
  562. *
  563. * <span class="ja"> エンタプライス・オブジェクトのメール・アトリビュートを検証します。(キーよりのアクセス)
  564. *
  565. * @param object
  566. * - 検証するオブジェクト
  567. * @param key
  568. * - アトリビュート名
  569. * @param email
  570. * - メール値
  571. *
  572. * @return 検証が失敗しない場合のメールアドレス </span>
  573. */
  574. public String validateEmail(EOEnterpriseObject object, String key, String email) {
  575. if (email != null) {
  576. if (!isValidEmail(email))
  577. throw ERXValidationFactory.defaultFactory().createException(object, key, email, "malformedEmail");
  578. }
  579. return email;
  580. }
  581. /**
  582. * <span class="en"> Predicate used to validate email well-formness.
  583. *
  584. * @return true if the email is valid
  585. * @param email
  586. * the email String value to validate
  587. * @return a <code>boolean</code> value </span>
  588. *
  589. * <span class="ja"> メールが正しいかどうかを検証します。
  590. *
  591. * @param email
  592. * - 検証するメール値
  593. *
  594. * @return メールが有効であれば true が戻ります。 </span>
  595. */
  596. public synchronized boolean isValidEmail(String email) {
  597. if (_pattern == null) {
  598. String patternString = ERXProperties.stringForKey("er.javamail.emailPattern");
  599. if (patternString == null || patternString.trim().length() == 0) {
  600. patternString = EMAIL_VALIDATION_PATTERN;
  601. }
  602. try {
  603. _pattern = Pattern.compile(patternString);
  604. }
  605. catch (PatternSyntaxException e) {
  606. throw new RuntimeException("The compilation of the email pattern '" + patternString + "' failed.", e);
  607. }
  608. }
  609. if (email != null) {
  610. return _pattern.matcher(email).matches();
  611. }
  612. return false;
  613. }
  614. // ===========================================================================
  615. // Black and White list email address filtering support
  616. // メール・フィルター: ホワイト&ブラック・リスト
  617. // ---------------------------------------------------------------------------
  618. /**
  619. * <span class="en"> holds the array of white list email addresses </span>
  620. *
  621. * <span class="ja"> ホワイト・リスト・メールアドレス配列を保持 </span>
  622. */
  623. protected NSArray<String> whiteListEmailAddressPatterns;
  624. /**
  625. * <span class="en"> holds the array of black list email addresses </span>
  626. *
  627. * <span class="ja"> ブラック・リスト・メールアドレス配列を保持 </span>
  628. */
  629. protected NSArray<String> blakListEmailAddressPatterns;
  630. /**
  631. * <span class="en"> holds the white list qualifier </span>
  632. *
  633. * <span class="ja"> ホワイト・リスト qualifier を保持 </span>
  634. */
  635. protected EOOrQualifier whiteListQualifier;
  636. /**
  637. * <span class="en"> holds the black list qualifier </span>
  638. *
  639. * <span class="ja"> ブラック・リスト qualifier を保持 </span>
  640. */
  641. protected EOOrQualifier blackListQualifier;
  642. /**
  643. * <span class="en"> Determines if a white list has been specified
  644. *
  645. * @return if the white list has any elements in it </span>
  646. *
  647. * <span class="ja"> ホワイト・リストがあるかどうかを戻します。
  648. *
  649. * @return ホワイト・リストがある場合には true が戻ります。 </span>
  650. */
  651. public boolean hasWhiteList() {
  652. return whiteListEmailAddressPatterns().count() > 0;
  653. }
  654. /**
  655. * <span class="en"> Determines if a black list has been specified
  656. *
  657. * @return if the black list has any elements in it </span>
  658. *
  659. * <span class="ja"> ブラック・リストがあるかどうかを戻します。
  660. *
  661. * @return ブラック・リストがある場合には true が戻ります。 </span>
  662. */
  663. public boolean hasBlackList() {
  664. return blackListEmailAddressPatterns().count() > 0;
  665. }
  666. /**
  667. * <span class="en"> Gets the array of white list email address patterns.
  668. *
  669. * @return array of white list email address patterns </span>
  670. *
  671. * <span class="ja"> ホワイト・リスト・メールアドレス配列パターンを戻します。
  672. *
  673. * @return ホワイト・リスト・メールアドレス配列パターン </span>
  674. */
  675. @SuppressWarnings("unchecked")
  676. public NSArray<String> whiteListEmailAddressPatterns() {
  677. if (whiteListEmailAddressPatterns == null) {
  678. whiteListEmailAddressPatterns = ERXProperties.arrayForKeyWithDefault("er.javamail.WhiteListEmailAddressPatterns", NSArray.EmptyArray);
  679. }
  680. return whiteListEmailAddressPatterns;
  681. }
  682. /**
  683. * <span class="en"> Gets the array of black list email address patterns.
  684. *
  685. * @return array of black list email address patterns </span>
  686. *
  687. * <span class="ja"> ブラック・リスト・メールアドレス配列パターンを戻します。
  688. *
  689. * @return ブラック・リスト・メールアドレス配列パターン </span>
  690. */
  691. @SuppressWarnings("unchecked")
  692. public NSArray<String> blackListEmailAddressPatterns() {
  693. if (blakListEmailAddressPatterns == null) {
  694. blakListEmailAddressPatterns = ERXProperties.arrayForKeyWithDefault("er.javamail.BlackListEmailAddressPatterns", NSArray.EmptyArray);
  695. }
  696. return blakListEmailAddressPatterns;
  697. }
  698. /**
  699. * <span class="en"> Whilte list Or qualifier to match any of the patterns in the white list.
  700. *
  701. * @return Or qualifier for the white list </span> <span class="ja"> ホワイト・リスト内でマッチするパタンのホワイト・リスト Or qualifier
  702. *
  703. * @return ホワイト・リスト Or qualifier </span>
  704. */
  705. public EOOrQualifier whiteListQualifier() {
  706. if (whiteListQualifier == null) {
  707. whiteListQualifier = qualifierArrayForEmailPatterns(whiteListEmailAddressPatterns());
  708. }
  709. return whiteListQualifier;
  710. }
  711. /**
  712. * <span class="en"> Gets the Or qualifier to match any of the patterns in the black list.
  713. *
  714. * @return or qualifier </span>
  715. *
  716. * <span class="ja"> ブラック・リスト内でマッチするパタンのブラック・リスト Or qualifier
  717. *
  718. * @return ブラック・リスト Or qualifier </span>
  719. */
  720. public EOOrQualifier blackListQualifier() {
  721. if (blackListQualifier == null) {
  722. blackListQualifier = qualifierArrayForEmailPatterns(blackListEmailAddressPatterns());
  723. }
  724. return blackListQualifier;
  725. }
  726. /**
  727. * <span class="en"> Constructs an Or qualifier for filtering an array of strings that might have the * wildcard
  728. * character. Will be nice when we have regex in Java 1.4.
  729. *
  730. * @param emailPatterns
  731. * array of email patterns
  732. * @return or qualifier to match any of the given patterns </span>
  733. *
  734. * <span class="ja"> ワイルドカード文字 * を持つ配列をフィルターする Or qualifier を作成します。
  735. *
  736. * @param emailPatterns
  737. * - メール・パタンの配列
  738. *
  739. * @return 指定パタンのマッチに使用する or qualifier </span>
  740. */
  741. protected EOOrQualifier qualifierArrayForEmailPatterns(NSArray<String> emailPatterns) {
  742. NSMutableArray<EOQualifier> patternQualifiers = new NSMutableArray<EOQualifier>();
  743. for (String pattern : emailPatterns) {
  744. patternQualifiers.addObject(EOQualifier.qualifierWithQualifierFormat("toString caseInsensitiveLike '" + pattern + "'", null));
  745. }
  746. return new EOOrQualifier(patternQualifiers);
  747. }
  748. /**
  749. * <span class="en"> Filters an array of email addresses by the black and white lists.
  750. *
  751. * @param emailAddresses
  752. * array of email addresses to be filtered
  753. * @return array of filtered email addresses </span>
  754. *
  755. * <span class="ja"> メールアドレス配列をホワイト&ブラック・リストでフィルターします。
  756. *
  757. * @param emailAddresses
  758. * - フィルターするメール・アドレス配列
  759. *
  760. * @return フィルター済みのメールアドレス配列 </span>
  761. */
  762. public NSArray<String> filterEmailAddresses(NSArray<String> emailAddresses) {
  763. NSMutableArray<String> filteredAddresses = null;
  764. if ((emailAddresses != null) && (emailAddresses.count() > 0) && (hasWhiteList() || hasBlackList())) {
  765. filteredAddresses = new NSMutableArray<String>(emailAddresses);
  766. if (log.isDebugEnabled()) {
  767. log.debug("Filtering email addresses: " + filteredAddresses);
  768. }
  769. if (hasWhiteList()) {
  770. EOQualifier.filterArrayWithQualifier(filteredAddresses, whiteListQualifier());
  771. if (log.isDebugEnabled()) {
  772. log.debug("White list qualifier: " + whiteListQualifier() + " after filtering: " + filteredAddresses);
  773. }
  774. }
  775. if (hasBlackList()) {
  776. NSArray<String> filteredOutAddresses = EOQualifier.filteredArrayWithQualifier(filteredAddresses, blackListQualifier());
  777. if (filteredOutAddresses.count() > 0)
  778. filteredAddresses.removeObjectsInArray(filteredOutAddresses);
  779. if (log.isDebugEnabled()) {
  780. log.debug("Black list qualifier: " + blackListQualifier() + " filtering: " + filteredAddresses);
  781. }
  782. }
  783. }
  784. return (filteredAddresses != null) ? filteredAddresses.immutableClone() : emailAddresses;
  785. }
  786. public static interface Delegate {
  787. public void willCreateSessionWithPropertiesForContext(Properties properties, String contextString);
  788. public void didCreateSession(javax.mail.Session session);
  789. }
  790. }