001: /*
002: Copyright (C) 2005 Know Gate S.L. All rights reserved.
003: C/Oņa, 107 1š2 28050 Madrid (Spain)
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions
007: are met:
008:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011:
012: 2. The end-user documentation included with the redistribution,
013: if any, must include the following acknowledgment:
014: "This product includes software parts from hipergate
015: (http://www.hipergate.org/)."
016: Alternately, this acknowledgment may appear in the software itself,
017: if and wherever such third-party acknowledgments normally appear.
018:
019: 3. The name hipergate must not be used to endorse or promote products
020: derived from this software without prior written permission.
021: Products derived from this software may not be called hipergate,
022: nor may hipergate appear in their name, without prior written
023: permission.
024:
025: This library is distributed in the hope that it will be useful,
026: but WITHOUT ANY WARRANTY; without even the implied warranty of
027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
028:
029: You should have received a copy of hipergate License with this code;
030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
031: */
032:
033: package com.knowgate.hipermail;
034:
035: import java.io.UnsupportedEncodingException;
036:
037: import java.sql.SQLException;
038: import java.sql.PreparedStatement;
039:
040: import javax.mail.Address;
041: import javax.mail.Message;
042: import javax.mail.MessagingException;
043: import javax.mail.internet.AddressException;
044: import javax.mail.internet.InternetAddress;
045: import javax.mail.internet.MimeMessage;
046:
047: import com.knowgate.jdc.JDCConnection;
048: import com.knowgate.debug.DebugFile;
049: import com.knowgate.dataobjs.DB;
050: import com.knowgate.crm.DistributionList;
051: import com.knowgate.misc.Gadgets;
052: import com.knowgate.workareas.WorkArea;
053:
054: /**
055: * Helper class for working with recipients lists
056: * @author Sergio Montoro Ten
057: * @version 3.0
058: */
059: public class RecipientsHelper {
060:
061: private InternetAddress[] aToAddrs;
062: private InternetAddress[] aCcAddrs;
063: private InternetAddress[] aBccAddrs;
064: private boolean bHasLists;
065: private String sWorkAreaId;
066:
067: // ---------------------------------------------------------------------------
068:
069: /**
070: * Default Constructor
071: */
072: public RecipientsHelper() {
073: bHasLists = false;
074: aToAddrs = null;
075: aCcAddrs = null;
076: aBccAddrs = null;
077: sWorkAreaId = null;
078: }
079:
080: // ---------------------------------------------------------------------------
081:
082: /**
083: * Construct and set default workarea for this recipients helper
084: */
085: public RecipientsHelper(String sWorkAreaGUID) {
086: bHasLists = false;
087: aToAddrs = null;
088: aCcAddrs = null;
089: aBccAddrs = null;
090: sWorkAreaId = sWorkAreaGUID;
091: }
092:
093: // ---------------------------------------------------------------------------
094:
095: /**
096: * Create RecipientsHelper and fill it with MimeMessage recipients
097: * @param oMsg MimeMessage
098: * @throws MessagingException
099: */
100: public RecipientsHelper(MimeMessage oMsg) throws MessagingException {
101: bHasLists = false;
102: setRecipients(oMsg);
103: }
104:
105: // ---------------------------------------------------------------------------
106:
107: /**
108: * If called after parseRecipientsList(), this methods returns whether or not
109: * any distribution list was expanded during the parsing process
110: * @return boolean
111: */
112: public boolean hasLists() {
113: return bHasLists;
114: }
115:
116: // ---------------------------------------------------------------------------
117:
118: /**
119: * Get array with recipients of a given type
120: * @param oRecTp RecipientType
121: * @return InternetAddress[]
122: */
123: public String[] getAddresses(Message.RecipientType oRecTp) {
124: String[] aEmails = null;
125: if (oRecTp.equals(Message.RecipientType.TO)) {
126: if (aToAddrs == null) {
127: aEmails = null;
128: } else {
129: aEmails = new String[aToAddrs.length];
130: for (int a = aToAddrs.length - 1; a >= 0; a--)
131: aEmails[a] = aToAddrs[a].getAddress();
132: }
133: } else if (oRecTp.equals(Message.RecipientType.CC)) {
134: if (aCcAddrs == null) {
135: aEmails = null;
136: } else {
137: aEmails = new String[aCcAddrs.length];
138: for (int a = aCcAddrs.length - 1; a >= 0; a--)
139: aEmails[a] = aCcAddrs[a].getAddress();
140: }
141: } else if (oRecTp.equals(Message.RecipientType.BCC)) {
142: if (aBccAddrs == null) {
143: aEmails = null;
144: } else {
145: aEmails = new String[aBccAddrs.length];
146: for (int a = aBccAddrs.length - 1; a >= 0; a--)
147: aEmails[a] = aBccAddrs[a].getAddress();
148: }
149: }
150: return aEmails;
151: } // getAddresses
152:
153: // ---------------------------------------------------------------------------
154:
155: /**
156: * Get array with recipients of a given type
157: * @param oRecTp RecipientType
158: * @return InternetAddress[]
159: */
160: public Address[] getRecipients(Message.RecipientType oRecTp) {
161: if (oRecTp.equals(Message.RecipientType.TO))
162: return aToAddrs;
163: else if (oRecTp.equals(Message.RecipientType.CC))
164: return aCcAddrs;
165: else if (oRecTp.equals(Message.RecipientType.BCC))
166: return aBccAddrs;
167: else
168: return null;
169: } // getRecipients
170:
171: // ---------------------------------------------------------------------------
172:
173: public void setRecipients(Address[] oAddrs,
174: Message.RecipientType oRecTp) throws ClassCastException {
175: if (oRecTp.equals(Message.RecipientType.TO))
176: aToAddrs = (InternetAddress[]) oAddrs;
177: else if (oRecTp.equals(Message.RecipientType.CC))
178: aCcAddrs = (InternetAddress[]) oAddrs;
179: else if (oRecTp.equals(Message.RecipientType.BCC))
180: aBccAddrs = (InternetAddress[]) oAddrs;
181: }
182:
183: // ---------------------------------------------------------------------------
184:
185: public void setRecipients(MimeMessage oMsg)
186: throws ClassCastException, MessagingException {
187: try {
188: aToAddrs = (InternetAddress[]) oMsg
189: .getRecipients(Message.RecipientType.TO);
190: } catch (AddressException adre) {
191: if (DebugFile.trace)
192: DebugFile.writeln("Recipient AddressException "
193: + adre.getMessage());
194: }
195: try {
196: aCcAddrs = (InternetAddress[]) oMsg
197: .getRecipients(Message.RecipientType.CC);
198: } catch (AddressException adre) {
199: if (DebugFile.trace)
200: DebugFile.writeln("Recipient AddressException "
201: + adre.getMessage());
202: }
203: try {
204: aBccAddrs = (InternetAddress[]) oMsg
205: .getRecipients(Message.RecipientType.BCC);
206: } catch (AddressException adre) {
207: if (DebugFile.trace)
208: DebugFile.writeln("Recipient AddressException "
209: + adre.getMessage());
210: }
211: }
212:
213: // ---------------------------------------------------------------------------
214:
215: /**
216: * Add recipients of a given type
217: * @param oAddrs InternetAddress[]
218: * @param oRecTp RecipientType
219: * @throws ClassCastException
220: */
221: public void addRecipients(Address[] oAddrs,
222: Message.RecipientType oRecTp) throws ClassCastException {
223: InternetAddress[] aTmpAddrs;
224: if (null == oAddrs)
225: return;
226: if (oAddrs.length == 0)
227: return;
228: if (oRecTp.equals(Message.RecipientType.TO)) {
229: if (null == aToAddrs) {
230: aToAddrs = new InternetAddress[oAddrs.length];
231: System.arraycopy(oAddrs, 0, aToAddrs, 0, oAddrs.length);
232: } else {
233: aTmpAddrs = new InternetAddress[aToAddrs.length
234: + oAddrs.length];
235: System.arraycopy(aToAddrs, 0, aTmpAddrs, 0,
236: aToAddrs.length);
237: System.arraycopy(oAddrs, 0, aTmpAddrs, aToAddrs.length,
238: oAddrs.length);
239: aToAddrs = aTmpAddrs;
240: }
241: } else if (oRecTp.equals(Message.RecipientType.CC)) {
242: if (null == aCcAddrs) {
243: aCcAddrs = new InternetAddress[oAddrs.length];
244: System.arraycopy(oAddrs, 0, aCcAddrs, 0, oAddrs.length);
245: } else {
246: aTmpAddrs = new InternetAddress[aCcAddrs.length
247: + oAddrs.length];
248: System.arraycopy(aCcAddrs, 0, aTmpAddrs, 0,
249: aCcAddrs.length);
250: System.arraycopy(oAddrs, 0, aTmpAddrs, aCcAddrs.length,
251: oAddrs.length);
252: aCcAddrs = aTmpAddrs;
253: }
254: } else if (oRecTp.equals(Message.RecipientType.BCC))
255: if (null == aBccAddrs) {
256: aBccAddrs = new InternetAddress[oAddrs.length];
257: System
258: .arraycopy(oAddrs, 0, aBccAddrs, 0,
259: oAddrs.length);
260: } else {
261: aTmpAddrs = new InternetAddress[aBccAddrs.length
262: + oAddrs.length];
263: System.arraycopy(aBccAddrs, 0, aTmpAddrs, 0,
264: aBccAddrs.length);
265: System.arraycopy(oAddrs, 0, aTmpAddrs,
266: aBccAddrs.length, oAddrs.length);
267: aBccAddrs = aTmpAddrs;
268: }
269: } // addRecipients
270:
271: // ---------------------------------------------------------------------------
272:
273: /**
274: * Join mail addresses array on a single String
275: * @param aRecipients Address[]
276: * @return String Mail addresses delimited by semicolons
277: */
278: public static String joinAddressList(Address[] aRecipients) {
279: InternetAddress oInetAdr;
280: String sList = "";
281: if (DebugFile.trace) {
282: DebugFile
283: .writeln("Begin RecipientsHelper.joinAddressList(Address[])");
284: DebugFile.incIdent();
285: }
286: if (aRecipients != null) {
287: int cRecipients = aRecipients.length;
288: if (cRecipients > 0) {
289: for (int a = 0; a < cRecipients; a++) {
290: oInetAdr = (InternetAddress) aRecipients[a];
291: if (0 != a)
292: sList += ";";
293: sList += oInetAdr.getAddress();
294: } // next
295: } // fi (cRecipients>0)
296: } // fi (aRecipients)
297: if (DebugFile.trace) {
298: DebugFile
299: .writeln("End RecipientsHelper.joinAddressList() : "
300: + sList);
301: DebugFile.incIdent();
302: }
303: return sList;
304: } // joinAddressList
305:
306: // ---------------------------------------------------------------------------
307:
308: /**
309: * <p>Parse a String of comma or semicolon delimited addresses</p>
310: * Addresses may be of any format accepted by DBInetAddr.parseAddress() method.<br>
311: * Distribution lists present at input string are expanded into BCC internal array.<br>
312: * Distribution list names begin with "list@" and end with ".list".<br>
313: * Or, also distribution list names are enclosed by brackets like "{this is a list}"<br>
314: * Thus if "engineers" is the GUID of a list containing members luke@engineers.com,peter@engineers.com
315: * then TO "jhon@code.com,martin@maths.com,list@engineers.list,steve@maths.com"
316: * will be parsed as<br>
317: * TO jhon@code.com,martin@maths.com,steve@maths.com<br>
318: * BCC luke@engineers.com,peter@engineers.com
319: * @param oAdCn JDCConnection
320: * @param sDelimitedList String with addresses to be parsed
321: * @param oRecTp RecipientType
322: * @throws SQLException
323: * @throws IndexOutOfBoundsException
324: * @throws NullPointerException
325: * @throws AddressException
326: * @throws UnsupportedEncodingException
327: */
328: public void parseRecipientsList(JDCConnection oAdCn,
329: String sDelimitedList, Message.RecipientType oRecTp)
330: throws SQLException, IndexOutOfBoundsException,
331: NullPointerException, AddressException,
332: UnsupportedEncodingException {
333: int nRecipients;
334:
335: if (DebugFile.trace) {
336: DebugFile
337: .writeln("Begin RecipientsHelper.parseRecipientsList([JDCConnection],"
338: + sDelimitedList + "," + oRecTp + ")");
339: DebugFile.incIdent();
340: }
341: String sLId;
342: String[] aRecipients = Gadgets.split(sDelimitedList,
343: new char[] { ',', ';' });
344: InternetAddress[] aAdrSet;
345: InternetAddress[] aBccSet;
346: int iPos;
347: int iListCount = 0;
348:
349: if (aRecipients != null) {
350: nRecipients = aRecipients.length;
351: if (nRecipients > 0) {
352: for (int a = 0; a < nRecipients; a++) {
353: sLId = aRecipients[a].trim();
354: if (sLId.length() > 4) {
355: if (sLId.startsWith("list@")
356: && sLId.endsWith(".list")
357: || sLId.charAt(0) == '{'
358: && sLId.charAt(sLId.length() - 1) == '}') {
359: bHasLists = true;
360: iListCount++;
361: // *******************************
362: // Resolve list name to member set
363: DistributionList oLst;
364: if (sLId.charAt(0) == '{') {
365: oLst = new DistributionList(oAdCn,
366: sLId.substring(1,
367: sLId.length() - 1),
368: sWorkAreaId);
369: if (oLst.isNull(DB.gu_list)) {
370: if (DebugFile.trace)
371: DebugFile.decIdent();
372: throw new AddressException(
373: "RecipientsHelper.parseRecipientsList() list "
374: + sLId
375: .substring(
376: 1,
377: sLId
378: .length() - 1)
379: + " not found");
380: }
381: } else {
382: oLst = new DistributionList(oAdCn, sLId
383: .substring(
384: sLId.indexOf('@') + 1,
385: sLId.indexOf('.')));
386: if (oLst.isNull(DB.gu_list)) {
387: if (DebugFile.trace)
388: DebugFile.decIdent();
389: throw new AddressException(
390: "RecipientsHelper.parseRecipientsList() list "
391: + sLId
392: .substring(
393: sLId
394: .indexOf('@') + 1,
395: sLId
396: .indexOf('.'))
397: + " not found");
398: }
399: }
400: String sPer = oLst.getStringNull(
401: DB.de_list, null);
402: String sLst = oLst.activeMembers(oAdCn);
403: if (sLst.length() > 0) {
404: String[] aLst = Gadgets
405: .split(sLst, ',');
406: int iLst = aLst.length;
407: if (null == aBccAddrs) {
408: iPos = 0;
409: aBccSet = new InternetAddress[iLst];
410: } else {
411: iPos = aBccAddrs.length;
412: aBccSet = new InternetAddress[iLst
413: + iPos];
414: System.arraycopy(aBccSet, 0,
415: aBccAddrs, 0, iPos);
416: }
417: if (sPer == null) {
418: for (int l = 0; l < iLst; l++)
419: aBccSet[l + iPos] = new InternetAddress(
420: aLst[l]);
421: } else {
422: for (int l = 0; l < iLst; l++)
423: aBccSet[l + iPos] = new InternetAddress(
424: aLst[l], sPer);
425: } // fi (sPer)
426: aBccAddrs = aBccSet;
427: aRecipients[a] = null;
428: } // fi (sLst!="")
429: } // fi (aRecipients[a] LIKE list@%.list)
430: } // fi (sLId.length>4)
431: } // next (a)
432: aAdrSet = new InternetAddress[nRecipients - iListCount];
433: iPos = 0;
434: for (int a = 0; a < nRecipients; a++) {
435: if (null != aRecipients[a]) {
436: aAdrSet[iPos] = DBInetAddr
437: .parseAddress(aRecipients[a]);
438: iPos++;
439: }
440: } // next
441: addRecipients(aAdrSet, oRecTp);
442: } // fi (nRecipients==0)
443: } // fi (aTo!=null)
444: if (DebugFile.trace) {
445: DebugFile.decIdent();
446: DebugFile
447: .writeln("End RecipientsHelper.parseRecipientsList()");
448: }
449: } // parseRecipientsList
450:
451: // ---------------------------------------------------------------------------
452:
453: /**
454: * Delete rows at k_inet_addrs table for given message
455: * @param oConn JDCConnection
456: * @param sGuMimeMsg String GUID of message which addresses are to be cleared
457: * @throws SQLException
458: */
459: public static void clearRecipientsForMessage(JDCConnection oConn,
460: String sGuMimeMsg) throws SQLException {
461: PreparedStatement oStmt = oConn.prepareStatement("DELETE FROM "
462: + DB.k_inet_addrs + " WHERE " + DB.gu_mimemsg + "=?");
463: oStmt.setString(1, sGuMimeMsg);
464: oStmt.executeUpdate();
465: oStmt.close();
466: } // clearRecipientsForMessage
467:
468: // ---------------------------------------------------------------------------
469:
470: public static InternetAddress getFromAddress(MimeMessage oMsg)
471: throws MessagingException {
472: Address[] aFrom = null;
473: try {
474: aFrom = oMsg.getFrom();
475: } catch (AddressException adre) {
476: if (DebugFile.trace)
477: DebugFile.writeln("From AddressException "
478: + adre.getMessage());
479: }
480: InternetAddress oFrom;
481: if (aFrom != null) {
482: if (aFrom.length > 0)
483: oFrom = (InternetAddress) aFrom[0];
484: else
485: oFrom = null;
486: } else
487: oFrom = null;
488: return oFrom;
489: } // getFromAddress
490:
491: // ---------------------------------------------------------------------------
492:
493: public static InternetAddress getReplyAddress(MimeMessage oMsg)
494: throws MessagingException {
495: Address[] aReply = null;
496: InternetAddress oReply;
497: try {
498: aReply = oMsg.getReplyTo();
499: } catch (AddressException adre) {
500: if (DebugFile.trace)
501: DebugFile.writeln("Reply-To AddressException "
502: + adre.getMessage());
503: }
504:
505: if (aReply != null) {
506: if (aReply.length > 0)
507: oReply = (InternetAddress) aReply[0];
508: else
509: oReply = null;
510: } else {
511: if (DebugFile.trace)
512: DebugFile.writeln("no reply-to address found");
513: oReply = null;
514: }
515: return oReply;
516: }
517: }
|