KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > james > imapserver > store > InMemoryStore


1 /***********************************************************************
2  * Copyright (c) 2000-2004 The Apache Software Foundation. *
3  * All rights reserved. *
4  * ------------------------------------------------------------------- *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you *
6  * may not use this file except in compliance with the License. You *
7  * may obtain a copy of the License at: *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14  * implied. See the License for the specific language governing *
15  * permissions and limitations under the License. *
16  ***********************************************************************/

17
18 package org.apache.james.imapserver.store;
19
20 import org.apache.james.core.MailImpl;
21 import org.apache.james.imapserver.ImapConstants;
22 import org.apache.avalon.framework.logger.AbstractLogEnabled;
23 import org.apache.avalon.framework.logger.LogKitLogger;
24 import org.apache.avalon.framework.logger.ConsoleLogger;
25 import org.apache.log.Logger;
26
27 import javax.mail.internet.MimeMessage JavaDoc;
28 import javax.mail.search.SearchTerm JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.Collections JavaDoc;
32 import java.util.Date JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.StringTokenizer JavaDoc;
36 import java.util.TreeMap JavaDoc;
37
38 /**
39  * A simple in-memory implementation of {@link ImapStore}, used for testing
40  * and development. Note: this implementation does not persist *anything* to disk.
41  *
42  *
43  * @version $Revision: 1.4.2.3 $
44  */

45 public class InMemoryStore
46         extends AbstractLogEnabled
47         implements ImapStore, ImapConstants
48 {
49     private RootMailbox rootMailbox = new RootMailbox();
50     private static MessageFlags mailboxFlags = new MessageFlags();
51     static {
52         mailboxFlags.setAnswered( true );
53         mailboxFlags.setDeleted( true );
54         mailboxFlags.setDraft( true );
55         mailboxFlags.setFlagged( true );
56         mailboxFlags.setSeen( true );
57     }
58
59     public ImapMailbox getMailbox( String JavaDoc absoluteMailboxName )
60     {
61         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc( absoluteMailboxName, HIERARCHY_DELIMITER );
62
63         // The first token must be "#mail"
64
if ( !tokens.hasMoreTokens() ||
65                 !tokens.nextToken().equalsIgnoreCase( USER_NAMESPACE ) ) {
66             return null;
67         }
68
69         HierarchicalMailbox parent = rootMailbox;
70         while ( parent != null && tokens.hasMoreTokens() ) {
71             String JavaDoc childName = tokens.nextToken();
72             parent = parent.getChild( childName );
73         }
74         return parent;
75     }
76
77     public ImapMailbox getMailbox( ImapMailbox parent, String JavaDoc name )
78     {
79         return ( ( HierarchicalMailbox ) parent ).getChild( name );
80     }
81
82     public ImapMailbox createMailbox( ImapMailbox parent,
83                                       String JavaDoc mailboxName,
84                                       boolean selectable )
85             throws MailboxException
86     {
87         if ( mailboxName.indexOf( HIERARCHY_DELIMITER_CHAR ) != -1 ) {
88             throw new MailboxException( "Invalid mailbox name." );
89         }
90         HierarchicalMailbox castParent = ( HierarchicalMailbox ) parent;
91         HierarchicalMailbox child = new HierarchicalMailbox( castParent, mailboxName );
92         castParent.getChildren().add( child );
93         child.setSelectable( selectable );
94         return child;
95     }
96
97     public void deleteMailbox( ImapMailbox mailbox ) throws MailboxException
98     {
99         HierarchicalMailbox toDelete = ( HierarchicalMailbox ) mailbox;
100
101         if ( !toDelete.getChildren().isEmpty() ) {
102             throw new MailboxException( "Cannot delete mailbox with children." );
103         }
104
105         if ( toDelete.getMessageCount() != 0 ) {
106             throw new MailboxException( "Cannot delete non-empty mailbox" );
107         }
108
109         HierarchicalMailbox parent = toDelete.getParent();
110         parent.getChildren().remove( toDelete );
111     }
112
113     public void renameMailbox( ImapMailbox existingMailbox, String JavaDoc newName ) throws MailboxException
114     {
115         HierarchicalMailbox toRename = ( HierarchicalMailbox ) existingMailbox;
116         toRename.setName( newName );
117     }
118
119     public Collection JavaDoc getChildren( ImapMailbox parent )
120     {
121         Collection JavaDoc children = ( ( HierarchicalMailbox ) parent ).getChildren();
122         return Collections.unmodifiableCollection( children );
123     }
124
125     public ImapMailbox setSelectable( ImapMailbox mailbox, boolean selectable )
126     {
127         ( ( HierarchicalMailbox ) mailbox ).setSelectable( selectable );
128         return mailbox;
129     }
130
131     /** @see org.apache.james.imapserver.store.ImapStore#listMailboxes */
132     public Collection JavaDoc listMailboxes( String JavaDoc searchPattern )
133             throws MailboxException
134     {
135         int starIndex = searchPattern.indexOf( '*' );
136         int percentIndex = searchPattern.indexOf( '%' );
137
138         // We only handle wildcard at the end of the search pattern.
139
if ( ( starIndex > -1 && starIndex < searchPattern.length() - 1 ) ||
140                 ( percentIndex > -1 && percentIndex < searchPattern.length() - 1 ) ) {
141             throw new MailboxException( "WIldcard characters are only handled as the last character of a list argument." );
142         }
143
144         ArrayList JavaDoc mailboxes = new ArrayList JavaDoc();
145         if ( starIndex != -1 || percentIndex != -1 ) {
146             int lastDot = searchPattern.lastIndexOf( HIERARCHY_DELIMITER );
147             String JavaDoc parentName = searchPattern.substring( 0, lastDot );
148             String JavaDoc matchPattern = searchPattern.substring( lastDot + 1, searchPattern.length() - 1 );
149
150             HierarchicalMailbox parent = ( HierarchicalMailbox ) getMailbox( parentName );
151             // If the parent from the search pattern doesn't exist,
152
// return empty.
153
if ( parent != null ) {
154                 Iterator JavaDoc children = parent.getChildren().iterator();
155                 while ( children.hasNext() ) {
156                     HierarchicalMailbox child = ( HierarchicalMailbox ) children.next();
157                     if ( child.getName().startsWith( matchPattern ) ) {
158                         mailboxes.add( child );
159
160                         if ( starIndex != -1 ) {
161                             addAllChildren( child, mailboxes );
162                         }
163                     }
164                 }
165             }
166
167         }
168         else {
169             ImapMailbox mailbox = getMailbox( searchPattern );
170             if ( mailbox != null ) {
171                 mailboxes.add( mailbox );
172             }
173         }
174
175         return mailboxes;
176     }
177
178     private void addAllChildren( HierarchicalMailbox mailbox, Collection JavaDoc mailboxes )
179     {
180         Collection JavaDoc children = mailbox.getChildren();
181         Iterator JavaDoc iterator = children.iterator();
182         while ( iterator.hasNext() ) {
183             HierarchicalMailbox child = ( HierarchicalMailbox ) iterator.next();
184             mailboxes.add( child );
185             addAllChildren( child, mailboxes );
186         }
187     }
188
189     private class RootMailbox extends HierarchicalMailbox
190     {
191         public RootMailbox()
192         {
193             super( null, ImapConstants.USER_NAMESPACE );
194         }
195
196         public String JavaDoc getFullName()
197         {
198             return name;
199         }
200     }
201
202     private class HierarchicalMailbox implements ImapMailbox
203     {
204         private Collection JavaDoc children;
205         private HierarchicalMailbox parent;
206
207         protected String JavaDoc name;
208         private boolean isSelectable = false;
209
210         private Map JavaDoc mailMessages = new TreeMap JavaDoc();
211         private long nextUid = 10;
212         private long uidValidity;
213
214         public HierarchicalMailbox( HierarchicalMailbox parent,
215                                     String JavaDoc name )
216         {
217             this.name = name;
218             this.children = new ArrayList JavaDoc();
219             this.parent = parent;
220             this.uidValidity = System.currentTimeMillis();
221         }
222
223         public Collection JavaDoc getChildren()
224         {
225             return children;
226         }
227
228         public HierarchicalMailbox getParent()
229         {
230             return parent;
231         }
232
233         public HierarchicalMailbox getChild( String JavaDoc name )
234         {
235             Iterator JavaDoc iterator = children.iterator();
236             while ( iterator.hasNext() ) {
237                 HierarchicalMailbox child = ( HierarchicalMailbox ) iterator.next();
238                 if ( child.getName().equalsIgnoreCase( name ) ) {
239                     return child;
240                 }
241             }
242             return null;
243         }
244
245         public void setName( String JavaDoc name )
246         {
247             this.name = name;
248         }
249
250         public String JavaDoc getName()
251         {
252             return name;
253         }
254
255         public String JavaDoc getFullName()
256         {
257             return parent.getFullName() + HIERARCHY_DELIMITER_CHAR + name;
258         }
259
260         public MessageFlags getAllowedFlags()
261         {
262             return mailboxFlags;
263         }
264
265         public int getMessageCount()
266         {
267             return mailMessages.size();
268         }
269
270         public long getUidValidity()
271         {
272             return uidValidity;
273         }
274
275         public long getUidNext()
276         {
277             return nextUid;
278         }
279
280         public int getUnseenCount()
281         {
282             return 0;
283         }
284
285         public int getFirstUnseen()
286         {
287             return 0;
288         }
289
290         public int getRecentCount()
291         {
292             return 0;
293         }
294
295         public int getMsn( long uid ) throws MailboxException
296         {
297             Collection JavaDoc keys = mailMessages.keySet();
298             Iterator JavaDoc iterator = keys.iterator();
299             for ( int msn = 1; iterator.hasNext(); msn++ ) {
300                 Long JavaDoc messageUid = ( Long JavaDoc ) iterator.next();
301                 if ( messageUid.longValue() == uid ) {
302                     return msn;
303                 }
304             }
305             throw new MailboxException( "No such message." );
306         }
307
308         public boolean isSelectable()
309         {
310             return isSelectable;
311         }
312
313         public void setSelectable( boolean selectable )
314         {
315             isSelectable = selectable;
316         }
317
318         public SimpleImapMessage createMessage( MimeMessage JavaDoc message,
319                                           MessageFlags flags,
320                                           Date JavaDoc internalDate )
321         {
322             long uid = nextUid;
323             nextUid+=10;
324
325             SimpleImapMessage imapMessage = new SimpleImapMessage( message, flags,
326                                                        internalDate, uid );
327             setupLogger( imapMessage );
328
329             mailMessages.put( new Long JavaDoc( uid ), imapMessage );
330             return imapMessage;
331         }
332
333         public void updateMessage( SimpleImapMessage message )
334                 throws MailboxException
335         {
336
337             Long JavaDoc key = new Long JavaDoc( message.getUid() );
338             if ( ! mailMessages.containsKey( key ) ) {
339                 throw new MailboxException( "Message doesn't exist" );
340             }
341             mailMessages.put( key, message );
342         }
343
344         public void store( MailImpl mail )
345                 throws Exception JavaDoc
346         {
347             MimeMessage JavaDoc message = mail.getMessage();
348             Date JavaDoc internalDate = new Date JavaDoc();
349             MessageFlags flags = new MessageFlags();
350             createMessage( message, flags, internalDate );
351         }
352
353         public SimpleImapMessage getMessage( long uid )
354         {
355             return (SimpleImapMessage)mailMessages.get( new Long JavaDoc(uid ) );
356         }
357
358         public long[] getMessageUids()
359         {
360             long[] uids = new long[ mailMessages.size() ];
361             Collection JavaDoc keys = mailMessages.keySet();
362             Iterator JavaDoc iterator = keys.iterator();
363             for ( int i = 0; iterator.hasNext(); i++ ) {
364                 Long JavaDoc key = ( Long JavaDoc ) iterator.next();
365                 uids[i] = key.longValue();
366             }
367             return uids;
368         }
369
370         public void deleteMessage( long uid )
371         {
372             mailMessages.remove( new Long JavaDoc( uid ) );
373         }
374
375     }
376 }
377
Popular Tags