JAMES-2050 IMAP Processor now can load configuration from XML file

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

Branch: refs/heads/master
Commit: af9ea35771afe27c46d6e9ae946e3ff44ef8f036
Parents: 1e6ef60
Author: quynhn <[email protected]>
Authored: Fri Jun 9 15:44:37 2017 +0700
Committer: quynhn <[email protected]>
Committed: Mon Jun 12 17:45:18 2017 +0700

----------------------------------------------------------------------
 .../james/imap/api/ImapConfiguration.java       | 169 +++++++++++++++++++
 .../james/imap/api/process/ImapProcessor.java   |   3 +
 .../imap/processor/CapabilityProcessor.java     |   8 +
 .../james/imap/processor/IdleProcessor.java     |  17 +-
 .../base/AbstractChainedProcessor.java          |   6 +
 .../processor/base/UnknownRequestProcessor.java |   5 +
 .../james/imap/api/ImapConfigurationTest.java   | 163 ++++++++++++++++++
 .../james/imapserver/netty/IMAPServer.java      |  41 ++++-
 8 files changed, 406 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/af9ea357/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
----------------------------------------------------------------------
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java 
b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
new file mode 100644
index 0000000..1552189
--- /dev/null
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
@@ -0,0 +1,169 @@
+/****************************************************************
+ * 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.imap.api;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.james.imap.processor.IdleProcessor;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+
+public class ImapConfiguration {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+        private static final Function<String, String> NORMALIZE_STRING = new 
Function<String, String>() {
+            @Override
+            public String apply(String disableCap) {
+                return StringUtils.normalizeSpace(disableCap);
+            }
+        };
+        private static final Predicate<String> NO_BLANK = new 
Predicate<String>() {
+            @Override
+            public boolean apply(String disableCap) {
+                return noBlankString(disableCap);
+            }
+        };
+
+        private static boolean noBlankString(String disableCap) {
+            return !StringUtils.isBlank(disableCap);
+        }
+
+        private Optional<Long> idleTimeInterval;
+        private Optional<TimeUnit> idleTimeIntervalUnit;
+        private Optional<Boolean> enableIdle;
+        private ImmutableSet<String> disabledCaps;
+
+        private Builder() {
+            this.idleTimeInterval = Optional.absent();
+            this.idleTimeIntervalUnit = Optional.absent();
+            this.enableIdle = Optional.absent();
+            this.disabledCaps = ImmutableSet.of();
+        }
+
+        public Builder idleTimeInterval(long idleTimeInterval) {
+            Preconditions.checkArgument(idleTimeInterval > 0, "The interval 
time should not be rezo or negative");
+            this.idleTimeInterval = Optional.of(idleTimeInterval);
+            return this;
+        }
+
+        public Builder idleTimeIntervalUnit(TimeUnit idleTimeIntervalUnit) {
+            this.idleTimeIntervalUnit = Optional.of(idleTimeIntervalUnit);
+            return this;
+        }
+
+        public Builder enableIdle(Boolean enableIdle) {
+            this.enableIdle = Optional.of(enableIdle);
+            return this;
+        }
+
+        public Builder disabledCaps(ImmutableSet<String> disabledCaps) {
+            this.disabledCaps = disabledCaps;
+            return this;
+        }
+
+        public Builder disabledCaps(String... disableCaps) {
+            this.disabledCaps = ImmutableSet.copyOf(disableCaps);
+            return this;
+        }
+
+        public Builder disabledCap(String disableCap) {
+            this.disabledCaps = ImmutableSet.of(disableCap);
+            return this;
+        }
+        public ImapConfiguration build() {
+            ImmutableSet<String> normalizeDisableCaps = 
FluentIterable.from(disabledCaps)
+                    .filter(NO_BLANK)
+                    .transform(NORMALIZE_STRING)
+                    .toSet();
+            return new ImapConfiguration(
+                    enableIdle.or(IdleProcessor.DEFAULT_ENABLE_IDLE),
+                    
idleTimeInterval.or(IdleProcessor.DEFAULT_HEARTBEAT_INTERVAL_IN_SECONDS),
+                    
idleTimeIntervalUnit.or(IdleProcessor.DEFAULT_HEARTBEAT_INTERVAL_UNIT),
+                    normalizeDisableCaps);
+        }
+    }
+
+    private final long idleTimeInterval;
+    private final TimeUnit idleTimeIntervalUnit;
+    private final ImmutableSet<String> disabledCaps;
+    private final boolean enableIdle;
+
+    private ImapConfiguration(boolean enableIdle, long idleTimeInterval, 
TimeUnit idleTimeIntervalUnit, ImmutableSet<String> disabledCaps) {
+        this.enableIdle = enableIdle;
+        this.idleTimeInterval = idleTimeInterval;
+        this.idleTimeIntervalUnit = idleTimeIntervalUnit;
+        this.disabledCaps = disabledCaps;
+    }
+
+    public long getIdleTimeInterval() {
+        return idleTimeInterval;
+    }
+
+    public TimeUnit getIdleTimeIntervalUnit() {
+        return idleTimeIntervalUnit;
+    }
+
+    public ImmutableSet<String> getDisabledCaps() {
+        return disabledCaps;
+    }
+
+    public boolean isEnableIdle() {
+        return enableIdle;
+    }
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (obj instanceof ImapConfiguration) {
+            ImapConfiguration that = (ImapConfiguration)obj;
+            return Objects.equal(that.isEnableIdle(), enableIdle)
+                && Objects.equal(that.getIdleTimeInterval(), idleTimeInterval)
+                && Objects.equal(that.getIdleTimeIntervalUnit(), 
idleTimeIntervalUnit)
+                && Objects.equal(that.getDisabledCaps(), disabledCaps);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hashCode(enableIdle, idleTimeInterval, 
idleTimeIntervalUnit, disabledCaps);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("enabledIdle", enableIdle)
+                .add("idleTimeInterval", idleTimeInterval)
+                .add("idleTimeIntervalUnit", idleTimeIntervalUnit)
+                .add("disabledCaps", disabledCaps)
+                .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/af9ea357/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapProcessor.java
----------------------------------------------------------------------
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapProcessor.java
index a77b58b..b3a6c26 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapProcessor.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.imap.api.process;
 
+import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.message.response.ImapResponseMessage;
 
@@ -44,6 +45,8 @@ public interface ImapProcessor {
      */
     void process(ImapMessage message, Responder responder, ImapSession 
session);
 
