package com.inter6.mail.gui.data;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import javax.annotation.PostConstruct;
import javax.mail.Address;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.inter6.mail.gui.ConfigObserver;
import com.inter6.mail.gui.action.LogPanel;
import com.inter6.mail.gui.component.DatePanel;
import com.inter6.mail.gui.component.EncodingTextPanel;
import com.inter6.mail.gui.component.TextViewDialog;
import com.inter6.mail.gui.data.edit.EditAddressPanel;
import com.inter6.mail.gui.data.edit.EditHeaderPanel;
import com.inter6.mail.gui.data.edit.EditMessagePanel;
import com.inter6.mail.gui.tab.TabComponentPanel;
import com.inter6.mail.job.SendJobBuilder;
import com.inter6.mail.job.smtp.AbstractSmtpSendJob;
import com.inter6.mail.job.smtp.MimeSmtpSendJob;
import com.inter6.mail.model.component.AddressData;
import com.inter6.mail.model.component.DateData;
import com.inter6.mail.model.component.EncodingTextData;
import com.inter6.mail.model.component.HeaderData;
import com.inter6.mail.model.component.content.PartData;
import com.inter6.mail.model.component.content.PartDataJsonDeserializer;
import com.inter6.mail.model.component.content.PartDataJsonSerializer;
import com.inter6.mail.model.data.EditSourceData;
import com.inter6.mail.module.AppConfig;
import com.inter6.mail.module.ModuleService;
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class EditSourcePanel extends TabComponentPanel implements SendJobBuilder, ConfigObserver {
private static final long serialVersionUID = -4373325495997044386L;
@Autowired
private AppConfig appConfig;
private EditAddressPanel editAddressPanel;
private EditHeaderPanel editHeaderPanel;
private EditMessagePanel editMessagePanel;
private LogPanel logPanel;
private final EncodingTextPanel subjectPanel = new EncodingTextPanel("Subject", 30, true);
private final DatePanel datePanel = new DatePanel("Date", 30, true, true);
public EditSourcePanel(String tabName) {
super(tabName);
}
@PostConstruct
private void init() {
editAddressPanel = tabComponentManager.getTabComponent(tabName, EditAddressPanel.class);
editHeaderPanel = tabComponentManager.getTabComponent(tabName, EditHeaderPanel.class);
editMessagePanel = tabComponentManager.getTabComponent(tabName, EditMessagePanel.class);
logPanel = tabComponentManager.getTabComponent(tabName, LogPanel.class);
this.setLayout(new BorderLayout());
JPanel wrapPanel = new JPanel();
wrapPanel.setLayout(new BoxLayout(wrapPanel, BoxLayout.Y_AXIS));
{
wrapPanel.add(this.subjectPanel);
wrapPanel.add(this.datePanel);
wrapPanel.add(this.editAddressPanel);
wrapPanel.add(this.editHeaderPanel);
wrapPanel.add(this.editMessagePanel);
}
this.add(wrapPanel, BorderLayout.CENTER);
JPanel actionPanel = new JPanel();
actionPanel.setLayout(new BoxLayout(actionPanel, BoxLayout.Y_AXIS));
{
JButton viewButton = new JButton("View");
viewButton.addActionListener(this.createViewEvent());
actionPanel.add(viewButton);
JButton saveButton = new JButton("Save");
saveButton.addActionListener(this.createSaveEvent());
actionPanel.add(saveButton);
}
this.add(actionPanel, BorderLayout.EAST);
}
private ActionListener createViewEvent() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
try {
byte[] message = EditSourcePanel.this.buildMessage();
TextViewDialog.createDialog(new String(message, "UTF-8")).setModal().setTitle("View MIME text - smtp-sender").setSize(600, 600).show();
} catch (Throwable e) {
EditSourcePanel.this.logPanel.error("build mime fail !", e);
}
}
};
}
private ActionListener createSaveEvent() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
try {
byte[] message = EditSourcePanel.this.buildMessage();
JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showSaveDialog(EditSourcePanel.this) != JFileChooser.APPROVE_OPTION) {
EditSourcePanel.this.logPanel.info("save to eml cancel.");
return;
}
File saveFile = fileChooser.getSelectedFile();
FileUtils.writeByteArrayToFile(saveFile, message);
EditSourcePanel.this.logPanel.info("save to eml success - FILE:" + saveFile);
} catch (Throwable e) {
EditSourcePanel.this.logPanel.error("save to eml fail !", e);
}
}
};
}
private byte[] buildMessage() throws Throwable {
MimeMessage mimeMessage = new MimeMessage(Session.getInstance(new Properties()));
this.buildMessageHeader(mimeMessage);
Object contentPart = this.editMessagePanel.buildContentPart();
if (contentPart instanceof MimeMultipart) {
mimeMessage.setContent((Multipart) contentPart);
} else if (contentPart instanceof MimeBodyPart) {
MimeBodyPart bodyPart = (MimeBodyPart) contentPart;
mimeMessage.setDataHandler(bodyPart.getDataHandler());
Enumeration headers = bodyPart.getAllHeaderLines();
while (headers.hasMoreElements()) {
mimeMessage.addHeaderLine((String) headers.nextElement());
}
}
mimeMessage.saveChanges();
ByteArrayOutputStream memStream = new ByteArrayOutputStream();
mimeMessage.writeTo(memStream);
return memStream.toByteArray();
}
private void buildMessageHeader(MimeMessage mimeMessage) throws MessagingException, UnsupportedEncodingException {
EncodingTextData subjectData = this.subjectPanel.getEncodingTextData();
if (subjectData.isUse()) {
mimeMessage.setSubject(subjectData.encodeSubject());
}
DateData dateData = this.datePanel.getDateData();
if (dateData.isUse()) {
if (dateData.isNow()) {
mimeMessage.setSentDate(new Date());
} else {
mimeMessage.setHeader("Date", dateData.getText());
}
}
List<AddressData> addressDatas = this.editAddressPanel.getAddressDatas();
for (AddressData addressData : addressDatas) {
if (!addressData.isUse()) {
continue;
}
RecipientType type = addressData.getRecipientType();
InternetAddress internetAddress = addressData.toInternetAddress();
if (type == null) {
mimeMessage.addFrom(new Address[] { internetAddress });
} else {
mimeMessage.addRecipient(type, internetAddress);
}
}
List<HeaderData> headerDatas = this.editHeaderPanel.getHeaderDatas();
for (HeaderData headerData : headerDatas) {
if (!headerData.isUse()) {
continue;
}
mimeMessage.addHeader(headerData.getKey(), headerData.getValue());
}
}
@Override
public AbstractSmtpSendJob buildSendJob() throws Throwable {
MimeSmtpSendJob mimeSmtpSendJob = ModuleService.getBean(MimeSmtpSendJob.class);
mimeSmtpSendJob.setTabName(tabName);
mimeSmtpSendJob.setMessageStream(new ByteArrayInputStream(this.buildMessage()));
return mimeSmtpSendJob;
}
private EditSourceData getEditSourceData() {
EditSourceData editSourceData = new EditSourceData();
editSourceData.setSubjectData(this.subjectPanel.getEncodingTextData());
editSourceData.setDateData(this.datePanel.getDateData());
editSourceData.setEditAddressData(this.editAddressPanel.getEditAddressData());
editSourceData.setEditHeaderData(this.editHeaderPanel.getEditHeaderData());
editSourceData.setEditMessageData(this.editMessagePanel.getEditMessageData());
return editSourceData;
}
@Override
public void loadConfig() {
Gson gson = new GsonBuilder().registerTypeAdapter(PartData.class, new PartDataJsonDeserializer()).create();
EditSourceData editSourceData = gson.fromJson(this.appConfig.getString(tabName + ".edit.source.data"), EditSourceData.class);
if (editSourceData == null) {
return;
}
this.subjectPanel.setEncodingTextData(editSourceData.getSubjectData());
this.datePanel.setDateData(editSourceData.getDateData());
this.editAddressPanel.setEditAddressData(editSourceData.getEditAddressData());
this.editHeaderPanel.setEditHeaderData(editSourceData.getEditHeaderData());
this.editMessagePanel.setEditMessageData(editSourceData.getEditMessageData());
}
@Override
public void updateConfig() {
Gson gson = new GsonBuilder().registerTypeAdapter(PartData.class, new PartDataJsonSerializer()).create();
this.appConfig.setProperty(tabName + ".edit.source.data", gson.toJson(this.getEditSourceData()));
}
}