KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > mail > gui > composer > ComposerModel


1 //The contents of this file are subject to the Mozilla Public License Version 1.1
2
//(the "License"); you may not use this file except in compliance with the
3
//License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
4
//
5
//Software distributed under the License is distributed on an "AS IS" basis,
6
//WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
7
//for the specific language governing rights and
8
//limitations under the License.
9
//
10
//The Original Code is "The Columba Project"
11
//
12
//The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
13
//Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
14
//
15
//All Rights Reserved.
16
package org.columba.mail.gui.composer;
17
18 import java.io.File JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.net.URI JavaDoc;
21 import java.net.URISyntaxException JavaDoc;
22 import java.nio.charset.Charset JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.Vector JavaDoc;
26 import java.util.logging.Logger JavaDoc;
27 import java.util.regex.Pattern JavaDoc;
28
29 import javax.swing.event.EventListenerList JavaDoc;
30
31 import org.columba.core.desktop.ColumbaDesktop;
32 import org.columba.mail.command.MailFolderCommandReference;
33 import org.columba.mail.config.AccountItem;
34 import org.columba.mail.config.MailConfig;
35 import org.columba.mail.message.ColumbaMessage;
36 import org.columba.mail.message.IColumbaMessage;
37 import org.columba.mail.parser.ListBuilder;
38 import org.columba.mail.parser.ListParser;
39 import org.columba.mail.parser.NormalizeRecipientListParser;
40 import org.columba.ristretto.io.FileSource;
41 import org.columba.ristretto.message.Address;
42 import org.columba.ristretto.message.Header;
43 import org.columba.ristretto.message.LocalMimePart;
44 import org.columba.ristretto.message.MimeHeader;
45 import org.columba.ristretto.message.StreamableMimePart;
46
47 /**
48  * @author frd
49  *
50  * Model for message composer dialog
51  *
52  */

