You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2013/07/31 02:42:18 UTC

svn commit: r1508693 - in /commons/proper/net/trunk/src: changes/changes.xml main/java/examples/mail/IMAPImportMbox.java main/java/org/apache/commons/net/imap/IMAPClient.java

Author: sebb
Date: Wed Jul 31 00:42:18 2013
New Revision: 1508693

URL: http://svn.apache.org/r1508693
Log:
NET-514 IMAP APPEND multiple issues in IMapClient.
Deprecated unusable append methods.
Added new append method, as well as example IMapImportMbox class to make use of it.

Added:
    commons/proper/net/trunk/src/main/java/examples/mail/IMAPImportMbox.java   (with props)
Modified:
    commons/proper/net/trunk/src/changes/changes.xml
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPClient.java

Modified: commons/proper/net/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/changes/changes.xml?rev=1508693&r1=1508692&r2=1508693&view=diff
==============================================================================
--- commons/proper/net/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/net/trunk/src/changes/changes.xml [utf-8] Wed Jul 31 00:42:18 2013
@@ -62,6 +62,14 @@ The <action> type attribute can be add,u
      -->
 
     <body>
+        <release version="3.4" date="2013-??-??" description="
+        ">
+            <action issue="NET-514" dev="sebb" type="fix">
+            IMAP APPEND multiple issues in IMapClient.
+            Deprecated unusable append methods.
+            Added new append method, as well as example IMapImportMbox class to make use of it.
+            </action>
+        </release>
         <release version="3.3" date="2013-06-??" description="
 This is mainly a bug-fix release. See further details below.
         ">

Added: commons/proper/net/trunk/src/main/java/examples/mail/IMAPImportMbox.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/examples/mail/IMAPImportMbox.java?rev=1508693&view=auto
==============================================================================
--- commons/proper/net/trunk/src/main/java/examples/mail/IMAPImportMbox.java (added)
+++ commons/proper/net/trunk/src/main/java/examples/mail/IMAPImportMbox.java Wed Jul 31 00:42:18 2013
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package examples.mail;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.apache.commons.net.imap.IMAPClient;
+import org.apache.commons.net.imap.IMAPSClient;
+
+/**
+ * This is an example program demonstrating how to use the IMAP[S]Client class.
+ * This program connects to a IMAP[S] server and imports messages into the folder from an mbox file.
+ * <p>
+ * Usage: IMAPMail <imap[s] server hostname> <folder> <username> <password> <mboxfile> [secure protocol, e.g. TLS]
+ * <p>
+ */
+public final class IMAPImportMbox
+{
+
+    private static final String CRLF = "\r\n";
+
+    public static void main(String[] args) throws IOException
+    {
+        if (args.length < 5)
+        {
+            System.err.println(
+                "Usage: IMAPImportMbox <imap server hostname> <folder> <username> <password> <mboxfile> [TLS]");
+            System.exit(1);
+        }
+
+        final String server   = args[0];
+        final String folder   = args[1];
+        final String username = args[2];
+        final String password = args[3];
+        final String file     = args[4];
+        final String proto = (args.length > 5) ? args[5] : null;
+
+        final File mbox = new File(file);
+        if (!mbox.isFile() || !mbox.canRead()) {
+            throw new IOException("Cannot read mailbox file: " + mbox);
+        }
+
+        IMAPClient imap;
+
+        if (proto != null) {
+            System.out.println("Using secure protocol: " + proto);
+            imap = new IMAPSClient(proto, true); // implicit
+        } else {
+            imap = new IMAPClient();
+        }
+        System.out.println("Connecting to server " + server + " on " + imap.getDefaultPort());
+
+        // We want to timeout if a response takes longer than 60 seconds
+        imap.setDefaultTimeout(60000);
+
+        try {
+            imap.connect(server);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not connect to server.", e);
+        }
+
+        try {
+            if (!imap.login(username, password)) {
+                System.err.println("Could not login to server. Check password.");
+                imap.disconnect();
+                System.exit(3);
+            }
+
+            imap.setSoTimeout(6000);
+
+            final BufferedReader br = new BufferedReader(new FileReader(file)); // TODO charset?
+
+            String line;
+            StringBuilder sb = new StringBuilder();
+            while((line=br.readLine())!=null) {
+                if (line.startsWith("From ")) { // start of message; i.e. end of previous (if any)
+                    process(sb, imap, folder);
+                    sb.setLength(0);
+                } else if (line.startsWith(">From ")) { // Unescape "From " in body text
+                    line = line.substring(1);
+                }
+                // TODO process first Received: line to determine arrival date?
+                sb.append(line);
+                sb.append(CRLF);
+            }
+            br.close();
+            process(sb, imap, folder); // end of last message (if any)
+        } catch (IOException e) {
+            System.out.println(imap.getReplyString());
+            e.printStackTrace();
+            System.exit(10);
+            return;
+        } finally {
+            imap.logout();
+            imap.disconnect();
+        }
+    }
+
+    private static void process(final StringBuilder sb, final IMAPClient imap, final String folder) throws IOException {
+        final int length = sb.length();
+        if (length > 2) {
+            System.out.println("Length " + length);
+            sb.setLength(length-2); // drop trailing CRLF
+            String msg = sb.toString();
+            if (!imap.append(folder, null, null, msg)) {
+                throw new IOException("Failed to import message: " + imap.getReplyString());
+            }
+        }
+    }
+}

