Skip to content

Commit

Permalink
IMAP-370 Solve inheritance bugg on request handling
Browse files Browse the repository at this point in the history
  • Loading branch information
chibenwa committed Mar 4, 2016
1 parent b06992f commit 792a87a
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 155 deletions.
@@ -0,0 +1,45 @@
/****************************************************************
* 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.james.imap.api.ImapCommand;
import org.apache.james.imap.api.ImapMessage;
import org.apache.james.imap.api.message.IdRange;
import org.apache.james.imap.api.process.ImapSession;
import org.apache.james.imap.decode.ImapRequestLineReader;
import org.apache.james.imap.message.request.AbstractMessageRangeRequest;
import org.apache.james.protocols.imap.DecodingException;

public abstract class AbstractMessageRangeCommandParser extends AbstractUidCommandParser {

public AbstractMessageRangeCommandParser(ImapCommand command) {
super(command);
}

protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, String tag, boolean useUids, ImapSession session) throws DecodingException {
IdRange[] idSet = request.parseIdRange(session);
String mailboxName = request.mailbox();
request.eol();
return createRequest(command, tag, useUids, idSet, mailboxName);
}

abstract protected AbstractMessageRangeRequest createRequest(ImapCommand command, String tag, boolean useUids, IdRange[] idSet, String mailboxName);

}
Expand Up @@ -30,31 +30,15 @@
/**
* Parse COPY commands
*/
public class CopyCommandParser extends AbstractUidCommandParser {
public class CopyCommandParser extends AbstractMessageRangeCommandParser {

public CopyCommandParser() {
this(ImapCommand.selectedStateCommand(ImapConstants.COPY_COMMAND_NAME));
super(ImapCommand.selectedStateCommand(ImapConstants.COPY_COMMAND_NAME));
}

protected CopyCommandParser(ImapCommand command) {
super(command);
@Override
protected CopyRequest createRequest(ImapCommand command, String tag, boolean useUids, IdRange[] idSet, String mailboxName) {
return new CopyRequest(command, idSet, mailboxName, useUids, tag);
}
/**
* @see
* org.apache.james.imap.decode.parser.AbstractUidCommandParser#decode(org.apache.james.imap.api.ImapCommand,
* org.apache.james.imap.decode.ImapRequestLineReader, java.lang.String,
* boolean, org.apache.james.imap.api.process.ImapSession)
*/
protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, String tag, boolean useUids, ImapSession session) throws DecodingException {
IdRange[] idSet = request.parseIdRange(session);
String mailboxName = request.mailbox();
request.eol();
return createRequest(command, tag, useUids, idSet, mailboxName);
}

protected CopyRequest createRequest(ImapCommand command, String tag,
boolean useUids, IdRange[] idSet, String mailboxName) {
return new CopyRequest(command, idSet, mailboxName, useUids, tag);
}

}
Expand Up @@ -8,12 +8,13 @@
/**
* Parse MOVE commands
*/
public class MoveCommandParser extends CopyCommandParser {
public class MoveCommandParser extends AbstractMessageRangeCommandParser {

public MoveCommandParser() {
super(ImapCommand.selectedStateCommand(ImapConstants.MOVE_COMMAND_NAME));
}


@Override
protected MoveRequest createRequest(ImapCommand command, String tag,
boolean useUids, IdRange[] idSet, String mailboxName) {
return new MoveRequest(command, idSet, mailboxName, useUids, tag);
Expand Down
@@ -0,0 +1,49 @@
/****************************************************************
* 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.ImapCommand;
import org.apache.james.imap.api.message.IdRange;

public abstract class AbstractMessageRangeRequest extends AbstractImapRequest {

private final IdRange[] idSet;
private final String mailboxName;
private final boolean useUids;

public AbstractMessageRangeRequest(ImapCommand command, IdRange[] idSet, String mailboxName, boolean useUids, String tag) {
super(tag, command);
this.idSet = idSet;
this.mailboxName = mailboxName;
this.useUids = useUids;
}

public final IdRange[] getIdSet() {
return idSet;
}

public final String getMailboxName() {
return mailboxName;
}

public final boolean isUseUids() {
return useUids;
}
}
Expand Up @@ -25,40 +25,9 @@
/**
* {@link ImapRequest} which request the copy of messages
*/
public class CopyRequest extends AbstractImapRequest {

private final IdRange[] idSet;

private final String mailboxName;

private final boolean useUids;
public class CopyRequest extends AbstractMessageRangeRequest {

public CopyRequest(ImapCommand command, IdRange[] idSet, String mailboxName, boolean useUids, String tag) {
super(tag, command);
this.idSet = idSet;
this.mailboxName = mailboxName;
this.useUids = useUids;
}

/**
* Return an Array of {@link IdRange} to copy
*
* @return range
*/
public final IdRange[] getIdSet() {
return idSet;
}

/**
* Return the name of the mailbox
*
* @return mailbox
*/
public final String getMailboxName() {
return mailboxName;
}

public final boolean isUseUids() {
return useUids;
super(command, idSet, mailboxName, useUids, tag);
}
}
Expand Up @@ -26,10 +26,9 @@
/**
* {@link ImapRequest} which request the move of messages
*/
public class MoveRequest extends CopyRequest {
public class MoveRequest extends AbstractMessageRangeRequest {

public MoveRequest(ImapCommand command, IdRange[] idSet,
String mailboxName, boolean useUids, String tag) {
public MoveRequest(ImapCommand command, IdRange[] idSet, String mailboxName, boolean useUids, String tag) {
super(command, idSet, mailboxName, useUids, tag);
}

Expand Down
@@ -0,0 +1,114 @@
/****************************************************************
* 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 java.util.ArrayList;
import java.util.List;

import org.apache.james.imap.api.ImapCommand;
import org.apache.james.imap.api.ImapSessionUtils;
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.api.message.IdRange;
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.api.process.SelectedMailbox;
import org.apache.james.imap.message.request.AbstractMessageRangeRequest;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageManager;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MessageRangeException;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.MessageRange;

public abstract class AbstractMessageRangeProcessor<M extends AbstractMessageRangeRequest> extends AbstractMailboxProcessor<M> {

public AbstractMessageRangeProcessor(Class<M> acceptableClass, ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory) {
super(acceptableClass, next, mailboxManager, factory);
}

abstract protected List<MessageRange> process(final MailboxPath targetMailbox,
final SelectedMailbox currentMailbox,
final MailboxSession mailboxSession,
final MailboxManager mailboxManager,
MessageRange messageSet) throws MailboxException;

abstract protected String getOperationName();

@Override
protected void doProcess(M request, ImapSession session, String tag, ImapCommand command, Responder responder) {
final MailboxPath targetMailbox = buildFullPath(session, request.getMailboxName());
final IdRange[] idSet = request.getIdSet();
final boolean useUids = request.isUseUids();
final SelectedMailbox currentMailbox = session.getSelected();
try {
final MailboxSession mailboxSession = ImapSessionUtils.getMailboxSession(session);
final MailboxManager mailboxManager = getMailboxManager();
final boolean mailboxExists = mailboxManager.mailboxExists(targetMailbox, mailboxSession);

if (!mailboxExists) {
no(command, tag, responder, HumanReadableText.FAILURE_NO_SUCH_MAILBOX, StatusResponse.ResponseCode.tryCreate());
} else {

final MessageManager mailbox = mailboxManager.getMailbox(targetMailbox, mailboxSession);

List<IdRange> resultRanges = new ArrayList<IdRange>();
for (IdRange range : idSet) {
MessageRange messageSet = messageRange(currentMailbox, range, useUids);
if (messageSet != null) {
List<MessageRange> processedUids = process(
targetMailbox, currentMailbox, mailboxSession,
mailboxManager, messageSet);
for (MessageRange mr : processedUids) {
// Set recent flag on copied message as this SHOULD be
// done.
// See RFC 3501 6.4.7. COPY Command
// See IMAP-287
//
// Disable this as this is now done directly in the scope of the copy operation.
// See MAILBOX-85
//mailbox.setFlags(new Flags(Flags.Flag.RECENT), true, false, mr, mailboxSession);
resultRanges.add(new IdRange(mr.getUidFrom(), mr.getUidTo()));
}
}
}
IdRange[] resultUids = IdRange.mergeRanges(resultRanges).toArray(new IdRange[0]);

// get folder UIDVALIDITY
Long uidValidity = mailbox.getMetaData(false, mailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN).getUidValidity();

unsolicitedResponses(session, responder, useUids);
okComplete(command, tag, StatusResponse.ResponseCode.copyUid(uidValidity, idSet, resultUids), responder);
}
} catch (MessageRangeException e) {
if (session.getLog().isDebugEnabled()) {
session.getLog().debug(getOperationName() + " failed from mailbox " + currentMailbox.getPath() + " to " + targetMailbox + " for invalid sequence-set " + idSet.toString(), e);
}
taggedBad(command, tag, responder, HumanReadableText.INVALID_MESSAGESET);
} catch (MailboxException e) {
if (session.getLog().isInfoEnabled()) {
session.getLog().info(getOperationName() + " failed from mailbox " + currentMailbox.getPath() + " to " + targetMailbox + " for sequence-set " + idSet.toString(), e);
}
no(command, tag, responder, HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING);
}
}
}

0 comments on commit 792a87a

Please sign in to comment.