Package org.apache.james.imap.processor.fetch

Source Code of org.apache.james.imap.processor.fetch.FetchProcessor

/****************************************************************
* 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.fetch;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
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.BodyFetchElement;
import org.apache.james.imap.api.message.FetchData;
import org.apache.james.imap.api.message.IdRange;
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.FetchRequest;
import org.apache.james.imap.message.response.FetchResponse;
import org.apache.james.imap.processor.AbstractMailboxProcessor;
import org.apache.james.mailbox.MailboxException;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageManager;
import org.apache.james.mailbox.MessageManager.MessageCallback;
import org.apache.james.mailbox.MessageRange;
import org.apache.james.mailbox.MessageRangeException;
import org.apache.james.mailbox.MessageResult;
import org.apache.james.mailbox.MessageResult.FetchGroup;
import org.apache.james.mailbox.MessageResult.MimePath;
import org.apache.james.mailbox.UnsupportedCriteriaException;
import org.apache.james.mailbox.util.FetchGroupImpl;
import org.apache.james.mime4j.field.address.parser.ParseException;

public class FetchProcessor extends AbstractMailboxProcessor<FetchRequest> {

    private int batchSize;

    public FetchProcessor(final ImapProcessor next, final MailboxManager mailboxManager, final StatusResponseFactory factory, int batchSize) {
        super(FetchRequest.class, next, mailboxManager, factory);
        this.batchSize = batchSize;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.apache.james.imap.processor.AbstractMailboxProcessor#doProcess(org
     * .apache.james.imap.api.message.request.ImapRequest,
     * org.apache.james.imap.api.process.ImapSession, java.lang.String,
     * org.apache.james.imap.api.ImapCommand,
     * org.apache.james.imap.api.process.ImapProcessor.Responder)
     */
    protected void doProcess(FetchRequest request, final ImapSession session, String tag, ImapCommand command, final Responder responder) {
        final boolean useUids = request.isUseUids();
        final IdRange[] idSet = request.getIdSet();
        final FetchData fetch = request.getFetch();
        try {
            final MessageManager mailbox = getSelectedMailbox(session);

            if (mailbox == null) {
                throw new MailboxException("Session not in SELECTED state");
            }

            final MailboxSession mailboxSession = ImapSessionUtils.getMailboxSession(session);
            List<MessageRange> ranges = new ArrayList<MessageRange>();

            for (int i = 0; i < idSet.length; i++) {
                MessageRange messageSet = messageRange(session.getSelected(), idSet[i], useUids);
                if (messageSet != null) {
                    MessageRange normalizedMessageSet = normalizeMessageRange(session.getSelected(), messageSet);
                    MessageRange batchedMessageSet = MessageRange.range(normalizedMessageSet.getUidFrom(), normalizedMessageSet.getUidTo(), batchSize);
                    ranges.add(batchedMessageSet);
                }
            }

            processMessageRanges(session, mailbox, ranges, fetch, useUids, mailboxSession, responder);

            // Don't send expunge responses if FETCH is used to trigger this
            // processor. See IMAP-284
            final boolean omitExpunged = (!useUids);
            unsolicitedResponses(session, responder, omitExpunged, useUids);
            okComplete(command, tag, responder);
        } catch (UnsupportedCriteriaException e) {
            no(command, tag, responder, HumanReadableText.UNSUPPORTED_SEARCH_CRITERIA);
        } catch (MessageRangeException e) {
            taggedBad(command, tag, responder, HumanReadableText.INVALID_MESSAGESET);
        } catch (MailboxException e) {
            no(command, tag, responder, HumanReadableText.SEARCH_FAILED);
        }
    }

    /**
     * Process the given message ranges by fetch them and pass them to the
     * {@link Responder}
     *
     * @param session
     * @param mailbox
     * @param range
     * @param fetch
     * @param useUids
     * @param mailboxSession
     * @param responder
     * @throws MailboxException
     */
    protected void processMessageRanges(final ImapSession session, final MessageManager mailbox, final List<MessageRange> ranges, final FetchData fetch, final boolean useUids, final MailboxSession mailboxSession, final Responder responder) throws MailboxException {
        final FetchResponseBuilder builder = new FetchResponseBuilder(new EnvelopeBuilder(session.getLog()));
        FetchGroup resultToFetch = getFetchGroup(fetch);

        for (int i = 0; i < ranges.size(); i++) {
            mailbox.getMessages(ranges.get(i), resultToFetch, mailboxSession, new MessageCallback() {

                public void onMessages(Iterator<MessageResult> it) throws MailboxException {
                    while (it.hasNext()) {
                        final MessageResult result = it.next();
                        try {
                            final FetchResponse response = builder.build(fetch, result, mailbox, session, useUids);
                            responder.respond(response);
                        } catch (ParseException e) {
                            // we can't for whatever reason parse the message so
                            // just skip it and log it to debug
                            session.getLog().debug("Unable to parse message with uid " + result.getUid(), e);
                        } catch (MessageRangeException e) {
                            // we can't for whatever reason find the message so
                            // just skip it and log it to debug
                            session.getLog().debug("Unable to find message with uid " + result.getUid(), e);
                        }
                    }
                }
            });
        }

    }

    protected FetchGroup getFetchGroup(FetchData fetch) {
        FetchGroupImpl result = new FetchGroupImpl();

        if (fetch.isEnvelope()) {
            result.or(FetchGroup.HEADERS);
        }
        if (fetch.isBody() || fetch.isBodyStructure()) {
            result.or(FetchGroup.MIME_DESCRIPTOR);
        }

        Collection<BodyFetchElement> bodyElements = fetch.getBodyElements();
        if (bodyElements != null) {
            for (final Iterator<BodyFetchElement> it = bodyElements.iterator(); it.hasNext();) {
                final BodyFetchElement element = it.next();
                final int sectionType = element.getSectionType();
                final int[] path = element.getPath();
                final boolean isBase = (path == null || path.length == 0);
                switch (sectionType) {
                case BodyFetchElement.CONTENT:
                    if (isBase) {
                        addContent(result, path, isBase, MessageResult.FetchGroup.FULL_CONTENT);
                    } else {
                        addContent(result, path, isBase, MessageResult.FetchGroup.MIME_CONTENT);
                    }
                    break;
                case BodyFetchElement.HEADER:
                case BodyFetchElement.HEADER_NOT_FIELDS:
                case BodyFetchElement.HEADER_FIELDS:
                    addContent(result, path, isBase, MessageResult.FetchGroup.HEADERS);
                    break;
                case BodyFetchElement.MIME:
                    addContent(result, path, isBase, MessageResult.FetchGroup.MIME_HEADERS);
                    break;
                case BodyFetchElement.TEXT:
                    addContent(result, path, isBase, MessageResult.FetchGroup.BODY_CONTENT);
                    break;
                default:
                    break;
                }

            }
        }
        return result;
    }

    private void addContent(FetchGroupImpl result, final int[] path, final boolean isBase, final int content) {
        if (isBase) {
            result.or(content);
        } else {
            MimePath mimePath = new MimePathImpl(path);
            result.addPartContent(mimePath, content);
        }
    }

}
TOP

Related Classes of org.apache.james.imap.processor.fetch.FetchProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.