KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > knowgate > crm > DirectList


1 /*
2   Copyright (C) 2003 Know Gate S.L. All rights reserved.
3                       C/Oņa, 107 1ē2 28050 Madrid (Spain)
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions
7   are met:
8
9   1. Redistributions of source code must retain the above copyright
10      notice, this list of conditions and the following disclaimer.
11
12   2. The end-user documentation included with the redistribution,
13      if any, must include the following acknowledgment:
14      "This product includes software parts from hipergate
15      (http://www.hipergate.org/)."
16      Alternately, this acknowledgment may appear in the software itself,
17      if and wherever such third-party acknowledgments normally appear.
18
19   3. The name hipergate must not be used to endorse or promote products
20      derived from this software without prior written permission.
21      Products derived from this software may not be called hipergate,
22      nor may hipergate appear in their name, without prior written
23      permission.
24
25   This library is distributed in the hope that it will be useful,
26   but WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28
29   You should have received a copy of hipergate License with this code;
30   if not, visit http://www.hipergate.org or mail to info@hipergate.org
31 */

32
33 package com.knowgate.crm;
34
35 import java.io.FileNotFoundException JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.io.UnsupportedEncodingException JavaDoc;
38
39 import java.sql.SQLException JavaDoc;
40 import java.sql.Statement JavaDoc;
41 import java.sql.ResultSet JavaDoc;
42
43 import com.knowgate.debug.DebugFile;
44 import com.knowgate.jdc.JDCConnection;
45 import com.knowgate.misc.Gadgets;
46 import com.knowgate.misc.CSVParser;
47 import com.knowgate.dataobjs.DB;
48
49 /**
50  * <p>DirectList</p>
51  * <p>A subclass of DistributionList with methods for loading List Members from
52  * text files.</p>
53  * <p>Copyright: Copyright (c) KnowGate 2003-2006</p>
54  * @author Sergio Montoro Ten
55  * @version 3.0
56  */

