001/****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one   *
003 * or more contributor license agreements.  See the NOTICE file *
004 * distributed with this work for additional information        *
005 * regarding copyright ownership.  The ASF licenses this file   *
006 * to you under the Apache License, Version 2.0 (the            *
007 * "License"); you may not use this file except in compliance   *
008 * with the License.  You may obtain a copy of the License at   *
009 *                                                              *
010 *   http://www.apache.org/licenses/LICENSE-2.0                 *
011 *                                                              *
012 * Unless required by applicable law or agreed to in writing,   *
013 * software distributed under the License is distributed on an  *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015 * KIND, either express or implied.  See the License for the    *
016 * specific language governing permissions and limitations      *
017 * under the License.                                           *
018 ****************************************************************/
019package org.apache.james.mailbox.copier;
020
021import java.io.IOException;
022import java.util.Calendar;
023import java.util.HashSet;
024import java.util.Iterator;
025import java.util.List;
026import java.util.Set;
027
028import javax.mail.Flags.Flag;
029
030import org.apache.james.mailbox.MailboxManager;
031import org.apache.james.mailbox.MailboxSession;
032import org.apache.james.mailbox.MessageManager;
033import org.apache.james.mailbox.exception.MailboxException;
034import org.apache.james.mailbox.exception.MailboxExistsException;
035import org.apache.james.mailbox.model.MailboxPath;
036import org.apache.james.mailbox.model.MessageRange;
037import org.apache.james.mailbox.model.MessageResult;
038import org.apache.james.mailbox.model.MessageResult.FetchGroup;
039import org.apache.james.mailbox.store.streaming.InputStreamContent;
040import org.slf4j.Logger;
041import org.slf4j.LoggerFactory;
042
043/**
044 * Implementation of the {@link MailboxCopier} interface.
045 * 
046 */
047public class MailboxCopierImpl implements MailboxCopier {
048
049    private final static FetchGroup GROUP = new FetchGroup() {
050
051        @Override
052        public int content() {
053            return FULL_CONTENT;
054        }
055
056        @Override
057        public Set<PartContentDescriptor> getPartContentDescriptors() {
058            return new HashSet<PartContentDescriptor>();
059        }
060        
061    };
062    
063    /**
064     * The logger.
065     */
066    private Logger log = LoggerFactory.getLogger(MailboxCopierImpl.class.getName());
067
068    /**
069     * @see org.apache.james.mailbox.copier.MailboxCopier#copyMailboxes(org.apache.james.mailbox.MailboxManager, org.apache.james.mailbox.MailboxManager)
070     */
071    public void copyMailboxes(MailboxManager srcMailboxManager, MailboxManager dstMailboxManager) throws MailboxException, IOException {
072        
073        Calendar start = Calendar.getInstance();
074
075        MailboxSession srcMailboxSession;
076        MailboxSession dstMailboxSession;
077
078        List<MailboxPath> mailboxPathList = null;
079
080        srcMailboxSession = srcMailboxManager.createSystemSession("manager", log);
081        srcMailboxManager.startProcessingRequest(srcMailboxSession);
082        mailboxPathList = srcMailboxManager.list(srcMailboxSession);
083        srcMailboxManager.endProcessingRequest(srcMailboxSession);
084
085        log.info("Found " + mailboxPathList.size() + " mailboxes in source mailbox manager.");
086        for (int i=0; i < mailboxPathList.size(); i++) {
087            log.info("Mailbox#" + i + " path=" + mailboxPathList.get(i));
088        }
089
090        MailboxPath mailboxPath = null;
091        
092        for (int i=0; i < mailboxPathList.size(); i++) {
093        
094            mailboxPath = mailboxPathList.get(i);
095            
096            if ((mailboxPath.getName() != null) && (mailboxPath.getName().trim().length() > 0)) {
097                
098                log.info("Ready to copy source mailbox path=" + mailboxPath.toString());
099
100                srcMailboxSession = srcMailboxManager.createSystemSession(mailboxPath.getUser(), log);
101                dstMailboxSession = dstMailboxManager.createSystemSession(mailboxPath.getUser(), log);
102
103                dstMailboxManager.startProcessingRequest(dstMailboxSession);
104                try {
105                    dstMailboxManager.createMailbox(mailboxPath, dstMailboxSession);
106                    log.info("Destination mailbox " + i + "/" + mailboxPathList.size() 
107                            + " created with path=" + mailboxPath.toString()
108                            + " after " + (Calendar.getInstance().getTimeInMillis() - start.getTimeInMillis()) + " ms.");
109                } catch (MailboxExistsException e) {
110                    log.error("Mailbox " + i + " with path=" + mailboxPath.toString() + " already exists.", e);
111                }
112                dstMailboxManager.endProcessingRequest(dstMailboxSession);
113
114                srcMailboxManager.startProcessingRequest(srcMailboxSession);
115                MessageManager srcMessageManager = srcMailboxManager.getMailbox(mailboxPath, srcMailboxSession);
116                srcMailboxManager.endProcessingRequest(srcMailboxSession);
117
118                dstMailboxManager.startProcessingRequest(dstMailboxSession);
119                MessageManager dstMessageManager = dstMailboxManager.getMailbox(mailboxPath, dstMailboxSession);
120
121                int j=0;
122                Iterator<MessageResult> messageResultIterator = srcMessageManager.getMessages(MessageRange.all(), GROUP, srcMailboxSession);
123                
124                while (messageResultIterator.hasNext()) {
125
126                    MessageResult messageResult = messageResultIterator.next();
127                    InputStreamContent content = (InputStreamContent) messageResult.getFullContent();
128
129                    dstMailboxManager.startProcessingRequest(dstMailboxSession);
130                    dstMessageManager.appendMessage(content.getInputStream(), messageResult.getInternalDate(), dstMailboxSession, messageResult.getFlags().contains(Flag.RECENT), messageResult.getFlags());
131                    dstMailboxManager.endProcessingRequest(dstMailboxSession);
132                    log.info("MailboxMessage #" + j + " appended in destination mailbox with path=" + mailboxPath.toString());
133                    j++;
134
135                }
136                dstMailboxManager.endProcessingRequest(dstMailboxSession);
137
138            }
139            
140            else {
141                
142                log.info("Destination mailbox " + i + "/" + mailboxPathList.size() 
143                        + " with path=" + mailboxPath.toString()
144                        + " has a null or empty name");
145
146            }
147
148        }
149
150        log.info("Mailboxes copied in " + (Calendar.getInstance().getTimeInMillis() - start.getTimeInMillis()) + " ms.");
151
152    }
153    
154    /**
155     * Set the logger.
156     * 
157     * @param log
158     */
159    public void setLog(Logger log) {
160        this.log = log;
161    }
162
163}