-1

How can I download a file given the following URL with Java-SE-7:

imap://georg@imap.acme.com:143/fetch%3EUID%3E/INBOX%3E18678?fileName=testmail.eml

Any help highly appreciated - thank you in advance.

salocinx
  • 3,715
  • 8
  • 61
  • 110
  • 1
    Maybe look at http://stackoverflow.com/questions/61176/getting-mail-from-gmail-into-java-application-using-imap https://javamail.java.net/nonav/docs/JavaMail-1.5.pdf https://javamail.java.net/nonav/docs/api/ ...good luck! – Steve Waldman May 14 '13 at 12:46
  • Thanks for your help. But I know these documents and it's not exactly what I want. The above URL results from a drag&drop action from Thunderbird to my application and it seems that the testmail.eml file is already created on the server. Now I think, I only have to find a way how to download this testmail.eml file over imap://... Any further suggestions? – salocinx May 14 '13 at 15:30
  • This URL is specific to thunderbird. There's no generic imap:// URL specification. However, you can pick some of this apart: username is georg, host is imap,acme.com, port is 143. You'll need the password through some other method. The next part is `fetch>UID>`, presumably saying to fetch something by UID. `INBOX>18678`, presumably means from the INBOX with UID 18678, and ?fileName=testmail.eml means to grab that the thing with that filename. This is actually a fairly large problem and you'd need to use an IMAP library to implement that, along with MIME parsing and other tools. – Max May 14 '13 at 16:33
  • I lied, there is a imap:// specification at http://tools.ietf.org/html/rfc5092, but it is not followed by Thunderbird. – Max May 14 '13 at 16:39
  • hi max, thanks for your suggestion. I'll try to implement such a "basic fetcher" with javax.mail; I already have some experience with that and it will be sufficient for me when it works for some well-established scenarios. I'll post my final solution here. – salocinx May 15 '13 at 08:42

1 Answers1

0

Here's my basic solution. The following code needs Apache Commons I/O 2.4 which can be downloaded here:

public class ImapMessage {

    private String authority;
    private String protocol;
    private String host;
    private int port;
    private String username;
    private String password;
    private String foldername;
    private long msgid;
    private String filename;
    private Message message;

    public ImapMessage(String url) throws IOException, MessagingException {
        parseURL(decodeURL(url));
    }

    @Override
    public String toString() {
        return "protocol: "+protocol+"\n"+
               "host: "+host+"\n"+
               "port: "+port+"\n"+
               "username: "+username+"\n"+
               "password: "+password+"\n"+
               "folder: "+foldername+"\n"+
               "msgid: "+msgid+"\n"+
               "filename: "+filename;
    }

    private String decodeURL(String url) throws IOException {
        if(url!=null && !url.isEmpty()) {
            url = StringUtils.replace(url, "%3E", ">");
            url = StringUtils.replace(url, "%20", " ");
            return url;
        } else {
            throw new IOException("The given URL is empty or invalid.");
        }
    }


    private void parseURL(String url) throws IOException, MalformedURLException {
        if(url!=null && !url.isEmpty()) {
            //<editor-fold defaultstate="collapsed" desc="Parse Protocol">
            if(url.startsWith("imaps")) {
                url = StringUtils.replace(url, "imaps", "http", 1);
                protocol = "imaps";
            } else if(url.startsWith("imap")) {
                url = StringUtils.replace(url, "imap", "http", 1);
                protocol = "imap";
            } else {
                throw new IOException("Unsupported protocol: "+url.substring(0, url.indexOf("://")));
            }

            try {
                URL newurl = new URL(url);
                String path = newurl.getPath();
                String query = newurl.getQuery();
                authority = newurl.getAuthority();
                host = newurl.getHost();
                port = newurl.getPort();
                username = newurl.getUserInfo();
                password = "provide your password here";
                foldername = path.substring(path.indexOf(">/")+2, path.lastIndexOf(">"));
                msgid = Long.parseLong(path.substring(path.lastIndexOf(">")+1, path.length()));
                filename = query.substring(query.indexOf("=")+1, query.length());
            } catch (MalformedURLException ex) {
                throw ex;
            }
        } else {
            throw new IOException("The given URL is empty or invalid.");
        }
    }

    public File fetchMessage() throws IOException, FileNotFoundException, MessagingException {

        Store store = null;
        Folder folder = null;
        File filepath = new File("/destination/directory");
        try {
            Properties props = System.getProperties();
            props.setProperty("mail.store.protocol", protocol);
            Session session = Session.getDefaultInstance(props, null);
            // session.setDebug(true);
            store = session.getStore(protocol);
            store.connect(host, port, username, password);
            folder = store.getFolder(foldername);
            folder.open(Folder.READ_ONLY);
            UIDFolder ufolder = (UIDFolder)folder;
            message = ufolder.getMessageByUID(msgid);
            if(message!=null) {
                File file = null;
                if(filename.equals("null")) {
                    file = new File(filepath.getAbsolutePath()+File.separator+Long.toString(System.nanoTime())+".eml");
                } else {
                    file = new File(filepath.getAbsolutePath()+File.separator+filename);
                }
                message.writeTo(new FileOutputStream(file));
                return file;
            } else {
                throw new MessagingException("The requested e-mail could not be found on the mail server.");
            }
        } catch(Exception ex) {
            throw ex;
        } finally {
            if(folder!=null) {
                folder.close(true);
            }
            if(store!=null) {
                store.close();
            }
        }
    }

}
salocinx
  • 3,715
  • 8
  • 61
  • 110