package com.baselet.gui; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.UIManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.baselet.control.config.Config; import com.baselet.control.config.ConfigMail; import com.baselet.control.constants.Constants; import com.baselet.control.enums.Program; import com.baselet.control.util.Path; import com.baselet.diagram.CurrentDiagram; import com.baselet.diagram.Notifier; import com.baselet.diagram.io.DiagramFileHandler; public class MailPanel extends JPanel { private static final Logger log = LoggerFactory.getLogger(MailPanel.class); private static final long serialVersionUID = 1L; /** * Some int and String */ private final int paddingTop = 1; private final int paddingBottom = 1; private final int outerPaddingLeft = 15; private final int outerPaddingRight = 15; private final int halfHorizontalDividerSpace = 2; private final int verticalDividerSpace = 10; /** * Components */ private final GridBagLayout layout = new GridBagLayout(); private final JLabel lb_from = new JLabel("From:"); private final JTextField tf_from = new JTextField(); private final JLink lnk_smtpInfo = new JLink(Program.getInstance().getWebsite() + "/smtp.htm", "What is SMTP?"); private final JLabel lb_smtp = new JLabel("SMTP:"); private final JTextField tf_smtp = new JTextField(); private final JCheckBox cb_smtp_auth = new JCheckBox(); private final JLabel lb_smtpUser = new JLabel("User:"); private final JTextField tf_smtpUser = new JTextField(); private final JLabel lb_smtpPW = new JLabel("PW:"); private final JPasswordField pf_smtpPW = new JPasswordField(); private final JCheckBox cb_pwSave = new JCheckBox(); private final JLabel lb_to = new JLabel("To:"); private final JTextField tf_to = new JTextField(); private final JLabel lb_cc = new JLabel("CC:"); private final JTextField tf_cc = new JTextField(); private final JLabel lb_bcc = new JLabel("BCC:"); private final JTextField tf_bcc = new JTextField(); private final JLabel lb_subject = new JLabel("Subject:"); private final JTextField tf_subject = new JTextField(); private final JTextArea ta_text = new JTextArea(5, 5); JScrollPane sp_text = new JScrollPane(ta_text); private final JCheckBox cb_attachXml = new JCheckBox(); private final JCheckBox cb_attachGif = new JCheckBox(); private final JCheckBox cb_attachPdf = new JCheckBox(); private final JButton bt_send = new JButton("Send"); private final JButton bt_cancel = new JButton("Cancel"); private final JPanel panel_attachments = new JPanel(new FlowLayout(FlowLayout.LEFT)); private final JPanel panel_attachmentsWithButton = new JPanel(layout); // the padding between lines is different for the labels and text components of the grid bag layout private final Insets paddingLeftLabel = new Insets(paddingTop, outerPaddingLeft, paddingBottom, halfHorizontalDividerSpace); private final Insets paddingMessagebox = new Insets(paddingTop, outerPaddingLeft, paddingBottom, outerPaddingRight); private final Insets paddingText = new Insets(paddingTop, halfHorizontalDividerSpace, paddingBottom, outerPaddingRight); private final Insets paddingCheckbox = new Insets(paddingTop - 2, halfHorizontalDividerSpace, paddingBottom - 2, outerPaddingRight); private final Insets paddingRightLabel = new Insets(paddingTop, halfHorizontalDividerSpace, paddingBottom, halfHorizontalDividerSpace); private final Insets noPadding = new Insets(0, 0, 0, 0); // the label doesn't get any additional space. it's always as short as possible private final double noWeight = 0; private final double fullWeight = 1; private final double leftWeight = 0.75; private final double rightWeight = 0.25; // the constraint int to fill the width private final int fillWidth = GridBagConstraints.HORIZONTAL; private final int fillBoth = GridBagConstraints.BOTH; public MailPanel() { initAndFillComponents(); setLayout(layout); setSize(new Dimension(0, Config.getInstance().getMail_split_position())); int line = 0; addComponent(this, layout, Box.createRigidArea(new Dimension(0, verticalDividerSpace)), 0, line, 10, 1, fillWidth, fullWeight, 0, noPadding); line++; addComponent(this, layout, lb_to, 0, line, 1, 1, fillWidth, noWeight, 0, paddingLeftLabel); addComponent(this, layout, tf_to, 1, line, 1, 1, fillWidth, leftWeight, 0, paddingText); addComponent(this, layout, lb_from, 2, line, 1, 1, fillWidth, noWeight, 0, paddingRightLabel); addComponent(this, layout, tf_from, 3, line, 1, 1, fillWidth, rightWeight, 0, paddingRightLabel); addComponent(this, layout, lnk_smtpInfo, 4, line, 1, 1, fillWidth, noWeight, 0, paddingText); line++; addComponent(this, layout, lb_cc, 0, line, 1, 1, fillWidth, noWeight, 0, paddingLeftLabel); addComponent(this, layout, tf_cc, 1, line, 1, 1, fillWidth, leftWeight, 0, paddingText); addComponent(this, layout, lb_smtp, 2, line, 1, 1, fillWidth, noWeight, 0, paddingRightLabel); addComponent(this, layout, tf_smtp, 3, line, 1, 1, fillWidth, rightWeight, 0, paddingRightLabel); addComponent(this, layout, cb_smtp_auth, 4, line, 1, 1, fillWidth, noWeight, 0, paddingText); line++; addComponent(this, layout, lb_bcc, 0, line, 1, 1, fillWidth, noWeight, 0, paddingLeftLabel); addComponent(this, layout, tf_bcc, 1, line, 1, 1, fillWidth, leftWeight, 0, paddingText); addComponent(this, layout, lb_smtpUser, 2, line, 1, 1, fillWidth, noWeight, 0, paddingRightLabel); addComponent(this, layout, tf_smtpUser, 3, line, 1, 1, fillWidth, rightWeight, 0, paddingRightLabel); line++; addComponent(this, layout, lb_subject, 0, line, 1, 1, fillWidth, noWeight, 0, paddingLeftLabel); addComponent(this, layout, tf_subject, 1, line, 1, 1, fillWidth, leftWeight, 0, paddingText); addComponent(this, layout, lb_smtpPW, 2, line, 1, 1, fillWidth, noWeight, 0, paddingRightLabel); addComponent(this, layout, pf_smtpPW, 3, line, 1, 1, fillWidth, rightWeight, 0, paddingRightLabel); addComponent(this, layout, cb_pwSave, 4, line, 1, 1, fillWidth, noWeight, 0, paddingCheckbox); line++; addComponent(this, layout, Box.createRigidArea(new Dimension(0, verticalDividerSpace)), 0, line, 10, 1, fillWidth, fullWeight, 0, noPadding); line++; addComponent(this, layout, sp_text, 0, line, 5, 1, fillBoth, leftWeight, 1, paddingMessagebox); line++; addComponent(this, layout, panel_attachmentsWithButton, 1, line, 5, 1, fillWidth, fullWeight, 0, noPadding); line++; addComponent(this, layout, Box.createRigidArea(new Dimension(0, verticalDividerSpace)), 0, line, 4, 1, fillWidth, fullWeight, 0, noPadding); } private void initAndFillComponents() { ta_text.setText(Constants.getDefaultMailtext()); cb_pwSave.setText("save in config"); cb_attachXml.setText("attach " + Program.getInstance().getExtension().toUpperCase()); cb_attachGif.setText("attach GIF"); cb_attachPdf.setText("attach PDF"); cb_smtp_auth.setText("authentication"); bt_send.addActionListener(new SendActionListener()); bt_cancel.addActionListener(new CancelActionListener()); cb_smtp_auth.addActionListener(new AuthentificationActionListener()); // Set Tooltips String adressToolTip = "Separate multiple adresses with ','"; cb_pwSave.setToolTipText("WARNING: The password is stored as plain text in " + Program.getInstance().getConfigName()); tf_from.setToolTipText(adressToolTip); tf_to.setToolTipText(adressToolTip); tf_cc.setToolTipText(adressToolTip); tf_bcc.setToolTipText(adressToolTip); // Fill Attachment Panel panel_attachments.add(cb_attachXml); panel_attachments.add(Box.createRigidArea(new Dimension(5, 0))); panel_attachments.add(cb_attachGif); panel_attachments.add(Box.createRigidArea(new Dimension(5, 0))); panel_attachments.add(cb_attachPdf); // Fill the superpanel which holds attachments and the send button addComponent(panel_attachmentsWithButton, layout, panel_attachments, 0, 0, 1, 1, fillWidth, fullWeight, 0, noPadding); addComponent(panel_attachmentsWithButton, layout, bt_send, 1, 0, 1, 1, fillWidth, fullWeight, 0, paddingText); addComponent(panel_attachmentsWithButton, layout, bt_cancel, 2, 0, 1, 1, fillWidth, fullWeight, 0, paddingText); setAllFonts(); readConstants(); checkVisibilityOfSmtpAuth(); } private void sendMail() { /** * Initialize some variables and objects */ String smtpHost = tf_smtp.getText(); String smtpUser = tf_smtpUser.getText(); String smtpPW = String.valueOf(pf_smtpPW.getPassword()); String from = tf_from.getText(); String[] to = removeWhitespaceAndSplitAt(tf_to.getText()); String[] cc = removeWhitespaceAndSplitAt(tf_cc.getText()); String[] bcc = removeWhitespaceAndSplitAt(tf_bcc.getText()); String subject = tf_subject.getText(); String text = ta_text.getText(); boolean useSmtpAuthentication = false; File diagramXml = null; File diagramGif = null; File diagramPdf = null; int nrOfAttachments = 0; // Set SMTP Authentication if the user or password field isn't empty if (!smtpUser.isEmpty() || !smtpPW.isEmpty()) { useSmtpAuthentication = true; } // Create the temp diagrams to send try { final String diagramName = "diagram_" + new SimpleDateFormat("yyyyMMdd_hhmmss").format(new Date()); DiagramFileHandler fileHandler = CurrentDiagram.getInstance().getDiagramHandler().getFileHandler(); if (cb_attachXml.isSelected()) { nrOfAttachments++; diagramXml = fileHandler.doSaveTempDiagram(diagramName, Program.getInstance().getExtension()); } if (cb_attachGif.isSelected()) { nrOfAttachments++; diagramGif = fileHandler.doSaveTempDiagram(diagramName, "gif"); } if (cb_attachPdf.isSelected()) { nrOfAttachments++; diagramPdf = fileHandler.doSaveTempDiagram(diagramName, "pdf"); } } catch (Exception e) { JOptionPane.showMessageDialog(this, "There has been an error with your diagram. Please make sure it's not empty.", "Diagram Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); return; } /** * Check if all necessary fields are filled */ String errorMsg = null; if (smtpHost.isEmpty()) { errorMsg = "The SMTP field must not be empty"; } else if (from.isEmpty()) { errorMsg = "The FROM field must not be empty"; } else if (to.length == 0) { errorMsg = "The TO field must not be empty"; } if (errorMsg != null) { JOptionPane.showMessageDialog(this, errorMsg, "Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); return; } /** * Set up the mail */ try { // Get system properties and session Properties props = System.getProperties(); Session session = Session.getInstance(props); // Define message and it's parts MimeMessage message = new MimeMessage(session); MimeBodyPart textPart = new MimeBodyPart(); MimeBodyPart[] attachmentPart = new MimeBodyPart[nrOfAttachments]; for (int i = 0; i < nrOfAttachments; i++) { attachmentPart[i] = new MimeBodyPart(); } // Build multipart message Multipart multipart = new MimeMultipart(); multipart.addBodyPart(textPart); for (int i = 0; i < nrOfAttachments; i++) { multipart.addBodyPart(attachmentPart[i]); } message.setContent(multipart); /** * Fill the message properties */ // Set the SMTP Host props.put("mail.smtp.host", smtpHost); // We want to close the connection immediately after sending props.put("mail.smtp.quitwait", "false"); // We want to use encryption if needed props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.ssl.protocols", "SSLv3 TLSv1"); // If authentication is needed we set it to true if (useSmtpAuthentication) { props.put("mail.smtp.auth", "true"); } else { props.put("mail.smtp.auth", "false"); } // Set all recipients of any kind (TO, CC, BCC) message.setFrom(new InternetAddress(from)); for (String element : to) { message.addRecipient(Message.RecipientType.TO, new InternetAddress(element)); } for (String element : cc) { message.addRecipient(Message.RecipientType.CC, new InternetAddress(element)); } for (String element : bcc) { message.addRecipient(Message.RecipientType.BCC, new InternetAddress(element)); } // Set subject, text and attachment message.setSubject(subject); textPart.setText(text); int i = 0; if (cb_attachXml.isSelected()) { attachmentPart[i++].attachFile(diagramXml); } if (cb_attachGif.isSelected()) { attachmentPart[i++].attachFile(diagramGif); } if (cb_attachPdf.isSelected()) { attachmentPart[i++].attachFile(diagramPdf); } /** * Send message (if no authentication is used, we use the short variant to send a mail */ if (useSmtpAuthentication) { Transport transport = session.getTransport("smtp"); try { transport.connect(smtpHost, smtpUser, smtpPW); transport.sendMessage(message, message.getAllRecipients()); } finally { transport.close(); } } else { // No SMTP Authentication Transport.send(message); } Notifier.getInstance().showInfo("Email sent"); closePanel(); } catch (MessagingException e) { log.error("SMTP Error", e); JOptionPane.showMessageDialog(this, "There has been an error with your smtp server." + Constants.NEWLINE + "Please recheck your smtp server and login data.", "SMTP Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } catch (IOException e) { log.error("Mail Error", e); JOptionPane.showMessageDialog(this, "There has been an error sending your mail." + Constants.NEWLINE + "Please recheck your input data.", "Sending Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } catch (Throwable e) { log.error("Mail Error", e); JOptionPane.showMessageDialog(this, "There has been an error sending your mail." + Constants.NEWLINE + "Please recheck your input data.", "Sending Error", JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } finally { if (diagramXml != null) { Path.safeDeleteFile(diagramXml, false); } if (diagramGif != null) { Path.safeDeleteFile(diagramGif, false); } if (diagramPdf != null) { Path.safeDeleteFile(diagramPdf, false); } } } /** * Adds a component to this panel * * @param gbl * The GridBagLayout of this component * @param c * The Component to add * @param x * The x value of grid where the component starts * @param y * The y value of grid where the component starts * @param width * How many spaces of the grid's width will be used by the component * @param height * How many spaces of the grid's height will be used by the component * @param fill * If the component's display area is larger than the component's requested size this param determines whether and how to resize the component * @param weightx * Specifies how to distribute extra horizontal space. * @param weighty * Specifies how to distribute extra vertical space. * @param insets * Specifies the external padding of the component (= minimum amount of space between the component and the edges of its display area) */ private void addComponent(JPanel panel, GridBagLayout gbl, Component c, int x, int y, int width, int height, int fill, double weightx, double weighty, Insets insets) { GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = width; gbc.gridheight = height; gbc.fill = fill; gbc.weightx = weightx; gbc.weighty = weighty; gbc.insets = insets; gbl.setConstraints(c, gbc); panel.add(c); } private String[] removeWhitespaceAndSplitAt(String inputString) { if (inputString.isEmpty()) { return new String[] {}; } StringBuilder sb = new StringBuilder(""); for (int i = 0; i < inputString.length(); i++) { if (inputString.charAt(i) != ' ') { sb.append(inputString.charAt(i)); } } return sb.toString().split(","); } private void storeConstants() { ConfigMail cfgMail = ConfigMail.getInstance(); cfgMail.setMail_smtp(tf_smtp.getText()); cfgMail.setMail_smtp_auth(cb_smtp_auth.isSelected()); cfgMail.setMail_smtp_user(tf_smtpUser.getText()); cfgMail.setMail_smtp_pw_store(cb_pwSave.isSelected()); if (cb_pwSave.isSelected()) { cfgMail.setMail_smtp_pw(String.valueOf(pf_smtpPW.getPassword())); } else { cfgMail.setMail_smtp_pw(""); } cfgMail.setMail_from(tf_from.getText()); cfgMail.setMail_to(tf_to.getText()); cfgMail.setMail_cc(tf_cc.getText()); cfgMail.setMail_bcc(tf_bcc.getText()); cfgMail.setMail_xml(cb_attachXml.isSelected()); cfgMail.setMail_gif(cb_attachGif.isSelected()); cfgMail.setMail_pdf(cb_attachPdf.isSelected()); } private void readConstants() { ConfigMail cfgMail = ConfigMail.getInstance(); tf_smtp.setText(cfgMail.getMail_smtp()); cb_smtp_auth.setSelected(cfgMail.isMail_smtp_auth()); tf_smtpUser.setText(cfgMail.getMail_smtp_user()); cb_pwSave.setSelected(cfgMail.isMail_smtp_pw_store()); pf_smtpPW.setText(cfgMail.getMail_smtp_pw()); tf_from.setText(cfgMail.getMail_from()); tf_to.setText(cfgMail.getMail_to()); tf_cc.setText(cfgMail.getMail_cc()); tf_bcc.setText(cfgMail.getMail_bcc()); cb_attachXml.setSelected(cfgMail.isMail_xml()); cb_attachGif.setSelected(cfgMail.isMail_gif()); cb_attachPdf.setSelected(cfgMail.isMail_pdf()); } private void setAllFonts() { Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 12); Font fontBold = new Font(Font.SANS_SERIF, Font.BOLD, 12); Font fontSmallItalic = new Font(Font.SANS_SERIF, Font.ITALIC, 10); lb_smtp.setFont(fontBold); tf_smtp.setFont(font); lb_smtpUser.setFont(fontBold); tf_smtpUser.setFont(font); lb_smtpPW.setFont(fontBold); pf_smtpPW.setFont(font); lb_from.setFont(fontBold); tf_from.setFont(font); lb_to.setFont(fontBold); tf_to.setFont(font); lb_cc.setFont(fontBold); tf_cc.setFont(font); lb_bcc.setFont(fontBold); tf_bcc.setFont(font); lb_subject.setFont(fontBold); tf_subject.setFont(font); ta_text.setFont(font); cb_attachXml.setFont(fontBold); cb_attachGif.setFont(fontBold); cb_attachPdf.setFont(fontBold); lnk_smtpInfo.setFont(fontSmallItalic); cb_smtp_auth.setFont(fontSmallItalic); cb_pwSave.setFont(fontSmallItalic); } public void closePanel() { storeConstants(); Config.getInstance().setMail_split_position((int) this.getSize().getHeight()); CurrentGui.getInstance().getGui().setMailPanelEnabled(false); } private class SendActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { sendMail(); } } private class CancelActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { closePanel(); } } private void checkVisibilityOfSmtpAuth() { boolean val = cb_smtp_auth.isSelected(); lb_smtpUser.setVisible(val); tf_smtpUser.setVisible(val); lb_smtpPW.setVisible(val); pf_smtpPW.setVisible(val); cb_pwSave.setVisible(val); if (!val) { tf_smtpUser.setText(""); pf_smtpPW.setText(""); cb_pwSave.setSelected(false); } repaint(); } private class AuthentificationActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { checkVisibilityOfSmtpAuth(); } } }