57
58 public class DirectList extends DistributionList {
59
60   private CSVParser oCSV;
61
62   // ----------------------------------------------------------
63

64   /**
65    * Default constructor
66    */

67   public DirectList() {
68     oCSV = new CSVParser();
69   }
70
71   // ----------------------------------------------------------
72

73   /**
74    * Constructor
75    * @param String Name of character set to be used when parsing files (ISO-8859-1, UTF-8, etc.)
76    * @since 3.0
77    */

78   public DirectList(String JavaDoc sCharSetName) {
79     oCSV = new CSVParser(sCharSetName);
80   }
81
82   // ----------------------------------------------------------
83

84   /**
85    * Get last error line
86    * @return int
87    */

88   public int errorLine() {
89     return oCSV.errorLine();
90   }
91
92   // ----------------------------------------------------------
93

94   /**
95    * Get line count after parsing a text file
96    * @return int
97    */

98   public int getLineCount() {
99     return oCSV.getLineCount();
100   }
101
102   // ----------------------------------------------------------
103

104   private int[] checkValues() throws IllegalStateException JavaDoc {
105
106     String JavaDoc sMail, sName, sSurN, sSalt, sFrmt;
107
108     if (DebugFile.trace) {
109       DebugFile.writeln("Begin DirectList.checkValues()");
110       DebugFile.incIdent();
111     }
112
113     if (0 == oCSV.getLineCount())
114       throw new IllegalStateException JavaDoc("Trying to parse an empty file");
115
116     int iMail = getColumnPosition(DB.tx_email);
117     int iName = getColumnPosition(DB.tx_name);
118     int iSurN = getColumnPosition(DB.tx_surname);
119     int iSalt = getColumnPosition(DB.tx_salutation);
120     int iFrmt = getColumnPosition(DB.id_format);
121
122     int CheckCodes[] = new int[oCSV.getLineCount()];
123
124     int iLines = oCSV.getLineCount();
125
126     for (int r=0; r<iLines; r++) {
127       CheckCodes[r] = CHECK_OK;
128
129       if (iMail>=0) {
130         sMail = getField(iMail, r);
131         if (sMail.length()>100)
132           CheckCodes[r] = CHECK_INVALID_EMAIL;
133         else if (!Gadgets.checkEMail(sMail))
134           CheckCodes[r] = CHECK_INVALID_EMAIL;
135       }
136
137       if (iName>=0) {
138         sName = getField(iName, r);
139         if (sName.length()>100)
140           CheckCodes[r] = CHECK_NAME_TOO_LONG;
141         else if (sName.indexOf(',')>=0 || sName.indexOf(';')>=0 || sName.indexOf('`')>=0 || sName.indexOf('¨')>=0 || sName.indexOf('?')>=0 || sName.indexOf('"')>=0)
142           CheckCodes[r] = CHECK_INVALID_NAME;
143       }
144
145       if (iSurN>=0) {
146         sSurN = getField(iName, r);
147         if (sSurN.length()>100)
148           CheckCodes[r] = CHECK_SURNAME_TOO_LONG;
149         else if (sSurN.indexOf(',')>=0 || sSurN.indexOf(';')>=0 || sSurN.indexOf('`')>=0 || sSurN.indexOf('¨')>=0 || sSurN.indexOf('?')>=0 || sSurN.indexOf('"')>=0)
150           CheckCodes[r] = CHECK_INVALID_SURNAME;
151       }
152
153       if (iSalt>=0) {
154         sSalt = getField(iSalt, r);
155         if (sSalt.length()>16)
156           CheckCodes[r] = CHECK_SALUTATION_TOO_LONG;
157         else if (sSalt.indexOf(',')>=0 || sSalt.indexOf(';')>=0 || sSalt.indexOf('`')>=0 || sSalt.indexOf('¨')>=0 || sSalt.indexOf('?')>=0 || sSalt.indexOf('"')>=0)
158           CheckCodes[r] = CHECK_INVALID_SALUTATION;
159       }
160
161       if (iFrmt>=0) {
162         sFrmt = getField(iFrmt, r);
163         if (sFrmt.length()>4)
164           CheckCodes[r] = CHECK_INVALID_FORMAT;
165         else if (sFrmt.indexOf(',')>=0 || sFrmt.indexOf(';')>=0 || sFrmt.indexOf('`')>=0 || sFrmt.indexOf('¨')>=0 || sFrmt.indexOf('?')>=0 || sFrmt.indexOf('"')>=0)
166           CheckCodes[r] = CHECK_INVALID_SALUTATION;
167       }
168
169     } // next
170

171     if (DebugFile.trace) {
172       DebugFile.decIdent();
173       DebugFile.writeln("End DirectList.checkValues()");
174     }
175
176     return CheckCodes;
177   } // checkValues
178

179   // ----------------------------------------------------------
180

181   /**
182    * Parse a delimited text file
183    * @param sFilePath File Path
184    * @param sFileDescriptor Delimited Column List.<br>
185    * The only valid column names are { tx_email, tx_name, tx_surname, id_format, tx_salutation }.<br>
186    * Column names may be delimited by ',' ';' or '\t'.
187    * Columns names may be quoted.
188    * @return Array of status for each parsed line.<br>
189    * <table><tr><td>CHECK_OK</td><td>Line is OK</td></tr>
190    * <tr><td>CHECK_INVALID_EMAIL</td><td>tx_email is longer than 100 characters or it is rejected by method Gadgets.checkEMail()</td></tr>
191    * <tr><td>CHECK_NAME_TOO_LONG</td><td>tx_name is longer than 100 characters</td></tr>
192    * <tr><td>CHECK_INVALID_NAME</td><td>tx_name contains forbidden characters { ',' ';' '`' '¨' '?' '"' }</td></tr>
193    * <tr><td>CHECK_SURNAME_TOO_LONG</td><td>tx_surname is longer than 100 characters</td></tr>
194    * <tr><td>CHECK_INVALID_SURNAME</td><td>tx_surname contains forbidden characters { ',' ';' '`' '¨' '?' '"' }</td></tr>
195    * <tr><td>CHECK_INVALID_FORMAT</td><td>id_format is longer than 4 characters</td></tr>
196    * <tr><td>CHECK_SALUTATION_TOO_LONG</td><td>tx_salutation is longer than 16 characters</td></tr>
197    * <tr><td>CHECK_INVALID_SALUTATION</td><td>tx_salutation contains forbidden characters { ',' ';' '`' '¨' '?' '"' }</td></tr>
198    * </table>
199    * @throws ArrayIndexOutOfBoundsException
200    * @throws FileNotFoundException
201    * @throws IllegalArgumentException
202    * @throws IOException
203    * @throws NullPointerException
204    * @throws UnsupportedEncodingException
205    * @see com.knowgate.misc.CSVParser
206    */

207   public int[] parseFile(String JavaDoc sFilePath, String JavaDoc sFileDescriptor)
208       throws ArrayIndexOutOfBoundsException JavaDoc,NullPointerException JavaDoc,
209              IllegalArgumentException JavaDoc,UnsupportedEncodingException JavaDoc,
210              IOException JavaDoc,FileNotFoundException JavaDoc {
211     int[] aRetVals;
212
213     if (DebugFile.trace) {
214       DebugFile.writeln("Begin DirectList.parseFile(" + sFilePath + "," + sFileDescriptor + "," + ")");
215       DebugFile.incIdent();
216     }
217
218     oCSV.parseFile(sFilePath, sFileDescriptor);
219
220     aRetVals = checkValues();
221
222     if (DebugFile.trace) {
223       DebugFile.decIdent();
224       DebugFile.writeln("End DirectList.parseFile()");
225     }
226
227     return aRetVals;
228   } // parseFile
229

230   // ----------------------------------------------------------
231

232   /**
233    * @param sColumnName Column Name
234    * @return Zero based index for column position or -1 if column was not found.
235    */

236   public int getColumnPosition(String JavaDoc sColumnName) {
237     return oCSV.getColumnPosition(sColumnName);
238   } // getColumnPosition
239

240   // ----------------------------------------------------------
241

242   /**
243    * <p>Get line from a parsed file.</p>
244    * Lines are delimited by the Line Feed (LF, CHAR(10), '\n') character
245    * @param iLine Line Number [0..getLineCount()-1]
246    * @return Full Text for Line. If iLine<0 or iLine>=getLineCount() then <b>null</b>
247    * @throws IllegalStateException If parseFile() has not been called prior to getLine()
248    */

249   public String JavaDoc getLine(int iLine) throws IllegalStateException JavaDoc {
250     String JavaDoc sRetVal;
251
252     try {
253       sRetVal = oCSV.getLine(iLine);
254     } catch (java.io.UnsupportedEncodingException JavaDoc e) { sRetVal = null; }
255
256     return sRetVal;
257   } // getLine
258

259   // ----------------------------------------------------------
260

261   /**
262    * <p>Get value for a field at a given row and column.</p>
263    * Column indexes are zero based.
264    * Row indexes range from 0 to getLineCount()-1.
265    * @param iCol Column Index
266    * @param iRow Row Index
267    * @return Field Value
268    * @throws IllegalStateException If parseFile() method was not called prior to
269    * getField()
270    * @throws ArrayIndexOutOfBoundsException If Column or Row Index is out of bounds.
271    */

272
273   public String JavaDoc getField(int iCol, int iRow) throws ArrayIndexOutOfBoundsException JavaDoc {
274     String JavaDoc sRetVal;
275
276     try {
277       sRetVal = oCSV.getField(iCol, iRow);
278     } catch (java.io.UnsupportedEncodingException JavaDoc e) { sRetVal = null; }
279
280     return sRetVal;
281   } // getField
282

283   // ----------------------------------------------------------
284

285   /**
286    * <p>Get value for a field at a given row and column.</p>
287    * @param sCol Column Name
288    * @param iRow Row Name
289    * @throws ArrayIndexOutOfBoundsException
290    */

291   public String JavaDoc getField(String JavaDoc sCol, int iRow) throws ArrayIndexOutOfBoundsException JavaDoc {
292
293     int iCol = getColumnPosition(sCol);
294
295     if (iCol==-1)
296       throw new ArrayIndexOutOfBoundsException JavaDoc ("Column " + sCol + " not found");
297
298     return getField(iCol, iRow);
299   }
300
301   // ----------------------------------------------------------
302

303   /**
304    * <p>Adds members to a Static, Direct or Black Distribution List.</p>
305    * @param oConn Database connection
306    * @param sListId DistributionList GUID
307    * @param iStatus 1 if loaded members are to be set as active, 0 if loaded member are to be set as unactive.
308    * @throws IllegalArgumentException If DistributionList does not exist.
309    * @throws ClassCastException If sListId type is DYNAMIC.
310    * @throws IllegalStateException If parseFile() has not been called prior to updateList()
311    * @throws StringIndexOutOfBoundsException If a row if malformed
312    * @throws SQLException
313    */

314   public void updateList(JDCConnection oConn, String JavaDoc sListId, short iStatus) throws IllegalArgumentException JavaDoc,IllegalStateException JavaDoc,ClassCastException JavaDoc,SQLException JavaDoc {
315     Statement JavaDoc oStmt;
316     ResultSet JavaDoc oRSet;
317     boolean bExists;
318     short iTpList;
319
320     if (DebugFile.trace) {
321       DebugFile.writeln("Begin DirectList.updateList([Connection], " + sListId + ")");
322       DebugFile.incIdent();
323     }
324
325     oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
326     oRSet = oStmt.executeQuery("SELECT " + DB.tp_list + " FROM " + DB.k_lists + " WHERE " + DB.gu_list + "='" + sListId + "'");
327     bExists = oRSet.next();
328     if (bExists)
329       iTpList = oRSet.getShort(1);
330     else
331       iTpList = -1;
332     oRSet.close();
333     oStmt.close();
334
335     if (!bExists)
336       throw new IllegalArgumentException JavaDoc("List does not exist");
337
338     if (iTpList==com.knowgate.crm.DistributionList.TYPE_DYNAMIC)
339       throw new IllegalArgumentException JavaDoc("Dynamic lists cannot be updated by directly loading members");
340
341     if (0 == oCSV.getLineCount())
342       throw new IllegalStateException JavaDoc("Must call parseFile() on a valid non-empty delimited file before calling updateList() method");
343
344     int iMail = getColumnPosition(DB.tx_email);
345     int iName = getColumnPosition(DB.tx_name);
346     int iSurN = getColumnPosition(DB.tx_surname);
347     int iSalt = getColumnPosition(DB.tx_salutation);
348     int iFrmt = getColumnPosition(DB.id_format);
349
350     int ChkCods[] = checkValues();
351
352     ListMember oMbr = new ListMember();
353
354     oMbr.put(DB.tp_member, ListMember.ClassId);
355     oMbr.put(DB.bo_active, iStatus);
356
357     int iLines = oCSV.getLineCount();
358
359     for (int r=0; r<iLines; r++) {
360
361       if (ChkCods[r] == CHECK_OK) {
362
363         oMbr.replace(DB.gu_member, Gadgets.generateUUID());
364
365         oMbr.replace(DB.tx_email, getField(iMail, r));
366
367         oMbr.replace(DB.tx_name, getField(iName, r));
368
369         oMbr.replace(DB.tx_surname, getField(iSurN, r));
370
371         oMbr.replace(DB.tx_salutation, getField(iSalt, r));
372
373         oMbr.replace(DB.tp_member, ListMember.ClassId);
374
375         if (iFrmt>=0)
376           oMbr.replace(DB.id_format, getField(iFrmt, r).toUpperCase());
377         else
378           oMbr.replace(DB.id_format, "TXT");
379
380         try {
381           oMbr.store(oConn, sListId);
382         }
383         catch (NoSuchFieldException JavaDoc nsfe) {
384           /* never really thrown with paramenters passed to ListMember.store() from this method */
385         }
386       } // fi (CHECK_OK)
387
} // next
388

389     if (DebugFile.trace) {
390       DebugFile.decIdent();
391       DebugFile.writeln("End DirectList.updateList()");
392     }
393   } // updateList
394

395
396   // ----------------------------------------------------------
397

398   /**
399    * <p>Remove members from a Static, Direct or Black Distribution List.</p>
400    * Members are matched by their e-mail address (tx_email column)
401    * @param oConn Database connection
402    * @param sListId DistributionList GUID
403    * @throws IllegalArgumentException If DistributionList does not exist.
404    * @throws ClassCastException If sListId type is DYNAMIC
405    * @throws IllegalStateException If parseFile() has not been called prior to updateList()
406    * @throws SQLException
407    */

408   public void removeFromList(JDCConnection oConn, String JavaDoc sListId) throws IllegalArgumentException JavaDoc,SQLException JavaDoc,ClassCastException JavaDoc {
409     Statement JavaDoc oDlte;
410     Statement JavaDoc oStmt;
411     ResultSet JavaDoc oRSet;
412     boolean bExists;
413     short iTpList;
414     String JavaDoc sSQL;
415
416     if (DebugFile.trace) {
417       DebugFile.writeln("Begin DirectList.removeFromList([Connection], " + sListId + ")");
418       DebugFile.incIdent();
419     }
420
421     oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
422     oRSet = oStmt.executeQuery("SELECT " + DB.tp_list + " FROM " + DB.k_lists + " WHERE " + DB.gu_list + "='" + sListId + "'");
423     bExists = oRSet.next();
424     if (bExists)
425       iTpList = oRSet.getShort(1);
426     else
427       iTpList = -1;
428     oRSet.close();
429     oStmt.close();
430
431     if (!bExists)
432       throw new IllegalArgumentException JavaDoc("List does not exist");
433
434     if (iTpList==com.knowgate.crm.DistributionList.TYPE_DYNAMIC)
435       throw new ClassCastException JavaDoc("Dynamic lists cannot be updated by directly removing members");
436
437     if (0 == oCSV.getLineCount())
438       throw new IllegalStateException JavaDoc("Must call parseFile() on a valid non-empty delimited file before calling updateList() method");
439
440     int iMail = getColumnPosition(DB.tx_email);
441
442     int ChkCods[] = checkValues();
443
444     int iLines = oCSV.getLineCount();
445
446     sSQL = "DELETE FROM " + DB.k_x_list_members + " WHERE " + DB.gu_list + "='" + sListId + "' AND " + DB.tx_email + "=";
447
448     oDlte = oConn.createStatement();
449
450     for (int r=0; r<iLines; r++) {
451       if (ChkCods[r] == CHECK_OK)
452         oDlte.addBatch(sSQL + "'" + getField(iMail, r) + "'");
453     } // next
454

455     oDlte.executeBatch();
456     oDlte.close();
457
458     if (DebugFile.trace) {
459       DebugFile.decIdent();
460       DebugFile.writeln("End DirectList.removeFromList()");
461     }
462   } // removeFromList
463

464   // ----------------------------------------------------------
465

466   // **********************************************************
467
// Constantes Publicas
468

469   public static final int CHECK_OK = 0;
470   public static final int CHECK_INVALID_EMAIL = 1;
471   public static final int CHECK_NAME_TOO_LONG = 2;
472   public static final int CHECK_SURNAME_TOO_LONG = 4;
473   public static final int CHECK_INVALID_FORMAT = 8;
474   public static final int CHECK_SALUTATION_TOO_LONG = 16;
475   public static final int CHECK_INVALID_NAME = 32;
476   public static final int CHECK_INVALID_SURNAME = 64;
477   public static final int CHECK_INVALID_SALUTATION = 128;
478
479   // **********************************************************
480
// Public Constants
481

482   public static final short ClassId = 96;
483
484 }
485
Popular Tags