import java.io.File;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.ContentType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
/**
* Klasse MailTool
*
* @author GUI-Programmer
* @version 04.01.2012
*/
public class MailTool {
// Attribute
private String username, password;
private Session session1;
private Transport transport;
private Store store;
private Message[] message;
private ArrayList<DataHandler> datahandlers;
private ArrayList<Integer> bodyPartSizes;
private Folder folder;
private boolean showDialog;
private int mailNumber;
private String separator;
// Konstruktor
public MailTool() {
username = null;
password = null;
session1 = null;
transport = null;
store = null;
datahandlers = new ArrayList<DataHandler>();
bodyPartSizes = new ArrayList<Integer>();
showDialog = false;
mailNumber = -1;
separator = System.getProperty("file.separator");
}
// Methoden
/**
* Es wird versucht eine Verbindung zu Googlemail aufzubauen und sich
* dort mit den Benutzernamen und den Passwort einzuloggen.
* @param username
* @param password
* @throws Exception
*/
public void login(final String username, final String password) throws Exception {
this.username = username;
this.password = password;
Properties props1=new Properties();
props1.put("mail.smtp.port", "587");
props1.put("mail.smtp.auth", "true");
props1.put("mail.smtp.starttls.enable", "true");
session1 = Session.getInstance(props1);
transport = session1.getTransport("smtp");
transport.connect("smtp.googlemail.com", username, password);
Properties props2 = System.getProperties();
props2.setProperty("mail.store.protocol", "imaps");
props2.setProperty("mail.imaps.partialfetch", "false");
props2.setProperty("mail.imap.host", "imap.gmail.com");
props2.setProperty("mail.imap.port", "993");
props2.setProperty("mail.imap.connectiontimeout", "5000");
props2.setProperty("mail.imap.timeout", "5000");
Session session2 = Session.getDefaultInstance(props2, null);
store = session2.getStore("imaps");
store.connect("imap.gmail.com", username, password);
folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
}
/**
* Versucht eine E-Mail an die angegebene Addresse/-n zu senden.
* @param recipientAddresses
* @param subject
* @param mailText
* @throws Exception
*/
public void sendMail(String recipientAddresses, String subject, String mailText, ArrayList<File> filelist) throws Exception {
login(username, password);
Address[] addresses = InternetAddress.parse(recipientAddresses);
Message message = new MimeMessage(session1);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO, addresses);
message.setSubject(subject);
// create the message part
Multipart multipart = new MimeMultipart();
MimeBodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText(mailText);
multipart.addBodyPart(textBodyPart);
for(int i=0; i<filelist.size(); i++) {
MimeBodyPart attachementBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filelist.get(i));
attachementBodyPart.setDataHandler(new DataHandler(source));
attachementBodyPart.setFileName(filelist.get(i).getName());
multipart.addBodyPart(attachementBodyPart);
}
message.setContent(multipart);
transport.sendMessage(message, addresses);
transport.close();
}
public void deleteMail(int number) throws Exception {
message = folder.getMessages();
int index = message.length - number-1;
message[index].setFlag(Flags.Flag.DELETED, true);
folder.close(true);
folder.open(Folder.READ_WRITE);
}
/**
* Die Anhänge der ausgewählten E-Mail werden ermittelt und als Strings zurückgegeben.
* @param number
* @return
* @throws Exception
*/
public ArrayList<String> getAttachments(int number) throws Exception {
final ArrayList<String> attachments = new ArrayList<String>();
datahandlers.removeAll(datahandlers);
bodyPartSizes.removeAll(bodyPartSizes);
login(username, password);
message = folder.getMessages();
int index = message.length - number;
if(message[index].getContentType().toString().startsWith("multipart")) {
Multipart content = (Multipart) message[index].getContent();
for(int i=0; i<content.getCount(); i++) {
BodyPart part = (BodyPart) content.getBodyPart(i);
String fileName = part.getFileName();
if(isAttachement(part.getContentType(), fileName)) {
fileName = encordeAttachement(fileName);
attachments.add(fileName);
datahandlers.add(part.getDataHandler());
bodyPartSizes.add(part.getSize());
}
}
}
return attachments;
}
private boolean isAttachement(String contentType, String fileName) {
boolean isAttachement = false;
if(!contentType.startsWith("text/html")
&& !contentType.startsWith("text/rtf")
&& !contentType.startsWith("text/plain")
&& fileName != null) {
isAttachement = true;
}
return isAttachement;
}
private String encordeAttachement(String s) throws UnsupportedEncodingException {
String temp = MimeUtility.decodeText(s);
String decoded = Normalizer.normalize(temp, Normalizer.Form.NFC);
return decoded;
}
/**
* Der Text der ausgewählten E-Mail wird ermittelt und als String zurückgegeben.
* @param number
* @return
* @throws Exception
*/
public String readMail(int number) throws Exception {
mailNumber = number;
String text = null;
message = folder.getMessages();
int index = message.length - number;
ContentType contentType = new ContentType(message[index].getContentType());
String type = contentType.getPrimaryType()+"/"+contentType.getSubType();
if(type.equals("TEXT/PLAIN")) {
text = message[index].getContent().toString().replaceAll("\n", "<br />");
} else if(type.equals("TEXT/HTML")) {
text = message[index].getContent().toString();
} else if(contentType.toString().startsWith("multipart")) {
text = getMultiPartText(message[index].getContent());
}
text = "<html>"+text+"</html>";
System.out.println(type.toString());
return text;
}
/**
* Behandelt den Inhalt einer E-Mail als multipart-Typ und versucht
* ihn als String zu konvertieren.
* @param m
* @return
* @throws Exception
*/
private String getMultiPartText(Object content) throws Exception {
String text = null;
StringBuffer buffer = new StringBuffer();
Multipart multipart = (Multipart) content;
for(int i=0; i<multipart.getCount(); i++) {
BodyPart part = multipart.getBodyPart( i );
ContentType ct = new ContentType(part.getContentType());
String type = ct.getPrimaryType()+"/"+ct.getSubType();
if(type.equals("TEXT/PLAIN")) {
buffer.append(part.getContent().toString().replaceAll("\n", "<br />"));
} else if(type.equals("TEXT/HTML")) {
buffer.append(part.getContent().toString());
} else if(type.startsWith("multipart")) {
buffer.append(getMultiPartText(part.getContent()));
}
System.out.println(type.toString());
text = buffer.toString();
}
return text;
}
/**
* Gibt den Benutzernamen das Nutzers zurück.
* @return
*/
public String getUsername() {
String user;
if(username.endsWith("@googlemail.com")) {
user = username.replaceAll("@googlemail.com", "");
} else {
user = username;
}
return user;
}
/**
* Liefert 2 String-Arrays. Das 1. enthält die Namen aller Absender
* der E-Mails, das 2. die dazugehörigen Betreffe.
* @return
*/
public String[][] getMails(final JProgressBar progress) {
progress.setValue(0);
String[][] mails = null;
try {
message = folder.getMessages();
mails = new String[message.length][message.length];
final String[] from = new String[message.length];
final String[] subject = new String[message.length];
progress.setMaximum(message.length);
for (int i=message.length-1; i>0; i--) {
try {
int temp = message.length-i;
Address[] froms = message[i].getFrom();
String email = froms == null ? null : ((InternetAddress) froms[0]).getAddress();
from[temp] = email;
subject[temp] = message[i].getSubject();
if(subject[temp] == null) subject[temp] = "<Kein Betreff>";
progress.setValue(temp);
} catch(Exception ignore) { }
}
progress.setValue(progress.getMaximum());
mails = new String[][] {from, subject};
} catch(Exception ex) {
ex.printStackTrace();
}
return mails;
}
public void downloadFile(final String filename, final int attachmentNumber, final Downloads dialogDownloads, final File directory) {
dialogDownloads.setTitle("Aktiver Download");
dialogDownloads.setVisible(true);
dialogDownloads.lblFileName.setText(filename+" wird heruntergeladen...");
dialogDownloads.prgrsbr.setValue(0);
final SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
showDialog = true;
Thread.sleep(200);
dialogDownloads.prgrsbr.setIndeterminate(true);
File file = new File(directory.getAbsolutePath()+separator+filename);
if(!file.exists()) file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
datahandlers.get(attachmentNumber).writeTo(fos);
fos.close();
return null;
}
@Override
public void done() {
showDialog = false;
dialogDownloads.prgrsbr.setIndeterminate(false);
dialogDownloads.prgrsbr.setValue(100);
dialogDownloads.setTitle("Download abgeschlossen");
Thread t = new Thread() {
boolean run = true;
public void run() {
while(run) {
try {
sleep(3000);
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
run = false;
dialogDownloads.setVisible(showDialog);
}
}
};
t.start();
}
};
worker.execute();
}
public void downloadAllFiles(final Downloads dialogDownloads, final File directory) {
System.out.println(directory.getAbsolutePath());
dialogDownloads.setTitle("Aktiver Download");
dialogDownloads.prgrsbr.setValue(0);
dialogDownloads.setVisible(true);
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
private ArrayList<String> fileList = null;
@Override
protected Void doInBackground() throws Exception {
Thread.sleep(200);
dialogDownloads.prgrsbr.setIndeterminate(true);
Thread t1 = new Thread(new Runnable() {
public void run() {
try { fileList = getAttachments(mailNumber); }
catch(Exception ex) { ex.printStackTrace(); }
}
}); t1.start(); t1.join();
for(int i=0; i<fileList.size(); i++) {
dialogDownloads.lblFileName.setText(fileList.get(i)+" wird heruntergeladen...");
final int k = i;
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
File file = new File(directory.getAbsolutePath()+separator+fileList.get(k));
if(!file.exists()) file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
datahandlers.get(k).writeTo(fos);
fos.close();
}
catch(Exception ex) { ex.printStackTrace(); }
}
}); t2.start(); t2.join();
dialogDownloads.prgrsbr.setIndeterminate(false);
dialogDownloads.prgrsbr.setValue(100);
Thread.sleep(100);
}
return null;
}
@Override
protected void done() {
dialogDownloads.setTitle("Downloads abgeschlossen");
Thread t3 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
dialogDownloads.setVisible(false);
}
catch(InterruptedException ex) { ex.printStackTrace(); }
}
}); t3.start();
}
};
worker.execute();
}
public boolean logout() {
boolean logout = false;
Thread t = new Thread(new Runnable() {
public void run() {
try {
store.close();
}
catch(MessagingException ex) {
ex.printStackTrace();
}
}
});
t.start();
try {
t.join();
logout = true;
} catch(InterruptedException ex) {
ex.printStackTrace();
}
return logout;
}
}