All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.james.mailbox.jcr.mail.JCRMessageMapper Maven / Gradle / Ivy

There is a newer version: 3.2.0
Show newest version
/****************************************************************
 * 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.mailbox.jcr.mail;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.mail.Flags;

import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.util.ISO9075;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.jcr.JCRImapConstants;
import org.apache.james.mailbox.jcr.MailboxSessionJCRRepository;
import org.apache.james.mailbox.jcr.mail.model.JCRMailboxMessage;
import org.apache.james.mailbox.model.MessageMetaData;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MessageRange.Type;
import org.apache.james.mailbox.store.SimpleMessageMetaData;
import org.apache.james.mailbox.store.mail.AbstractMessageMapper;
import org.apache.james.mailbox.store.mail.MessageMapper;
import org.apache.james.mailbox.store.mail.ModSeqProvider;
import org.apache.james.mailbox.store.mail.UidProvider;
import org.apache.james.mailbox.store.mail.model.Mailbox;
import org.apache.james.mailbox.store.mail.model.MailboxMessage;
import org.apache.james.mailbox.store.mail.utils.ApplicableFlagCalculator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * JCR implementation of a {@link MessageMapper}. The implementation store each
 * message as a seperate child node under the mailbox
 * 
 */
public class JCRMessageMapper extends AbstractMessageMapper implements JCRImapConstants {

    private static final Logger LOGGER = LoggerFactory.getLogger(JCRMessageMapper.class);

    @SuppressWarnings("deprecation")
    private static final String XPATH_LANGUAGE = Query.XPATH;

    /**
     * Store the messages directly in the mailbox: .../mailbox/
     */
    public static final int MESSAGE_SCALE_NONE = 0;

    /**
     * Store the messages under a year directory in the mailbox:
     * .../mailbox/2010/
     */
    public static final int MESSAGE_SCALE_YEAR = 1;

    /**
     * Store the messages under a year/month directory in the mailbox:
     * .../mailbox/2010/05/
     */
    public static final int MESSAGE_SCALE_MONTH = 2;

    /**
     * Store the messages under a year/month/day directory in the mailbox:
     * .../mailbox/2010/05/01/
     */
    public static final int MESSAGE_SCALE_DAY = 3;

    /**
     * Store the messages under a year/month/day/hour directory in the mailbox:
     * .../mailbox/2010/05/02/11
     */
    public static final int MESSAGE_SCALE_HOUR = 4;

    /**
     * Store the messages under a year/month/day/hour/min directory in the
     * mailbox: .../mailbox/2010/05/02/11/59
     */
    public static final int MESSAGE_SCALE_MINUTE = 5;

    private final int scaleType;

    private final MailboxSessionJCRRepository repository;

    /**
     * Construct a new {@link JCRMessageMapper} instance
     * 
     * @param repository
     *            {@link MailboxSessionJCRRepository} to use
     * @param mSession
     *            {@link MailboxSession} to which the mapper is bound
     * @param uidProvider
     *            {@link UidProvider} to use
     * @param modSeqProvider
     *            {@link ModSeqProvider} to use
     * @param scaleType
     *            message scale type either {@link #MESSAGE_SCALE_DAY},
     *            {@link #MESSAGE_SCALE_HOUR}, {@link #MESSAGE_SCALE_MINUTE},
     *            {@link #MESSAGE_SCALE_MONTH}, {@link #MESSAGE_SCALE_NONE} or
     *            {@link #MESSAGE_SCALE_YEAR}
     */
    public JCRMessageMapper(MailboxSessionJCRRepository repository, MailboxSession mSession,
            UidProvider uidProvider, ModSeqProvider modSeqProvider, int scaleType) {
        super(mSession, uidProvider, modSeqProvider);
        this.repository = repository;
        this.scaleType = scaleType;
    }

    /**
     * Construct a new {@link JCRMessageMapper} instance using
     * {@link #MESSAGE_SCALE_DAY} as default
     * 
     * @param repos
     *            {@link MailboxSessionJCRRepository} to use
     * @param session
     *            {@link MailboxSession} to which the mapper is bound
     * @param uidProvider
     *            {@link UidProvider} to use
     * @param modSeqProvider
     *            {@link ModSeqProvider} to use
     */
    public JCRMessageMapper(MailboxSessionJCRRepository repos, MailboxSession session,
            UidProvider uidProvider, ModSeqProvider modSeqProvider) {
        this(repos, session, uidProvider, modSeqProvider, MESSAGE_SCALE_DAY);
    }

