001    /***********************************************************************************************************************
002     *
003     * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail
004     * =======================================================================
005     *
006     * Copyright (C) 2014 by Hendrik Saly (http://saly.de)
007     * 
008     * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail)
009     *
010     ***********************************************************************************************************************
011     *
012     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
013     * the License. You may obtain a copy of the License at
014     *
015     *     http://www.apache.org/licenses/LICENSE-2.0
016     *
017     * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
018     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
019     * specific language governing permissions and limitations under the License.
020     *
021     ***********************************************************************************************************************
022     *
023     * $Id:$
024     *
025     **********************************************************************************************************************/
026    package de.saly.javamail.mock2;
027    
028    import java.io.IOException;
029    import java.io.InputStream;
030    import java.util.ArrayList;
031    import java.util.List;
032    import java.util.UUID;
033    
034    import javax.mail.FetchProfile;
035    import javax.mail.FolderClosedException;
036    import javax.mail.Message;
037    import javax.mail.MessagingException;
038    import javax.mail.MethodNotSupportedException;
039    import javax.mail.event.ConnectionEvent;
040    import javax.mail.event.MessageChangedEvent;
041    
042    import com.sun.mail.pop3.POP3MockFolder0;
043    
044    import de.saly.javamail.mock2.MailboxFolder.MailboxEventListener;
045    
046    public class POP3MockFolder extends POP3MockFolder0 implements MailboxEventListener {
047        private final MailboxFolder mailboxFolder;
048        private final UUID objectId = UUID.randomUUID();
049        private volatile boolean opened;
050        protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass());
051    
052        {
053            logger.warn("POP3 Mock Store in use");
054            System.out.println("POP3 Mock Store in use");
055        }
056    
057        protected POP3MockFolder(final POP3MockStore store, final MailboxFolder mailboxFolder) {
058            super(store);
059            this.mailboxFolder = mailboxFolder;
060            this.mailboxFolder.addMailboxEventListener(this);
061        }
062    
063        /*
064         * TODO superclass ok?
065        public Folder getParent(){
066            return null;
067        }
068          */
069    
070        @Override
071        public synchronized void close(final boolean expunge) throws MessagingException {
072            checkOpened();
073    
074            if (expunge) {
075                mailboxFolder.expunge();
076    
077            }
078    
079            opened = false;
080    
081            logger.debug("Folder closed " + objectId);
082            notifyConnectionListeners(ConnectionEvent.CLOSED);
083        }
084    
085        @Override
086        public void fetch(final Message[] msgs, final FetchProfile fp) throws MessagingException {
087            // just do nothing
088        }
089    
090        @Override
091        public void folderCreated(final MailboxFolder mf) {
092            // not valid for pop3
093    
094        }
095    
096        @Override
097        public void folderDeleted(final MailboxFolder mf) {
098            // not valid for pop3
099    
100        }
101    
102        @Override
103        public void folderRenamed(final String from, final MailboxFolder to) {
104            // not valid for pop3
105    
106        }
107    
108        @Override
109        public synchronized Message getMessage(final int msgnum) throws MessagingException {
110            checkOpened();
111            return new MockMessage(mailboxFolder.getByMsgNum(msgnum), this);
112        }
113    
114        @Override
115        public synchronized int getMessageCount() throws MessagingException {
116            return mailboxFolder.getMessageCount();
117        }
118    
119        @Override
120        public synchronized Message[] getMessages() throws MessagingException {
121            checkOpened();
122            final List<Message> messages = new ArrayList<Message>();
123            for (int i = 1; i <= mailboxFolder.getMessageCount(); i++) {
124                final Message m = mailboxFolder.getByMsgNum(i);
125                messages.add(new MockMessage(m, this));
126            }
127            return messages.toArray(new Message[messages.size()]);
128        }
129    
130        @Override
131        public synchronized Message[] getMessages(final int low, final int high) throws MessagingException {
132    
133            checkOpened();
134            final List<Message> messages = new ArrayList<Message>();
135            for (int i = low; i <= high; i++) {
136                final Message m = mailboxFolder.getByMsgNum(i);
137                messages.add(new MockMessage(m, this));
138            }
139            return messages.toArray(new Message[messages.size()]);
140        }
141    
142        @Override
143        public synchronized Message[] getMessages(final int[] msgnums) throws MessagingException {
144            checkOpened();
145    
146            final List<Integer> idlist = new ArrayList<Integer>();
147            for (final int value : msgnums) {
148                idlist.add(value);
149            }
150    
151            final List<Message> messages = new ArrayList<Message>();
152    
153            for (int i = 1; i <= mailboxFolder.getMessageCount(); i++) {
154    
155                if (!idlist.contains(new Integer(i))) {
156                    continue;
157                }
158    
159                final Message m = mailboxFolder.getByMsgNum(i);
160                messages.add(new MockMessage(m, this));
161            }
162            return messages.toArray(new Message[messages.size()]);
163        }
164    
165        @Override
166        public synchronized int getSize() throws MessagingException {
167            checkOpened();
168            return mailboxFolder.getSizeInBytes();
169        }
170    
171        @Override
172        public synchronized int[] getSizes() throws MessagingException {
173            checkOpened();
174            final int count = getMessageCount();
175            final int[] sizes = new int[count];
176    
177            for (int i = 1; i <= count; i++) {
178                sizes[i - 1] = getMessage(i).getSize();
179            }
180    
181            return sizes;
182    
183        }
184    
185        @Override
186        public synchronized String getUID(final Message msg) throws MessagingException {
187            checkOpened();
188            return String.valueOf(((MockMessage) msg).getMockid());
189        }
190    
191        @Override
192        public boolean isOpen() {
193            return opened;
194        }
195    
196        @Override
197        public InputStream listCommand() throws MessagingException, IOException {
198            throw new MethodNotSupportedException();
199        }
200    
201        @Override
202        public void messageAdded(final MailboxFolder mf, final MockMessage msg) {
203            // ignore
204            // TODO JavaMail impl seems to not fire a event here for pop3, so we
205            // ignore it
206    
207        }
208    
209        @Override
210        public void messageChanged(final MailboxFolder mf, final MockMessage msg, final boolean headerChanged, final boolean flagsChanged) {
211            notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, msg);
212    
213        }
214    
215        @Override
216        public void messageExpunged(final MailboxFolder mf, final MockMessage msg, final boolean removed) {
217            // not valid for pop3
218    
219        }
220    
221        @Override
222        public synchronized void open(final int mode) throws MessagingException {
223            checkClosed();
224            opened = true;
225            logger.debug("Open " + objectId);
226            notifyConnectionListeners(ConnectionEvent.OPENED);
227        }
228    
229        @Override
230        public void uidInvalidated() {
231            // not valid for pop3
232    
233        }
234    
235        protected synchronized void checkClosed() {
236            if (opened) {
237                throw new IllegalStateException("This operation is not allowed on an open folder " + objectId);
238            }
239        }
240    
241        protected synchronized void checkOpened() throws FolderClosedException {
242    
243            if (!opened) {
244    
245                throw new IllegalStateException("This operation is not allowed on a closed folder " + objectId);
246    
247            }
248        }
249    
250    }