PROTOCOLS-115 A new FrameHandler should be user for each pipeline

Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/d4f18a98
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/d4f18a98
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/d4f18a98

Branch: refs/heads/master
Commit: d4f18a98d27db2a1e3410c85f5183d3457c79867
Parents: 6595c21
Author: Raphael Ouazana <[email protected]>
Authored: Tue Jan 31 09:47:54 2017 +0100
Committer: Raphael Ouazana <[email protected]>
Committed: Thu Feb 2 15:23:43 2017 +0100

----------------------------------------------------------------------
 .../protocols/lmtp/AbstractLMTPServerTest.java  |  15 ++-
 .../netty/AbstractChannelPipelineFactory.java   |  15 +--
 .../AbstractSSLAwareChannelPipelineFactory.java |   9 +-
 .../protocols/netty/ChannelHandlerFactory.java  |  26 ++++
 ...LineDelimiterBasedChannelHandlerFactory.java |  37 ++++++
 .../james/protocols/netty/NettyServer.java      |  25 ++--
 .../james/protocols/netty/NettyServerTest.java  |   5 +-
 protocols/smtp/pom.xml                          |   1 -
 ...rtTlsLineDelimiterChannelHandlerFactory.java |  37 ++++++
 .../protocols/smtp/AbstractSMTPServerTest.java  | 124 +++++++++++++++----
 .../smtp/netty/NettyStartTlsSMTPServerTest.java |   5 +-
 protocols/smtp/src/test/resources/a50.eml       |  50 ++++++++
 .../james/imapserver/netty/IMAPServer.java      |   9 +-
 ...leLineDelimiterBasedFrameDecoderFactory.java |  37 ++++++
 .../netty/AbstractConfigurableAsyncServer.java  |  14 +--
 ...ractExecutorAwareChannelPipelineFactory.java |  10 +-
 .../james/lmtpserver/netty/LMTPServer.java      |   9 +-
 .../netty/ManageSieveServer.java                |  11 +-
 .../james/pop3server/netty/POP3Server.java      |   9 +-
 .../james/smtpserver/netty/SMTPServer.java      |   9 +-
 20 files changed, 357 insertions(+), 100 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/AbstractLMTPServerTest.java
----------------------------------------------------------------------
diff --git 
a/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/AbstractLMTPServerTest.java
 
