Author: elecharny
Date: Tue Dec  6 22:04:58 2011
New Revision: 1211201

URL: http://svn.apache.org/viewvc?rev=1211201&view=rev
Log:
o Added the IoSession.isCreated() method
o Added the changeState(SessionState from, SessionState to) method
o Protected the session state with a ReentrantReadWriteLock
o Added the processHandShake method (not finished yet)
o Some other minor refactoring

Modified:
    mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java
    mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java
    mina/trunk/core/src/main/java/org/apache/mina/session/SslHelper.java
    
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java
    
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioTcpSession.java

Modified: mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java?rev=1211201&r1=1211200&r2=1211201&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java Tue Dec  6 
22:04:58 2011
@@ -89,13 +89,6 @@ public interface IoSession {
     /* READ / WRITE / CLOSE */
 
     /**
-     * Tells if the session is currently connected and able to process 
incoming requests and to send outgoing responses.
-     * 
-     * @return <code>true</code> if this session is connected with remote peer.
-     */
-    boolean isConnected();
-
-    /**
      * Tells if the session is currently closed.
      * 
      * @return <code>true</code> if this session is disconnected with remote 
peer.
@@ -110,6 +103,20 @@ public interface IoSession {
     boolean isClosing();
 
     /**
+     * Tells if the session is currently connected and able to process 
incoming requests and to send outgoing responses.
+     * 
+     * @return <code>true</code> if this session is connected with remote peer.
+     */
+    boolean isConnected();
+
+    /**
+     * Tells if the session is created.
+     * 
+     * @return <code>true</code> if this session is created.
+     */
+    boolean isCreated();
+
+    /**
      * Tells if the session is processing a SSL/TLS handshake.
      * 
      * @return <code>true</tt> if and only if this session is processing a 
SSL/TLS handshake.
@@ -124,6 +131,27 @@ public interface IoSession {
     boolean isSecured();
     
     /**
+     * Changes the session's state from a given state to another state. Not 
all the
+     * transition are allowed. Here is the list of all the possible 
transitions :<br/>
+     * <ul>
+     *   <li>CREATED   -> CONNECTED</li>
+     *   <li>CREATED   -> SECURING</li>
+     *   <li>CREATED   -> CLOSING</li>
+     *   <li>CONNECTED -> SECURING</li>
+     *   <li>CONNECTED -> CLOSING</li>
+     *   <li>SECURING  -> SECURED</li>
+     *   <li>SECURING  -> CLOSING</li>
+     *   <li>SECURED   -> CONNECTED</li>
+     *   <li>SECURED   -> CLOSING</li>
+     *   <li>CLOSING   -> CLOSED</li>
+     * </ul>
+     * 
+     * @param from The initial SessionState
+     * @param to The final SessionState
+     */
+    void changeState(SessionState from, SessionState to) throws 
IllegalStateException;
+    
+    /**
      * Initializes the SSL/TLS environment for this session.
      * 
      * @param sslContext The SLLCOntext instance to use.
@@ -275,8 +303,6 @@ public interface IoSession {
      */
     Set<String> getAttributeNames();
 
-    SessionState getState();
-
     /**
      * State of a {@link IoSession}
      * 
@@ -284,7 +310,7 @@ public interface IoSession {
      * 
      */
     public enum SessionState {
-        CREATED, CONNECTED, CLOSING, CLOSED, SECURING, CONNECTED_SECURED
+        CREATED, CONNECTED, CLOSING, CLOSED, SECURING, SECURED
     }
 
     /* SESSION WRITING */

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java?rev=1211201&r1=1211200&r2=1211201&view=diff
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java 
(original)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java 
Tue Dec  6 22:04:58 2011
@@ -82,8 +82,19 @@ public abstract class AbstractIoSession 
 
     protected final Object stateMonitor = new Object();
 
+    /** The session's state : one of CREATED, CONNECTED, CLOSING, CLOSED, 
SECURING, CONNECTED_SECURED */
     protected volatile SessionState state;
     
+    /** A lock to protect the access to the session's state */
+    private final ReadWriteLock stateLock = new ReentrantReadWriteLock();
+    
+    /** A Read lock on the reentrant session's state lock */
+    private final Lock stateReadLock = stateLock.readLock();
+
+    /** A Write lock on the reentrant session's state lock */
+    private final Lock stateWriteLock = stateLock.writeLock();
+
+
     /** Tells if the session is secured or not */
     protected volatile boolean secured;
 
@@ -132,7 +143,13 @@ public abstract class AbstractIoSession 
      */
     @Override
     public boolean isClosed() {
-        return state == SessionState.CLOSED;
+        try {
+            stateReadLock.lock();
+            
+            return state == SessionState.CLOSED;
+        } finally {
+            stateReadLock.unlock();
+        }
     }
 
     /**
@@ -140,7 +157,13 @@ public abstract class AbstractIoSession 
      */
     @Override
     public boolean isClosing() {
-        return state == SessionState.CLOSING;
+        try {
+            stateReadLock.lock();
+            
+            return state == SessionState.CLOSING;
+        } finally {
+            stateReadLock.unlock();
+        }
     }
     
     /**
@@ -148,7 +171,27 @@ public abstract class AbstractIoSession 
      */
     @Override
     public boolean isConnected() {
-        return state == SessionState.CONNECTED;
+        try {
+            stateReadLock.lock();
+            
+            return state == SessionState.CONNECTED;
+        } finally {
+            stateReadLock.unlock();
+        }
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCreated() {
+        try {
+            stateReadLock.lock();
+            
+            return state == SessionState.CREATED;
+        } finally {
+            stateReadLock.unlock();
+        }
     }
 
     /**
@@ -156,7 +199,13 @@ public abstract class AbstractIoSession 
      */
     @Override
     public boolean isSecuring() {
-        return state == SessionState.SECURING;
+        try {
+            stateReadLock.lock();
+            
+            return state == SessionState.SECURING;
+        } finally {
+            stateReadLock.unlock();
+        }
     }
 
     /**
@@ -164,11 +213,91 @@ public abstract class AbstractIoSession 
      */
     @Override
     public boolean isConnectedSecured() {
-        return state == SessionState.CONNECTED_SECURED;
+        try {
+            stateReadLock.lock();
+            
+            return state == SessionState.SECURED;
+        } finally {
+            stateReadLock.unlock();
+        }
     }
-
-    public SessionState getState() {
-        return state;
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void changeState(SessionState from, SessionState to) throws 
IllegalStateException {
+        try {
+            stateWriteLock.lock();
+            
+            switch (from) {
+                case CREATED :
+                    switch (to) {
+                        case CONNECTED :
+                        case SECURING :
+                        case CLOSING :
+                            state = to;
+                            break;
+                            
+                        default :
+                            throw new IllegalStateException("Cannot transit 
from " + from + " to " + to );
+                    }
+                    
+                    break;
+                    
+                case CONNECTED :
+                    switch (to) {
+                        case SECURING :
+                        case CLOSING :
+                            state = to;
+                            break;
+                            
+                        default :
+                            throw new IllegalStateException("Cannot transit 
from " + from + " to " + to );
+                    }
+                    
+                    break;
+                    
+                case SECURING :
+                    switch (to) {
+                        case SECURED :
+                        case CLOSING :
+                            state = to;
+                            break;
+                            
+                        default :
+                            throw new IllegalStateException("Cannot transit 
from " + from + " to " + to );
+                    }
+                    
+                    break;
+                    
+                    
+                case SECURED :
+                    switch (to) {
+                        case CONNECTED :
+                        case CLOSING :
+                            state = to;
+                            break;
+                            
+                        default :
+                            throw new IllegalStateException("Cannot transit 
from " + from + " to " + to );
+                    }
+                    
+                    break;
+                case CLOSING :
+                    if (to != SessionState.CLOSED) {
+                        throw new IllegalStateException("Cannot transit from " 
+ from + " to " + to );
+                    }
+
+                    state = to;
+                    
+                    break;
+                    
+                case CLOSED :
+                    throw new IllegalStateException("The session is already 
closed. cannot switch to " + to );
+            }
+        } finally {
+            stateWriteLock.unlock();
+        }
     }
 
     //------------------------------------------------------------------------

Modified: mina/trunk/core/src/main/java/org/apache/mina/session/SslHelper.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/session/SslHelper.java?rev=1211201&r1=1211200&r2=1211201&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/session/SslHelper.java 
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/session/SslHelper.java Tue 
Dec  6 22:04:58 2011
@@ -33,12 +33,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * An helper class used to manage everyting related to SSL/TLS establishement
+ * An helper class used to manage everything related to SSL/TLS establishement
  * and management.
  * 
  * @author <a href="http://mina.apache.org";>Apache MINA Project</a>
  */
-/** No qualifier */ class SslHelper
+public class SslHelper
 {
     /** A logger for this class */
     private final static Logger LOGGER = 
LoggerFactory.getLogger(SslHelper.class);
@@ -95,7 +95,7 @@ import org.slf4j.LoggerFactory;
     /**
      * @return The associated SSLEngine
      */
-    /* no qualifier */ SSLEngine getEngine() {
+    public SSLEngine getEngine() {
         return sslEngine;
     }
 

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java?rev=1211201&r1=1211200&r2=1211201&view=diff
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java
 (original)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java
 Tue Dec  6 22:04:58 2011
@@ -36,7 +36,9 @@ import java.util.concurrent.ConcurrentLi
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
 
 import org.apache.mina.api.IoServer;
 import org.apache.mina.api.IoService;
@@ -46,6 +48,7 @@ import org.apache.mina.service.AbstractI
 import org.apache.mina.service.SelectorProcessor;
 import org.apache.mina.service.SelectorStrategy;
 import org.apache.mina.session.DefaultWriteFuture;
+import org.apache.mina.session.SslHelper;
 import org.apache.mina.session.WriteRequest;
 import org.apache.mina.transport.tcp.nio.NioTcpServer;
 import org.slf4j.Logger;
@@ -457,13 +460,41 @@ public class NioSelectorProcessor implem
                 
                 if (session.isSecured() && !session.isConnectedSecured()) {
                     // Process the SSL handshake now
-                    //processHandShake(session, readBuffer);
+                    processHandShake(session, readBuffer);
                 } else {
                     session.getFilterChain().processMessageReceived(session, 
readBuffer);
                 }
             }
         }
         
+        private void processHandShake( IoSession session, ByteBuffer buffer) 
throws SSLException{
+            SslHelper sslHelper = session.getAttribute( IoSession.SSL_HELPER );
+            
+            SSLEngine engine = sslHelper.getEngine();
+            
+            HandshakeStatus hsStatus = engine.getHandshakeStatus();
+            
+            while ((hsStatus != HandshakeStatus.FINISHED) && (hsStatus != 
HandshakeStatus.NOT_HANDSHAKING)) {
+                switch (hsStatus) {
+                    case NOT_HANDSHAKING :
+                        // This is the very first step. We have to initialize 
the handShake
+                        engine.beginHandshake();
+                        break;
+                        
+                    case NEED_TASK :
+                    case NEED_WRAP :
+                    case NEED_UNWRAP :
+                    case FINISHED :
+                        if ( LOGGER.isDebugEnabled()) {
+                            LOGGER.debug("{} processing the FINISHED state", 
session);
+                        }
+                        
+                        session.getState().
+                        break;
+                }
+            }
+        }
+        
         /**
          * Processes the Write action for the given SelectionKey
          */

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioTcpSession.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioTcpSession.java?rev=1211201&r1=1211200&r2=1211201&view=diff
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioTcpSession.java 
(original)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioTcpSession.java 
Tue Dec  6 22:04:58 2011
@@ -219,7 +219,8 @@ public class NioTcpSession extends Abstr
      * Set this session status as connected. To be called by the processor 
selecting/polling this session.
      */
     void setConnected() {
-        if (getState() != SessionState.CREATED) {
+        
+        if (!isCreated()) {
             throw new RuntimeException("Trying to open a non created session");
         }
         state = SessionState.CONNECTED;


Reply via email to