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]
