All Downloads are FREE. Search and download functionalities are using the official Maven repository.

base.email.ImapReader Maven / Gradle / Ivy

/**
 * Creative commons Attribution-NonCommercial license.
 *
 * http://creativecommons.org/licenses/by-nc/2.5/au/deed.en_GB
 *
 * NO WARRANTY IS GIVEN OR IMPLIED, USE AT YOUR OWN RISK.
 */
package base.email;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * Provides basic access to an IMAP account, without requring learning
 * a huge chunky library. Example usage:
 * 
 * ImapReader i = new ImapReader();
 * i.setHostname("mailserver.com");
 * i.setUsername("[email protected]");
 * i.setPassword("password");
 * try {
 *	 i.connect();
 *	 int count = i.readMailbox("INBOX");
 *	 System.out.println("Found "+count+" emails.");
 *	 for(int x = 1; x <= count; x++) {
 *	   i.readMail(x);
 *	 }
 *	 i.logout();
 * } catch(IOException e) {
 *	 System.out.println("Problem accessing server. "+e);
 * }
 * 
*/ public class ImapReader { static Socket imap = null; static OutputStreamWriter outStream = null; static InputStream inStream = null; static BufferedReader reader = null; /** Default to insecure port 143, use port 993 for SSL */ private int port = 143; private String host = ""; private String username = ""; private String password = ""; private int command = 1; private boolean ssh = false; /** * Specify the host name to connect to. */ public void setHostname(String h) { host = h; } /** * Specify the user name to be used for this transaction. * * @param username Username to provide to IMAP server. */ public void setUsername(String username) { if(username == null) { username = ""; } this.username=username; } /** * Specify the password to be used with this transaction. * @param password The password to use for this connection. */ public void setPassword(String password) { if(password == null) { password = ""; } this.password = password; } /** * Initiate connection to the server */ public int connect() throws IOException { SSLContext sc = null; String line = null; Random r = new Random(); command = Math.abs(r.nextInt()%1000000); try { if(ssh) { /* * Create a trust manager that does not validate certificate chains */ TrustManager[] trustAllCerts=new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; // Install the all-trusting trust manager try { sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); } catch (Exception e) { e.printStackTrace(); } // connect with the IMAP server SocketFactory socketFactory = sc.getSocketFactory(); imap = socketFactory.createSocket(host, port); } else { imap = new Socket(host, 143); } outStream = new OutputStreamWriter(imap.getOutputStream()); inStream = imap.getInputStream(); reader = new BufferedReader(new java.io.InputStreamReader(inStream)); line = readLine(); if(!line.substring(0, 4).equalsIgnoreCase("* OK")) { return 2; } write("LOGIN "+username+" "+password); line = readLine(); if(!line.substring(0, 5).equalsIgnoreCase("J1 OK")) { return 4; } } catch(UnknownHostException e) { throw new IOException("Unable to resolve hostname.", e); } return 0; } /** * Marks a message as deleted/ready for deletion. * * @param id Id of the mail as provided by the readMail function. */ public void deleteMail(int id) throws IOException { write("store "+id+" +FLAGS (\\Deleted)"); String line = readLine(); while(line.charAt(0) == '*') { line = readLine(); } } /** * Flushes all email messages that are marked for deletion. */ public void emptyTrash() throws IOException { write("expunge"); String line = readLine(); while(line.charAt(0) == '*') { line=readLine(); } } private static final Pattern END_CHECK = Pattern.compile("J(\\d+) OK.*"); /** * Read contents of a particular email. May only be called after * first using the readMailbox function to select which mail folder * we which to read. * * @param id of email * @return Contents of email. */ public EmailMessage readMail(int id) throws IOException { StringBuffer content=new StringBuffer(); write("fetch "+id+" body[header]"); String line = readLine(); EmailMessage e = new EmailMessage(); while(true) { Matcher m = END_CHECK.matcher(line); if(m.matches()) { break; } if(line.length() > 0 && (line.charAt(0) == ' ' || line.charAt(0) == '\t')) { content.append(line); } else { content.append("\n"); content.append(line); } line=readLine(); } e.setHeaders(content.toString()); content = new StringBuffer(); write("fetch "+id+" body[text]"); line = readLine(); //Skip first line, its just the command response line = readLine(); while(true) { Matcher m = END_CHECK.matcher(line); if(m.matches()) { break; } content.append(line); content.append("\n"); line = readLine(); } String data = content.toString(); data = data.substring(0, data.lastIndexOf(')')); e.setBody(data); return e; } /** * Download the exact content of the full email message. * * @param id of email * @return String containing the entire message content */ public String downloadMessage(int id) throws IOException { StringBuffer content = new StringBuffer(); String line; write("fetch "+id+" body[header]"); line = readLine(); //TODO: We currently ignore response line! line = readLine(); while(true) { Matcher m = END_CHECK.matcher(line); if(m.matches()) { break; } content.append(line); content.append("\n"); line = readLine(); } content.append("\n"); String data = content.toString(); data = data.substring(0, data.lastIndexOf(')')); content = new StringBuffer(); write("fetch "+id+" body[text]"); line = readLine(); //TODO: We currently ignore response line! line = readLine(); while(true) { Matcher m = END_CHECK.matcher(line); if(m.matches()) { break; } content.append(line); content.append("\n"); line = readLine(); } data = data+content.toString(); data = data.substring(0, data.lastIndexOf(')')); return data; } private static final Pattern EXIST_CHECK = Pattern.compile(".*\\* (\\d+) EXIST.*"); /** * Select a particular mail box for reading. Once selected, use the * readMail() command to read the messages in this folder. * * @return Total number of email's in this mail box. */ public int readMailbox(String email) throws IOException { write("select "+email); String line = readLine(); int count = 0; //write("fetch "+1+" body[text]"); //line=readLine(); while(line.charAt(0) == '*') { Matcher m = EXIST_CHECK.matcher(line); if(m.matches()) { count = Integer.parseInt(m.group(1)); } line=readLine(); } return count; } /** * Once all actions are completed, logout is called to disconnect from * the server. */ public void logout() { try { write("logout"); readLine(); } catch(IOException e) { } disconnect(); } /** * Cleanup all connections and data when complete */ private void disconnect() { try { if(inStream != null) { inStream.close(); inStream = null; } if(outStream != null) { outStream.close(); outStream = null; } if(reader != null) { reader.close(); reader = null; } if(imap != null) { imap.close(); imap = null; } } catch(IOException e) { } } private String lastCommand = ""; /** * Sent a command to the server */ private void write(String cmd) throws IOException { command = command+1; lastCommand = cmd; try { outStream.write("J"+command+" "+cmd+"\n"); outStream.flush(); } catch(IOException e) { disconnect(); throw e; } } /** * Read response from the server */ private String readLine() throws IOException{ try { String line = reader.readLine(); if(line.indexOf("J"+command+" BAD") == 0) { throw new IOException("Imap server responded 'BAD' to "+lastCommand); } if(line.indexOf("J"+command+" NO") == 0) { throw new IOException("Imap server responded 'NO' to "+lastCommand); } return line; } catch(IOException e) { disconnect(); throw e; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy