1 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 ; 28 import javax.mail.search.SearchTerm ; 29 import java.util.ArrayList ; 30 import java.util.Collection ; 31 import java.util.Collections ; 32 import java.util.Date ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.StringTokenizer ; 36 import java.util.TreeMap ; 37 38 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 absoluteMailboxName ) 60 { 61 StringTokenizer tokens = new StringTokenizer ( absoluteMailboxName, HIERARCHY_DELIMITER ); 62 63 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 childName = tokens.nextToken(); 72 parent = parent.getChild( childName ); 73 } 74 return parent; 75 } 76 77 public ImapMailbox getMailbox( ImapMailbox parent, String name ) 78 { 79 return ( ( HierarchicalMailbox ) parent ).getChild( name ); 80 } 81 82 public ImapMailbox createMailbox( ImapMailbox parent, 83 String 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 newName ) throws MailboxException 114 { 115 HierarchicalMailbox toRename = ( HierarchicalMailbox ) existingMailbox; 116 toRename.setName( newName ); 117 } 118 119 public Collection getChildren( ImapMailbox parent ) 120 { 121 Collection 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 132 public Collection listMailboxes( String searchPattern ) 133 throws MailboxException 134 { 135 int starIndex = searchPattern.indexOf( '*' ); 136 int percentIndex = searchPattern.indexOf( '%' ); 137 138 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 mailboxes = new ArrayList (); 145 if ( starIndex != -1 || percentIndex != -1 ) { 146 int lastDot = searchPattern.lastIndexOf( HIERARCHY_DELIMITER ); 147 String parentName = searchPattern.substring( 0, lastDot ); 148 String matchPattern = searchPattern.substring( lastDot + 1, searchPattern.length() - 1 ); 149 150 HierarchicalMailbox parent = ( HierarchicalMailbox ) getMailbox( parentName ); 151 if ( parent != null ) { 154 Iterator 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 mailboxes ) 179 { 180 Collection children = mailbox.getChildren(); 181 Iterator 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 getFullName() 197 { 198 return name; 199 } 200 } 201 202 private class HierarchicalMailbox implements ImapMailbox 203 { 204 private Collection children; 205 private HierarchicalMailbox parent; 206 207 protected String name; 208 private boolean isSelectable = false; 209 210 private Map mailMessages = new TreeMap (); 211 private long nextUid = 10; 212 private long uidValidity; 213 214 public HierarchicalMailbox( HierarchicalMailbox parent, 215 String name ) 216 { 217 this.name = name; 218 this.children = new ArrayList (); 219 this.parent = parent; 220 this.uidValidity = System.currentTimeMillis(); 221 } 222 223 public Collection getChildren() 224 { 225 return children; 226 } 227 228 public HierarchicalMailbox getParent() 229 { 230 return parent; 231 } 232 233 public HierarchicalMailbox getChild( String name ) 234 { 235 Iterator 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 name ) 246 { 247 this.name = name; 248 } 249 250 public String getName() 251 { 252 return name; 253 } 254 255 public String 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 keys = mailMessages.keySet(); 298 Iterator iterator = keys.iterator(); 299 for ( int msn = 1; iterator.hasNext(); msn++ ) { 300 Long messageUid = ( Long ) 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 message, 319 MessageFlags flags, 320 Date 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 ( uid ), imapMessage ); 330 return imapMessage; 331 } 332 333 public void updateMessage( SimpleImapMessage message ) 334 throws MailboxException 335 { 336 337 Long key = new Long ( 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 346 { 347 MimeMessage message = mail.getMessage(); 348 Date internalDate = new Date (); 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 (uid ) ); 356 } 357 358 public long[] getMessageUids() 359 { 360 long[] uids = new long[ mailMessages.size() ]; 361 Collection keys = mailMessages.keySet(); 362 Iterator iterator = keys.iterator(); 363 for ( int i = 0; iterator.hasNext(); i++ ) { 364 Long key = ( Long ) 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 ( uid ) ); 373 } 374 375 } 376 } 377 | Popular Tags |