Source Code Cross Referenced for Folder.java in  » EJB-Server-GlassFish » mail » javax » mail » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server GlassFish » mail » javax.mail 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common Development
0008:         * and Distribution License("CDDL") (collectively, the "License").  You
0009:         * may not use this file except in compliance with the License. You can obtain
0010:         * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
0011:         * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
0012:         * language governing permissions and limitations under the License.
0013:         *
0014:         * When distributing the software, include this License Header Notice in each
0015:         * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
0016:         * Sun designates this particular file as subject to the "Classpath" exception
0017:         * as provided by Sun in the GPL Version 2 section of the License file that
0018:         * accompanied this code.  If applicable, add the following below the License
0019:         * Header, with the fields enclosed by brackets [] replaced by your own
0020:         * identifying information: "Portions Copyrighted [year]
0021:         * [name of copyright owner]"
0022:         *
0023:         * Contributor(s):
0024:         *
0025:         * If you wish your version of this file to be governed by only the CDDL or
0026:         * only the GPL Version 2, indicate your decision by adding "[Contributor]
0027:         * elects to include this software in this distribution under the [CDDL or GPL
0028:         * Version 2] license."  If you don't indicate a single choice of license, a
0029:         * recipient has the option to distribute your version of this file under
0030:         * either the CDDL, the GPL Version 2 or to extend the choice of license to
0031:         * its licensees as provided above.  However, if you add GPL Version 2 code
0032:         * and therefore, elected the GPL Version 2 license, then the option applies
0033:         * only if the new code is made subject to such option by the copyright
0034:         * holder.
0035:         */
0036:
0037:        /*
0038:         * @(#)Folder.java	1.58 07/05/04
0039:         */
0040:
0041:        package javax.mail;
0042:
0043:        import java.io.*;
0044:        import java.lang.*;
0045:        import java.util.Vector;
0046:        import java.util.StringTokenizer;
0047:        import javax.mail.search.SearchTerm;
0048:        import javax.mail.event.*;
0049:
0050:        /**
0051:         * Folder is an abstract class that represents a folder for mail
0052:         * messages. Subclasses implement protocol specific Folders.<p>
0053:         *
0054:         * Folders can contain Messages, other Folders or both, thus providing
0055:         * a tree-like hierarchy rooted at the Store's default folder. (Note 
0056:         * that some Folder implementations may not allow both Messages and 
0057:         * other Folders in the same Folder).<p>
0058:         *
0059:         * The interpretation of folder names is implementation dependent.
0060:         * The different levels of hierarchy in a folder's full name
0061:         * are separated from each other by the hierarchy delimiter 
0062:         * character.<p>
0063:         *
0064:         * The case-insensitive full folder name (that is, the full name
0065:         * relative to the default folder for a Store) <strong>INBOX</strong>
0066:         * is reserved to mean the "primary folder for this user on this
0067:         * server".  Not all Stores will provide an INBOX folder, and not
0068:         * all users will have an INBOX folder at all times.  The name
0069:         * <strong>INBOX</strong> is reserved to refer to this folder,
0070:         * when it exists, in Stores that provide it. <p>
0071:         *
0072:         * A Folder object obtained from a Store need not actually exist
0073:         * in the backend store. The <code>exists</code> method tests whether
0074:         * the folder exists or not. The <code>create</code> method
0075:         * creates a Folder. <p>
0076:         *
0077:         * A Folder is initially in the closed state. Certain methods are valid
0078:         * in this state; the documentation for those methods note this.  A
0079:         * Folder is opened by calling its 'open' method. All Folder methods,
0080:         * except <code>open</code>, <code>delete</code> and 
0081:         * <code>renameTo</code>, are valid in this state. <p>
0082:         *
0083:         * The only way to get a Folder is by invoking the 
0084:         * <code>getFolder</code> method on Store, Folder, or Session, or by invoking 
0085:         * the <code>list</code> or <code>listSubscribed</code> methods 
0086:         * on Folder. Folder objects returned by the above methods are not 
0087:         * cached by the Store. Thus, invoking the <code>getFolder</code> method
0088:         * with the same folder name multiple times will return distinct Folder 
0089:         * objects.  Likewise for the <code>list</code> and <code>listSubscribed</code>
0090:         * methods. <p>
0091:         *
0092:         * The Message objects within the Folder are cached by the Folder.
0093:         * Thus, invoking <code>getMessage(msgno)</code> on the same message number
0094:         * multiple times will return the same Message object, until an 
0095:         * expunge is done on this Folder. <p>
0096:         *
0097:         * Note that a Message's message number can change within a
0098:         * session if the containing Folder is expunged using the expunge
0099:         * method.  Clients that use message numbers as references to messages
0100:         * should be aware of this and should be prepared to deal with 
0101:         * situation (probably by flushing out existing message number references
0102:         * and reloading them). Because of this complexity, it is better for
0103:         * clients to use Message objects as references to messages, rather than
0104:         * message numbers. Expunged Message objects still have to be
0105:         * pruned, but other Message objects in that folder are not affected by the 
0106:         * expunge.
0107:         *
0108:         * @author John Mani
0109:         * @author Bill Shannon
0110:         */
0111:
0112:        public abstract class Folder {
0113:
0114:            /**
0115:             * The parent store.
0116:             */
0117:            protected Store store;
0118:
0119:            /**
0120:             * The open mode of this folder.  The open mode is
0121:             * <code>Folder.READ_ONLY</code>, <code>Folder.READ_WRITE</code>,
0122:             * or -1 if not known.
0123:             * @since	JavaMail 1.1
0124:             */
0125:            protected int mode = -1;
0126:
0127:            /**
0128:             * Constructor that takes a Store object.
0129:             *
0130:             * @param store the Store that holds this folder
0131:             */
0132:            protected Folder(Store store) {
0133:                this .store = store;
0134:            }
0135:
0136:            /**
0137:             * Returns the name of this Folder. <p>
0138:             *
0139:             * This method can be invoked on a closed Folder.
0140:             *
0141:             * @return		name of the Folder
0142:             */
0143:            public abstract String getName();
0144:
0145:            /**
0146:             * Returns the full name of this Folder. If the folder resides under
0147:             * the root hierarchy of this Store, the returned name is relative
0148:             * to the root. Otherwise an absolute name, starting with the 
0149:             * hierarchy delimiter, is returned. <p>
0150:             *
0151:             * This method can be invoked on a closed Folder.
0152:             *
0153:             * @return		full name of the Folder
0154:             */
0155:            public abstract String getFullName();
0156:
0157:            /**
0158:             * Return a URLName representing this folder.  The returned URLName
0159:             * does <em>not</em> include the password used to access the store.
0160:             *
0161:             * @return	the URLName representing this folder
0162:             * @see	URLName
0163:             * @since	JavaMail 1.1
0164:             */
0165:            public URLName getURLName() throws MessagingException {
0166:                URLName storeURL = getStore().getURLName();
0167:                String fullname = getFullName();
0168:                StringBuffer encodedName = new StringBuffer();
0169:                char separator = getSeparator();
0170:
0171:                if (fullname != null) {
0172:                    /*
0173:                    // We need to encode each of the folder's names.
0174:                    StringTokenizer tok = new StringTokenizer(
0175:                    fullname, new Character(separator).toString(), true);
0176:
0177:                    while (tok.hasMoreTokens()) {
0178:                    String s = tok.nextToken();
0179:                    if (s.charAt(0) == separator)
0180:                        encodedName.append(separator);
0181:                    else
0182:                        // XXX - should encode, but since there's no decoder...
0183:                        //encodedName.append(java.net.URLEncoder.encode(s));
0184:                        encodedName.append(s);
0185:                    }
0186:                     */
0187:                    // append the whole thing, until we can encode
0188:                    encodedName.append(fullname);
0189:                }
0190:
0191:                /*
0192:                 * Sure would be convenient if URLName had a
0193:                 * constructor that took a base URLName.
0194:                 */
0195:                return new URLName(storeURL.getProtocol(), storeURL.getHost(),
0196:                        storeURL.getPort(), encodedName.toString(), storeURL
0197:                                .getUsername(), null /* no password */);
0198:            }
0199:
0200:            /**
0201:             * Returns the Store that owns this Folder object.
0202:             * This method can be invoked on a closed Folder.
0203:             * @return 		the Store
0204:             */
0205:            public Store getStore() {
0206:                return store;
0207:            }
0208:
0209:            /**
0210:             * Returns the parent folder of this folder.
0211:             * This method can be invoked on a closed Folder. If this folder
0212:             * is the top of a folder hierarchy, this method returns null. <p>
0213:             *
0214:             * Note that since Folder objects are not cached, invoking this method
0215:             * returns a new distinct Folder object.
0216:             *
0217:             * @return		Parent folder
0218:             */
0219:            public abstract Folder getParent() throws MessagingException;
0220:
0221:            /**
0222:             * Tests if this folder physically exists on the Store.
0223:             * This method can be invoked on a closed Folder.
0224:             *
0225:             * @return true if the folder exists, otherwise false
0226:             * @see    #create
0227:             * @exception	MessagingException typically if the connection 
0228:             *			to the server is lost.
0229:             */
0230:            public abstract boolean exists() throws MessagingException;
0231:
0232:            /**
0233:             * Returns a list of Folders belonging to this Folder's namespace
0234:             * that match the specified pattern. Patterns may contain the wildcard
0235:             * characters <code>"%"</code>, which matches any character except hierarchy
0236:             * delimiters, and <code>"*"</code>, which matches any character. <p>
0237:             *
0238:             * As an example, given the folder hierarchy: <pre>
0239:             *    Personal/
0240:             *       Finance/
0241:             *          Stocks
0242:             *          Bonus
0243:             *          StockOptions
0244:             *       Jokes
0245:             * </pre>
0246:             * <code>list("*")</code> on "Personal" will return the whole 
0247:             * hierarchy. <br>
0248:             * <code>list("%")</code> on "Personal" will return "Finance" and 
0249:             * "Jokes". <br>
0250:             * <code>list("Jokes")</code> on "Personal" will return "Jokes".<br>
0251:             * <code>list("Stock*")</code> on "Finance" will return "Stocks"
0252:             * and "StockOptions". <p>
0253:             *
0254:             * Folder objects are not cached by the Store, so invoking this
0255:             * method on the same pattern multiple times will return that many
0256:             * distinct Folder objects. <p>
0257:             *
0258:             * This method can be invoked on a closed Folder.
0259:             *
0260:             * @param pattern	the match pattern
0261:             * @return		array of matching Folder objects. An empty
0262:             *			array is returned if no matching Folders exist.
0263:             * @see 		#listSubscribed
0264:             * @exception 	FolderNotFoundException if this folder does 
0265:             *			not exist.
0266:             * @exception 	MessagingException
0267:             */
0268:            public abstract Folder[] list(String pattern)
0269:                    throws MessagingException;
0270:
0271:            /**
0272:             * Returns a list of subscribed Folders belonging to this Folder's
0273:             * namespace that match the specified pattern. If the folder does
0274:             * not support subscription, this method should resolve to
0275:             * <code>list</code>.
0276:             * (The default implementation provided here, does just this).
0277:             * The pattern can contain wildcards as for <code>list</code>. <p>
0278:             *
0279:             * Note that, at a given level of the folder hierarchy, a particular
0280:             * folder may not be subscribed, but folders underneath that folder
0281:             * in the folder hierarchy may be subscribed.  In order to allow
0282:             * walking the folder hierarchy, such unsubscribed folders may be
0283:             * returned, indicating that a folder lower in the hierarchy is
0284:             * subscribed.  The <code>isSubscribed</code> method on a folder will
0285:             * tell whether any particular folder is actually subscribed. <p>
0286:             *
0287:             * Folder objects are not cached by the Store, so invoking this
0288:             * method on the same pattern multiple times will return that many
0289:             * distinct Folder objects. <p>
0290:             *
0291:             * This method can be invoked on a closed Folder.
0292:             *
0293:             * @param pattern	the match pattern
0294:             * @return		array of matching subscribed Folder objects. An
0295:             *			empty array is returned if no matching
0296:             *			subscribed folders exist.
0297:             * @see 		#list
0298:             * @exception 	FolderNotFoundException if this folder does
0299:             *			not exist.
0300:             * @exception 	MessagingException
0301:             */
0302:            public Folder[] listSubscribed(String pattern)
0303:                    throws MessagingException {
0304:                return list(pattern);
0305:            }
0306:
0307:            /**
0308:             * Convenience method that returns the list of folders under this
0309:             * Folder. This method just calls the <code>list(String pattern)</code>
0310:             * method with <code>"%"</code> as the match pattern. This method can
0311:             * be invoked on a closed Folder.
0312:             *
0313:             * @return		array of Folder objects under this Folder. An
0314:             *			empty array is returned if no subfolders exist.
0315:             * @see		#list
0316:             * @exception 	FolderNotFoundException if this folder does
0317:             *			not exist.
0318:             * @exception 	MessagingException
0319:             */
0320:
0321:            public Folder[] list() throws MessagingException {
0322:                return list("%");
0323:            }
0324:
0325:            /**
0326:             * Convenience method that returns the list of subscribed folders 
0327:             * under this Folder. This method just calls the
0328:             * <code>listSubscribed(String pattern)</code> method with <code>"%"</code>
0329:             * as the match pattern. This method can be invoked on a closed Folder.
0330:             *
0331:             * @return		array of subscribed Folder objects under this 
0332:             *			Folder. An empty array is returned if no subscribed 
0333:             *			subfolders exist.
0334:             * @see		#listSubscribed
0335:             * @exception 	FolderNotFoundException if this folder does
0336:             *			not exist.
0337:             * @exception 	MessagingException
0338:             */
0339:            public Folder[] listSubscribed() throws MessagingException {
0340:                return listSubscribed("%");
0341:            }
0342:
0343:            /**
0344:             * Return the delimiter character that separates this Folder's pathname
0345:             * from the names of immediate subfolders. This method can be invoked 
0346:             * on a closed Folder.
0347:             *
0348:             * @exception 	FolderNotFoundException if the implementation
0349:             *			requires the folder to exist, but it does not
0350:             * @return          Hierarchy separator character
0351:             */
0352:            public abstract char getSeparator() throws MessagingException;
0353:
0354:            /**
0355:             * This folder can contain messages
0356:             */
0357:            public final static int HOLDS_MESSAGES = 0x01;
0358:
0359:            /**
0360:             * This folder can contain other folders
0361:             */
0362:            public final static int HOLDS_FOLDERS = 0x02;
0363:
0364:            /**
0365:             * Returns the type of this Folder, that is, whether this folder can hold
0366:             * messages or subfolders or both. The returned value is an integer
0367:             * bitfield with the appropriate bits set. This method can be invoked
0368:             * on a closed folder.
0369:             * 
0370:             * @return 		integer with appropriate bits set
0371:             * @exception 	FolderNotFoundException if this folder does 
0372:             *			not exist.
0373:             * @see 		#HOLDS_FOLDERS 
0374:             * @see		#HOLDS_MESSAGES
0375:             */
0376:            public abstract int getType() throws MessagingException;
0377:
0378:            /**
0379:             * Create this folder on the Store. When this folder is created, any
0380:             * folders in its path that do not exist are also created. <p>
0381:             *
0382:             * If the creation is successful, a CREATED FolderEvent is delivered
0383:             * to any FolderListeners registered on this Folder and this Store.
0384:             *
0385:             * @param  type	The type of this folder. 
0386:             *
0387:             * @return		true if the creation succeeds, else false.
0388:             * @exception 	MessagingException  
0389:             * @see 		#HOLDS_FOLDERS
0390:             * @see		#HOLDS_MESSAGES
0391:             * @see		javax.mail.event.FolderEvent
0392:             */
0393:            public abstract boolean create(int type) throws MessagingException;
0394:
0395:            /**
0396:             * Returns true if this Folder is subscribed. <p>
0397:             *
0398:             * This method can be invoked on a closed Folder. <p>
0399:             *
0400:             * The default implementation provided here just returns true.
0401:             *
0402:             * @return		true if this Folder is subscribed
0403:             */
0404:            public boolean isSubscribed() {
0405:                return true;
0406:            }
0407:
0408:            /**
0409:             * Subscribe or unsubscribe this Folder. Not all Stores support
0410:             * subscription. <p>
0411:             *
0412:             * This method can be invoked on a closed Folder. <p>
0413:             *
0414:             * The implementation provided here just throws the
0415:             * MethodNotSupportedException.
0416:             *
0417:             * @param subscribe	true to subscribe, false to unsubscribe
0418:             * @exception 	FolderNotFoundException if this folder does
0419:             *			not exist.
0420:             * @exception 	MethodNotSupportedException if this store
0421:             *			does not support subscription
0422:             * @exception 	MessagingException
0423:             */
0424:            public void setSubscribed(boolean subscribe)
0425:                    throws MessagingException {
0426:                throw new MethodNotSupportedException();
0427:            }
0428:
0429:            /**
0430:             * Returns true if this Folder has new messages since the last time
0431:             * this indication was reset.  When this indication is set or reset
0432:             * depends on the Folder implementation (and in the case of IMAP,
0433:             * depends on the server).  This method can be used to implement
0434:             * a lightweight "check for new mail" operation on a Folder without
0435:             * opening it.  (For example, a thread that monitors a mailbox and
0436:             * flags when it has new mail.)  This method should indicate whether
0437:             * any messages in the Folder have the <code>RECENT</code> flag set. <p>
0438:             *
0439:             * Note that this is not an incremental check for new mail, i.e.,
0440:             * it cannot be used to determine whether any new messages have
0441:             * arrived since the last time this method was invoked. To
0442:             * implement incremental checks, the Folder needs to be opened. <p>
0443:             *
0444:             * This method can be invoked on a closed Folder that can contain
0445:             * Messages.
0446:             *
0447:             * @return		true if the Store has new Messages
0448:             * @exception	FolderNotFoundException if this folder does
0449:             *			not exist.
0450:             * @exception 	MessagingException
0451:             */
0452:            public abstract boolean hasNewMessages() throws MessagingException;
0453:
0454:            /**
0455:             * Return the Folder object corresponding to the given name. Note that
0456:             * this folder does not physically have to exist in the Store. The
0457:             * <code>exists()</code> method on a Folder indicates whether it really
0458:             * exists on the Store. <p>
0459:             *
0460:             * In some Stores, name can be an absolute path if it starts with the
0461:             * hierarchy delimiter.  Otherwise, it is interpreted relative to
0462:             * this Folder. <p>
0463:             *
0464:             * Folder objects are not cached by the Store, so invoking this
0465:             * method on the same name multiple times will return that many
0466:             * distinct Folder objects. <p>
0467:             *
0468:             * This method can be invoked on a closed Folder.
0469:             *
0470:             * @param name 	name of the Folder
0471:             * @return		Folder object
0472:             * @exception 	MessagingException
0473:             */
0474:            public abstract Folder getFolder(String name)
0475:                    throws MessagingException;
0476:
0477:            /**
0478:             * Delete this Folder. This method will succeed only on a closed
0479:             * Folder. <p>
0480:             *
0481:             * The <code>recurse</code> flag controls whether the deletion affects
0482:             * subfolders or not. If true, all subfolders are deleted, then this
0483:             * folder itself is deleted. If false, the behaviour is dependent on
0484:             * the folder type and is elaborated below: <p>
0485:             *
0486:             * <ul>
0487:             * <li>
0488:             * The folder can contain only messages: (type == HOLDS_MESSAGES).
0489:             * <br>
0490:             * All messages within the folder are removed. The folder 
0491:             * itself is then removed. An appropriate FolderEvent is generated by 
0492:             * the Store and this folder. <p>
0493:             *
0494:             * <li>
0495:             * The folder can contain only subfolders: (type == HOLDS_FOLDERS).
0496:             * <br>
0497:             * If this folder is empty (does not contain any 
0498:             * subfolders at all), it is removed. An appropriate FolderEvent is 
0499:             * generated by the Store and this folder.<br>
0500:             * If this folder contains any subfolders, the delete fails 
0501:             * and returns false. <p>
0502:             *
0503:             * <li>
0504:             * The folder can contain subfolders as well as messages: <br>
0505:             * If the folder is empty (no messages or subfolders), it
0506:             * is removed. If the folder contains no subfolders, but only messages,
0507:             * then all messages are removed. The folder itself is then removed.
0508:             * In both the above cases, an appropriate FolderEvent is
0509:             * generated by the Store and this folder. <p>
0510:             *
0511:             * If the folder contains subfolders there are 3 possible
0512:             * choices an implementation is free to do: <p>
0513:             * 
0514:             *  <ol>
0515:             *   <li> The operation fails, irrespective of whether this folder
0516:             * contains messages or not. Some implementations might elect to go
0517:             * with this simple approach. The delete() method returns false.
0518:             *
0519:             *   <li> Any messages within the folder are removed. Subfolders
0520:             * are not removed. The folder itself is not removed or affected
0521:             * in any manner. The delete() method returns true. And the 
0522:             * exists() method on this folder will return true indicating that
0523:             * this folder still exists. <br>
0524:             * An appropriate FolderEvent is generated by the Store and this folder.
0525:             *
0526:             *   <li> Any messages within the folder are removed. Subfolders are
0527:             * not removed. The folder itself changes its type from 
0528:             * HOLDS_FOLDERS | HOLDS_MESSAGES to HOLDS_FOLDERS. Thus new 
0529:             * messages cannot be added to this folder, but new subfolders can
0530:             * be created underneath. The delete() method returns true indicating
0531:             * success. The exists() method on this folder will return true
0532:             * indicating that this folder still exists. <br>
0533:             * An appropriate FolderEvent is generated by the Store and this folder.
0534:             * </ol>
0535:             * </ul>
0536:             *
0537:             * @return		true if the Folder is deleted successfully
0538:             * @exception	FolderNotFoundException if this folder does 
0539:             *			not exist
0540:             * @exception	IllegalStateException if this folder is not in 
0541:             *			the closed state.
0542:             * @exception       MessagingException
0543:             * @see		javax.mail.event.FolderEvent
0544:             */
0545:            public abstract boolean delete(boolean recurse)
0546:                    throws MessagingException;
0547:
0548:            /**
0549:             * Rename this Folder. This method will succeed only on a closed
0550:             * Folder. <p>
0551:             *
0552:             * If the rename is successful, a RENAMED FolderEvent is delivered
0553:             * to FolderListeners registered on this folder and its containing
0554:             * Store.
0555:             *
0556:             * @param f		a folder representing the new name for this Folder
0557:             * @return		true if the Folder is renamed successfully
0558:             * @exception	FolderNotFoundException if this folder does 
0559:             *			not exist
0560:             * @exception	IllegalStateException if this folder is not in 
0561:             *			the closed state.
0562:             * @exception       MessagingException
0563:             * @see		javax.mail.event.FolderEvent
0564:             */
0565:            public abstract boolean renameTo(Folder f)
0566:                    throws MessagingException;
0567:
0568:            /**
0569:             * The Folder is read only.  The state and contents of this
0570:             * folder cannot be modified.
0571:             */
0572:            public static final int READ_ONLY = 1;
0573:
0574:            /**
0575:             * The state and contents of this folder can be modified.
0576:             */
0577:            public static final int READ_WRITE = 2;
0578:
0579:            /**
0580:             * Open this Folder. This method is valid only on Folders that
0581:             * can contain Messages and that are closed. <p>
0582:             *
0583:             * If this folder is opened successfully, an OPENED ConnectionEvent
0584:             * is delivered to any ConnectionListeners registered on this 
0585:             * Folder. <p>
0586:             *
0587:             * The effect of opening multiple connections to the same folder
0588:             * on a specifc Store is implementation dependent. Some implementations
0589:             * allow multiple readers, but only one writer. Others allow
0590:             * multiple writers as well as readers.
0591:             *
0592:             * @param mode	open the Folder READ_ONLY or READ_WRITE
0593:             * @exception	FolderNotFoundException if this folder does 
0594:             *			not exist.
0595:             * @exception	IllegalStateException if this folder is not in 
0596:             *			the closed state.
0597:             * @exception       MessagingException
0598:             * @see 		#READ_ONLY
0599:             * @see 		#READ_WRITE
0600:             * @see 		#getType()
0601:             * @see 		javax.mail.event.ConnectionEvent
0602:             */
0603:            public abstract void open(int mode) throws MessagingException;
0604:
0605:            /**
0606:             * Close this Folder. This method is valid only on open Folders. <p>
0607:             *
0608:             * A CLOSED ConnectionEvent is delivered to any ConnectionListeners
0609:             * registered on this Folder. Note that the folder is closed even
0610:             * if this method terminates abnormally by throwing a
0611:             * MessagingException.
0612:             *
0613:             * @param expunge	expunges all deleted messages if this flag is true
0614:             * @exception	IllegalStateException if this folder is not opened
0615:             * @exception       MessagingException
0616:             * @see 		javax.mail.event.ConnectionEvent
0617:             */
0618:            public abstract void close(boolean expunge)
0619:                    throws MessagingException;
0620:
0621:            /**
0622:             * Indicates whether this Folder is in the 'open' state.
0623:             * @return  true if this Folder is in the 'open' state.
0624:             */
0625:            public abstract boolean isOpen();
0626:
0627:            /**
0628:             * Return the open mode of this folder.  Returns
0629:             * <code>Folder.READ_ONLY</code>, <code>Folder.READ_WRITE</code>,
0630:             * or -1 if the open mode is not known (usually only because an older
0631:             * <code>Folder</code> provider has not been updated to use this new
0632:             * method).
0633:             *
0634:             * @exception	IllegalStateException if this folder is not opened
0635:             * @return	        the open mode of this folder
0636:             * @since		JavaMail 1.1
0637:             */
0638:            public int getMode() {
0639:                if (!isOpen())
0640:                    throw new IllegalStateException("Folder not open");
0641:                return mode;
0642:            }
0643:
0644:            /**
0645:             * Get the permanent flags supported by this Folder. Returns a Flags
0646:             * object that contains all the flags supported. <p>
0647:             *
0648:             * The special flag <code>Flags.USER </code> indicates that this Folder
0649:             * supports arbitrary user-defined flags. <p>
0650:             *
0651:             * The supported permanent flags for a folder may not be available
0652:             * until the folder is opened.
0653:             * 
0654:             * @return 		permanent flags, or null if not known
0655:             */
0656:            public abstract Flags getPermanentFlags();
0657:
0658:            /**
0659:             * Get total number of messages in this Folder. <p>
0660:             *
0661:             * This method can be invoked on a closed folder. However, note
0662:             * that for some folder implementations, getting the total message
0663:             * count can be an expensive operation involving actually opening 
0664:             * the folder. In such cases, a provider can choose not to support 
0665:             * this functionality in the closed state, in which case this method
0666:             * must return -1. <p>
0667:             *
0668:             * Clients invoking this method on a closed folder must be aware
0669:             * that this is a potentially expensive operation. Clients must
0670:             * also be prepared to handle a return value of -1 in this case.
0671:             * 
0672:             * @return 		total number of messages. -1 may be returned
0673:             *			by certain implementations if this method is
0674:             *			invoked on a closed folder.
0675:             * @exception	FolderNotFoundException if this folder does 
0676:             *			not exist.
0677:             * @exception       MessagingException
0678:             */
0679:            public abstract int getMessageCount() throws MessagingException;
0680:
0681:            /**
0682:             * Get the number of new messages in this Folder. <p>
0683:             *
0684:             * This method can be invoked on a closed folder. However, note
0685:             * that for some folder implementations, getting the new message
0686:             * count can be an expensive operation involving actually opening 
0687:             * the folder. In such cases, a provider can choose not to support 
0688:             * this functionality in the closed state, in which case this method
0689:             * must return -1. <p>
0690:             *
0691:             * Clients invoking this method on a closed folder must be aware
0692:             * that this is a potentially expensive operation. Clients must
0693:             * also be prepared to handle a return value of -1 in this case. <p>
0694:             *
0695:             * This implementation returns -1 if this folder is closed. Else
0696:             * this implementation gets each Message in the folder using
0697:             * <code>getMessage(int)</code> and checks whether its
0698:             * <code>RECENT</code> flag is set. The total number of messages
0699:             * that have this flag set is returned.
0700:             *
0701:             * @return 		number of new messages. -1 may be returned
0702:             *			by certain implementations if this method is
0703:             *			invoked on a closed folder.
0704:             * @exception	FolderNotFoundException if this folder does 
0705:             *			not exist.
0706:             * @exception       MessagingException
0707:             */
0708:            public synchronized int getNewMessageCount()
0709:                    throws MessagingException {
0710:                if (!isOpen())
0711:                    return -1;
0712:
0713:                int newmsgs = 0;
0714:                int total = getMessageCount();
0715:                for (int i = 1; i <= total; i++) {
0716:                    try {
0717:                        if (getMessage(i).isSet(Flags.Flag.RECENT))
0718:                            newmsgs++;
0719:                    } catch (MessageRemovedException me) {
0720:                        // This is an expunged message, ignore it.
0721:                        continue;
0722:                    }
0723:                }
0724:                return newmsgs;
0725:            }
0726:
0727:            /**
0728:             * Get the total number of unread messages in this Folder. <p>
0729:             *
0730:             * This method can be invoked on a closed folder. However, note
0731:             * that for some folder implementations, getting the unread message
0732:             * count can be an expensive operation involving actually opening 
0733:             * the folder. In such cases, a provider can choose not to support 
0734:             * this functionality in the closed state, in which case this method
0735:             * must return -1. <p>
0736:             *
0737:             * Clients invoking this method on a closed folder must be aware
0738:             * that this is a potentially expensive operation. Clients must
0739:             * also be prepared to handle a return value of -1 in this case. <p>
0740:             *
0741:             * This implementation returns -1 if this folder is closed. Else
0742:             * this implementation gets each Message in the folder using
0743:             * <code>getMessage(int)</code> and checks whether its
0744:             * <code>SEEN</code> flag is set. The total number of messages
0745:             * that do not have this flag set is returned.
0746:             *
0747:             * @return 		total number of unread messages. -1 may be returned
0748:             *			by certain implementations if this method is
0749:             *			invoked on a closed folder.
0750:             * @exception	FolderNotFoundException if this folder does 
0751:             *			not exist.
0752:             * @exception       MessagingException
0753:             */
0754:            public synchronized int getUnreadMessageCount()
0755:                    throws MessagingException {
0756:                if (!isOpen())
0757:                    return -1;
0758:
0759:                int unread = 0;
0760:                int total = getMessageCount();
0761:                for (int i = 1; i <= total; i++) {
0762:                    try {
0763:                        if (!getMessage(i).isSet(Flags.Flag.SEEN))
0764:                            unread++;
0765:                    } catch (MessageRemovedException me) {
0766:                        // This is an expunged message, ignore it.
0767:                        continue;
0768:                    }
0769:                }
0770:                return unread;
0771:            }
0772:
0773:            /**
0774:             * Get the number of deleted messages in this Folder. <p>
0775:             *
0776:             * This method can be invoked on a closed folder. However, note
0777:             * that for some folder implementations, getting the deleted message
0778:             * count can be an expensive operation involving actually opening 
0779:             * the folder. In such cases, a provider can choose not to support 
0780:             * this functionality in the closed state, in which case this method
0781:             * must return -1. <p>
0782:             *
0783:             * Clients invoking this method on a closed folder must be aware
0784:             * that this is a potentially expensive operation. Clients must
0785:             * also be prepared to handle a return value of -1 in this case. <p>
0786:             *
0787:             * This implementation returns -1 if this folder is closed. Else
0788:             * this implementation gets each Message in the folder using
0789:             * <code>getMessage(int)</code> and checks whether its
0790:             * <code>DELETED</code> flag is set. The total number of messages
0791:             * that have this flag set is returned.
0792:             *
0793:             * @return 		number of deleted messages. -1 may be returned
0794:             *			by certain implementations if this method is
0795:             *			invoked on a closed folder.
0796:             * @exception	FolderNotFoundException if this folder does 
0797:             *			not exist.
0798:             * @exception       MessagingException
0799:             * @since		JavaMail 1.3
0800:             */
0801:            public synchronized int getDeletedMessageCount()
0802:                    throws MessagingException {
0803:                if (!isOpen())
0804:                    return -1;
0805:
0806:                int deleted = 0;
0807:                int total = getMessageCount();
0808:                for (int i = 1; i <= total; i++) {
0809:                    try {
0810:                        if (getMessage(i).isSet(Flags.Flag.DELETED))
0811:                            deleted++;
0812:                    } catch (MessageRemovedException me) {
0813:                        // This is an expunged message, ignore it.
0814:                        continue;
0815:                    }
0816:                }
0817:                return deleted;
0818:            }
0819:
0820:            /**
0821:             * Get the Message object corresponding to the given message
0822:             * number.  A Message object's message number is the relative
0823:             * position of this Message in its Folder. Messages are numbered
0824:             * starting at 1 through the total number of message in the folder.
0825:             * Note that the message number for a particular Message can change
0826:             * during a session if other messages in the Folder are deleted and
0827:             * the Folder is expunged. <p>
0828:             *
0829:             * Message objects are light-weight references to the actual message
0830:             * that get filled up on demand. Hence Folder implementations are 
0831:             * expected to provide light-weight Message objects. <p>
0832:             *
0833:             * Unlike Folder objects, repeated calls to getMessage with the
0834:             * same message number will return the same Message object, as
0835:             * long as no messages in this folder have been expunged. <p>
0836:             *
0837:             * Since message numbers can change within a session if the folder
0838:             * is expunged , clients are advised not to use message numbers as 
0839:             * references to messages. Use Message objects instead.
0840:             *
0841:             * @param msgnum	the message number
0842:             * @return 		the Message object
0843:             * @see		#getMessageCount
0844:             * @see		#fetch
0845:             * @exception	FolderNotFoundException if this folder does 
0846:             *			not exist.
0847:             * @exception	IllegalStateException if this folder is not opened
0848:             * @exception	IndexOutOfBoundsException if the message number
0849:             *			is out of range.
0850:             * @exception 	MessagingException
0851:             */
0852:            public abstract Message getMessage(int msgnum)
0853:                    throws MessagingException;
0854:
0855:            /**
0856:             * Get the Message objects for message numbers ranging from start
0857:             * through end, both start and end inclusive. Note that message 
0858:             * numbers start at 1, not 0. <p>
0859:             *
0860:             * Message objects are light-weight references to the actual message
0861:             * that get filled up on demand. Hence Folder implementations are 
0862:             * expected to provide light-weight Message objects. <p>
0863:             *
0864:             * This implementation uses getMessage(index) to obtain the required
0865:             * Message objects. Note that the returned array must contain 
0866:             * <code>(end-start+1)</code> Message objects.
0867:             * 
0868:             * @param start	the number of the first message
0869:             * @param end	the number of the last message
0870:             * @return 		the Message objects
0871:             * @see		#fetch
0872:             * @exception	FolderNotFoundException if this folder does 
0873:             *			not exist.
0874:             * @exception	IllegalStateException if this folder is not opened.
0875:             * @exception	IndexOutOfBoundsException if the start or end
0876:             *			message numbers are out of range.
0877:             * @exception 	MessagingException
0878:             */
0879:            public synchronized Message[] getMessages(int start, int end)
0880:                    throws MessagingException {
0881:                Message[] msgs = new Message[end - start + 1];
0882:                for (int i = start; i <= end; i++)
0883:                    msgs[i - start] = getMessage(i);
0884:                return msgs;
0885:            }
0886:
0887:            /**
0888:             * Get the Message objects for message numbers specified in
0889:             * the array. <p>
0890:             *
0891:             * Message objects are light-weight references to the actual message
0892:             * that get filled up on demand. Hence Folder implementations are 
0893:             * expected to provide light-weight Message objects. <p>
0894:             *
0895:             * This implementation uses getMessage(index) to obtain the required
0896:             * Message objects. Note that the returned array must contain 
0897:             * <code>msgnums.length</code> Message objects
0898:             *
0899:             * @param msgnums	the array of message numbers
0900:             * @return 		the array of Message objects. 
0901:             * @see		#fetch
0902:             * @exception	FolderNotFoundException if this folder does 
0903:             *			not exist.
0904:             * @exception	IllegalStateException if this folder is not opened.
0905:             * @exception	IndexOutOfBoundsException if any message number
0906:             *			in the given array is out of range.
0907:             * @exception 	MessagingException
0908:             */
0909:            public synchronized Message[] getMessages(int[] msgnums)
0910:                    throws MessagingException {
0911:                int len = msgnums.length;
0912:                Message[] msgs = new Message[len];
0913:                for (int i = 0; i < len; i++)
0914:                    msgs[i] = getMessage(msgnums[i]);
0915:                return msgs;
0916:            }
0917:
0918:            /**
0919:             * Get all Message objects from this Folder. Returns an empty array
0920:             * if the folder is empty.
0921:             *
0922:             * Clients can use Message objects (instead of sequence numbers) 
0923:             * as references to the messages within a folder; this method supplies 
0924:             * the Message objects to the client. Folder implementations are 
0925:             * expected to provide light-weight Message objects, which get
0926:             * filled on demand. <p>
0927:             *
0928:             * This implementation invokes <code>getMessageCount()</code> to get
0929:             * the current message count and then uses <code>getMessage()</code>
0930:             * to get Message objects from 1 till the message count.
0931:             *
0932:             * @return 		array of Message objects, empty array if folder
0933:             *			is empty.
0934:             * @see		#fetch
0935:             * @exception	FolderNotFoundException if this folder does 
0936:             *			not exist.
0937:             * @exception	IllegalStateException if this folder is not opened.
0938:             * @exception 	MessagingException
0939:             */
0940:            public synchronized Message[] getMessages()
0941:                    throws MessagingException {
0942:                if (!isOpen()) // otherwise getMessageCount might return -1
0943:                    throw new IllegalStateException("Folder not open");
0944:                int total = getMessageCount();
0945:                Message[] msgs = new Message[total];
0946:                for (int i = 1; i <= total; i++)
0947:                    msgs[i - 1] = getMessage(i);
0948:                return msgs;
0949:            }
0950:
0951:            /**
0952:             * Append given Messages to this folder. This method can be 
0953:             * invoked on a closed Folder. An appropriate MessageCountEvent 
0954:             * is delivered to any MessageCountListener registered on this 
0955:             * folder when the messages arrive in the folder. <p>
0956:             *
0957:             * Folder implementations must not abort this operation if a
0958:             * Message in the given message array turns out to be an
0959:             * expunged Message.
0960:             *
0961:             * @param msgs	array of Messages to be appended
0962:             * @exception	FolderNotFoundException if this folder does 
0963:             *			not exist.
0964:             * @exception 	MessagingException if the append failed.
0965:             */
0966:            public abstract void appendMessages(Message[] msgs)
0967:                    throws MessagingException;
0968:
0969:            /**
0970:             * Prefetch the items specified in the FetchProfile for the
0971:             * given Messages. <p>
0972:             *
0973:             * Clients use this method to indicate that the specified items are 
0974:             * needed en-masse for the given message range. Implementations are 
0975:             * expected to retrieve these items for the given message range in
0976:             * a efficient manner. Note that this method is just a hint to the
0977:             * implementation to prefetch the desired items. <p>
0978:             *
0979:             * An example is a client filling its header-view window with
0980:             * the Subject, From and X-mailer headers for all messages in the 
0981:             * folder.<p>
0982:             * <blockquote><pre>
0983:             *
0984:             *  Message[] msgs = folder.getMessages();
0985:             *
0986:             *  FetchProfile fp = new FetchProfile();
0987:             *  fp.add(FetchProfile.Item.ENVELOPE);
0988:             *  fp.add("X-mailer");
0989:             *  folder.fetch(msgs, fp);
0990:             *  
0991:             *  for (int i = 0; i < folder.getMessageCount(); i++) {
0992:             *      display(msg[i].getFrom());
0993:             *      display(msg[i].getSubject());
0994:             *      display(msg[i].getHeader("X-mailer"));
0995:             *  }
0996:             *
0997:             * </pre></blockquote><p>
0998:             *
0999:             * The implementation provided here just returns without
1000:             * doing anything useful. Providers wanting to provide a real 
1001:             * implementation for this method should override this method.
1002:             *
1003:             * @param msgs	fetch items for these messages
1004:             * @param fp	the FetchProfile
1005:             * @exception	IllegalStateException if this folder is not opened
1006:             * @exception	MessagingException.
1007:             */
1008:            public void fetch(Message[] msgs, FetchProfile fp)
1009:                    throws MessagingException {
1010:                return;
1011:            }
1012:
1013:            /**
1014:             * Set the specified flags on the messages specified in the array.
1015:             * This will result in appropriate MessageChangedEvents being
1016:             * delivered to any MessageChangedListener registered on this
1017:             * Message's containing folder. <p>
1018:             *
1019:             * Note that the specified Message objects <strong>must</strong> 
1020:             * belong to this folder. Certain Folder implementations can
1021:             * optimize the operation of setting Flags for a group of messages,
1022:             * so clients might want to use this method, rather than invoking
1023:             * <code>Message.setFlags</code> for each Message. <p>
1024:             *
1025:             * This implementation degenerates to invoking <code>setFlags()</code>
1026:             * on each Message object. Specific Folder implementations that can 
1027:             * optimize this case should do so. 
1028:             * Also, an implementation must not abort the operation if a Message 
1029:             * in the array turns out to be an expunged Message.
1030:             *
1031:             * @param msgs	the array of message objects
1032:             * @param flag	Flags object containing the flags to be set
1033:             * @param value	set the flags to this boolean value
1034:             * @exception	IllegalStateException if this folder is not opened
1035:             *			or if it has been opened READ_ONLY.
1036:             * @exception 	MessagingException
1037:             * @see		Message#setFlags
1038:             * @see		javax.mail.event.MessageChangedEvent
1039:             */
1040:            public synchronized void setFlags(Message[] msgs, Flags flag,
1041:                    boolean value) throws MessagingException {
1042:                for (int i = 0; i < msgs.length; i++) {
1043:                    try {
1044:                        msgs[i].setFlags(flag, value);
1045:                    } catch (MessageRemovedException me) {
1046:                        // This message is expunged, skip 
1047:                    }
1048:                }
1049:            }
1050:
1051:            /**
1052:             * Set the specified flags on the messages numbered from start
1053:             * through end, both start and end inclusive. Note that message 
1054:             * numbers start at 1, not 0.
1055:             * This will result in appropriate MessageChangedEvents being
1056:             * delivered to any MessageChangedListener registered on this
1057:             * Message's containing folder. <p>
1058:             *
1059:             * Certain Folder implementations can
1060:             * optimize the operation of setting Flags for a group of messages,
1061:             * so clients might want to use this method, rather than invoking
1062:             * <code>Message.setFlags</code> for each Message. <p>
1063:             *
1064:             * The default implementation uses <code>getMessage(int)</code> to
1065:             * get each <code>Message</code> object and then invokes
1066:             * <code>setFlags</code> on that object to set the flags.
1067:             * Specific Folder implementations that can optimize this case should do so.
1068:             * Also, an implementation must not abort the operation if a message 
1069:             * number refers to an expunged message.
1070:             *
1071:             * @param start	the number of the first message
1072:             * @param end	the number of the last message
1073:             * @param flag	Flags object containing the flags to be set
1074:             * @param value	set the flags to this boolean value
1075:             * @exception	IllegalStateException if this folder is not opened
1076:             *			or if it has been opened READ_ONLY.
1077:             * @exception	IndexOutOfBoundsException if the start or end
1078:             *			message numbers are out of range.
1079:             * @exception 	MessagingException
1080:             * @see		Message#setFlags
1081:             * @see		javax.mail.event.MessageChangedEvent
1082:             */
1083:            public synchronized void setFlags(int start, int end, Flags flag,
1084:                    boolean value) throws MessagingException {
1085:                for (int i = start; i <= end; i++) {
1086:                    try {
1087:                        Message msg = getMessage(i);
1088:                        msg.setFlags(flag, value);
1089:                    } catch (MessageRemovedException me) {
1090:                        // This message is expunged, skip 
1091:                    }
1092:                }
1093:            }
1094:
1095:            /**
1096:             * Set the specified flags on the messages whose message numbers
1097:             * are in the array.
1098:             * This will result in appropriate MessageChangedEvents being
1099:             * delivered to any MessageChangedListener registered on this
1100:             * Message's containing folder. <p>
1101:             *
1102:             * Certain Folder implementations can
1103:             * optimize the operation of setting Flags for a group of messages,
1104:             * so clients might want to use this method, rather than invoking
1105:             * <code>Message.setFlags</code> for each Message. <p>
1106:             *
1107:             * The default implementation uses <code>getMessage(int)</code> to
1108:             * get each <code>Message</code> object and then invokes
1109:             * <code>setFlags</code> on that object to set the flags.
1110:             * Specific Folder implementations that can optimize this case should do so.
1111:             * Also, an implementation must not abort the operation if a message 
1112:             * number refers to an expunged message.
1113:             *
1114:             * @param msgnums	the array of message numbers
1115:             * @param flag	Flags object containing the flags to be set
1116:             * @param value	set the flags to this boolean value
1117:             * @exception	IllegalStateException if this folder is not opened
1118:             *			or if it has been opened READ_ONLY.
1119:             * @exception	IndexOutOfBoundsException if any message number
1120:             *			in the given array is out of range.
1121:             * @exception 	MessagingException
1122:             * @see		Message#setFlags
1123:             * @see		javax.mail.event.MessageChangedEvent
1124:             */
1125:            public synchronized void setFlags(int[] msgnums, Flags flag,
1126:                    boolean value) throws MessagingException {
1127:                for (int i = 0; i < msgnums.length; i++) {
1128:                    try {
1129:                        Message msg = getMessage(msgnums[i]);
1130:                        msg.setFlags(flag, value);
1131:                    } catch (MessageRemovedException me) {
1132:                        // This message is expunged, skip 
1133:                    }
1134:                }
1135:            }
1136:
1137:            /**
1138:             * Copy the specified Messages from this Folder into another 
1139:             * Folder. This operation appends these Messages to the 
1140:             * destination Folder. The destination Folder does not have to 
1141:             * be opened.  An appropriate MessageCountEvent 
1142:             * is delivered to any MessageCountListener registered on the 
1143:             * destination folder when the messages arrive in the folder. <p>
1144:             *
1145:             * Note that the specified Message objects <strong>must</strong> 
1146:             * belong to this folder. Folder implementations might be able
1147:             * to optimize this method by doing server-side copies. <p>
1148:             *
1149:             * This implementation just invokes <code>appendMessages()</code>
1150:             * on the destination folder to append the given Messages. Specific
1151:             * folder implementations that support server-side copies should
1152:             * do so, if the destination folder's Store is the same as this
1153:             * folder's Store. 
1154:             * Also, an implementation must not abort the operation if a 
1155:             * Message in the array turns out to be an expunged Message.
1156:             *
1157:             * @param msgs	the array of message objects
1158:             * @param folder	the folder to copy the messages to
1159:             * @exception	FolderNotFoundException if the destination
1160:             *			folder does not exist.
1161:             * @exception	IllegalStateException if this folder is not opened.
1162:             * @exception	MessagingException
1163:             * @see		#appendMessages
1164:             */
1165:            public void copyMessages(Message[] msgs, Folder folder)
1166:                    throws MessagingException {
1167:                if (!folder.exists())
1168:                    throw new FolderNotFoundException(folder.getFullName()
1169:                            + " does not exist", folder);
1170:
1171:                folder.appendMessages(msgs);
1172:            }
1173:
1174:            /**
1175:             * Expunge (permanently remove) messages marked DELETED. Returns an
1176:             * array containing the expunged message objects.  The
1177:             * <code>getMessageNumber</code> method
1178:             * on each of these message objects returns that Message's original
1179:             * (that is, prior to the expunge) sequence number. A MessageCountEvent 
1180:             * containing the expunged messages is delivered to any 
1181:             * MessageCountListeners registered on the folder. <p>
1182:             *
1183:             * Expunge causes the renumbering of Message objects subsequent to
1184:             * the expunged messages. Clients that use message numbers as 
1185:             * references to messages should be aware of this and should be 
1186:             * prepared to deal with the situation (probably by flushing out 
1187:             * existing message number caches and reloading them). Because of 
1188:             * this complexity, it is better for clients to use Message objects
1189:             * as references to messages, rather than message numbers. Any 
1190:             * expunged Messages objects still have to be pruned, but other 
1191:             * Messages in that folder are not affected by the expunge. <p>
1192:             *
1193:             * After a message is expunged, only the <code>isExpunged</code> and 
1194:             * <code>getMessageNumber</code> methods are still valid on the
1195:             * corresponding Message object; other methods may throw
1196:             * <code>MessageRemovedException</code>
1197:             *
1198:             * @return		array of expunged Message objects
1199:             * @exception	FolderNotFoundException if this folder does not
1200:             *			exist
1201:             * @exception	IllegalStateException if this folder is not opened.
1202:             * @exception       MessagingException
1203:             * @see		Message#isExpunged
1204:             * @see		javax.mail.event.MessageCountEvent
1205:             */
1206:            public abstract Message[] expunge() throws MessagingException;
1207:
1208:            /**
1209:             * Search this Folder for messages matching the specified
1210:             * search criterion. Returns an array containing the matching
1211:             * messages . Returns an empty array if no matches were found. <p>
1212:             *
1213:             * This implementation invokes 
1214:             * <code>search(term, getMessages())</code>, to apply the search 
1215:             * over all the messages in this folder. Providers that can implement
1216:             * server-side searching might want to override this method to provide
1217:             * a more efficient implementation.
1218:             *
1219:             * @param term	the search criterion
1220:             * @return 		array of matching messages 
1221:             * @exception       javax.mail.search.SearchException if the search 
1222:             *			term is too complex for the implementation to handle.
1223:             * @exception	FolderNotFoundException if this folder does 
1224:             *			not exist.
1225:             * @exception	IllegalStateException if this folder is not opened.
1226:             * @exception       MessagingException
1227:             * @see		javax.mail.search.SearchTerm
1228:             */
1229:            public Message[] search(SearchTerm term) throws MessagingException {
1230:                return search(term, getMessages());
1231:            }
1232:
1233:            /**
1234:             * Search the given array of messages for those that match the 
1235:             * specified search criterion. Returns an array containing the 
1236:             * matching messages. Returns an empty array if no matches were 
1237:             * found. <p>
1238:             *
1239:             * Note that the specified Message objects <strong>must</strong> 
1240:             * belong to this folder. <p>
1241:             *
1242:             * This implementation iterates through the given array of messages,
1243:             * and applies the search criterion on each message by calling
1244:             * its <code>match()</code> method with the given term. The
1245:             * messages that succeed in the match are returned. Providers
1246:             * that can implement server-side searching might want to override
1247:             * this method to provide a more efficient implementation. If the
1248:             * search term is too complex or contains user-defined terms that
1249:             * cannot be executed on the server, providers may elect to either
1250:             * throw a SearchException or degenerate to client-side searching by
1251:             * calling <code>super.search()</code> to invoke this implementation.
1252:             *
1253:             * @param term	the search criterion
1254:             * @param msgs 	the messages to be searched
1255:             * @return 		array of matching messages 
1256:             * @exception       javax.mail.search.SearchException if the search 
1257:             *			term is too complex for the implementation to handle.
1258:             * @exception	IllegalStateException if this folder is not opened
1259:             * @exception       MessagingException
1260:             * @see		javax.mail.search.SearchTerm
1261:             */
1262:            public Message[] search(SearchTerm term, Message[] msgs)
1263:                    throws MessagingException {
1264:                Vector matchedMsgs = new Vector();
1265:
1266:                // Run thru the given messages
1267:                for (int i = 0; i < msgs.length; i++) {
1268:                    try {
1269:                        if (msgs[i].match(term)) // matched
1270:                            matchedMsgs.addElement(msgs[i]); // add it
1271:                    } catch (MessageRemovedException mrex) {
1272:                    }
1273:                }
1274:
1275:                Message[] m = new Message[matchedMsgs.size()];
1276:                matchedMsgs.copyInto(m);
1277:                return m;
1278:            }
1279:
1280:            /*
1281:             * The set of listeners are stored in Vectors appropriate to their
1282:             * type.  We mark all listener Vectors as "volatile" because, while
1283:             * we initialize them inside this folder's synchronization lock,
1284:             * they are accessed (checked for null) in the "notify" methods,
1285:             * which can't be synchronized due to lock ordering constraints.
1286:             * Since the listener fields (the handles on the Vector objects)
1287:             * are only ever set, and are never cleared, we believe this is
1288:             * safe.  The code that dispatches the notifications will either
1289:             * see the null and assume there are no listeners or will see the
1290:             * Vector and will process the listeners.  There's an inherent race
1291:             * between adding a listener and notifying the listeners; the lack
1292:             * of synchronization during notification does not make the race
1293:             * condition significantly worse.  If one thread is setting a
1294:             * listener at the "same" time an event is being dispatched, the
1295:             * dispatch code might not see the listener right away.  The
1296:             * dispatch code doesn't have to worry about the Vector handle
1297:             * being set to null, and thus using an out-of-date set of
1298:             * listeners, because we never set the field to null.
1299:             */
1300:
1301:            // Vector of connection listeners.
1302:            private volatile Vector connectionListeners = null;
1303:
1304:            /**
1305:             * Add a listener for Connection events on this Folder. <p>
1306:             *
1307:             * The implementation provided here adds this listener
1308:             * to an internal list of ConnectionListeners.
1309:             *
1310:             * @param l 	the Listener for Connection events
1311:             * @see		javax.mail.event.ConnectionEvent
1312:             */
1313:            public synchronized void addConnectionListener(ConnectionListener l) {
1314:                if (connectionListeners == null)
1315:                    connectionListeners = new Vector();
1316:                connectionListeners.addElement(l);
1317:            }
1318:
1319:            /**
1320:             * Remove a Connection event listener. <p>
1321:             *
1322:             * The implementation provided here removes this listener
1323:             * from the internal list of ConnectionListeners.
1324:             *
1325:             * @param l 	the listener
1326:             * @see		#addConnectionListener
1327:             */
1328:            public synchronized void removeConnectionListener(
1329:                    ConnectionListener l) {
1330:                if (connectionListeners != null)
1331:                    connectionListeners.removeElement(l);
1332:            }
1333:
1334:            /**
1335:             * Notify all ConnectionListeners. Folder implementations are
1336:             * expected to use this method to broadcast connection events. <p>
1337:             *
1338:             * The provided implementation queues the event into
1339:             * an internal event queue. An event dispatcher thread dequeues
1340:             * events from the queue and dispatches them to the registered
1341:             * ConnectionListeners. Note that the event dispatching occurs
1342:             * in a separate thread, thus avoiding potential deadlock problems.
1343:             *
1344:             * @param type	the ConnectionEvent type
1345:             * @see		javax.mail.event.ConnectionEvent
1346:             */
1347:            protected void notifyConnectionListeners(int type) {
1348:                if (connectionListeners != null) {
1349:                    ConnectionEvent e = new ConnectionEvent(this , type);
1350:                    queueEvent(e, connectionListeners);
1351:                }
1352:
1353:                /* Fix for broken JDK1.1.x Garbage collector :
1354:                 *  The 'conservative' GC in JDK1.1.x occasionally fails to
1355:                 *  garbage-collect Threads which are in the wait state.
1356:                 *  This would result in thread (and consequently memory) leaks.
1357:                 * 
1358:                 * We attempt to fix this by sending a 'terminator' event
1359:                 * to the queue, after we've sent the CLOSED event. The
1360:                 * terminator event causes the event-dispatching thread to
1361:                 * self destruct.
1362:                 */
1363:                if (type == ConnectionEvent.CLOSED)
1364:                    terminateQueue();
1365:            }
1366:
1367:            // Vector of folder listeners
1368:            private volatile Vector folderListeners = null;
1369:
1370:            /**
1371:             * Add a listener for Folder events on this Folder. <p>
1372:             *
1373:             * The implementation provided here adds this listener
1374:             * to an internal list of FolderListeners.
1375:             *
1376:             * @param l 	the Listener for Folder events
1377:             * @see		javax.mail.event.FolderEvent
1378:             */
1379:            public synchronized void addFolderListener(FolderListener l) {
1380:                if (folderListeners == null)
1381:                    folderListeners = new Vector();
1382:                folderListeners.addElement(l);
1383:            }
1384:
1385:            /**
1386:             * Remove a Folder event listener. <p>
1387:             *
1388:             * The implementation provided here removes this listener
1389:             * from the internal list of FolderListeners.
1390:             *
1391:             * @param l 	the listener
1392:             * @see		#addFolderListener
1393:             */
1394:            public synchronized void removeFolderListener(FolderListener l) {
1395:                if (folderListeners != null)
1396:                    folderListeners.removeElement(l);
1397:            }
1398:
1399:            /**
1400:             * Notify all FolderListeners registered on this Folder and
1401:             * this folder's Store. Folder implementations are expected
1402:             * to use this method to broadcast Folder events. <p>
1403:             *
1404:             * The implementation provided here queues the event into
1405:             * an internal event queue. An event dispatcher thread dequeues
1406:             * events from the queue and dispatches them to the 
1407:             * FolderListeners registered on this folder. The implementation
1408:             * also invokes <code>notifyFolderListeners</code> on this folder's
1409:             * Store to notify any FolderListeners registered on the store.
1410:             *
1411:             * @param type	type of FolderEvent
1412:             * @see		#notifyFolderRenamedListeners
1413:             */
1414:            protected void notifyFolderListeners(int type) {
1415:                if (folderListeners != null) {
1416:                    FolderEvent e = new FolderEvent(this , this , type);
1417:                    queueEvent(e, folderListeners);
1418:                }
1419:                store.notifyFolderListeners(type, this );
1420:            }
1421:
1422:            /**
1423:             * Notify all FolderListeners registered on this Folder and
1424:             * this folder's Store about the renaming of this folder.
1425:             * Folder implementations are expected to use this method to
1426:             * broadcast Folder events indicating the renaming of folders. <p>
1427:             *
1428:             * The implementation provided here queues the event into
1429:             * an internal event queue. An event dispatcher thread dequeues
1430:             * events from the queue and dispatches them to the 
1431:             * FolderListeners registered on this folder. The implementation
1432:             * also invokes <code>notifyFolderRenamedListeners</code> on this 
1433:             * folder's Store to notify any FolderListeners registered on the store.
1434:             *
1435:             * @param	folder	Folder representing the new name.
1436:             * @see		#notifyFolderListeners
1437:             * @since		JavaMail 1.1
1438:             */
1439:            protected void notifyFolderRenamedListeners(Folder folder) {
1440:                if (folderListeners != null) {
1441:                    FolderEvent e = new FolderEvent(this , this , folder,
1442:                            FolderEvent.RENAMED);
1443:                    queueEvent(e, folderListeners);
1444:                }
1445:                store.notifyFolderRenamedListeners(this , folder);
1446:            }
1447:
1448:            // Vector of MessageCount listeners
1449:            private volatile Vector messageCountListeners = null;
1450:
1451:            /**
1452:             * Add a listener for MessageCount events on this Folder. <p>
1453:             *
1454:             * The implementation provided here adds this listener
1455:             * to an internal list of MessageCountListeners.
1456:             *
1457:             * @param l 	the Listener for MessageCount events
1458:             * @see		javax.mail.event.MessageCountEvent
1459:             */
1460:            public synchronized void addMessageCountListener(
1461:                    MessageCountListener l) {
1462:                if (messageCountListeners == null)
1463:                    messageCountListeners = new Vector();
1464:                messageCountListeners.addElement(l);
1465:            }
1466:
1467:            /**
1468:             * Remove a MessageCount listener. <p>
1469:             *
1470:             * The implementation provided here removes this listener
1471:             * from the internal list of MessageCountListeners.
1472:             *
1473:             * @param l 	the listener
1474:             * @see		#addMessageCountListener
1475:             */
1476:            public synchronized void removeMessageCountListener(
1477:                    MessageCountListener l) {
1478:                if (messageCountListeners != null)
1479:                    messageCountListeners.removeElement(l);
1480:            }
1481:
1482:            /**
1483:             * Notify all MessageCountListeners about the addition of messages
1484:             * into this folder. Folder implementations are expected to use this 
1485:             * method to broadcast MessageCount events for indicating arrival of
1486:             * new messages. <p>
1487:             *
1488:             * The provided implementation queues the event into
1489:             * an internal event queue. An event dispatcher thread dequeues
1490:             * events from the queue and dispatches them to the registered
1491:             * MessageCountListeners. Note that the event dispatching occurs
1492:             * in a separate thread, thus avoiding potential deadlock problems.
1493:             */
1494:            protected void notifyMessageAddedListeners(Message[] msgs) {
1495:                if (messageCountListeners == null)
1496:                    return;
1497:
1498:                MessageCountEvent e = new MessageCountEvent(this ,
1499:                        MessageCountEvent.ADDED, false, msgs);
1500:
1501:                queueEvent(e, messageCountListeners);
1502:            }
1503:
1504:            /**
1505:             * Notify all MessageCountListeners about the removal of messages
1506:             * from this Folder. Folder implementations are expected to use this 
1507:             * method to broadcast MessageCount events indicating removal of
1508:             * messages. <p>
1509:             *
1510:             * The provided implementation queues the event into
1511:             * an internal event queue. An event dispatcher thread dequeues
1512:             * events from the queue and dispatches them to the registered
1513:             * MessageCountListeners. Note that the event dispatching occurs
1514:             * in a separate thread, thus avoiding potential deadlock problems.
1515:             */
1516:            protected void notifyMessageRemovedListeners(boolean removed,
1517:                    Message[] msgs) {
1518:                if (messageCountListeners == null)
1519:                    return;
1520:
1521:                MessageCountEvent e = new MessageCountEvent(this ,
1522:                        MessageCountEvent.REMOVED, removed, msgs);
1523:                queueEvent(e, messageCountListeners);
1524:            }
1525:
1526:            // Vector of MessageChanged listeners.
1527:            private volatile Vector messageChangedListeners = null;
1528:
1529:            /**
1530:             * Add a listener for MessageChanged events on this Folder. <p>
1531:             *
1532:             * The implementation provided here adds this listener
1533:             * to an internal list of MessageChangedListeners.
1534:             *
1535:             * @param l 	the Listener for MessageChanged events
1536:             * @see		javax.mail.event.MessageChangedEvent
1537:             */
1538:            public synchronized void addMessageChangedListener(
1539:                    MessageChangedListener l) {
1540:                if (messageChangedListeners == null)
1541:                    messageChangedListeners = new Vector();
1542:                messageChangedListeners.addElement(l);
1543:            }
1544:
1545:            /**
1546:             * Remove a MessageChanged listener. <p>
1547:             *
1548:             * The implementation provided here removes this listener
1549:             * from the internal list of MessageChangedListeners.
1550:             *
1551:             * @param l 	the listener
1552:             * @see		#addMessageChangedListener
1553:             */
1554:            public synchronized void removeMessageChangedListener(
1555:                    MessageChangedListener l) {
1556:                if (messageChangedListeners != null)
1557:                    messageChangedListeners.removeElement(l);
1558:            }
1559:
1560:            /**
1561:             * Notify all MessageChangedListeners. Folder implementations are
1562:             * expected to use this method to broadcast MessageChanged events. <p>
1563:             *
1564:             * The provided implementation queues the event into
1565:             * an internal event queue. An event dispatcher thread dequeues
1566:             * events from the queue and dispatches them to registered
1567:             * MessageChangedListeners. Note that the event dispatching occurs
1568:             * in a separate thread, thus avoiding potential deadlock problems.
1569:             */
1570:            protected void notifyMessageChangedListeners(int type, Message msg) {
1571:                if (messageChangedListeners == null)
1572:                    return;
1573:
1574:                MessageChangedEvent e = new MessageChangedEvent(this , type, msg);
1575:                queueEvent(e, messageChangedListeners);
1576:            }
1577:
1578:            /*
1579:             * The queue of events to be delivered.
1580:             */
1581:            private EventQueue q;
1582:
1583:            /*
1584:             * A lock for creating the EventQueue object.  Only one thread should
1585:             * create an EventQueue for this folder.  We can't synchronize on the
1586:             * folder's lock because that would violate the locking hierarchy in
1587:             * some cases.  For details, see the IMAP provider.
1588:             */
1589:            private Object qLock = new Object();
1590:
1591:            /*
1592:             * Add the event and vector of listeners to the queue to be delivered.
1593:             */
1594:            private void queueEvent(MailEvent event, Vector vector) {
1595:                // synchronize creation of the event queue
1596:                synchronized (qLock) {
1597:                    if (q == null)
1598:                        q = new EventQueue();
1599:                }
1600:
1601:                /*
1602:                 * Copy the vector in order to freeze the state of the set
1603:                 * of EventListeners the event should be delivered to prior
1604:                 * to delivery.  This ensures that any changes made to the
1605:                 * Vector from a target listener's method during the delivery
1606:                 * of this event will not take effect until after the event is
1607:                 * delivered.
1608:                 */
1609:                Vector v = (Vector) vector.clone();
1610:                q.enqueue(event, v);
1611:            }
1612:
1613:            static class TerminatorEvent extends MailEvent {
1614:                private static final long serialVersionUID = 3765761925441296565L;
1615:
1616:                TerminatorEvent() {
1617:                    super (new Object());
1618:                }
1619:
1620:                public void dispatch(Object listener) {
1621:                    // Kill the event dispatching thread.
1622:                    Thread.currentThread().interrupt();
1623:                }
1624:            }
1625:
1626:            // Dispatch the terminator
1627:            private void terminateQueue() {
1628:                synchronized (qLock) {
1629:                    if (q != null) {
1630:                        Vector dummyListeners = new Vector();
1631:                        dummyListeners.setSize(1); // need atleast one listener
1632:                        q.enqueue(new TerminatorEvent(), dummyListeners);
1633:                        q = null;
1634:                    }
1635:                }
1636:            }
1637:
1638:            protected void finalize() throws Throwable {
1639:                super .finalize();
1640:                terminateQueue();
1641:            }
1642:
1643:            /**
1644:             * override the default toString(), it will return the String
1645:             * from Folder.getFullName() or if that is null, it will use
1646:             * the default toString() behavior.
1647:             */
1648:
1649:            public String toString() {
1650:                String s = getFullName();
1651:                if (s != null)
1652:                    return s;
1653:                else
1654:                    return super.toString();
1655:            }
1656:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.