+    void configure(ImapConfiguration imapConfiguration);
+
     /**
      * Response message sink.
      */

http://git-wip-us.apache.org/repos/asf/james-project/blob/af9ea357/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
----------------------------------------------------------------------
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
index 35f5bd2..ac1c7c8 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.display.CharsetUtil;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
@@ -76,6 +77,13 @@ public class CapabilityProcessor extends 
AbstractMailboxProcessor<CapabilityRequ
         
     }
 
+    @Override
+    public void configure(ImapConfiguration imapConfiguration) {
+        super.configure(imapConfiguration);
+
+        disabledCaps.addAll(imapConfiguration.getDisabledCaps());
+    }
+
     /**
      * @see
      * 
org.apache.james.imap.processor.AbstractMailboxProcessor#doProcess(org.apache.james.imap.api.message.request.ImapRequest,

http://git-wip-us.apache.org/repos/asf/james-project/blob/af9ea357/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
----------------------------------------------------------------------
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
index d2770df..670ef91 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
@@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapSessionState;
 import org.apache.james.imap.api.ImapSessionUtils;
 import org.apache.james.imap.api.display.HumanReadableText;
@@ -53,10 +54,12 @@ public class IdleProcessor extends 
AbstractMailboxProcessor<IdleRequest> impleme
     // 2 minutes
     public final static long DEFAULT_HEARTBEAT_INTERVAL_IN_SECONDS = 2 * 60;
     public final static TimeUnit DEFAULT_HEARTBEAT_INTERVAL_UNIT = 
TimeUnit.SECONDS;
+    public final static boolean DEFAULT_ENABLE_IDLE = true;
     public final static int DEFAULT_SCHEDULED_POOL_CORE_SIZE = 5;
     private final static String DONE = "DONE";
     private TimeUnit heartbeatIntervalUnit;
     private long heartbeatInterval;
+    private boolean enableIdle;
     private ScheduledExecutorService heartbeatExecutor;
 
     public IdleProcessor(ImapProcessor next, MailboxManager mailboxManager, 
StatusResponseFactory factory,
@@ -74,6 +77,18 @@ public class IdleProcessor extends 
AbstractMailboxProcessor<IdleRequest> impleme
 
     }
 
+    @Override
+    public void configure(ImapConfiguration imapConfiguration) {
+        super.configure(imapConfiguration);
+
+        this.heartbeatInterval = imapConfiguration.getIdleTimeInterval();
+        this.heartbeatIntervalUnit = 
imapConfiguration.getIdleTimeIntervalUnit();
+        this.enableIdle = imapConfiguration.isEnableIdle();
+        if (enableIdle) {
+            this.heartbeatExecutor = 
Executors.newScheduledThreadPool(DEFAULT_SCHEDULED_POOL_CORE_SIZE);
+        }
+    }
+
     protected void doProcess(IdleRequest message, final ImapSession session, 
final String tag, final ImapCommand command, final Responder responder) {
 
         try {
@@ -128,7 +143,7 @@ public class IdleProcessor extends 
AbstractMailboxProcessor<IdleRequest> impleme
             });
 
             // Check if we should send heartbeats
-            if (heartbeatInterval > 0) {
+            if (enableIdle) {
                 heartbeatExecutor.schedule(new Runnable() {
 
                     public void run() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/af9ea357/protocols/imap/src/main/java/org/apache/james/imap/processor/base/AbstractChainedProcessor.java
----------------------------------------------------------------------
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/AbstractChainedProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/AbstractChainedProcessor.java
index d403887..e6649e6 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/AbstractChainedProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/AbstractChainedProcessor.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.imap.processor.base;
 
+import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -56,6 +57,11 @@ abstract public class AbstractChainedProcessor<M extends 
ImapMessage> implements
         }
     }
 
+    @Override
+    public void configure(ImapConfiguration imapConfiguration) {
+        next.configure(imapConfiguration);
+    }
+
     /**
      * Is the given message acceptable?
      * 

http://git-wip-us.apache.org/repos/asf/james-project/blob/af9ea357/protocols/imap/src/main/java/org/apache/james/imap/processor/base/UnknownRequestProcessor.java
----------------------------------------------------------------------
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/UnknownRequestProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/UnknownRequestProcessor.java
index 290df08..b2e42c5 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/UnknownRequestProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/UnknownRequestProcessor.java
@@ -20,6 +20,7 @@
 package org.apache.james.imap.processor.base;
 
 import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.api.message.request.ImapRequest;
@@ -60,4 +61,8 @@ public class UnknownRequestProcessor implements ImapProcessor 
{
         responder.respond(response);
     }
 
+    @Override
+    public void configure(ImapConfiguration imapConfiguration) {
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/af9ea357/protocols/imap/src/test/java/org/apache/james/imap/api/ImapConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/protocols/imap/src/test/java/org/apache/james/imap/api/ImapConfigurationTest.java
 
b/protocols/imap/src/test/java/org/apache/james/imap/api/ImapConfigurationTest.java
new file mode 100644
index 0000000..1d5c5e8
--- /dev/null
+++ 
b/protocols/imap/src/test/java/org/apache/james/imap/api/ImapConfigurationTest.java
@@ -0,0 +1,163 @@
+/****************************************************************
+ * 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.imap.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.james.imap.processor.IdleProcessor;
+
+import com.google.common.collect.ImmutableSet;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class ImapConfigurationTest {
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldRespectBeanContract() {
+        EqualsVerifier.forClass(ImapConfiguration.class).verify();
+    }
+
+    @Test
+    public void idleKeepAliveShouldBeDefaultValueWhenNoSetting() throws 
Exception {
+        ImapConfiguration imapConfiguration = 
ImapConfiguration.builder().build();
+
+        
assertThat(imapConfiguration.getIdleTimeInterval()).isEqualTo(IdleProcessor.DEFAULT_HEARTBEAT_INTERVAL_IN_SECONDS);
+    }
+
+    @Test
+    public void idleKeepAliveShouldReturnSetValue() throws Exception {
+        long idleValue  = 1;
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .idleTimeInterval(idleValue)
+                .build();
+
+        
assertThat(imapConfiguration.getIdleTimeInterval()).isEqualTo(idleValue);
+    }
+
+    @Test
+    public void idleKeepAliveShouldThrowWhenRezo() throws Exception {
+        expectedException.expect(IllegalArgumentException.class);
+
+        ImapConfiguration.builder()
+                .idleTimeInterval(0L)
+                .build();
+    }
+
+    @Test
+    public void idleKeepAliveShouldThrowWhenNegative() throws Exception {
+        expectedException.expect(IllegalArgumentException.class);
+
+        ImapConfiguration.builder()
+                .idleTimeInterval(-1)
+                .build();
+    }
+
+    @Test
+    public void millisecondsShouldBeDefaultValueWhenNoSetting() throws 
Exception {
+        ImapConfiguration imapConfiguration = 
ImapConfiguration.builder().build();
+
+        
assertThat(imapConfiguration.getIdleTimeIntervalUnit()).isEqualTo(IdleProcessor.DEFAULT_HEARTBEAT_INTERVAL_UNIT);
+    }
+
+    @Test
+    public void millisecondsShouldReturnSetValue() throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .idleTimeIntervalUnit(TimeUnit.MINUTES)
+                .build();
+
+        
assertThat(imapConfiguration.getIdleTimeIntervalUnit()).isEqualTo(TimeUnit.MINUTES);
+    }
+
+    @Test
+    public void disabledCapsShouldBeEmptyAsDefault() throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .build();
+
+        assertThat(imapConfiguration.getDisabledCaps()).isEmpty();
+    }
+
+    @Test
+    public void disabledCapsShouldReturnSetValue() throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .disabledCaps(ImmutableSet.of("AnyValue"))
+                .build();
+
+        
assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue");
+    }
+
+    @Test
+    public void disabledCapsShouldReturnMultipleSetValues() throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .disabledCaps(ImmutableSet.of("AnyValue", "OtherValue"))
+                .build();
+
+        
assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue", 
"OtherValue");
+    }
+
+    @Test
+    public void disabledCapsShouldReturnMultipleSetValuesWithNormalizeValue() 
throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .disabledCaps(ImmutableSet.of("   AnyValue   ", "  OtherValue  
 "))
+                .build();
+
+        
assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue", 
"OtherValue");
+    }
+
+    @Test
+    public void 
disabledCapsFromStringArrayShouldReturnMultipleSetValuesWithNormalizeValue() 
throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .disabledCaps("   AnyValue   ", "  OtherValue   ")
+                .build();
+
+        
assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue", 
"OtherValue");
+    }
+
+    @Test
+    public void disabledCapShouldReturnMultipleStringWithNormalizeValue() 
throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .disabledCap("   AnyValue   ")
+                .build();
+
+        
assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue");
+    }
+
+    @Test
+    public void idleShouldEnableByDefault() throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .build();
+
+        assertThat(imapConfiguration.isEnableIdle()).isTrue();
+    }
+
+    @Test
+    public void idleShouldBeDisable() throws Exception {
+        ImapConfiguration imapConfiguration = ImapConfiguration.builder()
+                .enableIdle(false)
+                .build();
+
+        assertThat(imapConfiguration.isEnableIdle()).isFalse();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/af9ea357/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 06488c3..d3f2aea 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
@@ -19,23 +19,28 @@
 package org.apache.james.imapserver.netty;
 
 import static org.jboss.netty.channel.Channels.pipeline;
-
 import java.util.concurrent.TimeUnit;
-
 import javax.net.ssl.SSLEngine;
 
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.decode.ImapDecoder;
 import org.apache.james.imap.encode.ImapEncoder;
+import org.apache.james.imap.processor.IdleProcessor;
 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.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+
 import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
@@ -46,13 +51,18 @@ import org.jboss.netty.handler.ssl.SslHandler;
 import org.jboss.netty.handler.stream.ChunkedWriteHandler;
 import org.jboss.netty.handler.timeout.IdleStateHandler;
 import org.jboss.netty.util.HashedWheelTimer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * NIO IMAP Server which use Netty.
  */
 public class IMAPServer extends AbstractConfigurableAsyncServer implements 
