001: //The contents of this file are subject to the Mozilla Public License Version 1.1
002: //(the "License"); you may not use this file except in compliance with the
003: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004: //
005: //Software distributed under the License is distributed on an "AS IS" basis,
006: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007: //for the specific language governing rights and
008: //limitations under the License.
009: //
010: //The Original Code is "The Columba Project"
011: //
012: //The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
013: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
014: //
015: //All Rights Reserved.
016:
017: package org.columba.mail.gui.config.account;
018:
019: import java.awt.Font;
020: import java.awt.GridBagConstraints;
021: import java.awt.GridBagLayout;
022: import java.awt.Insets;
023: import java.awt.event.ActionEvent;
024: import java.awt.event.ActionListener;
025: import java.io.File;
026: import java.util.Iterator;
027: import java.util.LinkedList;
028: import java.util.List;
029: import java.util.logging.Logger;
030: import java.util.regex.Matcher;
031: import java.util.regex.Pattern;
032:
033: import javax.swing.BorderFactory;
034: import javax.swing.JButton;
035: import javax.swing.JCheckBox;
036: import javax.swing.JComboBox;
037: import javax.swing.JDialog;
038: import javax.swing.JLabel;
039: import javax.swing.JOptionPane;
040: import javax.swing.JPanel;
041: import javax.swing.JSpinner;
042: import javax.swing.JTextField;
043: import javax.swing.SpinnerNumberModel;
044:
045: import org.columba.core.config.DefaultConfigDirectory;
046: import org.columba.core.gui.base.ButtonWithMnemonic;
047: import org.columba.core.gui.base.CheckBoxWithMnemonic;
048: import org.columba.core.gui.base.LabelWithMnemonic;
049: import org.columba.core.gui.exception.ExceptionHandler;
050: import org.columba.mail.config.AccountItem;
051: import org.columba.mail.config.MailConfig;
052: import org.columba.mail.config.OutgoingItem;
053: import org.columba.mail.smtp.SMTPServer;
054: import org.columba.mail.util.AuthenticationManager;
055: import org.columba.mail.util.MailResourceLoader;
056: import org.columba.ristretto.smtp.SMTPException;
057:
058: import com.jgoodies.forms.builder.DefaultFormBuilder;
059: import com.jgoodies.forms.layout.FormLayout;
060:
061: /**
062: * @author fdietz
063: */
064: public class OutgoingServerPanel extends DefaultPanel implements
065: ActionListener {
066:
067: /** JDK 1.4+ logging framework logger, used for logging. */
068: private static final Logger LOG = Logger
069: .getLogger("org.columba.mail.gui.config.account");
070:
071: private static final Pattern AUTH_MODE_TOKENIZE_PATTERN = Pattern
072: .compile("(\\d+);?");
073:
074: private JLabel hostLabel;
075:
076: private JTextField hostTextField;
077:
078: private JLabel portLabel;
079:
080: private JSpinner portSpinner;
081:
082: private JLabel loginLabel;
083:
084: private JTextField loginTextField;
085:
086: private JCheckBox secureCheckBox;
087:
088: private JCheckBox needAuthCheckBox;
089:
090: private JCheckBox storePasswordCheckBox;
091:
092: private JLabel authenticationLabel;
093:
094: private JComboBox authenticationComboBox;
095:
096: private JCheckBox defaultAccountCheckBox;
097:
098: private OutgoingItem item;
099:
100: private AccountItem accountItem;
101:
102: private JButton checkAuthMethods;
103:
104: private JDialog dialog;
105:
106: public OutgoingServerPanel(JDialog parent, AccountItem accountItem) {
107: super ();
108: this .accountItem = accountItem;
109: item = accountItem.getSmtpItem();
110: dialog = parent;
111:
112: initComponents();
113: updateComponents(true);
114: }
115:
116: public String getHost() {
117: return hostTextField.getText();
118: }
119:
120: public String getLogin() {
121: return loginTextField.getText();
122: }
123:
124: public boolean isESmtp() {
125: return needAuthCheckBox.isSelected();
126: }
127:
128: protected void updateComponents(boolean b) {
129: if (b) {
130: hostTextField.setText(item.get(OutgoingItem.HOST));
131: String port = item.get(OutgoingItem.PORT);
132: portSpinner.setValue(new Integer(port));
133: loginTextField.setText(item.get(OutgoingItem.USER));
134: storePasswordCheckBox.setSelected(item
135: .getBoolean(OutgoingItem.SAVE_PASSWORD));
136: secureCheckBox.setSelected(item.getBooleanWithDefault(
137: OutgoingItem.ENABLE_SSL, false));
138:
139: if (!(item.get(OutgoingItem.LOGIN_METHOD).equals(
140: Integer.toString(AuthenticationManager.NONE)) || item
141: .get(OutgoingItem.LOGIN_METHOD).equals(
142: OutgoingItem.NONE))) {
143: needAuthCheckBox.setSelected(true);
144:
145: storePasswordCheckBox.setEnabled(true);
146: loginLabel.setEnabled(true);
147: loginTextField.setEnabled(true);
148:
149: String loginMethod = item
150: .get(OutgoingItem.LOGIN_METHOD);
151: try {
152: authenticationComboBox.setSelectedItem(new Integer(
153: loginMethod));
154: } catch (NumberFormatException e) {
155: }
156: } else {
157: needAuthCheckBox.setSelected(false);
158:
159: storePasswordCheckBox.setEnabled(false);
160: loginLabel.setEnabled(false);
161: loginTextField.setEnabled(false);
162: authenticationLabel.setEnabled(false);
163: authenticationComboBox.setEnabled(false);
164: }
165:
166: defaultAccountCheckBox
167: .setEnabled(MailConfig.getInstance()
168: .getAccountList().getDefaultAccountUid() != accountItem
169: .getInteger(OutgoingItem.UID));
170:
171: if (defaultAccountCheckBox.isEnabled()
172: && defaultAccountCheckBox.isSelected()) {
173: showDefaultAccountWarning();
174: } else {
175: layoutComponents();
176: }
177: } else {
178: item.setString(OutgoingItem.USER, loginTextField.getText());
179: item.setBoolean(OutgoingItem.SAVE_PASSWORD,
180: storePasswordCheckBox.isSelected());
181: item.setString(OutgoingItem.PORT, ((Integer) portSpinner
182: .getValue()).toString());
183: item.setString(OutgoingItem.HOST, hostTextField.getText());
184:
185: item.setBoolean(OutgoingItem.ENABLE_SSL, secureCheckBox
186: .isSelected());
187:
188: if (needAuthCheckBox.isSelected()) {
189: item.setString(OutgoingItem.LOGIN_METHOD,
190: authenticationComboBox.getSelectedItem()
191: .toString());
192: } else {
193: item.setString(OutgoingItem.LOGIN_METHOD, Integer
194: .toString(AuthenticationManager.NONE));
195: }
196:
197: item.setBoolean(OutgoingItem.USE_DEFAULT_ACCOUNT,
198: defaultAccountCheckBox.isSelected());
199:
200: item.getRoot().notifyObservers();
201: }
202: }
203:
204: protected void layoutComponents() {
205: // Create a FormLayout instance.
206: FormLayout layout = new FormLayout(
207: "10dlu, 10dlu, max(60dlu;default), 3dlu, fill:max(150dlu;default):grow, 3dlu, default, 3dlu, default ",
208:
209: // 2 columns
210: ""); // rows are added dynamically (no need to define them
211: // here)
212:
213: DefaultFormBuilder builder = new DefaultFormBuilder(layout,
214: this );
215:
216: // create EmptyBorder between components and dialog-frame
217: builder.setDefaultDialogBorder();
218:
219: // skip the first column
220: builder.setLeadingColumnOffset(1);
221:
222: // Add components to the panel:
223: // builder.append(defaultAccountCheckBox, 7);
224: // builder.nextLine();
225:
226: builder.appendSeparator(MailResourceLoader.getString("dialog",
227: "account", "configuration"));
228: builder.nextLine();
229:
230: // builder.setLeadingColumnOffset(1);
231:
232: builder.append(loginLabel, 2);
233: builder.append(loginTextField, 5);
234: builder.nextLine();
235:
236: builder.append(hostLabel, 2);
237: builder.append(hostTextField);
238: // builder.nextLine();
239:
240: builder.append(portLabel);
241: builder.append(portSpinner);
242: builder.nextLine();
243:
244: builder.setLeadingColumnOffset(1);
245:
246: builder.appendSeparator(MailResourceLoader.getString("dialog",
247: "account", "security"));
248: builder.nextLine();
249:
250: builder.append(needAuthCheckBox, 8);
251: builder.nextLine();
252:
253: builder.setLeadingColumnOffset(2);
254:
255: JPanel panel = new JPanel();
256: FormLayout l = new FormLayout(
257: "default, 3dlu, left:pref:grow, 3dlu, left:pref:grow",
258:
259: // 2 columns
260: "fill:default:grow"); // rows are added dynamically (no need
261: // to
262: // define them here)
263:
264: // create a form builder
265: DefaultFormBuilder b = new DefaultFormBuilder(l, panel);
266: b.append(authenticationLabel, authenticationComboBox,
267: checkAuthMethods);
268: // b.nextLine();
269: // b.append(loginLabel, loginTextField);
270: builder.append(panel, 5);
271: builder.nextLine();
272:
273: // builder.setLeadingColumnOffset(1);
274: builder.append(secureCheckBox, 6);
275: builder.nextLine();
276:
277: JPanel panel2 = new JPanel();
278: FormLayout l2 = new FormLayout("default, 3dlu, left:pref",
279:
280: // 2 columns
281: "fill:default:grow"); // rows are added dynamically (no need
282: // to
283: // define them here)
284:
285: // create a form builder
286: DefaultFormBuilder b2 = new DefaultFormBuilder(l2, panel2);
287: b2.setRowGroupingEnabled(true);
288: builder.append(panel2, 3);
289: builder.nextLine();
290:
291: builder.append(storePasswordCheckBox, 5);
292: builder.nextLine();
293:
294: // builder.setLeadingColumnOffset(1);
295: }
296:
297: protected void showDefaultAccountWarning() {
298: setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
299:
300: GridBagLayout mainLayout = new GridBagLayout();
301: GridBagConstraints mainConstraints = new GridBagConstraints();
302:
303: setLayout(mainLayout);
304:
305: mainConstraints.gridwidth = GridBagConstraints.REMAINDER;
306: mainConstraints.anchor = GridBagConstraints.NORTHWEST;
307: mainConstraints.weightx = 1.0;
308: mainConstraints.insets = new Insets(0, 10, 5, 0);
309: mainLayout.setConstraints(defaultAccountCheckBox,
310: mainConstraints);
311: add(defaultAccountCheckBox);
312:
313: mainConstraints = new GridBagConstraints();
314: mainConstraints.weighty = 1.0;
315: mainConstraints.gridwidth = GridBagConstraints.REMAINDER;
316:
317: JLabel label = new JLabel(MailResourceLoader.getString(
318: "dialog", "account", "using_default_account_settings"));
319: Font newFont = label.getFont().deriveFont(Font.BOLD);
320: label.setFont(newFont);
321: mainLayout.setConstraints(label, mainConstraints);
322: add(label);
323: }
324:
325: protected void initComponents() {
326: defaultAccountCheckBox = new CheckBoxWithMnemonic(
327: MailResourceLoader.getString("dialog", "account",
328: "use_default_account_settings"));
329:
330: // defaultAccountCheckBox.setEnabled(false);
331: defaultAccountCheckBox.setActionCommand("DEFAULT_ACCOUNT");
332: defaultAccountCheckBox.addActionListener(this );
333:
334: hostLabel = new LabelWithMnemonic(MailResourceLoader.getString(
335: "dialog", "account", OutgoingItem.HOST)); //$NON-NLS-1$
336:
337: hostTextField = new JTextField();
338: hostLabel.setLabelFor(hostTextField);
339: portLabel = new LabelWithMnemonic(MailResourceLoader.getString(
340: "dialog", "account", OutgoingItem.PORT)); //$NON-NLS-1$
341:
342: portSpinner = new JSpinner(new SpinnerNumberModel(100, 1,
343: 65535, 1));
344: portLabel.setLabelFor(portSpinner);
345:
346: needAuthCheckBox = new CheckBoxWithMnemonic(
347: MailResourceLoader
348: .getString(
349: "dialog", "account", "server_needs_authentification")); //$NON-NLS-1$
350:
351: needAuthCheckBox.setActionCommand("AUTH"); //$NON-NLS-1$
352: needAuthCheckBox.addActionListener(this );
353:
354: storePasswordCheckBox = new CheckBoxWithMnemonic(
355: MailResourceLoader.getString("dialog", "account",
356: "store_password_in_configuration_file"));
357:
358: storePasswordCheckBox.setActionCommand("SAVE");
359: storePasswordCheckBox.addActionListener(this );
360:
361: secureCheckBox = new CheckBoxWithMnemonic(MailResourceLoader
362: .getString("dialog", "account",
363: "use_SSL_for_secure_connection"));
364:
365: authenticationLabel = new LabelWithMnemonic(MailResourceLoader
366: .getString("dialog", "account", "authentication_type"));
367:
368: authenticationComboBox = new JComboBox();
369: authenticationComboBox
370: .setRenderer(new AuthenticationListCellRenderer());
371: authenticationLabel.setLabelFor(authenticationComboBox);
372:
373: updateAuthenticationComboBox();
374:
375: checkAuthMethods = new ButtonWithMnemonic(MailResourceLoader
376: .getString("dialog", "account",
377: "authentication_checkout_methods"));
378: checkAuthMethods.setActionCommand("CHECK_AUTHMETHODS");
379: checkAuthMethods.addActionListener(this );
380:
381: // authenticationComboBox.addActionListener(this);
382: authenticationLabel.setLabelFor(authenticationComboBox);
383:
384: loginLabel = new LabelWithMnemonic(MailResourceLoader
385: .getString("dialog", "account", "login"));
386:
387: loginTextField = new JTextField();
388: loginLabel.setLabelFor(loginTextField);
389: }
390:
391: /**
392: *
393: */
394: private void updateAuthenticationComboBox() {
395: authenticationComboBox.removeAllItems();
396: authenticationComboBox.addItem(new Integer(0));
397:
398: if (accountItem.isPopAccount()) {
399: authenticationComboBox.addItem(new Integer(
400: AuthenticationManager.POP_BEFORE_SMTP));
401: }
402:
403: String authMethods = accountItem.getString("smtpserver",
404: "authentication_methods");
405:
406: // Add previously fetch authentication modes
407: if (authMethods != null) {
408: Matcher matcher = AUTH_MODE_TOKENIZE_PATTERN
409: .matcher(authMethods);
410: while (matcher.find()) {
411: authenticationComboBox.addItem(new Integer(matcher
412: .group(1)));
413: }
414: }
415: }
416:
417: public void actionPerformed(ActionEvent e) {
418: String action = e.getActionCommand();
419:
420: if (e.getSource() == authenticationComboBox) {
421: loginLabel.setEnabled(true);
422: loginTextField.setEnabled(true);
423: storePasswordCheckBox.setEnabled(true);
424: } else if (action.equals("DEFAULT_ACCOUNT")) {
425: removeAll();
426:
427: if (defaultAccountCheckBox.isSelected()) {
428: showDefaultAccountWarning();
429: } else {
430: layoutComponents();
431: }
432:
433: revalidate();
434: } else if (action.equals("AUTH")) {
435: boolean enabled = needAuthCheckBox.isSelected();
436: loginLabel.setEnabled(enabled);
437: loginTextField.setEnabled(enabled);
438: storePasswordCheckBox.setEnabled(enabled);
439: authenticationLabel.setEnabled(enabled);
440: authenticationComboBox.setEnabled(enabled);
441: checkAuthMethods.setEnabled(enabled);
442: } else if (action.equals("CHECK_AUTHMETHODS")) {
443: fetchSupportedAuthenticationMechanisms();
444: } else if (action.equals("SAVE")) {
445: if (!storePasswordCheckBox.isSelected()) {
446: return;
447: } else {
448: File configPath = DefaultConfigDirectory.getInstance()
449: .getCurrentPath();
450: File defaultConfigPath = DefaultConfigDirectory
451: .getDefaultPath();
452: while (!configPath.equals(defaultConfigPath)) {
453: configPath = configPath.getParentFile();
454: if (configPath == null) {
455: JOptionPane.showMessageDialog(dialog,
456: MailResourceLoader.getString("dialog",
457: "password", "warn_save_msg"),
458: MailResourceLoader.getString("dialog",
459: "password", "warn_save_title"),
460: JOptionPane.WARNING_MESSAGE);
461: return;
462: }
463: }
464: }
465: }
466: }
467:
468: private AccountItem getCurrentDialogSettings() {
469: AccountItem account = (AccountItem) accountItem.clone();
470: OutgoingItem item = account.getSmtpItem();
471: item.setString(OutgoingItem.USER, loginTextField.getText());
472: item.setBoolean(OutgoingItem.SAVE_PASSWORD,
473: storePasswordCheckBox.isSelected());
474: item.setString(OutgoingItem.PORT, ((Integer) portSpinner
475: .getValue()).toString());
476: item.setString(OutgoingItem.HOST, hostTextField.getText());
477: item.setBoolean(OutgoingItem.ENABLE_SSL, secureCheckBox
478: .isSelected());
479:
480: return account;
481: }
482:
483: private void fetchSupportedAuthenticationMechanisms() {
484: List list = new LinkedList();
485:
486: try {
487: SMTPServer server = new SMTPServer(
488: getCurrentDialogSettings());
489: list = server.checkSupportedAuthenticationMethods();
490: } catch (SMTPException e1) {
491: LOG.severe("Server does not support the CAPA command");
492: } catch (Exception e) {
493: // let exception handler process other errors
494: new ExceptionHandler().processException(e);
495: }
496:
497: // Save the authentication modes
498: if (list.size() > 0) {
499: StringBuffer authMethods = new StringBuffer();
500: Iterator it = list.iterator();
501: authMethods.append(it.next());
502:
503: while (it.hasNext()) {
504: authMethods.append(';');
505: authMethods.append(it.next());
506: }
507:
508: accountItem.setString("smtpserver",
509: "authentication_methods", authMethods.toString());
510: } else {
511: accountItem.setString("smtpserver",
512: "authentication_methods", "");
513: }
514:
515: updateAuthenticationComboBox();
516: }
517:
518: public boolean isFinished() {
519: String host = getHost();
520: boolean esmtp = isESmtp();
521:
522: if (host.length() == 0) {
523: JOptionPane.showMessageDialog(this , MailResourceLoader
524: .getString("dialog", "account",
525: "You_have_to_enter_a_host_name"));
526:
527: return false;
528: } else if (esmtp) {
529: String login = getLogin();
530:
531: if (login.length() == 0) {
532: JOptionPane.showMessageDialog(this , MailResourceLoader
533: .getString("dialog", "account",
534: "You_have_to_enter_a_login_name"));
535:
536: return false;
537: }
538: }
539:
540: return true;
541: }
542: }
|