···4040import org.logicprobe.LogicMail.message.MessageFlags;
4141import org.logicprobe.LogicMail.message.MimeMessageContent;
4242import org.logicprobe.LogicMail.message.MimeMessagePart;
4343+import org.logicprobe.LogicMail.util.Connection;
43444445/**
4546 * Provides a generic interface to different incoming mail protocols.
···5758 * </p>
5859 */
5960public interface IncomingMailClient extends MailClient {
6161+ /**
6262+ * Open a new session with the mail server, on an already open connection.
6363+ * This method assumes that it is being provided a newly created socket
6464+ * connection, which it will then send protocol-specific login commands to.
6565+ * It should also be possible to invoke this method multiple times
6666+ * to correct for authentication failures, without having to reopen
6767+ * the underlying connection.
6868+ *
6969+ * @param connection Newly opened socket connection
7070+ * @return True if successful, false on authentication failure
7171+ * @throws IOException on I/O errors
7272+ * @throws MailException on protocol errors
7373+ */
7474+ boolean open(Connection connection) throws IOException, MailException;
7575+6076 /**
6177 * Set the listener used to handle asynchronous events from the mail client.
6278 *
···5353 * @throws IOException on I/O errors
5454 * @throws MailException on protocol errors
5555 */
5656- public abstract boolean open() throws IOException, MailException;
5656+ boolean open() throws IOException, MailException;
57575858 /**
5959 * Close an existing connection.
···6363 * @throws IOException on I/O errors
6464 * @throws MailException on protocol errors
6565 */
6666- public abstract void close() throws IOException, MailException;
6666+ void close() throws IOException, MailException;
67676868 /**
6969 * Gets the connection configuration associated with this client.
7070 * @return Connection configuration.
7171 */
7272- public abstract ConnectionConfig getConnectionConfig();
7272+ ConnectionConfig getConnectionConfig();
73737474 /**
7575 * Find out if the connection is active.
7676 * @return True if the connection is active, false otherwise
7777 */
7878- public abstract boolean isConnected();
7878+ boolean isConnected();
79798080 /**
8181+ * Gets the type of connection that was opened.
8282+ *
8383+ * @return the connection type, based on the
8484+ * <code>ConnectionConfig.TRANSPORT_XXXX</code> constants.
8585+ */
8686+ int getConnectionType();
8787+8888+ /**
8189 * Checks if a valid username and password are required for this client.
8290 * @return true, if login is required
8391 */
8484- public abstract boolean isLoginRequired();
9292+ boolean isLoginRequired();
85938694 /**
8795 * Get the configured username for this client.
8896 * @return Configured username, empty if none, null if n/a
8997 */
9090- public abstract String getUsername();
9898+ String getUsername();
919992100 /**
93101 * Set the username for this client to use
94102 * @param username The username
95103 */
9696- public abstract void setUsername(String username);
104104+ void setUsername(String username);
9710598106 /**
99107 * Get the configured password for this client.
100108 * @return Configured password, empty if none, null if n/a
101109 */
102102- public abstract String getPassword();
110110+ String getPassword();
103111104112 /**
105113 * Set the password for this client to use
106114 * @param password The password
107115 */
108108- public abstract void setPassword(String password);
116116+ void setPassword(String password);
109117}
···11+/*-
22+ * Copyright (c) 2011, Derek Konigsberg
33+ * All rights reserved.
44+ *
55+ * Redistribution and use in source and binary forms, with or without
66+ * modification, are permitted provided that the following conditions
77+ * are met:
88+ *
99+ * 1. Redistributions of source code must retain the above copyright
1010+ * notice, this list of conditions and the following disclaimer.
1111+ * 2. Redistributions in binary form must reproduce the above copyright
1212+ * notice, this list of conditions and the following disclaimer in the
1313+ * documentation and/or other materials provided with the distribution.
1414+ * 3. Neither the name of the project nor the names of its
1515+ * contributors may be used to endorse or promote products derived
1616+ * from this software without specific prior written permission.
1717+ *
1818+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1919+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2020+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2121+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2222+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2323+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2424+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2525+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2626+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2727+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2828+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2929+ * OF THE POSSIBILITY OF SUCH DAMAGE.
3030+ */
3131+package org.logicprobe.LogicMail.mail;
3232+3333+import java.io.IOException;
3434+3535+import org.logicprobe.LogicMail.conf.ConnectionConfig;
3636+import org.logicprobe.LogicMail.conf.MailSettings;
3737+import org.logicprobe.LogicMail.util.Connection;
3838+import org.logicprobe.LogicMail.util.NetworkConnector;
3939+import org.logicprobe.LogicMail.util.UtilFactory;
4040+4141+import net.rim.device.api.system.WLANInfo;
4242+4343+class NetworkHandoverRequest extends NetworkMailStoreRequest implements MailStoreRequest {
4444+ private String attemptedSSID;
4545+ private long attemptTime;
4646+4747+ NetworkHandoverRequest(NetworkMailStore mailStore) {
4848+ super(mailStore);
4949+ }
5050+5151+ protected String getInitialStatus() {
5252+ return null;
5353+ }
5454+5555+ public String getAttemptedSSID() {
5656+ return attemptedSSID;
5757+ }
5858+5959+ public long getAttemptTime() {
6060+ return attemptTime;
6161+ }
6262+6363+ public void execute(MailClient client) throws IOException, MailException {
6464+ IncomingMailClient incomingClient = (IncomingMailClient)client;
6565+ if(!prepareForHandover(incomingClient)) {
6666+ fireMailStoreRequestFailed(null, true);
6767+ return;
6868+ }
6969+7070+ Connection connection;
7171+ try {
7272+ NetworkConnector connector = UtilFactory.getInstance().getNetworkConnector(
7373+ MailSettings.getInstance().getGlobalConfig(),
7474+ incomingClient.getAcctConfig());
7575+ connection = connector.open(incomingClient.getAcctConfig(), true);
7676+ if(connection.getConnectionType() != ConnectionConfig.TRANSPORT_WIFI_ONLY) {
7777+ connection.close();
7878+ connection = null;
7979+ }
8080+ } catch (IOException e) {
8181+ fireMailStoreRequestFailed(e, true);
8282+ return;
8383+ }
8484+8585+ if(connection == null) {
8686+ fireMailStoreRequestFailed(null, true);
8787+ }
8888+8989+ incomingClient.close();
9090+ incomingClient.open(connection);
9191+ fireMailStoreRequestComplete();
9292+ }
9393+9494+ private boolean prepareForHandover(IncomingMailClient incomingClient) {
9595+ if(incomingClient.getConnectionType() != ConnectionConfig.TRANSPORT_WIFI_ONLY
9696+ && WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
9797+ WLANInfo.WLANAPInfo apInfo = WLANInfo.getAPInfo();
9898+ if(apInfo != null) {
9999+ attemptedSSID = apInfo.getSSID();
100100+ attemptTime = System.currentTimeMillis();
101101+ return true;
102102+ }
103103+ }
104104+ return false;
105105+ }
106106+}
···319319 }
320320 }
321321322322+ /**
323323+ * Submits the request to the mail store for processing, placing it at the
324324+ * top of the request queue.
325325+ *
326326+ * @param request the request to process
327327+ */
328328+ public void processRequestFirst(MailStoreRequest request) {
329329+ if(request instanceof NetworkMailStoreRequest
330330+ && request instanceof ConnectionHandlerRequest) {
331331+ connectionHandler.pushRequest((ConnectionHandlerRequest)request);
332332+ }
333333+ else {
334334+ throw new IllegalArgumentException();
335335+ }
336336+ }
337337+322338 IncomingMailConnectionHandler getConnectionHandler() {
323339 return connectionHandler;
324340 }
···4848 Connection open(ConnectionConfig connectionConfig) throws IOException;
49495050 /**
5151+ * Open a new network connection, using the provided configuration.
5252+ *
5353+ * @param connectionConfig the connection configuration
5454+ * @param forceWiFi true, if only WiFi should be attempted
5555+ * @return the opened connection instance
5656+ * @throws IOException Signals that an I/O exception has occurred.
5757+ */
5858+ Connection open(ConnectionConfig connectionConfig, boolean forceWiFi) throws IOException;
5959+6060+ /**
5161 * Returns a connection instance that has been switched into TLS mode,
5262 * as is commonly done after sending a protocol-specific <tt>STARTTLS</tt>
5363 * command to the server.
···6969 tail = tail.next;
7070 }
7171 }
7272+7373+ /**
7474+ * Pushes an element onto the head of the queue.
7575+ * @param element The element
7676+ * @throws NullPointerException if the item is null
7777+ */
7878+ public void push(Object element) {
7979+ if(element == null) {
8080+ throw new NullPointerException();
8181+ }
8282+ Node node = new Node();
8383+ node.item = element;
8484+8585+ if(head == null) {
8686+ node.next = null;
8787+ head = node;
8888+ tail = head;
8989+ }
9090+ else {
9191+ node.next = head;
9292+ head = node;
9393+ }
9494+ }
72957396 /**
7497 * Retrieves the element at the head of the queue.