001: /*
002: * This file is part of the Echo Web Application Framework (hereinafter "Echo").
003: * Copyright (C) 2002-2005 NextApp, Inc.
004: *
005: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006: *
007: * The contents of this file are subject to the Mozilla Public License Version
008: * 1.1 (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: * http://www.mozilla.org/MPL/
011: *
012: * Software distributed under the License is distributed on an "AS IS" basis,
013: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014: * for the specific language governing rights and limitations under the
015: * License.
016: *
017: * Alternatively, the contents of this file may be used under the terms of
018: * either the GNU General Public License Version 2 or later (the "GPL"), or
019: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020: * in which case the provisions of the GPL or the LGPL are applicable instead
021: * of those above. If you wish to allow use of your version of this file only
022: * under the terms of either the GPL or the LGPL, and not to allow others to
023: * use your version of this file under the terms of the MPL, indicate your
024: * decision by deleting the provisions above and replace them with the notice
025: * and other provisions required by the GPL or the LGPL. If you do not delete
026: * the provisions above, a recipient may use your version of this file under
027: * the terms of any one of the MPL, the GPL or the LGPL.
028: */
029:
030: package echo2example.email;
031:
032: import java.util.StringTokenizer;
033:
034: import javax.mail.Message;
035: import javax.mail.MessagingException;
036: import javax.mail.Transport;
037: import javax.mail.internet.AddressException;
038: import javax.mail.internet.InternetAddress;
039: import javax.mail.internet.MimeMessage;
040:
041: import nextapp.echo2.app.Button;
042: import nextapp.echo2.app.Column;
043: import nextapp.echo2.app.Extent;
044: import nextapp.echo2.app.Grid;
045: import nextapp.echo2.app.Insets;
046: import nextapp.echo2.app.Label;
047: import nextapp.echo2.app.Row;
048: import nextapp.echo2.app.SplitPane;
049: import nextapp.echo2.app.TextArea;
050: import nextapp.echo2.app.TextField;
051: import nextapp.echo2.app.WindowPane;
052: import nextapp.echo2.app.event.ActionEvent;
053: import nextapp.echo2.app.event.ActionListener;
054: import nextapp.echo2.app.event.WindowPaneEvent;
055: import nextapp.echo2.app.event.WindowPaneListener;
056:
057: /**
058: * The message composition window.
059: */
060: public class ComposeWindow extends WindowPane {
061:
062: private static final Extent DIALOG_OFFSET_X = new Extent(80);
063: private static final Extent DIALOG_OFFSET_Y = new Extent(26);
064:
065: /**
066: * Adds recipient e-mail addresses contained in a comma-delimited string
067: * to an outgoing e-mail <code>Message</code>.
068: *
069: * @param message the <code>Message</code> object to which the addresses
070: * will be added
071: * @param recipientType the type of recipient to which the addresses
072: * should be added (to, cc, or bcc)
073: * @param recipients a comma-delimited string of recipient addresses
074: */
075: private static void addRecipients(Message message,
076: Message.RecipientType recipientType, String recipients)
077: throws AddressException, MessagingException {
078: if (recipients != null && recipients.trim().length() > 0) {
079: // Tokenize the recipient string based on commas.
080: StringTokenizer tokenizer = new StringTokenizer(recipients,
081: ",");
082: while (tokenizer.hasMoreTokens()) {
083: // Add each recipient.
084: String recipient = tokenizer.nextToken();
085: message.addRecipient(recipientType,
086: new InternetAddress(recipient));
087: }
088: }
089: }
090:
091: private TextField toField;
092: private TextField ccField;
093: private TextField bccField;
094: private TextField subjectField;
095: private TextArea messageField;
096:
097: /**
098: * Creates a new <code>ComposeWindow</code>.
099: *
100: * @param replyMessage the message being replied to, or null if composing
101: * a new message.
102: */
103: public ComposeWindow(Message replyMessage) {
104: super (Messages.getString("ComposeWindow.Title"),
105: new Extent(600), new Extent(480));
106: setResizable(false);
107: setDefaultCloseOperation(WindowPane.DO_NOTHING_ON_CLOSE);
108: setStyleName("Default");
109:
110: addWindowPaneListener(new WindowPaneListener() {
111: public void windowPaneClosing(WindowPaneEvent e) {
112: processDiscard();
113: }
114: });
115:
116: SplitPane mainPane = new SplitPane(
117: SplitPane.ORIENTATION_VERTICAL, new Extent(32));
118: add(mainPane);
119:
120: Row controlPane = new Row();
121: controlPane.setStyleName("ControlPane");
122: mainPane.add(controlPane);
123:
124: Button sendButton = new Button(Messages
125: .getString("ComposeWindow.SendButton"),
126: Styles.ICON_24_YES);
127: sendButton.setStyleName("ControlPane.Button");
128: sendButton.addActionListener(new ActionListener() {
129: public void actionPerformed(ActionEvent e) {
130: if (sendMessage()) {
131: ((EmailApp) getApplicationInstance())
132: .getDefaultWindow().getContent().remove(
133: ComposeWindow.this );
134: }
135: }
136: });
137: controlPane.add(sendButton);
138:
139: Button cancelButton = new Button(Messages
140: .getString("ComposeWindow.DiscardButton"),
141: Styles.ICON_24_NO);
142: cancelButton.setStyleName("ControlPane.Button");
143: cancelButton.addActionListener(new ActionListener() {
144: public void actionPerformed(ActionEvent e) {
145: processDiscard();
146: }
147: });
148: controlPane.add(cancelButton);
149:
150: Column layoutColumn = new Column();
151: layoutColumn.setCellSpacing(new Extent(10));
152: layoutColumn.setInsets(new Insets(10));
153: mainPane.add(layoutColumn);
154:
155: Grid headerGrid = new Grid();
156: headerGrid.setInsets(new Insets(0, 2));
157: layoutColumn.add(headerGrid);
158:
159: Label label;
160:
161: label = new Label(Messages.getString("Message.PromptLabel.To"));
162: headerGrid.add(label);
163:
164: toField = new TextField();
165: toField.setStyleName("Default");
166: toField.setWidth(new Extent(450));
167: headerGrid.add(toField);
168:
169: label = new Label(Messages.getString("Message.PromptLabel.Cc"));
170: headerGrid.add(label);
171:
172: ccField = new TextField();
173: ccField.setStyleName("Default");
174: ccField.setWidth(new Extent(450));
175: headerGrid.add(ccField);
176:
177: label = new Label(Messages.getString("Message.PromptLabel.Bcc"));
178: headerGrid.add(label);
179:
180: bccField = new TextField();
181: bccField.setStyleName("Default");
182: bccField.setWidth(new Extent(450));
183: headerGrid.add(bccField);
184:
185: label = new Label(Messages
186: .getString("Message.PromptLabel.Subject"));
187: headerGrid.add(label);
188:
189: subjectField = new TextField();
190: subjectField.setStyleName("Default");
191: subjectField.setWidth(new Extent(450));
192: headerGrid.add(subjectField);
193:
194: messageField = new TextArea();
195: messageField.setStyleName("Default");
196: messageField.setWidth(new Extent(520));
197: messageField.setHeight(new Extent(18, Extent.EM));
198: layoutColumn.add(messageField);
199:
200: if (replyMessage == null) {
201: EmailApp.getActive().setFocusedComponent(toField);
202: } else {
203: EmailApp.getActive().setFocusedComponent(messageField);
204: try {
205: toField.setText(MessageUtil.clean(replyMessage
206: .getFrom()[0].toString(), -1, -1));
207: subjectField.setText(MessageUtil.clean(replyMessage
208: .getSubject(), -1, -1));
209: } catch (MessagingException ex) {
210: EmailApp.getApp().processFatalException(ex);
211: }
212: }
213: }
214:
215: /**
216: * Handles a user request to discard the message being composed.
217: */
218: private void processDiscard() {
219: if (messageField.getText().trim().length() > 0) {
220: MessageDialog confirmDialog = new MessageDialog(
221: Messages
222: .getString("ComposeWindow.ConfirmDiscard.Title"),
223: Messages
224: .getString("ComposeWindow.ConfirmDiscard.Message"),
225: MessageDialog.TYPE_CONFIRM,
226: MessageDialog.CONTROLS_YES_NO);
227: confirmDialog.setPositionX(Extent.add(getPositionX(),
228: DIALOG_OFFSET_X));
229: confirmDialog.setPositionY(Extent.add(getPositionY(),
230: DIALOG_OFFSET_Y));
231: confirmDialog.addActionListener(new ActionListener() {
232: public void actionPerformed(ActionEvent e) {
233: if (MessageDialog.COMMAND_OK.equals(e
234: .getActionCommand())) {
235: getParent().remove(ComposeWindow.this );
236: }
237: }
238: });
239: getApplicationInstance().getDefaultWindow().getContent()
240: .add(confirmDialog);
241: } else {
242: getParent().remove(this );
243: }
244: }
245:
246: /**
247: * Sends the message.
248: * This message will display an error dialog if the message cannot be
249: * sent.
250: *
251: * @return True if the message was sent.
252: */
253: private boolean sendMessage() {
254: MimeMessage message = new MimeMessage(
255: ((EmailApp) getApplicationInstance()).getMailSession());
256: try {
257: // Validate.
258: String errorMessage = null;
259: if (toField.getText().length() == 0) {
260: errorMessage = Messages
261: .getString("ComposeWindow.SendError.NoToField");
262: } else if (subjectField.getText().length() == 0) {
263: errorMessage = Messages
264: .getString("ComposeWindow.SendError.NoSubjectField");
265: } else if (messageField.getText().length() == 0) {
266: errorMessage = Messages
267: .getString("ComposeWindow.SendError.NoMessageContent");
268: }
269: if (errorMessage != null) {
270: MessageDialog messageDialog = new MessageDialog(
271: Messages
272: .getString("ComposeWindow.SendError.Title"),
273: errorMessage, MessageDialog.TYPE_ERROR,
274: MessageDialog.CONTROLS_OK);
275: messageDialog.setPositionX(Extent.add(getPositionX(),
276: DIALOG_OFFSET_X));
277: messageDialog.setPositionY(Extent.add(getPositionY(),
278: DIALOG_OFFSET_Y));
279: getApplicationInstance().getDefaultWindow()
280: .getContent().add(messageDialog);
281: return false;
282: }
283:
284: // Set sender address.
285: message.setFrom(new InternetAddress(
286: ((EmailApp) getApplicationInstance())
287: .getEmailAddress()));
288:
289: // Add recipients contained in recipient text fields.
290: addRecipients(message, Message.RecipientType.TO, toField
291: .getText());
292: addRecipients(message, Message.RecipientType.CC, ccField
293: .getText());
294: addRecipients(message, Message.RecipientType.BCC, bccField
295: .getText());
296:
297: // Set the subject and content of the message.
298: message.setSubject(subjectField.getText());
299: message.setText(messageField.getText());
300:
301: // Attempt to send the message.
302: if (!EmailApp.FAUX_MODE) {
303: Transport.send(message);
304: }
305: return true;
306: } catch (AddressException ex) {
307: // Process an exception pertaining to an invalid recipient e-mail address: Raise an error.
308: MessageDialog messageDialog = new MessageDialog(
309: Messages.getString("ComposeWindow.SendError.Title"),
310: Messages
311: .getString("ComposeWindow.SendError.InvalidAddress"),
312: MessageDialog.TYPE_ERROR, MessageDialog.CONTROLS_OK);
313: messageDialog.setPositionX(Extent.add(getPositionX(),
314: DIALOG_OFFSET_X));
315: messageDialog.setPositionY(Extent.add(getPositionY(),
316: DIALOG_OFFSET_Y));
317: getApplicationInstance().getDefaultWindow().getContent()
318: .add(messageDialog);
319: return false;
320: } catch (MessagingException ex) {
321: // Handle a fatal exception.
322: EmailApp.getApp().processFatalException(ex);
323: return false;
324: }
325: }
326: }
|