b/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/AbstractLMTPServerTest.java
index 3b4d1dd..333a961 100644
--- 
a/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/AbstractLMTPServerTest.java
+++ 
b/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/AbstractLMTPServerTest.java
@@ -50,6 +50,7 @@ import org.apache.james.protocols.smtp.hook.HookResult;
 import org.apache.james.protocols.smtp.hook.HookReturnCode;
 import org.apache.james.protocols.smtp.hook.MessageHook;
 import org.apache.james.protocols.smtp.utils.TestMessageHook;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public abstract class AbstractLMTPServerTest extends AbstractSMTPServerTest{
@@ -70,23 +71,27 @@ public abstract class AbstractLMTPServerTest extends 
AbstractSMTPServerTest{
         return new SMTPProtocol(chain, new LMTPConfigurationImpl(), new 
MockLogger());
     }
     
-    
+
+    @Ignore("LMTP can't handle the queue")
+    @Override
+    public void testDeliveryWith4SimultaneousThreads() {
+    }
+
+    @Ignore("Disable")
     @Override
     public void testInvalidNoBracketsEnformance() throws Exception {
-        // Disable
     }
 
 
+    @Ignore("Disable")
     @Override
     public void testHeloEnforcement() throws Exception {
-        // Disable
     }
 
 
+    @Ignore("Disable")
     @Override
     public void testHeloEnforcementDisabled() throws Exception {
-        // Disable
-
     }
 
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java
----------------------------------------------------------------------
diff --git 
a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java
 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java
index 39a5b5f..04a91ac 100644
--- 
a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java
+++ 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractChannelPipelineFactory.java
@@ -20,13 +20,10 @@ package org.apache.james.protocols.netty;
 
 import static org.jboss.netty.channel.Channels.pipeline;
 
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
 import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
-import org.jboss.netty.handler.codec.frame.Delimiters;
 import org.jboss.netty.handler.execution.ExecutionHandler;
 import org.jboss.netty.handler.stream.ChunkedWriteHandler;
 import org.jboss.netty.util.ExternalResourceReleasable;
@@ -38,27 +35,27 @@ import org.jboss.netty.util.HashedWheelTimer;
  *
  */
 public abstract class AbstractChannelPipelineFactory implements 
ChannelPipelineFactory, ExternalResourceReleasable{
-
     public final static int MAX_LINE_LENGTH = 8192;
+
     protected final ConnectionLimitUpstreamHandler connectionLimitHandler;
     protected final ConnectionPerIpLimitUpstreamHandler 
connectionPerIpLimitHandler;
     private final HashedWheelTimer timer = new HashedWheelTimer();
     private final ChannelGroupHandler groupHandler;
        private final int timeout;
     private final ExecutionHandler eHandler;
-    private final ChannelHandler frameHandler;
+    private final ChannelHandlerFactory frameHandlerFactory;
     public AbstractChannelPipelineFactory(int timeout, int maxConnections, int 
maxConnectsPerIp, ChannelGroup channels) {
-        this(timeout, maxConnections, maxConnectsPerIp, channels, null, new 
DelimiterBasedFrameDecoder(MAX_LINE_LENGTH, false, Delimiters.lineDelimiter()));
+        this(timeout, maxConnections, maxConnectsPerIp, channels, null, new 
LineDelimiterBasedChannelHandlerFactory(MAX_LINE_LENGTH));
     }
     
     public AbstractChannelPipelineFactory(int timeout, int maxConnections, int 
maxConnectsPerIp, ChannelGroup channels, ExecutionHandler eHandler,
-            ChannelHandler frameHandler) {
+            ChannelHandlerFactory frameHandlerFactory) {
         this.connectionLimitHandler = new 
ConnectionLimitUpstreamHandler(maxConnections);
         this.connectionPerIpLimitHandler = new 
ConnectionPerIpLimitUpstreamHandler(maxConnectsPerIp);
         this.groupHandler = new ChannelGroupHandler(channels);
         this.timeout = timeout;
         this.eHandler = eHandler;
-        this.frameHandler = frameHandler;
+        this.frameHandlerFactory = frameHandlerFactory;
     }
     
     
@@ -76,7 +73,7 @@ public abstract class AbstractChannelPipelineFactory 
implements ChannelPipelineF
 
         
         // Add the text line decoder which limit the max line length, don't 
strip the delimiter and use CRLF as delimiter
-        pipeline.addLast(HandlerConstants.FRAMER, frameHandler);
+        pipeline.addLast(HandlerConstants.FRAMER, 
frameHandlerFactory.create());
        
         // Add the ChunkedWriteHandler to be able to write ChunkInput
         pipeline.addLast(HandlerConstants.CHUNK_HANDLER, new 
ChunkedWriteHandler());

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java
----------------------------------------------------------------------
diff --git 
a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java
 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java
index e78695c..e40f0a1 100644
--- 
a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java
+++ 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java
@@ -21,7 +21,6 @@ package org.apache.james.protocols.netty;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.group.ChannelGroup;
 import org.jboss.netty.handler.execution.ExecutionHandler;
@@ -39,14 +38,14 @@ public abstract class 
AbstractSSLAwareChannelPipelineFactory extends AbstractCha
 
     public AbstractSSLAwareChannelPipelineFactory(int timeout,
             int maxConnections, int maxConnectsPerIp, ChannelGroup group, 
ExecutionHandler eHandler,
-            ChannelHandler frameHandler) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, eHandler, 
frameHandler);
+            ChannelHandlerFactory frameHandlerFactory) {
+        super(timeout, maxConnections, maxConnectsPerIp, group, eHandler, 
frameHandlerFactory);
     }
 
     public AbstractSSLAwareChannelPipelineFactory(int timeout,
             int maxConnections, int maxConnectsPerIp, ChannelGroup group, 
String[] enabledCipherSuites, ExecutionHandler eHandler,
-            ChannelHandler frameHandler) {
-        this(timeout, maxConnections, maxConnectsPerIp, group, eHandler, 
frameHandler);
+            ChannelHandlerFactory frameHandlerFactory) {
+        this(timeout, maxConnections, maxConnectsPerIp, group, eHandler, 
frameHandlerFactory);
         
         // We need to copy the String array becuase of possible security 
issues.
         // See https://issues.apache.org/jira/browse/PROTOCOLS-18

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelHandlerFactory.java
----------------------------------------------------------------------
diff --git 
a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelHandlerFactory.java
 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelHandlerFactory.java
new file mode 100644
index 0000000..eba8210
--- /dev/null
+++ 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ChannelHandlerFactory.java
@@ -0,0 +1,26 @@
+/****************************************************************
+ * 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 org.apache.james.protocols.netty;
+
+import org.jboss.netty.channel.ChannelHandler;
+
+public interface ChannelHandlerFactory {
+    ChannelHandler create();
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineDelimiterBasedChannelHandlerFactory.java
----------------------------------------------------------------------
diff --git 
a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineDelimiterBasedChannelHandlerFactory.java
 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineDelimiterBasedChannelHandlerFactory.java
new file mode 100644
index 0000000..dcd9b7c
--- /dev/null
+++ 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineDelimiterBasedChannelHandlerFactory.java
@@ -0,0 +1,37 @@
+/****************************************************************
+ * 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 org.apache.james.protocols.netty;
+
+import org.jboss.netty.channel.ChannelHandler;
+import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
+import org.jboss.netty.handler.codec.frame.Delimiters;
+
+public class LineDelimiterBasedChannelHandlerFactory implements 
ChannelHandlerFactory {
+    private final int maxLineLength;
+
+    public LineDelimiterBasedChannelHandlerFactory(int maxLineLength) {
+        this.maxLineLength = maxLineLength;
+    }
+
+    @Override
+    public ChannelHandler create() {
+        return new DelimiterBasedFrameDecoder(maxLineLength, false, 
Delimiters.lineDelimiter());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java
----------------------------------------------------------------------
diff --git 
a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java
 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java
index d2a9285..eb983f9 100644
--- 
a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java
+++ 
b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java
@@ -24,12 +24,9 @@ import javax.net.ssl.SSLContext;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.Protocol;
 import org.apache.james.protocols.api.handler.ProtocolHandler;
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
 import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
-import org.jboss.netty.handler.codec.frame.Delimiters;
 import org.jboss.netty.handler.execution.ExecutionHandler;
 import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
 
@@ -49,11 +46,11 @@ public class NettyServer extends AbstractAsyncServer {
     public static class Builder {
         private Protocol protocol;
         private Optional<Encryption> secure;
-        private Optional<ChannelHandler> frameHandler;
+        private Optional<ChannelHandlerFactory> frameHandlerFactory;
 
         private Builder() {
             secure = Optional.absent();
-            frameHandler = Optional.absent();
+            frameHandlerFactory = Optional.absent();
         }
 
         public Builder protocol(Protocol protocol) {
@@ -67,8 +64,8 @@ public class NettyServer extends AbstractAsyncServer {
             return this;
         }
 
-        public Builder frameHandler(ChannelHandler frameHandler) {
-            this.frameHandler = Optional.fromNullable(frameHandler);
+        public Builder frameHandlerFactory(ChannelHandlerFactory 
frameHandlerFactory) {
+            this.frameHandlerFactory = 
Optional.fromNullable(frameHandlerFactory);
             return this;
         }
 
@@ -76,13 +73,13 @@ public class NettyServer extends AbstractAsyncServer {
             Preconditions.checkState(protocol != null, "'protocol' is 
mandatory");
             return new NettyServer(protocol, 
                     secure.orNull(),
-                    frameHandler.or(new 
DelimiterBasedFrameDecoder(AbstractChannelPipelineFactory.MAX_LINE_LENGTH, 
false, Delimiters.lineDelimiter())));
+                    frameHandlerFactory.or(new 
LineDelimiterBasedChannelHandlerFactory(AbstractChannelPipelineFactory.MAX_LINE_LENGTH)));
         }
     }
 
     protected final Protocol protocol;
     protected final Encryption secure;
-    private final ChannelHandler frameHandler;
+    private final ChannelHandlerFactory frameHandlerFactory;
     
     private ExecutionHandler eHandler;
     
@@ -92,10 +89,10 @@ public class NettyServer extends AbstractAsyncServer {
 
     private int maxCurConnectionsPerIP;
    
-    private NettyServer(Protocol protocol, Encryption secure, ChannelHandler 
frameHandler) {
+    private NettyServer(Protocol protocol, Encryption secure, 
ChannelHandlerFactory frameHandlerFactory) {
         this.protocol = protocol;
         this.secure = secure;
-        this.frameHandler = frameHandler;
+        this.frameHandlerFactory = frameHandlerFactory;
     }
     
     protected ExecutionHandler createExecutionHandler(int size) {
@@ -141,14 +138,14 @@ public class NettyServer extends AbstractAsyncServer {
         super.bind();
     }
 
-    private ChannelHandler getFrameHandler() {
-        return frameHandler;
+    private ChannelHandlerFactory getFrameHandlerFactory() {
+        return frameHandlerFactory;
     }
 
     @Override
     protected ChannelPipelineFactory createPipelineFactory(ChannelGroup group) 
{
 
-        return new AbstractSSLAwareChannelPipelineFactory(getTimeout(), 
maxCurConnections, maxCurConnectionsPerIP, group, eHandler, getFrameHandler()) {
+        return new AbstractSSLAwareChannelPipelineFactory(getTimeout(), 
maxCurConnections, maxCurConnectionsPerIP, group, eHandler, 
getFrameHandlerFactory()) {
 
             @Override
             protected ChannelUpstreamHandler createHandler() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java
----------------------------------------------------------------------
diff --git 
a/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java
 
b/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java
index 1d327db..facb52f 100644
--- 
a/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java
+++ 
b/protocols/netty/src/test/java/org/apache/james/protocols/netty/NettyServerTest.java
@@ -25,7 +25,6 @@ import javax.net.ssl.SSLContext;
 
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.Protocol;
-import org.jboss.netty.channel.ChannelHandler;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -61,11 +60,11 @@ public class NettyServerTest {
     public void buildShouldWorkWhenEverythingIsGiven() throws Exception {
         Protocol protocol = mock(Protocol.class);
         Encryption encryption = 
Encryption.createStartTls(SSLContext.getDefault());
-        ChannelHandler channelHandler = mock(ChannelHandler.class);
+        ChannelHandlerFactory channelHandlerFactory = 
mock(ChannelHandlerFactory.class);
         NettyServer.builder()
             .protocol(protocol)
             .secure(encryption)
-            .frameHandler(channelHandler)
+            .frameHandlerFactory(channelHandlerFactory)
             .build();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/smtp/pom.xml
----------------------------------------------------------------------
diff --git a/protocols/smtp/pom.xml b/protocols/smtp/pom.xml
index a9f913f..b96cc1d 100644
--- a/protocols/smtp/pom.xml
+++ b/protocols/smtp/pom.xml
@@ -47,7 +47,6 @@
         <dependency>
             <groupId>org.apache.james.protocols</groupId>
             <artifactId>protocols-netty</artifactId>
-            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/AllButStartTlsLineDelimiterChannelHandlerFactory.java
----------------------------------------------------------------------
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/AllButStartTlsLineDelimiterChannelHandlerFactory.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/AllButStartTlsLineDelimiterChannelHandlerFactory.java
new file mode 100644
index 0000000..de33ac6
--- /dev/null
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/AllButStartTlsLineDelimiterChannelHandlerFactory.java
@@ -0,0 +1,37 @@
+/****************************************************************
+ * 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 org.apache.james.protocols.smtp;
+
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
+import org.jboss.netty.channel.ChannelHandler;
+import org.jboss.netty.handler.codec.frame.Delimiters;
+
+public class AllButStartTlsLineDelimiterChannelHandlerFactory implements 
ChannelHandlerFactory {
+
+    private int maxFrameLength;
+
+    public AllButStartTlsLineDelimiterChannelHandlerFactory(int 
maxFrameLength) {
+        this.maxFrameLength = maxFrameLength;
+    }
+
+    @Override
+    public ChannelHandler create() {
+        return new AllButStartTlsDelimiterChannelHandler(maxFrameLength, 
false, Delimiters.lineDelimiter());
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/AbstractSMTPServerTest.java
----------------------------------------------------------------------
diff --git 
a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/AbstractSMTPServerTest.java
 
b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/AbstractSMTPServerTest.java
index 801cf3b..d5027e8 100644
--- 
a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/AbstractSMTPServerTest.java
+++ 
b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/AbstractSMTPServerTest.java
@@ -26,6 +26,7 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.InetSocketAddress;
+import java.net.SocketException;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
@@ -53,9 +54,12 @@ import org.apache.james.protocols.smtp.hook.RcptHook;
 import org.apache.james.protocols.smtp.utils.TestMessageHook;
 import org.junit.Test;
 
+import com.google.common.base.Charsets;
+import com.google.common.io.CharStreams;
+
 public abstract class AbstractSMTPServerTest {
     
-    protected final static String MSG1 = "Subject: Testmessage\r\n\r\nThis is 
a message";
+    protected final static String MSG1 = "Subject: Testmessage\r\n\r\nThis is 
a message\r\n";
     protected final static String SENDER = "me@sender";
     protected final static String RCPT1 ="rpct1@domain";
     protected final static String RCPT2 ="rpct2@domain";
@@ -69,35 +73,62 @@ public abstract class AbstractSMTPServerTest {
             server = createServer(createProtocol(hook));
             server.bind();
             
-            SMTPClient client = createClient();
             InetSocketAddress bindedAddress = new 
ProtocolServerUtils(server).retrieveBindedAddress();
-            client.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
-            assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode()));
-            
-            client.helo("localhost");
-            assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode()));
 
-            client.setSender(SENDER);
-            assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
+            send(server, bindedAddress, MSG1);
 
-            client.addRecipient(RCPT1);
-            assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
+            Iterator<MailEnvelope> queued = hook.getQueued().iterator();
+            assertTrue(queued.hasNext());
+            
+            MailEnvelope env = queued.next();
+            checkEnvelope(env, SENDER, Arrays.asList(RCPT1, RCPT2), MSG1);
+            assertFalse(queued.hasNext());
 
-            client.addRecipient(RCPT2);
-            assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
+        } finally {
+            if (server != null) {
+                server.unbind();
+            }
+        }
+        
+    }
+    
+    @Test
+    public void testDeliveryWith4SimultaneousThreads() throws Exception {
+        TestMessageHook hook = new TestMessageHook();
+        ProtocolServer server = null;
+        try {
+            server = createServer(createProtocol(hook));
+            server.bind();
+            InetSocketAddress bindedAddress = new 
ProtocolServerUtils(server).retrieveBindedAddress();
 
-            assertTrue(client.sendShortMessageData(MSG1));
-            assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
-            
-            client.quit();
-            assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
-            client.disconnect();
+            String mailContent = CharStreams.toString(new 
InputStreamReader(ClassLoader.getSystemResourceAsStream("a50.eml"), 
Charsets.US_ASCII));
+            Thread thread1 = new SendThread(server, bindedAddress, 
mailContent);
+            Thread thread2 = new SendThread(server, bindedAddress, 
mailContent);
+            Thread thread3 = new SendThread(server, bindedAddress, 
mailContent);
+            Thread thread4 = new SendThread(server, bindedAddress, 
mailContent);
+            thread1.start();
+            thread2.start();
+            thread3.start();
+            thread4.start();
+            thread1.join(1000);
+            thread2.join(1000);
+            thread3.join(1000);
+            thread4.join(1000);
 
             Iterator<MailEnvelope> queued = hook.getQueued().iterator();
             assertTrue(queued.hasNext());
-            
+
             MailEnvelope env = queued.next();
-            checkEnvelope(env, SENDER, Arrays.asList(RCPT1, RCPT2), MSG1);
+            checkEnvelope(env, SENDER, Arrays.asList(RCPT1, RCPT2), 
mailContent);
+            assertTrue(queued.hasNext());
+            MailEnvelope env2 = queued.next();
+            checkEnvelope(env2, SENDER, Arrays.asList(RCPT1, RCPT2), 
mailContent);
+            assertTrue(queued.hasNext());
+            MailEnvelope env3 = queued.next();
+            checkEnvelope(env3, SENDER, Arrays.asList(RCPT1, RCPT2), 
mailContent);
+            assertTrue(queued.hasNext());
+            MailEnvelope env4 = queued.next();
+            checkEnvelope(env4, SENDER, Arrays.asList(RCPT1, RCPT2), 
mailContent);
             assertFalse(queued.hasNext());
 
         } finally {
@@ -105,7 +136,56 @@ public abstract class AbstractSMTPServerTest {
                 server.unbind();
             }
         }
+    }
+    
+    public class SendThread extends Thread {
+        private ProtocolServer server;
+        private InetSocketAddress bindedAddress;
+        private String msg;
+
+        public SendThread(ProtocolServer server, InetSocketAddress 
bindedAddress, String msg) {
+            this.server = server;
+            this.bindedAddress = bindedAddress;
+            this.msg = msg;
+        }
+        
+        @Override
+        public void run() {
+            try {
+                send(server, bindedAddress, msg);
+            } catch (SocketException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void send(ProtocolServer server, InetSocketAddress bindedAddress, 
String msg) throws SocketException, IOException {
+        SMTPClient client = createClient();
+        client.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
+        assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode()));
+        
+        client.helo("localhost");
+        assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode()));
+
+        client.setSender(SENDER);
+        assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
+
+        client.addRecipient(RCPT1);
+        assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
+
+        client.addRecipient(RCPT2);
+        assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
+
+        assertTrue(client.sendShortMessageData(msg));
+        assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
         
+        client.quit();
+        assertTrue("Reply="+ client.getReplyString(), 
SMTPReply.isPositiveCompletion(client.getReplyCode()));
+        client.disconnect();
     }
     
     @Test
@@ -1081,7 +1161,7 @@ public abstract class AbstractSMTPServerTest {
                     sb.append("\r\n");
                 }
             }
-            String msgQueued = sb.subSequence(0, sb.length() - 2).toString();
+            String msgQueued = sb.subSequence(0, sb.length()).toString();
 
             assertEquals(msg.length(), msgQueued.length());
             for (int i = 0; i < msg.length(); i++) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java
----------------------------------------------------------------------
diff --git 
a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java
 
b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java
index e0ae441..3c4edd7 100644
--- 
a/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java
+++ 
b/protocols/smtp/src/test/java/org/apache/james/protocols/smtp/netty/NettyStartTlsSMTPServerTest.java
@@ -44,13 +44,12 @@ import org.apache.james.protocols.api.utils.MockLogger;
 import org.apache.james.protocols.api.utils.ProtocolServerUtils;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.NettyServer;
-import org.apache.james.protocols.smtp.AllButStartTlsDelimiterChannelHandler;
+import 
org.apache.james.protocols.smtp.AllButStartTlsLineDelimiterChannelHandlerFactory;
 import org.apache.james.protocols.smtp.SMTPConfigurationImpl;
 import org.apache.james.protocols.smtp.SMTPProtocol;
 import org.apache.james.protocols.smtp.SMTPProtocolHandlerChain;
 import org.apache.james.protocols.smtp.utils.TestMessageHook;
 import org.assertj.core.api.AssertDelegateTarget;
-import org.jboss.netty.handler.codec.frame.Delimiters;
 import org.junit.After;
 import org.junit.Test;
 
@@ -75,7 +74,7 @@ public class NettyStartTlsSMTPServerTest {
         NettyServer server = NettyServer.builder()
                 .protocol(protocol)
                 .secure(enc)
-                .frameHandler(new 
AllButStartTlsDelimiterChannelHandler(AbstractChannelPipelineFactory.MAX_LINE_LENGTH,
 false, Delimiters.lineDelimiter()))
+                .frameHandlerFactory(new 
AllButStartTlsLineDelimiterChannelHandlerFactory(AbstractChannelPipelineFactory.MAX_LINE_LENGTH))
                 .build();
         server.setListenAddresses(new InetSocketAddress(LOCALHOST_IP, 
RANDOM_PORT));
         return server;

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/protocols/smtp/src/test/resources/a50.eml
----------------------------------------------------------------------
diff --git a/protocols/smtp/src/test/resources/a50.eml 
b/protocols/smtp/src/test/resources/a50.eml
new file mode 100644
index 0000000..2dc5903
--- /dev/null
+++ b/protocols/smtp/src/test/resources/a50.eml
@@ -0,0 +1,50 @@
+Subject: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Message-ID: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+X-Sender: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+User-Agent: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
index 371c50a..cc9c300 100644
--- 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
+++ 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
@@ -33,14 +33,13 @@ import org.apache.james.imap.encode.ImapEncoder;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.netty.ChannelGroupHandler;
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler;
 import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler;
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
 import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.codec.frame.Delimiters;
 import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
 import org.jboss.netty.handler.execution.ExecutionHandler;
 import org.jboss.netty.handler.ssl.SslHandler;
@@ -140,7 +139,7 @@ public class IMAPServer extends 
AbstractConfigurableAsyncServer implements ImapC
                 // Add the text line decoder which limit the max line length,
                 // don't strip the delimiter and use CRLF as delimiter
                 // Use a SwitchableDelimiterBasedFrameDecoder, see JAMES-1436
-                pipeline.addLast(FRAMER, createFrameHandler());
+                pipeline.addLast(FRAMER, getFrameHandlerFactory().create());
                
                 Encryption secure = getEncryption();
                 if (secure != null && !secure.isStartTLS()) {
@@ -194,8 +193,8 @@ public class IMAPServer extends 
AbstractConfigurableAsyncServer implements ImapC
     }
 
     @Override
-    protected ChannelHandler createFrameHandler() {
-        return new SwitchableDelimiterBasedFrameDecoder(maxLineLength, false, 
Delimiters.lineDelimiter());
+    protected ChannelHandlerFactory createFrameHandlerFactory() {
+        return new 
SwitchableLineDelimiterBasedFrameDecoderFactory(maxLineLength);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineDelimiterBasedFrameDecoderFactory.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineDelimiterBasedFrameDecoderFactory.java
 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineDelimiterBasedFrameDecoderFactory.java
new file mode 100644
index 0000000..1335ae3
--- /dev/null
+++ 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableLineDelimiterBasedFrameDecoderFactory.java
@@ -0,0 +1,37 @@
+/****************************************************************
+ * 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 org.apache.james.imapserver.netty;
+
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
+import org.jboss.netty.channel.ChannelHandler;
+import org.jboss.netty.handler.codec.frame.Delimiters;
+
+public class SwitchableLineDelimiterBasedFrameDecoderFactory implements 
ChannelHandlerFactory {
+
+    private int maxLineLength;
+
+    public SwitchableLineDelimiterBasedFrameDecoderFactory(int maxLineLength) {
+        this.maxLineLength = maxLineLength;
+    }
+
+    @Override
+    public ChannelHandler create() {
+        return new SwitchableDelimiterBasedFrameDecoder(maxLineLength, false, 
Delimiters.lineDelimiter());
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java
 
b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java
index 3fbf7e5..211dd74 100644
--- 
a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java
+++ 
b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java
@@ -45,9 +45,9 @@ import org.apache.james.lifecycle.api.LogEnabled;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.lib.jmx.ServerMBean;
 import org.apache.james.protocols.netty.AbstractAsyncServer;
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.util.concurrent.JMXEnabledThreadPoolExecutor;
 import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
 import org.jboss.netty.channel.group.ChannelGroup;
@@ -111,7 +111,7 @@ public abstract class AbstractConfigurableAsyncServer 
extends AbstractAsyncServe
     private final ConnectionCountHandler countHandler = new 
ConnectionCountHandler();
 
     private ExecutionHandler executionHandler = null;
-    private ChannelHandler frameHandler;
+    private ChannelHandlerFactory frameHandlerFactory;
 
     private int maxExecutorThreads;
 
@@ -271,7 +271,7 @@ public abstract class AbstractConfigurableAsyncServer 
extends AbstractAsyncServe
             buildSSLContext();
             preInit();
             executionHandler = createExecutionHander();
-            frameHandler = createFrameHandler();
+            frameHandlerFactory = createFrameHandlerFactory();
             bind();
 
             mbeanServer = ManagementFactory.getPlatformMBeanServer();
@@ -568,7 +568,7 @@ public abstract class AbstractConfigurableAsyncServer 
extends AbstractAsyncServe
         return new ExecutionHandler(new 
JMXEnabledOrderedMemoryAwareThreadPoolExecutor(maxExecutorThreads, 0, 0, 
getThreadPoolJMXPath(), getDefaultJMXName() + "-executor"));
     }
 
-    protected abstract ChannelHandler createFrameHandler();
+    protected abstract ChannelHandlerFactory createFrameHandlerFactory();
 
     /**
      * Return the {@link ExecutionHandler} or null if non should be used. Be 
sure you call {@link #createExecutionHander()} before
@@ -579,15 +579,15 @@ public abstract class AbstractConfigurableAsyncServer 
extends AbstractAsyncServe
         return executionHandler;
     }
     
-    protected ChannelHandler getFrameHandler() {
-        return frameHandler;
+    protected ChannelHandlerFactory getFrameHandlerFactory() {
+        return frameHandlerFactory;
     }
 
     protected abstract ChannelUpstreamHandler createCoreHandler();
     
     @Override
     protected ChannelPipelineFactory createPipelineFactory(ChannelGroup group) 
{
-        return new AbstractExecutorAwareChannelPipelineFactory(getTimeout(), 
connectionLimit, connPerIP, group, enabledCipherSuites, getExecutionHandler(), 
getFrameHandler()) {
+        return new AbstractExecutorAwareChannelPipelineFactory(getTimeout(), 
connectionLimit, connPerIP, group, enabledCipherSuites, getExecutionHandler(), 
getFrameHandlerFactory()) {
             @Override
             protected SSLContext getSSLContext() {
                 if (encryption == null) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java
 
b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java
index 6b71a51..da06bda 100644
--- 
a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java
+++ 
b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractExecutorAwareChannelPipelineFactory.java
@@ -19,8 +19,8 @@
 package org.apache.james.protocols.lib.netty;
 
 import org.apache.james.protocols.netty.AbstractSSLAwareChannelPipelineFactory;
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.HandlerConstants;
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.group.ChannelGroup;
 import org.jboss.netty.handler.execution.ExecutionHandler;
@@ -32,12 +32,12 @@ import org.jboss.netty.handler.execution.ExecutionHandler;
  */
 public abstract class AbstractExecutorAwareChannelPipelineFactory extends 
AbstractSSLAwareChannelPipelineFactory{
 
-    public AbstractExecutorAwareChannelPipelineFactory(int timeout, int 
maxConnections, int maxConnectsPerIp, ChannelGroup group, ExecutionHandler 
eHandler, ChannelHandler frameHandler) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, eHandler, 
frameHandler);
+    public AbstractExecutorAwareChannelPipelineFactory(int timeout, int 
maxConnections, int maxConnectsPerIp, ChannelGroup group, ExecutionHandler 
eHandler, ChannelHandlerFactory frameHandlerFactory) {
+        super(timeout, maxConnections, maxConnectsPerIp, group, eHandler, 
frameHandlerFactory);
     }
 
-    public AbstractExecutorAwareChannelPipelineFactory(int timeout, int 
maxConnections, int maxConnectsPerIp, ChannelGroup group, String[] 
enabledCipherSuites, ExecutionHandler eHandler, ChannelHandler frameHandler) {
-        super(timeout, maxConnections, maxConnectsPerIp, group, 
enabledCipherSuites, eHandler, frameHandler);
+    public AbstractExecutorAwareChannelPipelineFactory(int timeout, int 
maxConnections, int maxConnectsPerIp, ChannelGroup group, String[] 
enabledCipherSuites, ExecutionHandler eHandler, ChannelHandlerFactory 
frameHandlerFactory) {
+        super(timeout, maxConnections, maxConnectsPerIp, group, 
enabledCipherSuites, eHandler, frameHandlerFactory);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
 
b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
index f6c4fee..422e8ef 100644
--- 
a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
+++ 
b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
@@ -28,12 +28,11 @@ import 
org.apache.james.protocols.lib.handler.HandlersPackage;
 import org.apache.james.protocols.lib.netty.AbstractProtocolAsyncServer;
 import org.apache.james.protocols.lmtp.LMTPConfiguration;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
+import 
org.apache.james.protocols.netty.LineDelimiterBasedChannelHandlerFactory;
 import org.apache.james.protocols.smtp.SMTPProtocol;
 import org.apache.james.smtpserver.netty.SMTPChannelUpstreamHandler;
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
-import org.jboss.netty.handler.codec.frame.Delimiters;
 
 public class LMTPServer extends AbstractProtocolAsyncServer implements 
LMTPServerMBean {
 
@@ -160,8 +159,8 @@ public class LMTPServer extends AbstractProtocolAsyncServer 
implements LMTPServe
     }
 
     @Override
-    protected ChannelHandler createFrameHandler() {
-        return new 
DelimiterBasedFrameDecoder(AbstractChannelPipelineFactory.MAX_LINE_LENGTH, 
false, Delimiters.lineDelimiter());
+    protected ChannelHandlerFactory createFrameHandlerFactory() {
+        return new 
LineDelimiterBasedChannelHandlerFactory(AbstractChannelPipelineFactory.MAX_LINE_LENGTH);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
 
b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
index 82c8ed3..827fa40 100644
--- 
a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
+++ 
b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
@@ -27,15 +27,14 @@ import 
org.apache.james.managesieve.transcode.ManageSieveProcessor;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.netty.ChannelGroupHandler;
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
 import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler;
 import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler;
-import org.jboss.netty.channel.ChannelHandler;
+import 
org.apache.james.protocols.netty.LineDelimiterBasedChannelHandlerFactory;
 import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
 import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
-import org.jboss.netty.handler.codec.frame.Delimiters;
 import org.jboss.netty.handler.codec.string.StringDecoder;
 import org.jboss.netty.handler.codec.string.StringEncoder;
 import org.jboss.netty.handler.execution.ExecutionHandler;
@@ -115,7 +114,7 @@ public class ManageSieveServer extends 
AbstractConfigurableAsyncServer implement
                 // Add the text line decoder which limit the max line length,
                 // don't strip the delimiter and use CRLF as delimiter
                 // Use a SwitchableDelimiterBasedFrameDecoder, see JAMES-1436
-                pipeline.addLast(FRAMER, createFrameHandler());
+                pipeline.addLast(FRAMER, getFrameHandlerFactory().create());
                 pipeline.addLast(CONNECTION_COUNT_HANDLER, 
getConnectionCountHandler());
                 pipeline.addLast(CHUNK_WRITE_HANDLER, new 
ChunkedWriteHandler());
 
@@ -139,7 +138,7 @@ public class ManageSieveServer extends 
AbstractConfigurableAsyncServer implement
     }
 
     @Override
-    protected ChannelHandler createFrameHandler() {
-        return new DelimiterBasedFrameDecoder(maxLineLength, false, 
Delimiters.lineDelimiter());
+    protected ChannelHandlerFactory createFrameHandlerFactory() {
+        return new LineDelimiterBasedChannelHandlerFactory(maxLineLength);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java
 
b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java
index 5b14d46..5a4acb5 100644
--- 
a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java
+++ 
b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/netty/POP3Server.java
@@ -26,11 +26,10 @@ import 
org.apache.james.protocols.lib.handler.HandlersPackage;
 import org.apache.james.protocols.lib.netty.AbstractProtocolAsyncServer;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.BasicChannelUpstreamHandler;
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
+import 
org.apache.james.protocols.netty.LineDelimiterBasedChannelHandlerFactory;
 import org.apache.james.protocols.pop3.POP3Protocol;
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
-import org.jboss.netty.handler.codec.frame.Delimiters;
 
 /**
  * NIO POP3 Server which use Netty
@@ -105,8 +104,8 @@ public class POP3Server extends AbstractProtocolAsyncServer 
implements POP3Serve
     }
 
     @Override
-    protected ChannelHandler createFrameHandler() {
-        return new 
DelimiterBasedFrameDecoder(AbstractChannelPipelineFactory.MAX_LINE_LENGTH, 
false, Delimiters.lineDelimiter());
+    protected ChannelHandlerFactory createFrameHandlerFactory() {
+        return new 
LineDelimiterBasedChannelHandlerFactory(AbstractChannelPipelineFactory.MAX_LINE_LENGTH);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4f18a98/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
index cad8941..1de34d1 100644
--- 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
+++ 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
@@ -30,15 +30,14 @@ import 
org.apache.james.protocols.api.logger.ProtocolLoggerAdapter;
 import org.apache.james.protocols.lib.handler.HandlersPackage;
 import org.apache.james.protocols.lib.netty.AbstractProtocolAsyncServer;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
-import org.apache.james.protocols.smtp.AllButStartTlsDelimiterChannelHandler;
+import org.apache.james.protocols.netty.ChannelHandlerFactory;
+import 
org.apache.james.protocols.smtp.AllButStartTlsLineDelimiterChannelHandlerFactory;
 import org.apache.james.protocols.smtp.SMTPConfiguration;
 import org.apache.james.protocols.smtp.SMTPProtocol;
 import org.apache.james.smtpserver.CoreCmdHandlerLoader;
 import org.apache.james.smtpserver.ExtendedSMTPSession;
 import org.apache.james.smtpserver.jmx.JMXHandlersLoader;
-import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.frame.Delimiters;
 
 /**
  * NIO SMTPServer which use Netty
@@ -364,8 +363,8 @@ public class SMTPServer extends AbstractProtocolAsyncServer 
implements SMTPServe
     }
 
     @Override
-    protected ChannelHandler createFrameHandler() {
-        return new 
AllButStartTlsDelimiterChannelHandler(AbstractChannelPipelineFactory.MAX_LINE_LENGTH,
 false, Delimiters.lineDelimiter());
+    protected ChannelHandlerFactory createFrameHandlerFactory() {
+        return new 
AllButStartTlsLineDelimiterChannelHandlerFactory(AbstractChannelPipelineFactory.MAX_LINE_LENGTH);
     }
 
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to