    /**
     * Return the JCR Session
     * 
     * @return session
     */
    protected Session getSession() throws RepositoryException {
        return repository.login(mailboxSession);
    }

    /**
     * Begin is not supported by level 1 JCR implementations, however we refresh
     * the session
     */
    @Override
    protected void begin() throws MailboxException {
        try {
            getSession().refresh(true);
        } catch (RepositoryException e) {
            // do nothin on refresh
        }
        // Do nothing
    }

    /**
     * Just call save on the underlying JCR Session, because level 1 JCR
     * implementation does not offer Transactions
     */
    @Override
    protected void commit() throws MailboxException {
        try {
            if (getSession().hasPendingChanges()) {
                getSession().save();
            }
        } catch (RepositoryException e) {
            throw new MailboxException("Unable to commit", e);
        }
    }

    /**
     * Rollback is not supported by level 1 JCR implementations, so just do
     * nothing
     */
    @Override
    protected void rollback() throws MailboxException {
        try {
            // just refresh session and discard all pending changes
            getSession().refresh(false);
        } catch (RepositoryException e) {
            // just catch on rollback by now
        }
    }

    /**
     * Logout from open JCR Session
     */
    @Override
    public void endRequest() {
        repository.logout(mailboxSession);
    }

    @Override
    public long countMessagesInMailbox(Mailbox mailbox) throws MailboxException {
        try {
            // we use order by because without it count will always be 0 in
            // jackrabbit
            String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message) order by @"
                    + JCRMailboxMessage.UID_PROPERTY;
            QueryManager manager = getSession().getWorkspace().getQueryManager();
            QueryResult result = manager.createQuery(queryString, XPATH_LANGUAGE).execute();
            NodeIterator nodes = result.getNodes();
            long count = nodes.getSize();
            if (count == -1) {
                count = 0;
                while (nodes.hasNext()) {
                    nodes.nextNode();
                    count++;
                }
            }
            return count;
        } catch (RepositoryException e) {
            throw new MailboxException("Unable to count messages in mailbox " + mailbox, e);
        }

    }

    @Override
    public long countUnseenMessagesInMailbox(Mailbox mailbox) throws MailboxException {

        try {
            // we use order by because without it count will always be 0 in
            // jackrabbit
            String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                    + JCRMailboxMessage.SEEN_PROPERTY + "='false'] order by @" + JCRMailboxMessage.UID_PROPERTY;
            QueryManager manager = getSession().getWorkspace().getQueryManager();
            QueryResult result = manager.createQuery(queryString, XPATH_LANGUAGE).execute();
            NodeIterator nodes = result.getNodes();
            long count = nodes.getSize();

            if (count == -1) {
                count = 0;
                while (nodes.hasNext()) {
                    nodes.nextNode();

                    count++;
                }
            }
            return count;
        } catch (RepositoryException e) {
            throw new MailboxException("Unable to count unseen messages in mailbox " + mailbox, e);
        }
    }

    @Override
    public void delete(Mailbox mailbox, MailboxMessage message) throws MailboxException {
        JCRMailboxMessage membership = (JCRMailboxMessage) message;
        if (membership.isPersistent()) {
            try {

                getSession().getNodeByIdentifier(membership.getId()).remove();
            } catch (RepositoryException e) {
                throw new MailboxException("Unable to delete message " + message + " in mailbox " + mailbox, e);
            }
        }
    }

    @Override
    public Iterator findInMailbox(Mailbox mailbox, MessageRange set, FetchType fType, int max)
            throws MailboxException {
        try {
            List results;
            MessageUid from = set.getUidFrom();
            final MessageUid to = set.getUidTo();
            final Type type = set.getType();

            switch (type) {
            default:
            case ALL:
                results = findMessagesInMailbox(mailbox, max);
                break;
            case FROM:
                results = findMessagesInMailboxAfterUID(mailbox, from, max);
                break;
            case ONE:
                results = findMessageInMailboxWithUID(mailbox, from);
                break;
            case RANGE:
                results = findMessagesInMailboxBetweenUIDs(mailbox, from, to, max);
                break;
            }
            return results.iterator();
        } catch (RepositoryException e) {
            throw new MailboxException("Unable to search MessageRange " + set + " in mailbox " + mailbox, e);
        }
    }

    /*
     * 
     * TODO: Maybe we should better use an ItemVisitor and just traverse through
     * the child nodes. This could be a way faster
     */
    @Override
    public List findRecentMessageUidsInMailbox(Mailbox mailbox) throws MailboxException {

        try {

            List list = new ArrayList<>();
            String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                    + JCRMailboxMessage.RECENT_PROPERTY + "='true'] order by @" + JCRMailboxMessage.UID_PROPERTY;

            QueryManager manager = getSession().getWorkspace().getQueryManager();
            Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
            QueryResult result = query.execute();

            NodeIterator iterator = result.getNodes();
            while (iterator.hasNext()) {
                list.add(new JCRMailboxMessage(iterator.nextNode(), LOGGER).getUid());
            }
            return list;

        } catch (RepositoryException e) {
            throw new MailboxException("Unable to search recent messages in mailbox " + mailbox, e);
        }
    }

    @Override
    public MessageUid findFirstUnseenMessageUid(Mailbox mailbox) throws MailboxException {
        try {
            String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                    + JCRMailboxMessage.SEEN_PROPERTY + "='false'] order by @" + JCRMailboxMessage.UID_PROPERTY;

            QueryManager manager = getSession().getWorkspace().getQueryManager();

            Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
            query.setLimit(1);
            QueryResult result = query.execute();

            NodeIterator iterator = result.getNodes();
            if (iterator.hasNext()) {
                return new JCRMailboxMessage(iterator.nextNode(), LOGGER).getUid();
            } else {
                return null;
            }
        } catch (RepositoryException e) {
            throw new MailboxException("Unable to find first unseen message in mailbox " + mailbox, e);
        }
    }

    @Override
    public Map expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set)
            throws MailboxException {
        try {
            final List results;
            final MessageUid from = set.getUidFrom();
            final MessageUid to = set.getUidTo();
            final Type type = set.getType();
            switch (type) {
            default:
            case ALL:
                results = findDeletedMessagesInMailbox(mailbox);
                break;
            case FROM:
                results = findDeletedMessagesInMailboxAfterUID(mailbox, from);
                break;
            case ONE:
                results = findDeletedMessageInMailboxWithUID(mailbox, from);
                break;
            case RANGE:
                results = findDeletedMessagesInMailboxBetweenUIDs(mailbox, from, to);
                break;
            }
            Map uids = new HashMap<>();
            for (MailboxMessage m : results) {
                MessageUid uid = m.getUid();
                uids.put(uid, new SimpleMessageMetaData(m));
                delete(mailbox, m);
            }
            return uids;
        } catch (RepositoryException e) {
            throw new MailboxException("Unable to search MessageRange " + set + " in mailbox " + mailbox, e);
        }
    }

    @Override
    public MessageMetaData move(Mailbox mailbox, MailboxMessage original) throws MailboxException {
        throw new UnsupportedOperationException("Not implemented - see https://issues.apache.org/jira/browse/IMAP-370");
    }

    @Override
    protected MessageMetaData copy(Mailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original)
            throws MailboxException {
        try {
            String newMessagePath = getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath() + NODE_DELIMITER
                    + String.valueOf(uid.asLong());
            getSession().getWorkspace().copy(
                    ((JCRMailboxMessage) original).getNode().getPath(),
                    getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath() + NODE_DELIMITER
                            + String.valueOf(uid.asLong()));
            Node node = getSession().getNode(newMessagePath);
            node.setProperty(JCRMailboxMessage.MAILBOX_UUID_PROPERTY, mailbox.getMailboxId().serialize());
            node.setProperty(JCRMailboxMessage.UID_PROPERTY, uid.asLong());
            node.setProperty(JCRMailboxMessage.MODSEQ_PROPERTY, modSeq);
            // A copy of a message is recent
            // See MAILBOX-85
            node.setProperty(JCRMailboxMessage.RECENT_PROPERTY, true);
            return new SimpleMessageMetaData(new JCRMailboxMessage(node, LOGGER));
        } catch (RepositoryException e) {
            throw new MailboxException("Unable to copy message " + original + " in mailbox " + mailbox, e);
        }
    }

    @Override
    protected MessageMetaData save(Mailbox mailbox, MailboxMessage message) throws MailboxException {
        final JCRMailboxMessage membership = (JCRMailboxMessage) message;
        try {
    
            Node messageNode = null;
    
            if (membership.isPersistent()) {
                messageNode = getSession().getNodeByIdentifier(membership.getId());
            }
    
            if (messageNode == null) {
    
                Date date = message.getInternalDate();
                if (date == null) {
                    date = new Date();
                }
    
                // extracte the date from the message to create node structure
                // later
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
                final String year = convertIntToString(cal.get(Calendar.YEAR));
                final String month = convertIntToString(cal.get(Calendar.MONTH) + 1);
                final String day = convertIntToString(cal.get(Calendar.DAY_OF_MONTH));
                final String hour = convertIntToString(cal.get(Calendar.HOUR_OF_DAY));
                final String min = convertIntToString(cal.get(Calendar.MINUTE));
    
                Node mailboxNode = getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize());
                Node node = mailboxNode;
    
                if (scaleType > MESSAGE_SCALE_NONE) {
                    // we lock the whole mailbox with all its childs while
                    // adding the folder structure for the date
    
                    if (scaleType >= MESSAGE_SCALE_YEAR) {
                        node = JcrUtils.getOrAddFolder(node, year);
    
                        if (scaleType >= MESSAGE_SCALE_MONTH) {
                            node = JcrUtils.getOrAddFolder(node, month);
    
                            if (scaleType >= MESSAGE_SCALE_DAY) {
                                node = JcrUtils.getOrAddFolder(node, day);
    
                                if (scaleType >= MESSAGE_SCALE_HOUR) {
                                    node = JcrUtils.getOrAddFolder(node, hour);
    
                                    if (scaleType >= MESSAGE_SCALE_MINUTE) {
                                        node = JcrUtils.getOrAddFolder(node, min);
                                    }
                                }
                            }
                        }
                    }
    
                }
    
                MessageUid uid = membership.getUid();
                messageNode = mailboxNode.addNode(String.valueOf(uid.asLong()), "nt:file");
                messageNode.addMixin("jamesMailbox:message");
                try {
                    membership.merge(messageNode);
    
                } catch (IOException e) {
                    throw new RepositoryException("Unable to merge message in to tree", e);
                }
            } else {
                membership.merge(messageNode);
            }
            return new SimpleMessageMetaData(membership);
        } catch (RepositoryException | IOException e) {
            throw new MailboxException("Unable to save message " + message + " in mailbox " + mailbox, e);
        }
    }

    @Override
    public Flags getApplicableFlag(Mailbox mailbox) throws MailboxException {
        int maxBatchSize = -1;
        try {
            return new ApplicableFlagCalculator(findMessagesInMailbox(mailbox, maxBatchSize))
                .computeApplicableFlags();
        } catch (RepositoryException e) {
            throw new MailboxException("Unable to get message from in mailbox " + mailbox, e);
        }
    }

    /**
     * Return the path to the mailbox. This path is escaped to be able to use it
     * in xpath queries
     * 
     * See http://wiki.apache.org/jackrabbit/EncodingAndEscaping
     * 
     * @param mailbox
     * @return
     * @throws ItemNotFoundException
     * @throws RepositoryException
     */
    private String getMailboxPath(Mailbox mailbox) throws ItemNotFoundException, RepositoryException {
        return ISO9075.encodePath(getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath());
    }

    private List findMessagesInMailboxAfterUID(Mailbox mailbox, MessageUid from, int batchSize)
            throws RepositoryException {
        List list = new ArrayList<>();
        String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                + JCRMailboxMessage.UID_PROPERTY + ">=" + from + "] order by @" + JCRMailboxMessage.UID_PROPERTY;

        QueryManager manager = getSession().getWorkspace().getQueryManager();
        Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
        if (batchSize > 0) {
            query.setLimit(batchSize);
        }
        QueryResult result = query.execute();

        NodeIterator iterator = result.getNodes();
        while (iterator.hasNext()) {
            list.add(new JCRMailboxMessage(iterator.nextNode(), LOGGER));
        }
        return list;
    }

    private List findMessageInMailboxWithUID(Mailbox mailbox, MessageUid from)
            throws RepositoryException {
        List list = new ArrayList<>();
        String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                + JCRMailboxMessage.UID_PROPERTY + "=" + from + "]";

        QueryManager manager = getSession().getWorkspace().getQueryManager();
        Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
        query.setLimit(1);
        QueryResult result = query.execute();
        NodeIterator iterator = result.getNodes();
        while (iterator.hasNext()) {
            list.add(new JCRMailboxMessage(iterator.nextNode(), LOGGER));
        }
        return list;
    }

    private List findMessagesInMailboxBetweenUIDs(Mailbox mailbox, MessageUid from, MessageUid to,
                                                                         int batchSize) throws RepositoryException {
        List list = new ArrayList<>();
        String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                + JCRMailboxMessage.UID_PROPERTY + ">=" + from + " and @" + JCRMailboxMessage.UID_PROPERTY + "<=" + to
                + "] order by @" + JCRMailboxMessage.UID_PROPERTY;

        QueryManager manager = getSession().getWorkspace().getQueryManager();
        Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
        if (batchSize > 0) {
            query.setLimit(batchSize);
        }
        QueryResult result = query.execute();

        NodeIterator iterator = result.getNodes();
        while (iterator.hasNext()) {
            list.add(new JCRMailboxMessage(iterator.nextNode(), LOGGER));
        }
        return list;
    }

    private List findMessagesInMailbox(Mailbox mailbox, int batchSize)
            throws RepositoryException {
        List list = new ArrayList<>();

        String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message) order by @"
                + JCRMailboxMessage.UID_PROPERTY;
        QueryManager manager = getSession().getWorkspace().getQueryManager();
        Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
        if (batchSize > 0) {
            query.setLimit(batchSize);
        }
        QueryResult result = query.execute();

        NodeIterator iterator = result.getNodes();
        while (iterator.hasNext()) {
            list.add(new JCRMailboxMessage(iterator.nextNode(), LOGGER));
        }
        return list;
    }

    private List findDeletedMessagesInMailboxAfterUID(Mailbox mailbox, MessageUid from)
            throws RepositoryException {
        List list = new ArrayList<>();
        String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                + JCRMailboxMessage.UID_PROPERTY + ">=" + from + " and @" + JCRMailboxMessage.DELETED_PROPERTY + "='true'] order by @"
                + JCRMailboxMessage.UID_PROPERTY;

        QueryManager manager = getSession().getWorkspace().getQueryManager();
        QueryResult result = manager.createQuery(queryString, XPATH_LANGUAGE).execute();

        NodeIterator iterator = result.getNodes();
        while (iterator.hasNext()) {
            list.add(new JCRMailboxMessage(iterator.nextNode(), LOGGER));
        }
        return list;
    }

    private List findDeletedMessageInMailboxWithUID(Mailbox mailbox, MessageUid from)
            throws RepositoryException {
        List list = new ArrayList<>();
        String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                + JCRMailboxMessage.UID_PROPERTY + "=" + from + " and @" + JCRMailboxMessage.DELETED_PROPERTY + "='true']";
        QueryManager manager = getSession().getWorkspace().getQueryManager();
        Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
        query.setLimit(1);
        QueryResult result = query.execute();

        NodeIterator iterator = result.getNodes();
        while (iterator.hasNext()) {
            JCRMailboxMessage member = new JCRMailboxMessage(iterator.nextNode(), LOGGER);
            list.add(member);
        }
        return list;
    }

    private List findDeletedMessagesInMailboxBetweenUIDs(Mailbox mailbox, MessageUid from, MessageUid to)
            throws RepositoryException {
        List list = new ArrayList<>();
        String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                + JCRMailboxMessage.UID_PROPERTY + ">=" + from + " and @" + JCRMailboxMessage.UID_PROPERTY + "<=" + to + " and @"
                + JCRMailboxMessage.DELETED_PROPERTY + "='true'] order by @" + JCRMailboxMessage.UID_PROPERTY;

        QueryManager manager = getSession().getWorkspace().getQueryManager();
        QueryResult result = manager.createQuery(queryString, XPATH_LANGUAGE).execute();

        NodeIterator iterator = result.getNodes();
        while (iterator.hasNext()) {
            list.add(new JCRMailboxMessage(iterator.nextNode(), LOGGER));
        }
        return list;
    }

    private List findDeletedMessagesInMailbox(Mailbox mailbox) throws RepositoryException {

        List list = new ArrayList<>();
        String queryString = "/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)[@"
                + JCRMailboxMessage.DELETED_PROPERTY + "='true'] order by @" + JCRMailboxMessage.UID_PROPERTY;

        QueryManager manager = getSession().getWorkspace().getQueryManager();
        QueryResult result = manager.createQuery(queryString, XPATH_LANGUAGE).execute();

        NodeIterator iterator = result.getNodes();
        while (iterator.hasNext()) {
            JCRMailboxMessage member = new JCRMailboxMessage(iterator.nextNode(), LOGGER);
            list.add(member);
        }
        return list;
    }

    /**
     * Convert the given int value to a String. If the int value is smaller then
     * 9 it will prefix the String with 0.
     * 
     * @param value
     * @return stringValue
     */
    private String convertIntToString(int value) {
        if (value <= 9) {
            return "0" + String.valueOf(value);
        } else {
            return String.valueOf(value);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy