Source Code Cross Referenced for Service.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) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common Development
008:         * and Distribution License("CDDL") (collectively, the "License").  You
009:         * may not use this file except in compliance with the License. You can obtain
010:         * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011:         * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
012:         * language governing permissions and limitations under the License.
013:         *
014:         * When distributing the software, include this License Header Notice in each
015:         * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016:         * Sun designates this particular file as subject to the "Classpath" exception
017:         * as provided by Sun in the GPL Version 2 section of the License file that
018:         * accompanied this code.  If applicable, add the following below the License
019:         * Header, with the fields enclosed by brackets [] replaced by your own
020:         * identifying information: "Portions Copyrighted [year]
021:         * [name of copyright owner]"
022:         *
023:         * Contributor(s):
024:         *
025:         * If you wish your version of this file to be governed by only the CDDL or
026:         * only the GPL Version 2, indicate your decision by adding "[Contributor]
027:         * elects to include this software in this distribution under the [CDDL or GPL
028:         * Version 2] license."  If you don't indicate a single choice of license, a
029:         * recipient has the option to distribute your version of this file under
030:         * either the CDDL, the GPL Version 2 or to extend the choice of license to
031:         * its licensees as provided above.  However, if you add GPL Version 2 code
032:         * and therefore, elected the GPL Version 2 license, then the option applies
033:         * only if the new code is made subject to such option by the copyright
034:         * holder.
035:         */
036:
037:        /*
038:         * @(#)Service.java	1.33 07/05/14
039:         */
040:
041:        package javax.mail;
042:
043:        import java.io.*;
044:        import java.net.*;
045:        import java.util.*;
046:        import javax.mail.event.*;
047:
048:        /**
049:         * An abstract class that contains the functionality
050:         * common to messaging services, such as stores and transports. <p>
051:         * A messaging service is created from a <code>Session</code> and is
052:         * named using a <code>URLName</code>.  A service must be connected
053:         * before it can be used.  Connection events are sent to reflect
054:         * its connection status.
055:         *
056:         * @author Christopher Cotton
057:         * @author Bill Shannon
058:         * @author Kanwar Oberoi
059:         * @version 1.33, 07/05/14
060:         */
061:
062:        public abstract class Service {
063:
064:            /**
065:             * The session from which this service was created.
066:             */
067:            protected Session session;
068:
069:            /**
070:             * The <code>URLName</code> of this service.
071:             */
072:            protected URLName url = null;
073:
074:            /**
075:             * Debug flag for this service.  Set from the session's debug
076:             * flag when this service is created.
077:             */
078:            protected boolean debug = false;
079:
080:            private boolean connected = false;
081:            private Vector connectionListeners = null;
082:
083:            /**
084:             * Constructor.
085:             *
086:             * @param	session Session object for this service
087:             * @param	urlname	URLName object to be used for this service
088:             */
089:            protected Service(Session session, URLName urlname) {
090:                this .session = session;
091:                url = urlname;
092:                debug = session.getDebug();
093:            }
094:
095:            /**
096:             * A generic connect method that takes no parameters. Subclasses
097:             * can implement the appropriate authentication schemes. Subclasses
098:             * that need additional information might want to use some properties
099:             * or might get it interactively using a popup window. <p>
100:             *
101:             * If the connection is successful, an "open" <code>ConnectionEvent</code>
102:             * is delivered to any <code>ConnectionListeners</code> on this service. <p>
103:             *
104:             * Most clients should just call this method to connect to the service.<p>
105:             *
106:             * It is an error to connect to an already connected service. <p>
107:             *
108:             * The implementation provided here simply calls the following
109:             * <code>connect(String, String, String)</code> method with nulls.
110:             *
111:             * @exception AuthenticationFailedException	for authentication failures
112:             * @exception MessagingException	for other failures
113:             * @exception IllegalStateException	if the service is already connected
114:             *
115:             * @see javax.mail.event.ConnectionEvent
116:             */
117:            public void connect() throws MessagingException {
118:                connect(null, null, null);
119:            }
120:
121:            /**
122:             * Connect to the specified address. This method provides a simple
123:             * authentication scheme that requires a username and password. <p>
124:             *
125:             * If the connection is successful, an "open" <code>ConnectionEvent</code>
126:             * is delivered to any <code>ConnectionListeners</code> on this service. <p>
127:             *
128:             * It is an error to connect to an already connected service. <p>
129:             *
130:             * The implementation in the Service class will collect defaults
131:             * for the host, user, and password from the session, from the
132:             * <code>URLName</code> for this service, and from the supplied
133:             * parameters and then call the <code>protocolConnect</code> method.
134:             * If the <code>protocolConnect</code> method returns <code>false</code>,
135:             * the user will be prompted for any missing information and the
136:             * <code>protocolConnect</code> method will be called again.  The
137:             * subclass should override the <code>protocolConnect</code> method.
138:             * The subclass should also implement the <code>getURLName</code>
139:             * method, or use the implementation in this class. <p>
140:             *
141:             * On a successful connection, the <code>setURLName</code> method is
142:             * called with a URLName that includes the information used to make
143:             * the connection, including the password. <p>
144:             *
145:             * If the username passed in is null, a default value will be chosen
146:             * as described above.
147:             *
148:             * If the password passed in is null and this is the first successful
149:             * connection to this service, the user name and the password
150:             * collected from the user will be saved as defaults for subsequent
151:             * connection attempts to this same service when using other Service object
152:             * instances (the connection information is typically always saved within
153:             * a particular Service object instance).  The password is saved using the
154:             * Session method <code>setPasswordAuthentication</code>.  If the
155:             * password passed in is not null, it is not saved, on the assumption
156:             * that the application is managing passwords explicitly.
157:             *
158:             * @param host 	the host to connect to
159:             * @param user	the user name
160:             * @param password	this user's password
161:             * @exception AuthenticationFailedException	for authentication failures
162:             * @exception MessagingException		for other failures
163:             * @exception IllegalStateException	if the service is already connected
164:             * @see javax.mail.event.ConnectionEvent
165:             * @see javax.mail.Session#setPasswordAuthentication
166:             */
167:            public void connect(String host, String user, String password)
168:                    throws MessagingException {
169:                connect(host, -1, user, password);
170:            }
171:
172:            /**
173:             * Connect to the current host using the specified username
174:             * and password.  This method is equivalent to calling the
175:             * <code>connect(host, user, password)</code> method with null
176:             * for the host name.
177:             *
178:             * @param user      the user name
179:             * @param password  this user's password
180:             * @exception AuthenticationFailedException for authentication failures
181:             * @exception MessagingException            for other failures
182:             * @exception IllegalStateException if the service is already connected
183:             * @see javax.mail.event.ConnectionEvent
184:             * @see javax.mail.Session#setPasswordAuthentication
185:             * @see #connect(java.lang.String, java.lang.String, java.lang.String)
186:             * @since           JavaMail 1.4
187:             */
188:            public void connect(String user, String password)
189:                    throws MessagingException {
190:                connect(null, user, password);
191:            }
192:
193:            /**
194:             * Similar to connect(host, user, password) except a specific port
195:             * can be specified.
196:             *
197:             * @param host 	the host to connect to
198:             * @param port	the port to connect to (-1 means the default port)
199:             * @param user	the user name
200:             * @param password	this user's password
201:             * @exception AuthenticationFailedException	for authentication failures
202:             * @exception MessagingException		for other failures
203:             * @exception IllegalStateException	if the service is already connected
204:             * @see #connect(java.lang.String, java.lang.String, java.lang.String)
205:             * @see javax.mail.event.ConnectionEvent
206:             */
207:            public synchronized void connect(String host, int port,
208:                    String user, String password) throws MessagingException {
209:
210:                // see if the service is already connected
211:                if (isConnected())
212:                    throw new IllegalStateException("already connected");
213:
214:                PasswordAuthentication pw;
215:                boolean connected = false;
216:                boolean save = false;
217:                String protocol = null;
218:                String file = null;
219:
220:                // get whatever information we can from the URL
221:                // XXX - url should always be non-null here, Session
222:                //       passes it into the constructor
223:                if (url != null) {
224:                    protocol = url.getProtocol();
225:                    if (host == null)
226:                        host = url.getHost();
227:                    if (port == -1)
228:                        port = url.getPort();
229:
230:                    if (user == null) {
231:                        user = url.getUsername();
232:                        if (password == null) // get password too if we need it
233:                            password = url.getPassword();
234:                    } else {
235:                        if (password == null && user.equals(url.getUsername()))
236:                            // only get the password if it matches the username
237:                            password = url.getPassword();
238:                    }
239:
240:                    file = url.getFile();
241:                }
242:
243:                // try to get protocol-specific default properties
244:                if (protocol != null) {
245:                    if (host == null)
246:                        host = session
247:                                .getProperty("mail." + protocol + ".host");
248:                    if (user == null)
249:                        user = session
250:                                .getProperty("mail." + protocol + ".user");
251:                }
252:
253:                // try to get mail-wide default properties
254:                if (host == null)
255:                    host = session.getProperty("mail.host");
256:
257:                if (user == null)
258:                    user = session.getProperty("mail.user");
259:
260:                // try using the system username
261:                if (user == null) {
262:                    try {
263:                        user = System.getProperty("user.name");
264:                    } catch (SecurityException sex) {
265:                        if (debug)
266:                            sex.printStackTrace(session.getDebugOut());
267:                    }
268:                }
269:
270:                // if we don't have a password, look for saved authentication info
271:                if (password == null && url != null) {
272:                    // canonicalize the URLName
273:                    setURLName(new URLName(protocol, host, port, file, user,
274:                            null));
275:                    pw = session.getPasswordAuthentication(getURLName());
276:                    if (pw != null) {
277:                        if (user == null) {
278:                            user = pw.getUserName();
279:                            password = pw.getPassword();
280:                        } else if (user.equals(pw.getUserName())) {
281:                            password = pw.getPassword();
282:                        }
283:                    } else
284:                        save = true;
285:                }
286:
287:                // try connecting, if the protocol needs some missing
288:                // information (user, password) it will not connect.
289:                // if it tries to connect and fails, remember why for later.
290:                AuthenticationFailedException authEx = null;
291:                try {
292:                    connected = protocolConnect(host, port, user, password);
293:                } catch (AuthenticationFailedException ex) {
294:                    authEx = ex;
295:                }
296:
297:                // if not connected, ask the user and try again
298:                if (!connected) {
299:                    InetAddress addr;
300:                    try {
301:                        addr = InetAddress.getByName(host);
302:                    } catch (UnknownHostException e) {
303:                        addr = null;
304:                    }
305:                    pw = session.requestPasswordAuthentication(addr, port,
306:                            protocol, null, user);
307:                    if (pw != null) {
308:                        user = pw.getUserName();
309:                        password = pw.getPassword();
310:
311:                        // have the service connect again
312:                        connected = protocolConnect(host, port, user, password);
313:                    }
314:                }
315:
316:                // if we're not connected by now, we give up
317:                if (!connected) {
318:                    if (authEx != null)
319:                        throw authEx;
320:                    else
321:                        throw new AuthenticationFailedException();
322:                }
323:
324:                setURLName(new URLName(protocol, host, port, file, user,
325:                        password));
326:
327:                if (save)
328:                    session.setPasswordAuthentication(getURLName(),
329:                            new PasswordAuthentication(user, password));
330:
331:                // set our connected state
332:                setConnected(true);
333:
334:                // finally, deliver the connection event
335:                notifyConnectionListeners(ConnectionEvent.OPENED);
336:            }
337:
338:            /**
339:             * The service implementation should override this method to
340:             * perform the actual protocol-specific connection attempt.
341:             * The default implementation of the <code>connect</code> method
342:             * calls this method as needed. <p>
343:             *
344:             * The <code>protocolConnect</code> method should return
345:             * <code>false</code> if a user name or password is required
346:             * for authentication but the corresponding parameter is null;
347:             * the <code>connect</code> method will prompt the user when
348:             * needed to supply missing information.  This method may
349:             * also return <code>false</code> if authentication fails for
350:             * the supplied user name or password.  Alternatively, this method
351:             * may throw an AuthenticationFailedException when authentication
352:             * fails.  This exception may include a String message with more
353:             * detail about the failure. <p>
354:             *
355:             * The <code>protocolConnect</code> method should throw an
356:             * exception to report failures not related to authentication,
357:             * such as an invalid host name or port number, loss of a
358:             * connection during the authentication process, unavailability
359:             * of the server, etc.
360:             *
361:             * @param	host		the name of the host to connect to
362:             * @param	port		the port to use (-1 means use default port)
363:             * @param	user		the name of the user to login as
364:             * @param	password	the user's password
365:             * @return	true if connection successful, false if authentication failed
366:             * @exception AuthenticationFailedException	for authentication failures
367:             * @exception MessagingException	for non-authentication failures
368:             */
369:            protected boolean protocolConnect(String host, int port,
370:                    String user, String password) throws MessagingException {
371:                return false;
372:            }
373:
374:            /**
375:             * Is this service currently connected? <p>
376:             *
377:             * This implementation uses a private boolean field to 
378:             * store the connection state. This method returns the value
379:             * of that field. <p>
380:             *
381:             * Subclasses may want to override this method to verify that any
382:             * connection to the message store is still alive.
383:             *
384:             * @return	true if the service is connected, false if it is not connected
385:             */
386:            public synchronized boolean isConnected() {
387:                return connected;
388:            }
389:
390:            /**
391:             * Set the connection state of this service.  The connection state
392:             * will automatically be set by the service implementation during the
393:             * <code>connect</code> and <code>close</code> methods.
394:             * Subclasses will need to call this method to set the state
395:             * if the service was automatically disconnected. <p>
396:             *
397:             * The implementation in this class merely sets the private field
398:             * returned by the <code>isConnected</code> method.
399:             *
400:             * @param connected true if the service is connected,
401:             *                  false if it is not connected
402:             */
403:            protected synchronized void setConnected(boolean connected) {
404:                this .connected = connected;
405:            }
406:
407:            /**
408:             * Close this service and terminate its connection. A close
409:             * ConnectionEvent is delivered to any ConnectionListeners. Any
410:             * Messaging components (Folders, Messages, etc.) belonging to this
411:             * service are invalid after this service is closed. Note that the service
412:             * is closed even if this method terminates abnormally by throwing
413:             * a MessagingException. <p>
414:             *
415:             * This implementation uses <code>setConnected(false)</code> to set
416:             * this service's connected state to <code>false</code>. It will then
417:             * send a close ConnectionEvent to any registered ConnectionListeners.
418:             * Subclasses overriding this method to do implementation specific
419:             * cleanup should call this method as a last step to insure event
420:             * notification, probably by including a call to <code>super.close()</code>
421:             * in a <code>finally</code> clause.
422:             *
423:             * @see javax.mail.event.ConnectionEvent
424:             * @throws	MessagingException	for errors while closing
425:             */
426:            public synchronized void close() throws MessagingException {
427:                setConnected(false);
428:                notifyConnectionListeners(ConnectionEvent.CLOSED);
429:            }
430:
431:            /**
432:             * Return a URLName representing this service.  The returned URLName
433:             * does <em>not</em> include the password field.  <p>
434:             *
435:             * Subclasses should only override this method if their
436:             * URLName does not follow the standard format. <p>
437:             *
438:             * The implementation in the Service class returns (usually a copy of)
439:             * the <code>url</code> field with the password and file information
440:             * stripped out.
441:             *
442:             * @return	the URLName representing this service
443:             * @see	URLName
444:             */
445:            public synchronized URLName getURLName() {
446:                if (url != null
447:                        && (url.getPassword() != null || url.getFile() != null))
448:                    return new URLName(url.getProtocol(), url.getHost(), url
449:                            .getPort(), null /* no file */, url.getUsername(),
450:                            null /* no password */);
451:                else
452:                    return url;
453:            }
454:
455:            /**
456:             * Set the URLName representing this service.
457:             * Normally used to update the <code>url</code> field
458:             * after a service has successfully connected. <p>
459:             *
460:             * Subclasses should only override this method if their
461:             * URL does not follow the standard format.  In particular,
462:             * subclasses should override this method if their URL
463:             * does not require all the possible fields supported by
464:             * <code>URLName</code>; a new <code>URLName</code> should
465:             * be constructed with any unneeded fields removed. <p>
466:             *
467:             * The implementation in the Service class simply sets the
468:             * <code>url</code> field.
469:             *
470:             * @see URLName
471:             */
472:            protected synchronized void setURLName(URLName url) {
473:                this .url = url;
474:            }
475:
476:            /**
477:             * Add a listener for Connection events on this service. <p>
478:             *
479:             * The default implementation provided here adds this listener
480:             * to an internal list of ConnectionListeners.
481:             *
482:             * @param l         the Listener for Connection events
483:             * @see             javax.mail.event.ConnectionEvent
484:             */
485:            public synchronized void addConnectionListener(ConnectionListener l) {
486:                if (connectionListeners == null)
487:                    connectionListeners = new Vector();
488:                connectionListeners.addElement(l);
489:            }
490:
491:            /**
492:             * Remove a Connection event listener. <p>
493:             *
494:             * The default implementation provided here removes this listener
495:             * from the internal list of ConnectionListeners.
496:             *
497:             * @param l         the listener
498:             * @see             #addConnectionListener
499:             */
500:            public synchronized void removeConnectionListener(
501:                    ConnectionListener l) {
502:                if (connectionListeners != null)
503:                    connectionListeners.removeElement(l);
504:            }
505:
506:            /**
507:             * Notify all ConnectionListeners. Service implementations are
508:             * expected to use this method to broadcast connection events. <p>
509:             *
510:             * The provided default implementation queues the event into
511:             * an internal event queue. An event dispatcher thread dequeues
512:             * events from the queue and dispatches them to the registered
513:             * ConnectionListeners. Note that the event dispatching occurs
514:             * in a separate thread, thus avoiding potential deadlock problems.
515:             */
516:            protected synchronized void notifyConnectionListeners(int type) {
517:                if (connectionListeners != null) {
518:                    ConnectionEvent e = new ConnectionEvent(this , type);
519:                    queueEvent(e, connectionListeners);
520:                }
521:
522:                /* Fix for broken JDK1.1.x Garbage collector :
523:                 *  The 'conservative' GC in JDK1.1.x occasionally fails to
524:                 *  garbage-collect Threads which are in the wait state.
525:                 *  This would result in thread (and consequently memory) leaks.
526:                 *
527:                 * We attempt to fix this by sending a 'terminator' event
528:                 * to the queue, after we've sent the CLOSED event. The
529:                 * terminator event causes the event-dispatching thread to
530:                 * self destruct.
531:                 */
532:                if (type == ConnectionEvent.CLOSED)
533:                    terminateQueue();
534:            }
535:
536:            /**
537:             * Return <code>getURLName.toString()</code> if this service has a URLName,
538:             * otherwise it will return the default <code>toString</code>.
539:             */
540:            public String toString() {
541:                URLName url = getURLName();
542:                if (url != null)
543:                    return url.toString();
544:                else
545:                    return super .toString();
546:            }
547:
548:            /*
549:             * The queue of events to be delivered.
550:             */
551:            private EventQueue q;
552:
553:            /*
554:             * A lock for creating the EventQueue object.  Only one thread should
555:             * create an EventQueue for this service.  We can't synchronize on the
556:             * service's lock because that might violate the locking hierarchy in
557:             * some cases.
558:             */
559:            private Object qLock = new Object();
560:
561:            /**
562:             * Add the event and vector of listeners to the queue to be delivered.
563:             */
564:            protected void queueEvent(MailEvent event, Vector vector) {
565:                // synchronize creation of the event queue
566:                synchronized (qLock) {
567:                    if (q == null)
568:                        q = new EventQueue();
569:                }
570:
571:                /*
572:                 * Copy the vector in order to freeze the state of the set
573:                 * of EventListeners the event should be delivered to prior
574:                 * to delivery.  This ensures that any changes made to the
575:                 * Vector from a target listener's method during the delivery
576:                 * of this event will not take effect until after the event is
577:                 * delivered.
578:                 */
579:                Vector v = (Vector) vector.clone();
580:                q.enqueue(event, v);
581:            }
582:
583:            static class TerminatorEvent extends MailEvent {
584:                private static final long serialVersionUID = 5542172141759168416L;
585:
586:                TerminatorEvent() {
587:                    super (new Object());
588:                }
589:
590:                public void dispatch(Object listener) {
591:                    // Kill the event dispatching thread.
592:                    Thread.currentThread().interrupt();
593:                }
594:            }
595:
596:            // Dispatch the terminator
597:            private void terminateQueue() {
598:                synchronized (qLock) {
599:                    if (q != null) {
600:                        Vector dummyListeners = new Vector();
601:                        dummyListeners.setSize(1); // need atleast one listener
602:                        q.enqueue(new TerminatorEvent(), dummyListeners);
603:                        q = null;
604:                    }
605:                }
606:            }
607:
608:            /**
609:             * Stop the event dispatcher thread so the queue can be garbage collected.
610:             */
611:            protected void finalize() throws Throwable {
612:                super.finalize();
613:                terminateQueue();
614:            }
615:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.