1 17 18 package org.apache.james.imapserver; 19 20 import org.apache.james.services.User; 21 import org.apache.james.imapserver.store.ImapStore; 22 import org.apache.james.imapserver.store.InMemoryStore; 23 import org.apache.james.imapserver.store.ImapMailbox; 24 import org.apache.james.imapserver.store.MailboxException; 25 import org.apache.james.imapserver.store.SimpleImapMessage; 26 import org.apache.james.imapserver.store.MessageFlags; 27 import org.apache.avalon.framework.logger.AbstractLogEnabled; 28 import org.apache.avalon.framework.logger.ConsoleLogger; 29 30 import javax.mail.search.SearchTerm ; 31 import javax.mail.internet.MimeMessage ; 32 import javax.mail.MessagingException ; 33 import java.util.ArrayList ; 34 import java.util.Collection ; 35 import java.util.Iterator ; 36 import java.util.StringTokenizer ; 37 import java.util.Map ; 38 import java.util.HashMap ; 39 import java.util.Date ; 40 41 49 public class JamesImapHost 50 extends AbstractLogEnabled 51 implements ImapHost, ImapConstants 52 { 53 private ImapStore store; 54 private MailboxSubscriptions subscriptions; 55 56 59 public JamesImapHost() 60 { 61 enableLogging( new ConsoleLogger() ); 62 store = new InMemoryStore(); 63 setupLogger( store ); 64 subscriptions = new MailboxSubscriptions(); 65 } 66 67 public JamesImapHost( ImapStore store ) 68 { 69 this.store = store; 70 subscriptions = new MailboxSubscriptions(); 71 } 72 73 public char getHierarchyDelimiter() 74 { 75 return HIERARCHY_DELIMITER_CHAR; 76 } 77 78 79 public ImapMailbox getMailbox( User user, String mailboxName ) 80 { 81 String name = getQualifiedMailboxName( user, mailboxName ); 82 ImapMailbox mailbox = store.getMailbox( name ); 83 return ( checkViewable( mailbox ) ); 84 } 85 86 public ImapMailbox getMailbox( User user, String mailboxName, boolean mustExist ) 87 throws MailboxException 88 { 89 ImapMailbox mailbox = getMailbox( user, mailboxName ); 90 if ( mustExist && mailbox == null ) 91 { 92 throw new MailboxException( "No such mailbox." ); 93 } 94 return mailbox; 95 } 96 97 private ImapMailbox checkViewable( ImapMailbox mailbox ) 98 { 99 return mailbox; 101 } 102 103 104 public ImapMailbox getInbox( User user ) throws MailboxException 105 { 106 return getMailbox( user, INBOX_NAME ); 107 } 108 109 110 public void createPrivateMailAccount( User user ) throws MailboxException 111 { 112 ImapMailbox root = store.getMailbox( USER_NAMESPACE ); 113 ImapMailbox userRoot = store.createMailbox( root, user.getUserName(), false ); 114 store.createMailbox( userRoot, INBOX_NAME, true ); 115 } 116 117 118 public ImapMailbox createMailbox( User user, String mailboxName ) 119 throws AuthorizationException, MailboxException 120 { 121 String qualifiedName = getQualifiedMailboxName( user, mailboxName ); 122 if ( store.getMailbox( qualifiedName ) != null ) 123 { 124 throw new MailboxException( "Mailbox already exists." ); 125 } 126 127 StringTokenizer tokens = new StringTokenizer ( qualifiedName, 128 HIERARCHY_DELIMITER ); 129 130 if ( tokens.countTokens() < 2 ) { 131 throw new MailboxException( "Cannot create mailbox at namespace level." ); 132 } 133 134 String namespaceRoot = tokens.nextToken(); 135 ImapMailbox mailbox = store.getMailbox( namespaceRoot ); 136 if ( mailbox == null ) { 137 throw new MailboxException( "Invalid namespace." ); 138 } 139 140 while ( tokens.hasMoreTokens() ) { 141 String childName = tokens.nextToken(); 143 ImapMailbox child = store.getMailbox( mailbox, childName ); 144 if ( child == null ) { 146 boolean makeSelectable = ( !tokens.hasMoreTokens() ); 148 child = store.createMailbox( mailbox, childName, makeSelectable ); 149 } 150 mailbox = child; 151 } 152 153 return mailbox; 154 } 155 156 157 public void deleteMailbox( User user, String mailboxName ) 158 throws MailboxException, AuthorizationException 159 { 160 ImapMailbox toDelete = getMailbox( user, mailboxName, true ); 161 162 if ( store.getChildren( toDelete ).isEmpty() ) { 163 long[] uids = toDelete.getMessageUids(); 164 for ( int i = 0; i < uids.length; i++ ) { 165 long uid = uids[i]; 166 SimpleImapMessage imapMessage = toDelete.getMessage( uid ); 167 toDelete.deleteMessage( imapMessage.getUid() ); 168 } 169 store.deleteMailbox( toDelete ); 170 } 171 else { 172 if ( toDelete.isSelectable() ) { 173 store.setSelectable( toDelete, false ); 175 } 176 else { 177 throw new MailboxException( "Can't delete a non-selectable mailbox with children." ); 178 } 179 } 180 } 181 182 183 public void renameMailbox( User user, 184 String oldMailboxName, 185 String newMailboxName ) 186 throws MailboxException, AuthorizationException 187 { 188 189 ImapMailbox existingMailbox = getMailbox( user, oldMailboxName, true ); 190 191 193 String userInboxName = getQualifiedMailboxName( user, INBOX_NAME ); 197 if ( userInboxName.equals( existingMailbox.getFullName() ) ) { 198 ImapMailbox newBox = createMailbox( user, newMailboxName ); 199 return; 201 } 202 203 store.renameMailbox( existingMailbox, newMailboxName ); 204 } 205 206 207 public Collection listSubscribedMailboxes( User user, 208 String mailboxPattern ) 209 throws MailboxException 210 { 211 return listMailboxes( user, mailboxPattern, true ); 212 } 213 214 215 public Collection listMailboxes( User user, 216 String mailboxPattern ) 217 throws MailboxException 218 { 219 return listMailboxes( user, mailboxPattern, false ); 220 } 221 222 228 private Collection listMailboxes( User user, 229 String mailboxPattern, 230 boolean subscribedOnly ) 231 throws MailboxException 232 { 233 236 ArrayList mailboxes = new ArrayList (); 237 String qualifiedPattern = getQualifiedMailboxName( user, mailboxPattern ); 238 239 Iterator iter = store.listMailboxes( qualifiedPattern ).iterator(); 240 while ( iter.hasNext() ) { 241 ImapMailbox mailbox = ( ImapMailbox ) iter.next(); 242 243 if ( subscribedOnly ) { 245 if ( ! subscriptions.isSubscribed( user, mailbox ) ) { 246 mailbox = null; 248 } 249 } 250 251 mailbox = checkViewable( mailbox ); 253 254 if ( mailbox != null ) { 255 mailboxes.add( mailbox ); 256 } 257 } 258 259 return mailboxes; 260 } 261 262 263 public void subscribe( User user, String mailboxName ) 264 throws MailboxException 265 { 266 ImapMailbox mailbox = getMailbox( user, mailboxName, true ); 267 subscriptions.subscribe( user, mailbox ); 268 } 269 270 271 public void unsubscribe( User user, String mailboxName ) 272 throws MailboxException 273 { 274 ImapMailbox mailbox = getMailbox( user, mailboxName, true ); 275 subscriptions.unsubscribe( user, mailbox ); 276 } 277 278 public int[] expunge( ImapMailbox mailbox ) 279 throws MailboxException 280 { 281 ArrayList deletedMessages = new ArrayList (); 282 283 long[] uids = mailbox.getMessageUids(); 284 for ( int i = 0; i < uids.length; i++ ) { 285 long uid = uids[i]; 286 SimpleImapMessage message = mailbox.getMessage( uid ); 287 if ( message.getFlags().isDeleted() ) { 288 deletedMessages.add( message ); 289 } 290 } 291 292 int[] ids = new int[ deletedMessages.size() ]; 293 for ( int i = 0; i < ids.length; i++ ) { 294 SimpleImapMessage imapMessage = ( SimpleImapMessage ) deletedMessages.get( i ); 295 long uid = imapMessage.getUid(); 296 int msn = mailbox.getMsn( uid ); 297 ids[i] = msn; 298 mailbox.deleteMessage( uid ); 299 } 300 301 return ids; 302 } 303 304 public long[] search( SearchTerm searchTerm, ImapMailbox mailbox ) 305 { 306 ArrayList matchedMessages = new ArrayList (); 307 308 long[] allUids = mailbox.getMessageUids(); 309 for ( int i = 0; i < allUids.length; i++ ) { 310 long uid = allUids[i]; 311 SimpleImapMessage message = mailbox.getMessage( uid ); 312 if ( searchTerm.match( message.getMimeMessage() ) ) { 313 matchedMessages.add( message ); 314 } 315 } 316 317 long[] matchedUids = new long[ matchedMessages.size() ]; 318 for ( int i = 0; i < matchedUids.length; i++ ) { 319 SimpleImapMessage imapMessage = ( SimpleImapMessage ) matchedMessages.get( i ); 320 long uid = imapMessage.getUid(); 321 matchedUids[i] = uid; 322 } 323 return matchedUids; 324 } 325 326 327 public void copyMessage( long uid, ImapMailbox currentMailbox, ImapMailbox toMailbox ) 328 throws MailboxException 329 { 330 SimpleImapMessage originalMessage = currentMailbox.getMessage( uid ); 331 MimeMessage newMime = null; 332 try { 333 newMime = new MimeMessage ( originalMessage.getMimeMessage() ); 334 } 335 catch ( MessagingException e ) { 336 throw new MailboxException( "Messaging exception: " + e.getMessage() ); 338 } 339 MessageFlags newFlags = new MessageFlags(); 340 newFlags.setAll( originalMessage.getFlags() ); 341 Date newDate = originalMessage.getInternalDate(); 342 343 toMailbox.createMessage( newMime, newFlags, newDate); 344 } 345 346 357 private String getQualifiedMailboxName( User user, String mailboxName ) 358 { 359 String userName = user.getUserName(); 360 361 if ( "INBOX".equalsIgnoreCase( mailboxName ) ) { 362 return USER_NAMESPACE + HIERARCHY_DELIMITER + userName + 363 HIERARCHY_DELIMITER + INBOX_NAME; 364 } 365 366 if ( mailboxName.startsWith( NAMESPACE_PREFIX ) ) { 367 return mailboxName; 368 } 369 else { 370 if ( mailboxName.length() == 0 ) { 371 return USER_NAMESPACE + HIERARCHY_DELIMITER + userName; 372 } 373 else { 374 return USER_NAMESPACE + HIERARCHY_DELIMITER + userName + 375 HIERARCHY_DELIMITER + mailboxName; 376 } 377 } 378 } 379 380 385 private class MailboxSubscriptions 386 { 387 private Map userSubs = new HashMap (); 388 389 396 void subscribe( User user, ImapMailbox mailbox ) 397 throws MailboxException 398 { 399 getUserSubs( user ).add( mailbox.getFullName() ); 400 } 401 402 409 void unsubscribe( User user, ImapMailbox mailbox ) 410 throws MailboxException 411 { 412 getUserSubs( user ).remove( mailbox.getFullName() ); 413 } 414 415 421 boolean isSubscribed( User user, ImapMailbox mailbox ) 422 { 423 return getUserSubs( user ).contains( mailbox.getFullName() ); 424 } 425 426 private Collection getUserSubs( User user ) 427 { 428 Collection subs = (Collection )userSubs.get( user.getUserName() ); 429 if ( subs == null ) { 430 subs = new ArrayList (); 431 userSubs.put( user.getUserName(), subs ); 432 } 433 return subs; 434 } 435 } 436 437 438 } 439 | Popular Tags |