Ignore:
Timestamp:
06/03/09 17:40:24 (3 years ago)
Author:
octorian
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LogicMail/src/org/logicprobe/LogicMail/util/Connection.java

    r381 r449  
    6060package org.logicprobe.LogicMail.util; 
    6161 
     62import net.rim.device.api.system.EventLogger; 
     63import net.rim.device.api.ui.UiApplication; 
     64import net.rim.device.api.ui.component.Dialog; 
     65import net.rim.device.api.util.DataBuffer; 
     66 
     67import org.logicprobe.LogicMail.AppInfo; 
     68import org.logicprobe.LogicMail.conf.GlobalConfig; 
     69import org.logicprobe.LogicMail.conf.MailSettings; 
     70 
    6271import java.io.IOException; 
    6372import java.io.InputStream; 
    6473import java.io.OutputStream; 
     74 
    6575import java.util.Vector; 
     76 
     77import javax.microedition.io.Connector; 
    6678import javax.microedition.io.SocketConnection; 
    6779import javax.microedition.io.StreamConnection; 
    68 import javax.microedition.io.Connector; 
    69 import net.rim.device.api.system.EventLogger; 
    70 import net.rim.device.api.ui.UiApplication; 
    71 import net.rim.device.api.ui.component.Dialog; 
    72 import org.logicprobe.LogicMail.AppInfo; 
    73 import org.logicprobe.LogicMail.conf.GlobalConfig; 
    74 import org.logicprobe.LogicMail.conf.MailSettings; 
     80 
    7581 
    7682/** 
     
    9399 */ 
    94100public class Connection { 
     101    /** 
     102     * Byte array holding carriage return and line feed 
     103     */ 
     104    private static final byte[] CRLF = new byte[] { 13, 10 }; 
     105 
     106    /** 
     107     * Holds a list of open connections 
     108     */ 
     109    private static Vector openConnections = new Vector(); 
    95110    private String serverName; 
    96111    private int serverPort; 
     
    104119    private boolean useWiFi; 
    105120    private int fakeAvailable = -1; 
    106      
    107     /** 
    108      * Byte array holding carriage return and line feed 
    109      */ 
    110     private static final byte[] CRLF = new byte[] {13, 10}; 
    111      
     121 
    112122    /** 
    113123     * Provides a buffer used for incoming data. 
    114124     */ 
    115125    private byte[] buffer = new byte[128]; 
    116      
    117     /** 
    118      * Holds a list of open connections 
    119      */ 
    120     private static Vector openConnections = new Vector(); 
    121      
    122     public Connection(String serverName, int serverPort, boolean useSSL, boolean deviceSide) { 
     126 
     127    /** 
     128     * Provides a dynamic buffer for building results 
     129     */ 
     130    DataBuffer resultBuffer = new DataBuffer(); 
     131 
     132    public Connection(String serverName, int serverPort, boolean useSSL, 
     133        boolean deviceSide) { 
    123134        this.serverName = serverName; 
    124135        this.serverPort = serverPort; 
     
    130141        this.globalConfig = MailSettings.getInstance().getGlobalConfig(); 
    131142    } 
    132      
     143 
    133144    /** 
    134145     * Opens a connection. 
    135146     */ 
    136     public void open() throws IOException { 
    137         if(input != null || output != null || socket != null) { 
     147    public synchronized void open() throws IOException { 
     148        if ((input != null) || (output != null) || (socket != null)) { 
    138149            close(); 
    139150        } 
    140151 
    141         synchronized(openConnections) { 
    142             if(!openConnections.contains(this)) { 
     152        synchronized (openConnections) { 
     153            if (!openConnections.contains(this)) { 
    143154                openConnections.addElement(this); 
    144155            } 
    145156        } 
    146          
     157 
    147158        String protocolStr = (useSSL ? "ssl" : "socket"); 
     159 
    148160        // This parameter, which allows bypassing the MDS proxy, should probably 
    149161        // be a global user configurable option 
     
    151163 
    152164        useWiFi = false; 
    153         if(globalConfig.getWifiMode() == GlobalConfig.WIFI_PROMPT) { 
     165 
     166        if (globalConfig.getWifiMode() == GlobalConfig.WIFI_PROMPT) { 
    154167            UiApplication.getUiApplication().invokeAndWait(new Runnable() { 
    155                 public void run() { 
    156                     useWiFi = (Dialog.ask(Dialog.D_YES_NO, "Connect through WiFi?") == Dialog.YES); 
    157                 } 
    158             }); 
    159         } 
    160         else if(globalConfig.getWifiMode() == GlobalConfig.WIFI_ALWAYS) { 
     168                    public void run() { 
     169                        useWiFi = (Dialog.ask(Dialog.D_YES_NO, 
     170                                "Connect through WiFi?") == Dialog.YES); 
     171                    } 
     172                }); 
     173        } else if (globalConfig.getWifiMode() == GlobalConfig.WIFI_ALWAYS) { 
    161174            useWiFi = true; 
    162175        } 
    163          
    164         if(useWiFi) { 
     176 
     177        if (useWiFi) { 
    165178            paramStr = paramStr + ";interface=wifi"; 
    166179        } 
    167          
    168         String connectStr = protocolStr + "://" + serverName + ":" + serverPort + paramStr; 
    169          
    170         if(EventLogger.getMinimumLevel() >= EventLogger.INFORMATION) { 
    171             String msg = "Opening connection:\r\n"+connectStr+"\r\n"; 
    172             EventLogger.logEvent(AppInfo.GUID, msg.getBytes(), EventLogger.INFORMATION); 
    173         } 
    174          
    175         socket = (StreamConnection)Connector.open(connectStr, Connector.READ_WRITE, true); 
     180 
     181        String connectStr = protocolStr + "://" + serverName + ":" + 
     182            serverPort + paramStr; 
     183 
     184        if (EventLogger.getMinimumLevel() >= EventLogger.INFORMATION) { 
     185            String msg = "Opening connection:\r\n" + connectStr + "\r\n"; 
     186            EventLogger.logEvent(AppInfo.GUID, msg.getBytes(), 
     187                EventLogger.INFORMATION); 
     188        } 
     189 
     190        socket = (StreamConnection) Connector.open(connectStr, 
     191                Connector.READ_WRITE, true); 
    176192        input = socket.openDataInputStream(); 
    177193        output = socket.openDataOutputStream(); 
    178         localAddress = ((SocketConnection)socket).getLocalAddress(); 
    179  
    180         if(EventLogger.getMinimumLevel() >= EventLogger.INFORMATION) { 
    181             String msg = 
    182                 "Connection established:\r\n"+ 
    183                 "Socket: "+socket.getClass().toString()+"\r\n"+ 
    184                 "Local address: "+localAddress+"\r\n"; 
    185             EventLogger.logEvent(AppInfo.GUID, msg.getBytes(), EventLogger.INFORMATION); 
    186         } 
    187     } 
    188      
     194        localAddress = ((SocketConnection) socket).getLocalAddress(); 
     195 
     196        if (EventLogger.getMinimumLevel() >= EventLogger.INFORMATION) { 
     197            String msg = "Connection established:\r\n" + "Socket: " + 
     198                socket.getClass().toString() + "\r\n" + "Local address: " + 
     199                localAddress + "\r\n"; 
     200            EventLogger.logEvent(AppInfo.GUID, msg.getBytes(), 
     201                EventLogger.INFORMATION); 
     202        } 
     203    } 
     204 
    189205    /** 
    190206     * Closes a connection. 
    191207     */ 
    192     public void close() throws IOException { 
     208    public synchronized void close() throws IOException { 
    193209        try { 
    194             if(input != null) { 
     210            if (input != null) { 
    195211                input.close(); 
    196212                input = null; 
     
    199215            input = null; 
    200216        } 
     217 
    201218        try { 
    202             if(output != null) { 
     219            if (output != null) { 
    203220                output.close(); 
    204221                output = null; 
     
    207224            output = null; 
    208225        } 
     226 
    209227        try { 
    210             if(socket != null) { 
     228            if (socket != null) { 
    211229                socket.close(); 
    212230                socket = null; 
     
    216234        } 
    217235 
    218         synchronized(openConnections) { 
    219             if(openConnections.contains(this)) { 
     236        synchronized (openConnections) { 
     237            if (openConnections.contains(this)) { 
    220238                openConnections.removeElement(this); 
    221239            } 
    222240        } 
    223          
    224         EventLogger.logEvent(AppInfo.GUID, "Connection closed".getBytes(), EventLogger.INFORMATION); 
    225     } 
    226      
     241 
     242        EventLogger.logEvent(AppInfo.GUID, "Connection closed".getBytes(), 
     243            EventLogger.INFORMATION); 
     244    } 
     245 
    227246    /** 
    228247     * Determine whether open connections exist 
     
    232251    public static boolean hasOpenConnections() { 
    233252        boolean result; 
    234         synchronized(openConnections) { 
     253 
     254        synchronized (openConnections) { 
    235255            result = !openConnections.isEmpty(); 
    236256        } 
     257 
    237258        return result; 
    238259    } 
    239      
     260 
    240261    /** 
    241262     * Close all open connections 
    242263     */ 
    243264    public static void closeAllConnections() { 
    244         synchronized(openConnections) { 
     265        synchronized (openConnections) { 
    245266            int size = openConnections.size(); 
    246             for(int i = 0; i < size; i++) { 
     267 
     268            for (int i = 0; i < size; i++) { 
    247269                try { 
    248                     ((Connection)openConnections.elementAt(i)).close(); 
    249                 } catch (IOException e) { } 
    250             } 
     270                    ((Connection) openConnections.elementAt(i)).close(); 
     271                } catch (IOException e) { 
     272                } 
     273            } 
     274 
    251275            openConnections.removeAllElements(); 
    252276        } 
    253277    } 
    254      
     278 
    255279    /** 
    256280     * Determine whether we are currently connected 
     
    258282     */ 
    259283    public boolean isConnected() { 
    260         if(socket != null) 
     284        if (socket != null) { 
    261285            return true; 
    262         else 
     286        } else { 
    263287            return false; 
    264     } 
    265      
     288        } 
     289    } 
     290 
    266291    /** 
    267292     * Get the local address to which this connection is bound 
     
    271296        return localAddress; 
    272297    } 
    273      
     298 
    274299    /** 
    275300     * Get the server name used when this connection was created 
     
    279304        return serverName; 
    280305    } 
    281      
     306 
    282307    /** 
    283308     * Sends a string to the server. This method is used internally for 
     
    289314     * @see #receive 
    290315     */ 
    291     public void send(String s) throws IOException { 
     316    public synchronized void send(String s) throws IOException { 
    292317        byte[] bytes = s.getBytes(); 
    293318        int length = bytes.length; 
    294          
     319 
    295320        /** 
    296321         * Special case for empty strings: Only CR/LF is sent. 
    297322         */ 
    298323        if (s.length() == 0) { 
    299             if(globalConfig.getConnDebug()) { 
    300                 EventLogger.logEvent(AppInfo.GUID, "[SEND]".getBytes(), EventLogger.DEBUG_INFO); 
    301             } 
    302              
     324            if (globalConfig.getConnDebug()) { 
     325                EventLogger.logEvent(AppInfo.GUID, "[SEND]".getBytes(), 
     326                    EventLogger.DEBUG_INFO); 
     327            } 
     328 
    303329            output.write(CRLF, 0, 2); 
    304330        } 
     
    308334        else { 
    309335            int i = 0; 
     336 
    310337            while (i < length) { 
    311338                int j = i; 
    312                  
     339 
    313340                /** 
    314341                 * Find next occurrence of a line separator or the end of the 
    315342                 * string. 
    316343                 */ 
    317                 while ((j < length) && (bytes[j] != 0x0A) && (bytes[j] != 0x0D)) { 
     344                while ((j < length) && (bytes[j] != 0x0A) && 
     345                        (bytes[j] != 0x0D)) { 
    318346                    j++; 
    319347                } 
    320                  
    321                 if(globalConfig.getConnDebug()) { 
    322                     EventLogger.logEvent(AppInfo.GUID, ("[SEND] " + s.substring(i, j)).getBytes(), EventLogger.DEBUG_INFO); 
    323                 } 
    324                  
     348 
     349                if (globalConfig.getConnDebug()) { 
     350                    EventLogger.logEvent(AppInfo.GUID, 
     351                        ("[SEND] " + s.substring(i, j)).getBytes(), 
     352                        EventLogger.DEBUG_INFO); 
     353                } 
     354 
    325355                /** 
    326356                 * Write the string up to there and terminate it properly. 
    327357                 */ 
    328                 output.write((s.substring(i, j)+"\r\n").getBytes()); 
    329                  
     358                output.write((s.substring(i, j) + "\r\n").getBytes()); 
     359 
    330360                /** 
    331361                 * If we stopped at a CR, ignore a possibly following LF. 
    332362                 */ 
    333                 if ((j < length - 1) && (bytes[j] == 0x0D) && (bytes[j + 1] == 0x0A)) { 
     363                if ((j < (length - 1)) && (bytes[j] == 0x0D) && 
     364                        (bytes[j + 1] == 0x0A)) { 
    334365                    j++; 
    335366                } 
    336                  
     367 
    337368                i = j + 1; 
    338369            } 
    339370        } 
     371 
    340372        output.flush(); 
    341373    } 
    342      
     374 
    343375    /** 
    344376     * Sends a string to the server, terminating it with a CRLF. 
     
    346378     * is a prepared protocol command. 
    347379     */ 
    348     public void sendCommand(String s) throws IOException { 
    349         if(globalConfig.getConnDebug()) { 
    350             EventLogger.logEvent(AppInfo.GUID, ("[SEND CMD] " + s).getBytes(), EventLogger.DEBUG_INFO); 
    351         } 
    352  
    353         if(s == null) { 
     380    public synchronized void sendCommand(String s) throws IOException { 
     381        if (globalConfig.getConnDebug()) { 
     382            EventLogger.logEvent(AppInfo.GUID, ("[SEND CMD] " + s).getBytes(), 
     383                EventLogger.DEBUG_INFO); 
     384        } 
     385 
     386        if (s == null) { 
    354387            output.write(CRLF, 0, 2); 
    355         } 
    356         else { 
    357             output.write((s+"\r\n").getBytes()); 
    358         } 
     388        } else { 
     389            output.write((s + "\r\n").getBytes()); 
     390        } 
     391 
    359392        output.flush(); 
    360393    } 
    361      
     394 
    362395    /** 
    363396     * Sends a string to the server. This method is used to bypass all 
     
    368401     * @see #send 
    369402     */ 
    370     public void sendRaw(String s) throws IOException { 
     403    public synchronized void sendRaw(String s) throws IOException { 
    371404        byte[] bytes = s.getBytes(); 
    372          
    373         if(globalConfig.getConnDebug()) { 
    374             EventLogger.logEvent(AppInfo.GUID, ("[SEND RAW]\r\n" + s).getBytes(), EventLogger.DEBUG_INFO); 
    375         } 
    376          
     405 
     406        if (globalConfig.getConnDebug()) { 
     407            EventLogger.logEvent(AppInfo.GUID, 
     408                ("[SEND RAW]\r\n" + s).getBytes(), EventLogger.DEBUG_INFO); 
     409        } 
     410 
    377411        output.write(bytes, 0, bytes.length); 
    378          
     412 
    379413        output.flush(); 
    380414    } 
     
    383417     * Returns the number of bytes available for reading. 
    384418     * Used to poll the connection without blocking. 
    385      *  
     419     * 
    386420     * @see InputStream#available() 
    387421     */ 
    388422    public int available() throws IOException { 
    389         if(fakeAvailable == -1) { 
    390                 return input.available(); 
    391         } 
    392         else { 
    393                 return fakeAvailable; 
    394         } 
    395     } 
    396      
     423        if (fakeAvailable == -1) { 
     424            return input.available(); 
     425        } else { 
     426            return fakeAvailable; 
     427        } 
     428    } 
     429 
    397430    /** 
    398431     * Receives a string from the server. This method is used internally for 
     
    404437     * @see #send 
    405438     */ 
    406     public String receive() throws IOException { 
     439    public synchronized String receive() throws IOException { 
    407440        /** 
    408441         * A note on how this method works and why it is designed the 
     
    432465         * but there's not much one can about that. 
    433466         */ 
    434         StringBuffer resultBuffer = new StringBuffer(); 
    435467        boolean stop = false; 
     468        resultBuffer.reset(); 
     469 
    436470        int actualAvailable = input.available(); 
    437471        int readBytes = 0; 
    438472        int count; 
    439          
     473 
    440474        /** 
    441475         * The "stop" flag will be set as soon as we have received 
     
    445479        while (!stop) { 
    446480            count = 0; 
    447              
     481 
    448482            /** 
    449483             * The inner block reads single bytes from the InputStream 
     
    453487            while (true) { 
    454488                int actual = input.read(buffer, count, 1); 
    455                  
     489 
    456490                /** 
    457491                 * If -1 is returned, the InputStream is already closed, 
     
    461495                 */ 
    462496                if (actual == -1) { 
    463                     EventLogger.logEvent(AppInfo.GUID, "Unable to read from socket, closing connection".getBytes(), EventLogger.INFORMATION); 
     497                    EventLogger.logEvent(AppInfo.GUID, 
     498                        "Unable to read from socket, closing connection".getBytes(), 
     499                        EventLogger.INFORMATION); 
     500 
    464501                    try { 
    465502                        close(); 
    466                     } catch (IOException e) { } 
    467                      
     503                    } catch (IOException e) { 
     504                    } 
     505 
    468506                    throw new IOException("Connection closed"); 
    469507                } 
    470                  
    471508                /** 
    472509                 * If no bytes have been received, we wait a little 
     
    476513                    try { 
    477514                        Thread.yield(); 
    478                     } catch (Exception e) { } 
    479                 } 
    480                  
     515                    } catch (Exception e) { 
     516                    } 
     517                } 
    481518                /** 
    482519                 * If a byte has been read, examine it and put it in the 
    483520                 * buffer. 
    484521                 */ 
     522 
    485523                // Note: We really should look for CRLF, and not use this 
    486524                // approach which screws up on mid-line LFs. (DK) 
     
    488526                    byte b = buffer[count]; 
    489527                    readBytes++; 
    490                      
     528 
    491529                    /** 
    492530                     * Ignore all CRs. 
     
    500538                    else if (b == 0x0A) { 
    501539                        stop = true; 
     540 
    502541                        break; 
    503542                    } 
     
    507546                    else { 
    508547                        count++; 
     548 
    509549                        if (count == buffer.length) { 
    510550                            break; 
     
    513553                } 
    514554            } 
    515             resultBuffer.append(new String(buffer, 0, count)); 
    516         } 
    517          
    518         if(globalConfig.getConnDebug()) { 
    519             EventLogger.logEvent(AppInfo.GUID, ("[RECV] " + resultBuffer.toString()).getBytes(), EventLogger.DEBUG_INFO); 
    520         } 
    521         if(actualAvailable > readBytes) { 
    522                 fakeAvailable = actualAvailable - readBytes; 
    523         } 
    524         else { 
    525                 fakeAvailable = -1; 
    526         } 
    527          
    528         return resultBuffer.toString(); 
     555 
     556            resultBuffer.write(buffer, 0, count); 
     557        } 
     558 
     559        String result = new String(resultBuffer.toArray()); 
     560 
     561        if (globalConfig.getConnDebug()) { 
     562            EventLogger.logEvent(AppInfo.GUID, 
     563                ("[RECV] " + result).getBytes(), 
     564                EventLogger.DEBUG_INFO); 
     565        } 
     566 
     567        if (actualAvailable > readBytes) { 
     568            fakeAvailable = actualAvailable - readBytes; 
     569        } else { 
     570            fakeAvailable = -1; 
     571        } 
     572 
     573        return result; 
    529574    } 
    530575} 
    531  
Note: See TracChangeset for help on using the changeset viewer.