Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   *  Copyright (c) xlightweb.org, 2008 - 2010. All rights reserved.
   *
   *  This library is free software; you can redistribute it and/or
   *  modify it under the terms of the GNU Lesser General Public
   *  License as published by the Free Software Foundation; either
   *  version 2.1 of the License, or (at your option) any later version.
   *
   *  This library is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  *  Lesser General Public License for more details.
  *
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
  * The latest copy of this software may be found on http://www.xlightweb.org/
  */
 package org.xlightweb;
 
 
 import java.util.Map;
 

Author(s):
grro@xlightweb.org
 
 final class WebSocketHandlerAdapter {
     
     private static final Logger LOG = Logger.getLogger(WebSocketHandlerAdapter.class.getName());
     
     @SuppressWarnings("unchecked")
     private static final Map<ClassWebSocketHandlerInfowebSocketHandlerInfoCache = ConnectionUtils.newMapCache(25);
     
     
     private final IPostConnectInterceptor interceptor;
     private final AtomicBoolean isOnConnectCalled = new AtomicBoolean(false);
     private final AtomicBoolean isOnDisconnectCalled = new AtomicBoolean(false);
     private final WebSocketHandlerInfo handlerInfo;
     private final IWebSocketHandler handler;
     
     
     public WebSocketHandlerAdapter(IWebSocketHandler handlerIPostConnectInterceptor interceptor) {
         this. = handler;
         this. = getWebSocketHandlerInfo(handler);
         this. = interceptor;
     }
     
     
     public void onConnect(final WebSocketConnection con) {
         if (( != null) && !.getAndSet(true)) {
             
             if (.isUnsynchronized()) {
                 performOnConnect(con);
                 
             } else {
                 Runnable task = new Runnable() {
                     public void run() {
                        performOnConnect(con);
                     }
                 };
                 
                 if (.isOnConnectMultithreaded()) {
                     con.processMultithreaded(task);
                 } else {
                     con.processNonthreaded(task);
                 }
             }
         }
     }
     
     
     private void performOnConnect(WebSocketConnection con) {
         try {
             
             try {
                 .onConnect(con);
                 
             } catch (IOException ioe) {
                 if ( != null) {
                     .onConnectException(ioe);
                 }
                 
             } catch (Exception e) {
                 if ( != null) {
                     .onConnectException(new IOException(e.toString()));
                 }
            }
            
            if ( != null) {
                .onPostConnect();
            }
            
            performOnMessage(con);
            
        } catch (IOException ioe) {
            if (.isLoggable(.)) {
                .fine("[" + con.getId() + "] closing connection because an error has been occured by performing onConnect of " +  + " Reason: " + DataConverter.toString(ioe));
            }
            con.closeQuitly();
        } catch (Throwable t) {
            .warning("[" + con.getId() + "] closing connection. Error occured by performing onConnect of " +  +  " " + t.toString());
            con.closeQuitly();
        } 
    }
    public void onDisconnect(final WebSocketConnection conthrows IOException {
        if (( != null) && !.getAndSet(true)) {
            
            if (.isUnsynchronized()) {
                performOnConnect(con);
            } else {
                Runnable task = new Runnable() {
                    public void run() {
                        performOnDisconnect(con);
                    }
                };
                
                if (.isOnDisconnectMultithreaded()) {
                    con.processMultithreaded(task);
                } else {
                    con.processNonthreaded(task);
                }
            }
        }        
    }
    
    
    private void performOnDisconnect(WebSocketConnection con) {
        try {
            .onDisconnect(con);
        } catch (IOException ioe) {
            if (.isLoggable(.)) {
                .fine("[" + con.getId() + "] closing connection because an error has been occured by performing onDisconnect of " +  + " Reason: " + DataConverter.toString(ioe));
            }
            con.closeQuitly();
        } catch (Throwable t) {
            .warning("[" + con.getId() + "] closing connection. Error occured by performing onDisconnect of " +  +  " " + t.toString());
            con.closeQuitly();
        }
    }
    
    public void onMessage(final WebSocketConnection conthrows IOException {
        
        if ( != null) {
            
            if (.isUnsynchronized()) {
                performOnMessage(con);
            } else {
                Runnable task = new Runnable() {
                    public void run() {
                        performOnMessage(con);
                    }
                };
                
                if (.isOnMessageMultithreaded()) {
                    con.processMultithreaded(task);
                } else {
                    con.processNonthreaded(task);
                }
                con.processNonthreaded(task);
            }
        }
    }
    
    
    private void performOnMessage(WebSocketConnection con) {
        try {
            while (con.availableMessages() > 0) {
                int ver = con.getInQueueVersion();
                
                .onMessage(con);
                if (ver == con.getInQueueVersion()) {
                    return;
                }
            }
        } catch (IOException ioe) {
            if (.isLoggable(.)) {
                .fine("[" + con.getId() + "] closing connection because an error has been occured by performing onMessage of " +  + " Reason: " + DataConverter.toString(ioe));
            }
            con.closeQuitly();
        } catch (Throwable t) {
            .warning("[" + con.getId() + "] closing connection. Error occured by performing onMessage of " +  +  " " + t.toString());
            con.closeQuitly();
        }
    }
    
    
    
    private static WebSocketHandlerInfo getWebSocketHandlerInfo(Object webSocketHandler) {
        if (webSocketHandler == null) {
            if ( == null) {
                 = new WebSocketHandlerInfo(null);
            }
            return ;
        }
        WebSocketHandlerInfo webSocketHandlerInfo = .get(webSocketHandler.getClass());
        if (webSocketHandlerInfo == null) {
            webSocketHandlerInfo = new WebSocketHandlerInfo(webSocketHandler.getClass());
            .put(webSocketHandler.getClass(), webSocketHandlerInfo);
        }
        return webSocketHandlerInfo;
    }
    
    
    
    static final class WebSocketHandlerInfo  {
        
        private final boolean isUnsynchronized;
        private final boolean isOnConnectMultithreaded;
        private final boolean isOnMessageMultithreaded;
        private final boolean isOnDisconnectMultithreaded;
        @SuppressWarnings("unchecked")
        WebSocketHandlerInfo(Class clazz) {
            
            if ((clazz != null) &&  (IWebSocketHandler.class.isAssignableFrom(clazz))) {
                boolean isMultiThreaded = HttpUtils.isHandlerMultithreaded(clazztrue);
                 = IUnsynchronized.class.isAssignableFrom(clazz);
                 = HttpUtils.isMethodMultithreaded(clazz"onConnect"isMultiThreadedWebSocketConnection.class);
                 = HttpUtils.isMethodMultithreaded(clazz"onDisconnect"isMultiThreadedWebSocketConnection.class);
                 = HttpUtils.isMethodMultithreaded(clazz"onMessage"isMultiThreadedWebSocketConnection.class);
                
            } else { 
                 = true;
                 = false;
                 = false;
                 = false;
            }
        }
        public boolean isOnConnectMultithreaded() {
            return ;
        }
        
        public boolean isOnMessageMultithreaded() {
            return ;
        }
        
        public boolean isOnDisconnectMultithreaded() {
            return ;
        }
        
        public boolean isUnsynchronized() {
            return ;
        }
    }
    
    
    static interface IPostConnectInterceptor {
        
        void onConnectException(IOException ioe);
        
        void onPostConnect() throws IOException ;
    }
New to GrepCode? Check out our FAQ X