ImapConstants, IMAPServerMBean, NettyConstants {
+    private static final Logger LOG = 
LoggerFactory.getLogger(IMAPServer.class);
 
     private static final String softwaretype = "JAMES " + VERSION + " Server ";
+    private static final String DEFAULT_TIME_UNIT = "SECONDS";
+    private static final String CAPABILITY_SEPARATOR = "|";
 
     private final ImapProcessor processor;
     private final ImapEncoder encoder;
@@ -99,7 +109,28 @@ public class IMAPServer extends 
AbstractConfigurableAsyncServer implements ImapC
         if (timeout < 0) {
             timeout = 0;
         }
-        
+
+        processor.configure(getImapConfiguration(configuration));
+    }
+
+    @VisibleForTesting static ImapConfiguration 
getImapConfiguration(HierarchicalConfiguration configuration) {
+        ImmutableSet<String> disabledCaps = 
ImmutableSet.copyOf(Splitter.on(CAPABILITY_SEPARATOR).split(configuration.getString("disabledCaps",
 "")));
+
+        return ImapConfiguration.builder()
+                .enableIdle(configuration.getBoolean("enableIdle", 
IdleProcessor.DEFAULT_ENABLE_IDLE))
+                .idleTimeInterval(configuration.getLong("idleTimeInterval", 
IdleProcessor.DEFAULT_HEARTBEAT_INTERVAL_IN_SECONDS))
+                
.idleTimeIntervalUnit(getTimeIntervalUnit(configuration.getString("idleTimeIntervalUnit",
 DEFAULT_TIME_UNIT)))
+                .disabledCaps(disabledCaps)
+                .build();
+    }
+
+    private static TimeUnit getTimeIntervalUnit(String timeIntervalUnit) {
+        try {
+            return TimeUnit.valueOf(timeIntervalUnit);
+        } catch (IllegalArgumentException e) {
+            LOG.info("Time interval unit is not valid {}, the default {} value 
should be used", timeIntervalUnit, 
IdleProcessor.DEFAULT_HEARTBEAT_INTERVAL_UNIT);
+            return IdleProcessor.DEFAULT_HEARTBEAT_INTERVAL_UNIT;
+        }
     }
 
     /**


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

Reply via email to