📄 service.java
字号:
password = pw.getPassword(); // have the service connect again connected = protocolConnect(host, port, user, password); } } // if we're not connected by now, we give up if (!connected) { if (authEx != null) throw authEx; else throw new AuthenticationFailedException(); } setURLName(new URLName(protocol, host, port, file, user, password)); if (save) session.setPasswordAuthentication(getURLName(), new PasswordAuthentication(user, password)); // set our connected state setConnected(true); // finally, deliver the connection event notifyConnectionListeners(ConnectionEvent.OPENED); } /** * The service implementation should override this method to * perform the actual protocol-specific connection attempt. * The default implementation of the <code>connect</code> method * calls this method as needed. <p> * * The <code>protocolConnect</code> method should return * <code>false</code> if a user name or password is required * for authentication but the corresponding parameter is null; * the <code>connect</code> method will prompt the user when * needed to supply missing information. This method may * also return <code>false</code> if authentication fails for * the supplied user name or password. Alternatively, this method * may throw an AuthenticationFailedException when authentication * fails. This exception may include a String message with more * detail about the failure. <p> * * The <code>protocolConnect</code> method should throw an * exception to report failures not related to authentication, * such as an invalid host name or port number, loss of a * connection during the authentication process, unavailability * of the server, etc. * * @param host the name of the host to connect to * @param port the port to use (-1 means use default port) * @param user the name of the user to login as * @param password the user's password * @return true if connection successful, false if authentication failed * @exception AuthenticationFailedException for authentication failures * @exception MessagingException for non-authentication failures */ protected boolean protocolConnect(String host, int port, String user, String password) throws MessagingException { return false; } /** * Is this service currently connected? <p> * * This implementation uses a private boolean field to * store the connection state. This method returns the value * of that field. <p> * * Subclasses may want to override this method to verify that any * connection to the message store is still alive. * * @return true if the service is connected, false if it is not connected */ public synchronized boolean isConnected() { return connected; } /** * Set the connection state of this service. The connection state * will automatically be set by the service implementation during the * <code>connect</code> and <code>close</code> methods. * Subclasses will need to call this method to set the state * if the service was automatically disconnected. <p> * * The implementation in this class merely sets the private field * returned by the <code>isConnected</code> method. * * @param connected true if the service is connected, * false if it is not connected */ protected synchronized void setConnected(boolean connected) { this.connected = connected; } /** * Close this service and terminate its connection. A close * ConnectionEvent is delivered to any ConnectionListeners. Any * Messaging components (Folders, Messages, etc.) belonging to this * service are invalid after this service is closed. Note that the service * is closed even if this method terminates abnormally by throwing * a MessagingException. <p> * * This implementation uses <code>setConnected(false)</code> to set * this service's connected state to <code>false</code>. It will then * send a close ConnectionEvent to any registered ConnectionListeners. * Subclasses overriding this method to do implementation specific * cleanup should call this method as a last step to insure event * notification, probably by including a call to <code>super.close()</code> * in a <code>finally</code> clause. * * @see javax.mail.event.ConnectionEvent * @throws MessagingException for errors while closing */ public synchronized void close() throws MessagingException { setConnected(false); notifyConnectionListeners(ConnectionEvent.CLOSED); } /** * Return a URLName representing this service. The returned URLName * does <em>not</em> include the password field. <p> * * Subclasses should only override this method if their * URLName does not follow the standard format. <p> * * The implementation in the Service class returns (usually a copy of) * the <code>url</code> field with the password and file information * stripped out. * * @return the URLName representing this service * @see URLName */ public synchronized URLName getURLName() { if (url != null && (url.getPassword() != null || url.getFile() != null)) return new URLName(url.getProtocol(), url.getHost(), url.getPort(), null /* no file */, url.getUsername(), null /* no password */); else return url; } /** * Set the URLName representing this service. * Normally used to update the <code>url</code> field * after a service has successfully connected. <p> * * Subclasses should only override this method if their * URL does not follow the standard format. In particular, * subclasses should override this method if their URL * does not require all the possible fields supported by * <code>URLName</code>; a new <code>URLName</code> should * be constructed with any unneeded fields removed. <p> * * The implementation in the Service class simply sets the * <code>url</code> field. * * @see URLName */ protected synchronized void setURLName(URLName url) { this.url = url; } /** * Add a listener for Connection events on this service. <p> * * The default implementation provided here adds this listener * to an internal list of ConnectionListeners. * * @param l the Listener for Connection events * @see javax.mail.event.ConnectionEvent */ public synchronized void addConnectionListener(ConnectionListener l) { if (connectionListeners == null) connectionListeners = new Vector(); connectionListeners.addElement(l); } /** * Remove a Connection event listener. <p> * * The default implementation provided here removes this listener * from the internal list of ConnectionListeners. * * @param l the listener * @see #addConnectionListener */ public synchronized void removeConnectionListener(ConnectionListener l) { if (connectionListeners != null) connectionListeners.removeElement(l); } /** * Notify all ConnectionListeners. Service implementations are * expected to use this method to broadcast connection events. <p> * * The provided default implementation queues the event into * an internal event queue. An event dispatcher thread dequeues * events from the queue and dispatches them to the registered * ConnectionListeners. Note that the event dispatching occurs * in a separate thread, thus avoiding potential deadlock problems. */ protected synchronized void notifyConnectionListeners(int type) { if (connectionListeners != null) { ConnectionEvent e = new ConnectionEvent(this, type); queueEvent(e, connectionListeners); } /* Fix for broken JDK1.1.x Garbage collector : * The 'conservative' GC in JDK1.1.x occasionally fails to * garbage-collect Threads which are in the wait state. * This would result in thread (and consequently memory) leaks. * * We attempt to fix this by sending a 'terminator' event * to the queue, after we've sent the CLOSED event. The * terminator event causes the event-dispatching thread to * self destruct. */ if (type == ConnectionEvent.CLOSED) terminateQueue(); } /** * Return <code>getURLName.toString()</code> if this service has a URLName, * otherwise it will return the default <code>toString</code>. */ public String toString() { URLName url = getURLName(); if (url != null) return url.toString(); else return super.toString(); } /* * The queue of events to be delivered. */ private EventQueue q; /* * A lock for creating the EventQueue object. Only one thread should * create an EventQueue for this service. We can't synchronize on the * service's lock because that might violate the locking hierarchy in * some cases. */ private Object qLock = new Object(); /** * Add the event and vector of listeners to the queue to be delivered. */ protected void queueEvent(MailEvent event, Vector vector) { // synchronize creation of the event queue synchronized (qLock) { if (q == null) q = new EventQueue(); } /* * Copy the vector in order to freeze the state of the set * of EventListeners the event should be delivered to prior * to delivery. This ensures that any changes made to the * Vector from a target listener's method during the delivery * of this event will not take effect until after the event is * delivered. */ Vector v = (Vector)vector.clone(); q.enqueue(event, v); } static class TerminatorEvent extends MailEvent { private static final long serialVersionUID = 5542172141759168416L; TerminatorEvent() { super(new Object()); } public void dispatch(Object listener) { // Kill the event dispatching thread. Thread.currentThread().interrupt(); } } // Dispatch the terminator private void terminateQueue() { synchronized (qLock) { if (q != null) { Vector dummyListeners = new Vector(); dummyListeners.setSize(1); // need atleast one listener q.enqueue(new TerminatorEvent(), dummyListeners); q = null; } } } /** * Stop the event dispatcher thread so the queue can be garbage collected. */ protected void finalize() throws Throwable { super.finalize(); terminateQueue(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -