Author: niklas
Date: Wed Dec 15 16:00:25 2010
New Revision: 1049622
URL: http://svn.apache.org/viewvc?rev=1049622&view=rev
Log:
Added initial support for IDLE (IMAP-239).
Added:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ContinuationReader.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/IdleCommandParser.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ContinuationResponseEncoder.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/IdleRequest.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ContinuationResponse.java
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
Modified:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapConstants.java
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapMessageFactory.java
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/display/HumanReadableText.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseWriter.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/main/ChannelImapResponseWriter.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/BaseImap4Rev1MessageFactory.java
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/MockImapResponseWriter.java
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ByteImapResponseWriter.java
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java
Added:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ContinuationReader.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ContinuationReader.java?rev=1049622&view=auto
==============================================================================
---
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ContinuationReader.java
(added)
+++
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ContinuationReader.java
Wed Dec 15 16:00:25 2010
@@ -0,0 +1,27 @@
+/****************************************************************
+ * 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.io.IOException;
+
+public interface ContinuationReader {
+
+ public String readContinuation() throws IOException;
+
+}
Modified:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapConstants.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapConstants.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapConstants.java
(original)
+++
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapConstants.java
Wed Dec 15 16:00:25 2010
@@ -31,6 +31,8 @@ public interface ImapConstants {
public static final String UNTAGGED = "*";
+ public static final String CONTINUATION = "+";
+
public static final String SP = " ";
public static final String NIL = "NIL";
@@ -105,6 +107,8 @@ public interface ImapConstants {
public static final String SUPPORTS_STARTTLS = "STARTTLS";
+ public static final String SUPPORTS_IDLE = "IDLE";
+
public static final char HIERARCHY_DELIMITER_CHAR = '.';
public static final char NAMESPACE_PREFIX_CHAR = '#';
@@ -183,6 +187,8 @@ public interface ImapConstants {
public static final String NOOP_COMMAND_NAME = "NOOP";
+ public static final String IDLE_COMMAND_NAME = "IDLE";
+
public static final String LSUB_COMMAND_NAME = "LSUB";
public static final String LOGOUT_COMMAND_NAME = "LOGOUT";
Modified:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapMessageFactory.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapMessageFactory.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapMessageFactory.java
(original)
+++
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/ImapMessageFactory.java
Wed Dec 15 16:00:25 2010
@@ -68,6 +68,9 @@ public interface ImapMessageFactory {
public ImapMessage createNoopMessage(final ImapCommand command,
final String tag);
+ public ImapMessage createIdleMessage(final ImapCommand command,
+ final ContinuationReader reader, final String tag);
+
public ImapMessage createCloseMessage(final ImapCommand command,
final String tag);
Modified:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/display/HumanReadableText.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/api/src/main/java/org/apache/james/imap/api/display/HumanReadableText.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/display/HumanReadableText.java
(original)
+++
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/display/HumanReadableText.java
Wed Dec 15 16:00:25 2010
@@ -196,6 +196,9 @@ public class HumanReadableText {
public static final HumanReadableText BYE_UNKNOWN_COMMAND = new
HumanReadableText(
"org.apache.james.imap.BYE_UNKNOWN_COMMAND", "Unknown command.");
+ public static final HumanReadableText IDLING = new HumanReadableText(
+ "org.apache.james.imap.IDLING", "Idling");
+
private final String defaultValue;
private final String key;
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java
Wed Dec 15 16:00:25 2010
@@ -19,8 +19,10 @@
package org.apache.james.imap.decode;
+import java.io.IOException;
import java.io.InputStream;
+import org.apache.james.imap.api.ContinuationReader;
import org.apache.james.imap.api.display.HumanReadableText;
/**
@@ -30,7 +32,7 @@ import org.apache.james.imap.api.display
*
* @version $Revision: 109034 $
*/
-public abstract class ImapRequestLineReader {
+public abstract class ImapRequestLineReader implements ContinuationReader {
protected boolean nextSeen = false;
@@ -154,4 +156,22 @@ public abstract class ImapRequestLineRea
}
consume();
}
+
+ public String readContinuation() throws IOException {
+ // Consume the '\n' from the previous line.
+ consume();
+
+ StringBuilder sb = new StringBuilder();
+ char next = nextChar();
+ while (next != '\r') {
+ sb.append(next);
+ consume();
+ next = nextChar();
+ }
+ consume();
+
+ // NOTE: This code leaves the '\n' as next char. This seems to be what
is expected by the code which parses commands.
+
+ return sb.toString();
+ }
}
Added:
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/IdleCommandParser.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/IdleCommandParser.java?rev=1049622&view=auto
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/IdleCommandParser.java
(added)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/IdleCommandParser.java
Wed Dec 15 16:00:25 2010
@@ -0,0 +1,51 @@
+/****************************************************************
+ * 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.decode.parser;
+
+import org.apache.commons.logging.Log;
+import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.decode.ImapRequestLineReader;
+import org.apache.james.imap.decode.DecodingException;
+import org.apache.james.imap.decode.base.AbstractImapCommandParser;
+
+/**
+ *
+ * Parses IDLE commands
+ *
+ */
+public class IdleCommandParser extends AbstractImapCommandParser {
+
+ public IdleCommandParser() {
+
super(ImapCommand.selectedStateCommand(ImapConstants.IDLE_COMMAND_NAME));
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.apache.james.imap.decode.base.AbstractImapCommandParser#decode(org.apache.james.imap.api.ImapCommand,
org.apache.james.imap.decode.ImapRequestLineReader, java.lang.String,
org.apache.commons.logging.Log)
+ */
+ protected ImapMessage decode(ImapCommand command,
+ ImapRequestLineReader request, String tag, Log logger) throws
DecodingException {
+ endLine(request);
+ final ImapMessage result =
getMessageFactory().createIdleMessage(command, request, tag);
+ return result;
+ }
+
+}
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java
Wed Dec 15 16:00:25 2010
@@ -104,7 +104,7 @@ public class ImapParserFactory implement
// _imapCommands.put( "MYRIGHTS", MyRightsCommand.class );
// Commands only valid in SELECTED state.
- // CHECK, CLOSE, EXPUNGE, SEARCH, FETCH, STORE, COPY, and UID
+ // CHECK, CLOSE, EXPUNGE, SEARCH, FETCH, STORE, COPY, UID and IDLE
_imapCommands.put(ImapConstants.CHECK_COMMAND_NAME,
CheckCommandParser.class);
_imapCommands.put(ImapConstants.CLOSE_COMMAND_NAME,
@@ -121,6 +121,8 @@ public class ImapParserFactory implement
StoreCommandParser.class);
_imapCommands.put(ImapConstants.UID_COMMAND_NAME,
UidCommandParser.class);
+ _imapCommands.put(ImapConstants.IDLE_COMMAND_NAME,
+ IdleCommandParser.class);
_imapCommands.put(ImapConstants.STARTTLS, StartTLSCommandParser.class);
}
Added:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ContinuationResponseEncoder.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ContinuationResponseEncoder.java?rev=1049622&view=auto
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ContinuationResponseEncoder.java
(added)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ContinuationResponseEncoder.java
Wed Dec 15 16:00:25 2010
@@ -0,0 +1,60 @@
+/****************************************************************
+ * 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.encode;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.display.Locales;
+import org.apache.james.imap.api.display.Localizer;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
+import org.apache.james.imap.message.response.ContinuationResponse;
+
+public class ContinuationResponseEncoder extends AbstractChainedImapEncoder {
+
+ private final Localizer localizer;
+
+ public ContinuationResponseEncoder(ImapEncoder next, final Localizer
localizer) {
+ super(next);
+ this.localizer = localizer;
+ }
+
+ protected void doEncode(ImapMessage acceptableMessage,
+ ImapResponseComposer composer, ImapSession session) throws
IOException {
+
+ ContinuationResponse response = (ContinuationResponse)
acceptableMessage;
+ final String message = response.getData() != null ? response.getData()
: asString(response.getTextKey(), session);
+ composer.continuationResponse(message);
+ }
+
+ private String asString(HumanReadableText text, ImapSession session) {
+ // TODO: calculate locales
+ return localizer.localize(text, new Locales(new ArrayList<Locale>(),
null));
+ }
+
+ protected boolean isAcceptable(ImapMessage message) {
+ return (message instanceof ContinuationResponse);
+ }
+
+}
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
Wed Dec 15 16:00:25 2010
@@ -293,4 +293,13 @@ public interface ImapResponseComposer {
* @throws IOException
*/
public ImapResponseComposer capabilities(List<String> capabilities) throws
IOException;
+
+ /**
+ * Writes a continuation response.
+ *
+ * @param message
+ * message for display, not null
+ */
+ public abstract void continuationResponse(String message) throws
IOException;
+
}
\ No newline at end of file
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseWriter.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseWriter.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseWriter.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseWriter.java
Wed Dec 15 16:00:25 2010
@@ -47,6 +47,14 @@ public interface ImapResponseWriter {
void tag(String tag) throws IOException;
/**
+ * Starts a continuation response.
+ *
+ * @param message
+ * the message, not null
+ */
+ void continuation(String message) throws IOException;
+
+ /**
* Writes a command name.
*
* @param commandName
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
Wed Dec 15 16:00:25 2010
@@ -90,6 +90,15 @@ public class ImapResponseComposerImpl im
/**
* @throws IOException
+ * @see
org.apache.james.imap.encode.ImapResponseComposer#continuationResponse(String)
+ */
+ public void continuationResponse(String message) throws IOException {
+ writer.continuation(message);
+ end();
+ }
+
+ /**
+ * @throws IOException
* @see
org.apache.james.imap.encode.ImapResponseComposer#flagsResponse(javax.mail.Flags)
*/
public void flagsResponse(Flags flags) throws IOException {
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
Wed Dec 15 16:00:25 2010
@@ -21,6 +21,7 @@ package org.apache.james.imap.encode.mai
import org.apache.james.imap.api.display.Localizer;
import org.apache.james.imap.encode.CapabilityResponseEncoder;
+import org.apache.james.imap.encode.ContinuationResponseEncoder;
import org.apache.james.imap.encode.ExistsResponseEncoder;
import org.apache.james.imap.encode.ExpungeResponseEncoder;
import org.apache.james.imap.encode.FetchResponseEncoder;
@@ -73,7 +74,9 @@ public class DefaultImapEncoderFactory i
listResponseEncoder);
final CapabilityResponseEncoder capabilityResponseEncoder = new
CapabilityResponseEncoder(
flagsResponseEncoder);
- return capabilityResponseEncoder;
+ final ContinuationResponseEncoder continuationResponseEncoder = new
ContinuationResponseEncoder(
+ capabilityResponseEncoder, localizer);
+ return continuationResponseEncoder;
}
private final Localizer localizer;
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/main/ChannelImapResponseWriter.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/main/ChannelImapResponseWriter.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/main/ChannelImapResponseWriter.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/main/ChannelImapResponseWriter.java
Wed Dec 15 16:00:25 2010
@@ -253,4 +253,8 @@ public class ChannelImapResponseWriter i
public void quoteUpperCaseAscii(String message) throws IOException {
upperCaseAscii(message, true);
}
+
+ public void continuation(String message) throws IOException {
+ writeASCII(CONTINUATION + SP + message);
+ }
}
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/BaseImap4Rev1MessageFactory.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/BaseImap4Rev1MessageFactory.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/BaseImap4Rev1MessageFactory.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/BaseImap4Rev1MessageFactory.java
Wed Dec 15 16:00:25 2010
@@ -23,6 +23,7 @@ import java.util.Date;
import javax.mail.Flags;
+import org.apache.james.imap.api.ContinuationReader;
import org.apache.james.imap.api.ImapMessageFactory;
import org.apache.james.imap.api.ImapCommand;
import org.apache.james.imap.api.ImapMessage;
@@ -85,6 +86,14 @@ public class BaseImap4Rev1MessageFactory
/*
* (non-Javadoc)
+ * @see
org.apache.james.imap.api.ImapMessageFactory#createNoopMessage(org.apache.james.imap.api.ImapCommand,
java.lang.String)
+ */
+ public ImapMessage createIdleMessage(ImapCommand command,
ContinuationReader reader, String tag) {
+ return new IdleRequest(command, reader, tag);
+ }
+
+ /*
+ * (non-Javadoc)
* @see
org.apache.james.imap.api.ImapMessageFactory#createCloseMessage(org.apache.james.imap.api.ImapCommand,
java.lang.String)
*/
public ImapMessage createCloseMessage(ImapCommand command, String tag) {
Added:
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/IdleRequest.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/IdleRequest.java?rev=1049622&view=auto
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/IdleRequest.java
(added)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/IdleRequest.java
Wed Dec 15 16:00:25 2010
@@ -0,0 +1,36 @@
+/****************************************************************
+ * 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.message.request;
+
+import org.apache.james.imap.api.ContinuationReader;
+import org.apache.james.imap.api.ImapCommand;
+
+public class IdleRequest extends AbstractImapRequest {
+
+ private final ContinuationReader reader;
+
+ public IdleRequest(ImapCommand command, ContinuationReader reader, String
tag) {
+ super(tag, command);
+ this.reader = reader;
+ }
+
+ public ContinuationReader getContinuationReader() {
+ return reader;
+ }
+}
Added:
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ContinuationResponse.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ContinuationResponse.java?rev=1049622&view=auto
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ContinuationResponse.java
(added)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ContinuationResponse.java
Wed Dec 15 16:00:25 2010
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.message.response;
+
+import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.response.ImapResponseMessage;
+
+public class ContinuationResponse implements ImapResponseMessage {
+
+ private final String data;
+
+ private final HumanReadableText textKey;
+
+ public ContinuationResponse(final String data) {
+ super();
+ this.data = data;
+ this.textKey = null;
+ }
+
+ public ContinuationResponse(final HumanReadableText textKey) {
+ super();
+ this.data = null;
+ this.textKey = textKey;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public HumanReadableText getTextKey() {
+ return textKey;
+ }
+}
Modified:
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/MockImapResponseWriter.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/MockImapResponseWriter.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/MockImapResponseWriter.java
(original)
+++
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/MockImapResponseWriter.java
Wed Dec 15 16:00:25 2010
@@ -279,6 +279,17 @@ public class MockImapResponseWriter impl
}
+ public static class ContinuationOperation {
+ public boolean equals(Object obj) {
+ return obj instanceof ContinuationOperation;
+ }
+
+ public int hashCode() {
+ return 3;
+ }
+
+ }
+
public void closeParen() {
operations.add(new BracketOperation(false, false));
}
@@ -442,4 +453,8 @@ public class MockImapResponseWriter impl
public void space() {
}
+
+ public void continuation(String message) {
+ operations.add(new ContinuationOperation());
+ }
}
Modified:
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ByteImapResponseWriter.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ByteImapResponseWriter.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ByteImapResponseWriter.java
(original)
+++
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/base/ByteImapResponseWriter.java
Wed Dec 15 16:00:25 2010
@@ -204,4 +204,8 @@ public class ByteImapResponseWriter impl
public void quoteUpperCaseAscii(String message) {
upperCaseAscii(message, true);
}
+
+ public void continuation(String message) throws IOException {
+ writer.print(CONTINUATION + SP + message);
+ }
}
Modified:
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java?rev=1049622&r1=1049621&r2=1049622&view=diff
==============================================================================
---
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java
(original)
+++
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java
Wed Dec 15 16:00:25 2010
@@ -84,8 +84,10 @@ public class DefaultProcessorChain {
appendProcessor, mailboxManager, statusResponseFactory);
final NoopProcessor noopProcessor = new NoopProcessor(storeProcessor,
mailboxManager, statusResponseFactory);
+ final IdleProcessor idleProcessor = new IdleProcessor(noopProcessor,
+ mailboxManager, statusResponseFactory);
final StatusProcessor statusProcessor = new StatusProcessor(
- noopProcessor, mailboxManager, statusResponseFactory);
+ idleProcessor, mailboxManager, statusResponseFactory);
final LSubProcessor lsubProcessor = new LSubProcessor(statusProcessor,
mailboxManager, subscriptionManager, statusResponseFactory);
final ListProcessor listProcessor = new ListProcessor(lsubProcessor,
@@ -97,6 +99,7 @@ public class DefaultProcessorChain {
final NamespaceProcessor namespaceProcessor = new NamespaceProcessor(
selectProcessor, mailboxManager, statusResponseFactory);
+ capabilityProcessor.addProcessor(idleProcessor);
capabilityProcessor.addProcessor(namespaceProcessor);
final ImapProcessor fetchProcessor = new
FetchProcessor(namespaceProcessor,
Added:
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/IdleProcessor.java?rev=1049622&view=auto
==============================================================================
---
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
(added)
+++
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
Wed Dec 15 16:00:25 2010
@@ -0,0 +1,134 @@
+/****************************************************************
+ * 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.processor;
+
+import static org.apache.james.imap.api.ImapConstants.SUPPORTS_IDLE;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.james.imap.api.ContinuationReader;
+import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.request.ImapRequest;
+import org.apache.james.imap.api.message.response.StatusResponse;
+import org.apache.james.imap.api.message.response.StatusResponseFactory;
+import org.apache.james.imap.api.process.ImapProcessor;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.message.request.IdleRequest;
+import org.apache.james.imap.message.response.ContinuationResponse;
+import org.apache.james.imap.processor.base.ImapSessionUtils;
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+
+public class IdleProcessor extends AbstractMailboxProcessor implements
CapabilityImplementingProcessor {
+
+ private final StatusResponseFactory factory;
+
+ public IdleProcessor(final ImapProcessor next, final MailboxManager
mailboxManager,
+ final StatusResponseFactory factory) {
+ super(next, mailboxManager, factory);
+
+ this.factory = factory;
+ }
+
+ protected boolean isAcceptable(ImapMessage message) {
+ return (message instanceof IdleRequest);
+ }
+
+ protected void doProcess(ImapRequest message, ImapSession session,
+ String tag, ImapCommand command, Responder responder) {
+
+ try {
+ IdleRequest request = (IdleRequest) message;
+ ContinuationReader reader = request.getContinuationReader();
+
+ responder.respond(new
ContinuationResponse(HumanReadableText.IDLING));
+ unsolicitedResponses(session, responder, false);
+
+ MailboxManager mailboxManager = getMailboxManager();
+ MailboxSession mailboxSession =
ImapSessionUtils.getMailboxSession(session);
+ AtomicBoolean closed = new AtomicBoolean(false);
+
+ String line = null;
+ try {
+ mailboxManager.addListener(session.getSelected().getPath(),
+ new IdleMailboxListener(closed, session, responder),
mailboxSession);
+
+ line = reader.readContinuation();
+ } finally {
+ synchronized (session) {
+ closed.set(true);
+ }
+ }
+ if (!"DONE".equals(line.toUpperCase())) {
+ StatusResponse response = factory.taggedBad(tag, command,
+ HumanReadableText.INVALID_COMMAND);
+ responder.respond(response);
+ } else {
+ okComplete(command, tag, responder);
+ }
+ } catch (IOException e) {
+ // TODO: What should we do here?
+ no(command, tag, responder,
HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING);
+ } catch (MailboxException e) {
+ // TODO: What should we do here?
+ no(command, tag, responder,
HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING);
+ }
+ }
+
+ public List<String> getImplementedCapabilities(ImapSession session) {
+ return Arrays.asList(SUPPORTS_IDLE);
+ }
+
+ private class IdleMailboxListener implements MailboxListener {
+
+ private final AtomicBoolean closed;
+ private final ImapSession session;
+ private final Responder responder;
+
+ public IdleMailboxListener(AtomicBoolean closed, ImapSession session,
Responder responder) {
+ this.closed = closed;
+ this.session = session;
+ this.responder = responder;
+ }
+
+ public void event(Event event) {
+ synchronized (session) {
+ if (isClosed()) {
+ return;
+ }
+ if (event instanceof Added || event instanceof Expunged ||
event instanceof FlagsUpdated) {
+ unsolicitedResponses(session, responder, false);
+ }
+ }
+ }
+
+ public boolean isClosed() {
+ return closed.get();
+ }
+
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]