Propchange: commons/proper/net/trunk/src/main/java/examples/mail/IMAPImportMbox.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/net/trunk/src/main/java/examples/mail/IMAPImportMbox.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPClient.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPClient.java?rev=1508693&r1=1508692&r2=1508693&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPClient.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPClient.java Wed Jul 31 00:42:18 2013
@@ -26,6 +26,9 @@ import java.io.IOException;
 public class IMAPClient extends IMAP
 {
 
+    private static final char DQUOTE = '"';
+    private static final String DQUOTE_S = "\"";
+
     // --------- commands available in all states
 
     /**
@@ -237,9 +240,46 @@ public class IMAPClient extends IMAP
      * @param mailboxName The mailbox name.
      * @param flags The flag parenthesized list (optional).
      * @param datetime The date/time string (optional).
+     * @param message The message to append.
+     * @return {@code true} if the command was successful,{@code false} if not.
+     * @exception IOException If a network I/O error occurs.
+     */
+    public boolean append(String mailboxName, String flags, String datetime, String message) throws IOException
+    {
+        StringBuilder args = new StringBuilder(mailboxName);
+        if (flags != null) {
+            args.append(" ").append(flags);
+        }
+        if (datetime != null) {
+            args.append(" ");
+            if (datetime.charAt(0) == DQUOTE) {
+                args.append(datetime);
+            } else {
+                args.append(DQUOTE).append(datetime).append(DQUOTE);
+            }
+        }
+        args.append(" ");
+        // String literal (probably not used much - it at all)
+        if (message.startsWith(DQUOTE_S) && message.endsWith(DQUOTE_S)) {
+            args.append(message);
+            return doCommand (IMAPCommand.APPEND, args.toString());
+        }
+        args.append('{').append(message.length()).append('}'); // length of message
+        final int status = sendCommand(IMAPCommand.APPEND, args.toString());
+        return IMAPReply.isContinuation(status) // expecting continuation response
+            && IMAPReply.isSuccess(sendData(message)); // if so, send the data
+    }
+
+    /**
+     * Send an APPEND command to the server.
+     * @param mailboxName The mailbox name.
+     * @param flags The flag parenthesized list (optional).
+     * @param datetime The date/time string (optional).
      * @return {@code true} if the command was successful,{@code false} if not.
      * @exception IOException If a network I/O error occurs.
+     * @deprecated (3.4) Does not work; the message body is not optional. Use {@link #append(String, String, String, String)} instead.
      */
+    @Deprecated
     public boolean append(String mailboxName, String flags, String datetime) throws IOException
     {
         String args = mailboxName;
@@ -261,7 +301,9 @@ public class IMAPClient extends IMAP
      * @param mailboxName The mailbox name.
      * @return {@code true} if the command was successful,{@code false} if not.
      * @exception IOException If a network I/O error occurs.
+     * @deprecated (3.4) Does not work; the message body is not optional. Use {@link #append(String, String, String, String)} instead.
      */
+    @Deprecated
     public boolean append(String mailboxName) throws IOException
     {
         return append(mailboxName, null, null);