53 public class ComposerModel {
54
55     /** JDK 1.4+ logging framework logger, used for logging. */
56     private static final Logger JavaDoc LOG = Logger
57             .getLogger("org.columba.mail.gui.composer"); //$NON-NLS-1$
58

59     private ColumbaMessage message;
60
61     private AccountItem accountItem;
62
63     private String JavaDoc bodytext;
64
65     private Charset JavaDoc charset;
66
67     private List JavaDoc attachments;
68
69     private List JavaDoc<String JavaDoc> toList;
70
71     private List JavaDoc<String JavaDoc> ccList;
72
73     private List JavaDoc<String JavaDoc> bccList;
74
75     private boolean signMessage;
76
77     private boolean encryptMessage;
78
79     /**
80      * this regular expression should cover anything from a@a.pt or a@a.com to
81      * a@a.info. Permits usage of invalid top domains though.
82      * <p>
83      * [bug] fdietz: added "." and "-" as regular characters
84      * (example:mail@toplevel.mail.de)
85      * <p>
86      * TODO: see if we can replace the matching code with Ristretto stuff
87      *
88      */

89     private static final String JavaDoc emailRegExp = "[a-zA-Z0-9]+([_\\.-][a-zA-Z0-9]+)*@([a-zA-Z0-9]+([\\.-][a-zA-Z0-9]+)*)+\\.[a-zA-Z]{2,}";
90
91     // original: "^[a-zA-Z0-9]+@[a-zA-Z0-9\\.\\-]+\\.[a-zA-Z]{2,4}+$";
92

93     private static final Pattern JavaDoc emailPattern = Pattern.compile(emailRegExp);
94
95     /**
96      * source reference
97      * <p>
98      * When replying/forwarding this is the original message you selected in the
99      * message-list and replied to
100      */

101     private MailFolderCommandReference ref;
102
103     /**
104      * Flag indicating whether this model holds a html message (true) or plain
105      * text (false)
106      */

107     private boolean isHtmlMessage;
108
109     private EventListenerList JavaDoc listenerList = new EventListenerList JavaDoc();
110
111     /**
112      * Create a new model with an empty plain text message (default behaviour)
113      */

114     public ComposerModel() {
115         this(null, false); // default ~ plain text
116
}
117
118     /**
119      * Creates a new model with a plain text message
120      *
121      * @param message
122      * Initial message to hold in the model
123      */

124     public ComposerModel(ColumbaMessage message) {
125         this(message, false);
126     }
127
128     /**
129      * Creates a new model with an empty message
130      *
131      * @param html
132      * True for a html message, false for plain text
133      */

134     public ComposerModel(boolean html) {
135         this(null, html);
136     }
137
138     /**
139      * Constructs a new ComposerModel. The parameters are read from the
140      * messageOptions.
141      *
142      * @param messageOptions
143      */

144     public ComposerModel(Map JavaDoc<String JavaDoc,String JavaDoc> messageOptions) {
145         this();
146         setMessageOptions(messageOptions);
147     }
148
149     /**
150      * Creates a new model
151      *
152      * @param message
153      * Initial message to hold in the model
154      * @param html
155      * True for a html message, false for plain text
156      */

157     public ComposerModel(ColumbaMessage message, boolean html) {
158         // set message
159
if (message == null) {
160             message = new ColumbaMessage();
161         }
162
163         this.message = message;
164
165         // set whether the model should handle html or plain text
166
isHtmlMessage = html;
167
168         // more initialization
169
toList = new Vector JavaDoc();
170         ccList = new Vector JavaDoc();
171         bccList = new Vector JavaDoc();
172         attachments = new Vector JavaDoc();
173     }
174
175     /**
176      * Set source reference.
177      * <p>
178      * The message you are for example replying to.
179      *
180      * @param ref
181      * source reference
182      */

183     public void setSourceReference(MailFolderCommandReference ref) {
184         this.ref = ref;
185     }
186
187     /**
188      * Get source reference.
189      * <p>
190      * The message you are for example replying to.
191      *
192      * @return source reference
193      */

194     public MailFolderCommandReference getSourceReference() {
195         return ref;
196     }
197
198     /**
199      * Set To: header
200      *
201      * @param a
202      * address array
203      */

204     public void setTo(Address[] a) {
205         getToList().clear();
206
207         for (int i = 0; i < a.length; i++) {
208             getToList().add(a[i].toString());
209         }
210
211     }
212
213     /**
214      * Set Cc: header
215      *
216      * @param a
217      * address array
218      */

219     public void setCc(Address[] a) {
220         getCcList().clear();
221         for (int i = 0; i < a.length; i++) {
222             getCcList().add(a[i].toString());
223         }
224     }
225
226     /**
227      * Set Bcc: header
228      *
229      * @param a
230      * address array
231      */

232     public void setBcc(Address[] a) {
233         getBccList().clear();
234         for (int i = 0; i < a.length; i++) {
235             getBccList().add(a[i].toString());
236         }
237     }
238
239     public void setTo(String JavaDoc s) {
240         LOG.fine("to-headerfield:" + s);
241
242         if (s == null) {
243             return;
244         }
245
246         if (s.length() == 0) {
247             return;
248         }
249
250         List JavaDoc v = ListParser.createListFromString(s);
251         toList = v;
252     }
253
254     public void setHeaderField(String JavaDoc key, String JavaDoc value) {
255         message.getHeader().set(key, value);
256     }
257
258     public void setHeader(Header header) {
259         message.setHeader(header);
260     }
261
262     public String JavaDoc getHeaderField(String JavaDoc key) {
263         return (String JavaDoc) message.getHeader().get(key);
264     }
265
266     public void setToList(List JavaDoc<String JavaDoc> v) {
267         this.toList = v;
268     }
269
270     public void setCcList(List JavaDoc<String JavaDoc> v) {
271         this.ccList = v;
272     }
273
274     public void setBccList(List JavaDoc<String JavaDoc> v) {
275         this.bccList = v;
276     }
277
278     public List JavaDoc<String JavaDoc> getToList() {
279         return toList;
280     }
281
282     public List JavaDoc<String JavaDoc> getCcList() {
283         return ccList;
284     }
285
286     public List JavaDoc<String JavaDoc> getBccList() {
287         return bccList;
288     }
289
290     public void setAccountItem(AccountItem item) {
291         this.accountItem = item;
292     }
293
294     public AccountItem getAccountItem() {
295         if (accountItem == null) {
296             return MailConfig.getInstance().getAccountList().get(0);
297         } else {
298             return accountItem;
299         }
300     }
301
302     public void setMessage(ColumbaMessage message) {
303         this.message = message;
304     }
305
306     public IColumbaMessage getMessage() {
307         return message;
308     }
309
310     public String JavaDoc getHeader(String JavaDoc key) {
311         return (String JavaDoc) message.getHeader().get(key);
312     }
313
314     public void addMimePart(StreamableMimePart mp) {
315         attachments.add(mp);
316
317         // notifyListeners();
318
}
319
320     public void addFileAttachment(File JavaDoc file) {
321         if (file.isFile()) {
322
323             String JavaDoc mimetype = ColumbaDesktop.getInstance().getMimeType(file);
324
325             MimeHeader header = new MimeHeader(mimetype.substring(0, mimetype
326                     .indexOf('/')), mimetype
327                     .substring(mimetype.indexOf('/') + 1));
328             header.putContentParameter("name", file.getName());
329             header.setContentDisposition("attachment");
330             header.putDispositionParameter("filename", file.getName());
331             header.setContentTransferEncoding("base64");
332
333             try {
334                 LocalMimePart mimePart = new LocalMimePart(header,
335                         new FileSource(file));
336
337                 attachments.add(mimePart);
338             } catch (IOException JavaDoc e) {
339                 LOG.warning("Could not add the file '" + file
340                         + "' to the attachment list, due to:" + e);
341             }
342         }
343
344     }
345
346     public void setBodyText(String JavaDoc str) {
347         this.bodytext = str;
348
349         // notifyListeners();
350
}
351
352     public String JavaDoc getSignature() {
353         return "signature";
354     }
355
356     public String JavaDoc getBodyText() {
357         return bodytext;
358     }
359
360     public String JavaDoc getSubject() {
361         return (String JavaDoc) message.getHeader().get("Subject");
362     }
363
364     public void setSubject(String JavaDoc s) {
365         message.getHeader().set("Subject", s);
366     }
367
368     public List JavaDoc getAttachments() {
369         return attachments;
370     }
371
372     public void setAccountItem(String JavaDoc host, String JavaDoc address) {
373         setAccountItem(MailConfig.getInstance().getAccountList()
374                 .hostGetAccount(host, address));
375     }
376
377     /**
378      * Returns the charsetName.
379      *
380      * @return String
381      */

382     public Charset JavaDoc getCharset() {
383         if (charset == null) {
384             charset = Charset.forName(System.getProperty("file.encoding"));
385         }
386
387         return charset;
388     }
389
390     /**
391      * Sets the charsetName.
392      *
393      * @param charsetName
394      * The charsetName to set
395      */

396     public void setCharset(Charset JavaDoc charset) {
397         this.charset = charset;
398     }
399
400     /**
401      * Returns the signMessage.
402      *
403      * @return boolean
404      */

405     public boolean isSignMessage() {
406         return signMessage;
407     }
408
409     /**
410      * Sets the signMessage.
411      *
412      * @param signMessage
413      * The signMessage to set
414      */

415     public void setSignMessage(boolean signMessage) {
416         this.signMessage = signMessage;
417     }
418
419     /**
420      * Returns the encryptMessage.
421      *
422      * @return boolean
423      */

424     public boolean isEncryptMessage() {
425         return encryptMessage;
426     }
427
428     /**
429      * Sets the encryptMessage.
430      *
431      * @param encryptMessage
432      * The encryptMessage to set
433      */

434     public void setEncryptMessage(boolean encryptMessage) {
435         this.encryptMessage = encryptMessage;
436     }
437
438     public String JavaDoc getPriority() {
439         if (message.getHeader().get("X-Priority") == null) {
440             return "Normal";
441         } else {
442             return (String JavaDoc) message.getHeader().get("X-Priority");
443         }
444     }
445
446     public void setPriority(String JavaDoc s) {
447         message.getHeader().set("X-Priority", s);
448     }
449
450     /**
451      * Returns whether the model holds a html message or plain text
452      *
453      * @return True for html, false for text
454      */

455     public boolean isHtml() {
456         return isHtmlMessage;
457     }
458
459     /**
460      * Sets whether the model holds a html message or plain text
461      *
462      * @param html
463      * True for html, false for text
464      */

465     public void setHtml(boolean html) {
466         isHtmlMessage = html;
467     }
468
469     public List JavaDoc getRCPTVector() {
470         List JavaDoc<String JavaDoc> output = new Vector JavaDoc<String JavaDoc>();
471
472         List JavaDoc<String JavaDoc> l = new NormalizeRecipientListParser()
473                 .normalizeRCPTVector(ListBuilder.createFlatList(getToList()));
474         if (l != null)
475             output.addAll(l);
476
477         l = new NormalizeRecipientListParser().normalizeRCPTVector(ListBuilder
478                 .createFlatList(getCcList()));
479         if (l != null)
480             output.addAll(l);
481         l = new NormalizeRecipientListParser().normalizeRCPTVector(ListBuilder
482                 .createFlatList(getBccList()));
483         if (l != null)
484             output.addAll(l);
485
486         return output;
487     }
488
489     public void setMessageOptions(Map JavaDoc<String JavaDoc,String JavaDoc> options) {
490
491         addAddresses(options, "to");
492         addAddresses(options, "cc");
493         addAddresses(options, "bcc");
494
495         if (options.get("subject") != null) {
496             setSubject((String JavaDoc) options.get("subject"));
497         }
498
499         if (options.get("body") != null) {
500             String JavaDoc body = (String JavaDoc) options.get("body");
501             /*
502              * *20030917, karlpeder* Set the model to html or text based on the
503              * body specified on the command line. This is done using a simple
504              * check: Does the body contain <html> and </html>
505              */

506             boolean html = false;
507             String JavaDoc lcase = body.toLowerCase();
508
509             if ((lcase.indexOf("<html>") != -1)
510                     && (lcase.indexOf("</html>") != -1)) {
511                 html = true;
512             }
513
514             setHtml(html);
515
516             // set the body text
517
setBodyText(body);
518         }
519
520         if (options.get("attachment") != null) {
521             if (options.get("attachment") instanceof String JavaDoc) {
522                 String JavaDoc s = (String JavaDoc) options.get("attachment");
523                 try {
524                     URI JavaDoc uri = new URI JavaDoc(s);
525                     addFileAttachment(new File JavaDoc(uri));
526                 } catch (URISyntaxException JavaDoc e) {
527                     // if this is no URI
528
addFileAttachment(new File JavaDoc(s));
529                 }
530             }
531         }
532
533     }
534
535     /**
536      * @param options
537      */

538     private void addAddresses(Map JavaDoc options, String JavaDoc type) {
539         List JavaDoc list;
540
541         if (type.equals("to")) {
542             list = getToList();
543         } else if (type.equals("cc")) {
544             list = getCcList();
545         } else {
546             list = getBccList();
547         }
548
549         if (options.get(type) != null) {
550             if (options.get(type) instanceof String JavaDoc) {
551                 list.add((String JavaDoc) options.get(type));
552             } else {
553                 String JavaDoc[] addresses = (String JavaDoc[]) options.get(type);
554
555                 for (int i = 0; i < addresses.length; i++) {
556                     list.add(addresses[i]);
557                 }
558             }
559
560         }
561     }
562
563     /** **************************** event handling ***************************** */
564
565     /**
566      * Adds a listener.
567      */

568     public void addModelChangedListener(IComposerModelChangedListener listener) {
569         listenerList.add(IComposerModelChangedListener.class, listener);
570     }
571
572     /**
573      * Removes a previously registered listener.
574      */

575     public void removeModelChangedListener(
576             IComposerModelChangedListener listener) {
577         listenerList.remove(IComposerModelChangedListener.class, listener);
578     }
579
580     /**
581      * Propagates an event to all registered listeners notifying them of changes
582      */

583     public void fireModelChanged() {
584         ComposerModelChangedEvent e = new ComposerModelChangedEvent(this);
585         // Guaranteed to return a non-null array
586
Object JavaDoc[] listeners = listenerList.getListenerList();
587
588         // Process the listeners last to first, notifying
589
// those that are interested in this event
590
for (int i = listeners.length - 2; i >= 0; i -= 2) {
591             if (listeners[i] == IComposerModelChangedListener.class) {
592                 ((IComposerModelChangedListener) listeners[i + 1])
593                         .modelChanged(e);
594             }
595         }
596     }
597
598     /**
599      * Propagates an event to all registered listeners notifying them of changes
600      */

601     public void fireHtmlModelChanged(boolean htmlEnabled) {
602         ComposerModelChangedEvent e = new ComposerModelChangedEvent(this, htmlEnabled);
603         // Guaranteed to return a non-null array
604
Object JavaDoc[] listeners = listenerList.getListenerList();
605
606         // Process the listeners last to first, notifying
607
// those that are interested in this event
608
for (int i = listeners.length - 2; i >= 0; i -= 2) {
609             if (listeners[i] == IComposerModelChangedListener.class) {
610                 ((IComposerModelChangedListener) listeners[i + 1])
611                         .htmlModeChanged(e);
612             }
613         }
614     }
615 }
Popular Tags