package net.sourceforge.guacamole.net.basic;

/*
 *  Guacamole - Clientless Remote Desktop
 *  Copyright (C) 2010  Michael Jumper
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import net.sourceforge.guacamole.GuacamoleException;

/**
 * Simple HttpServlet which outputs XML containing a list of all authorized
 * configurations for the current user.
 * 
 * @author Michael Jumper
 */
public class WebSocketSupportLoader implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {

        try {

            // Attempt to find WebSocket servlet
            Class<Servlet> servlet = (Class<Servlet>) GuacamoleClassLoader.getInstance().findClass(
                "net.sourceforge.guacamole.net.basic.BasicGuacamoleTunnelServlet"
                //"net.sourceforge.guacamole.net.basic.BasicGuacamoleWebSocketTunnelServlet"
            ); 

            // Dynamically add servlet IF SERVLET 3.0 API AVAILABLE!
            try {

                // Get servlet registration class
                Class regClass = Class.forName("javax.servlet.ServletRegistration");

                // Get and invoke addServlet()
                Method addServlet = ServletContext.class.getMethod("addServlet", String.class, Class.class);
                Object reg = addServlet.invoke(sce.getServletContext(), "WebSocketTunnel", servlet);

                // Get and invoke addMapping()
                Method addMapping = regClass.getMethod("addMapping", String[].class);
                addMapping.invoke(reg, (Object) new String[]{"/websocket-tunnel"});

                // If we succesfully load and register the WebSocket tunnel servlet,
                // WebSocket is supported.
                System.err.println("WebSocket support found!");

            }
            catch (ClassNotFoundException e) {
                // Servlet API 3.0 unsupported
                System.err.println("Servlet API 3.0 not found.");
            }
            catch (NoSuchMethodException e) {
                // Servlet API 3.0 unsupported
                System.err.println("Servlet API 3.0 not found.");
            }
            catch (IllegalAccessException e) {
            }
            catch (InvocationTargetException e) {
            }

        }
        catch (ClassNotFoundException e) {
            
            // If no such servlet class, WebSocket support not present
            System.err.println("WebSocket support not found.");

        }
        catch (GuacamoleException e) {
            e.printStackTrace();
        }

    }

}


@@ -1099,16 +1099,73 @@
 ception;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0A/**%0A *
@@ -1176,112 +1176,378 @@
 ple 
-Http
 Servlet
- which outputs XML containing a list of all authorized%0A * configurations for the current user
+ContextListener which loads a WebSocket tunnel implementation%0A * if available, using the Servlet 3.0 API to dynamically load and install%0A * the tunnel servlet.%0A * %0A * Note that because Guacamole depends on the Servlet 2.5 API, and 3.0 may%0A * not be available or needed if WebSocket is not desired, the 3.0 API is%0A * detected and invoked dynamically via reflection
 .%0A *
@@ -1647,24 +1647,108 @@
 Listener %7B%0A%0A
+    private Logger logger = LoggerFactory.getLogger(WebSocketSupportLoader.class);%0A%0A
     @Overrid
@@ -2077,92 +2077,8 @@
     
-%22net.sourceforge.guacamole.net.basic.BasicGuacamoleTunnelServlet%22%0A                //
 %22net
@@ -3009,34 +3009,27 @@
         
-System.err.println
+logger.info
 (%22WebSoc
@@ -3045,17 +3045,28 @@
 rt found
-!
+ and loaded.
 %22);%0A%0A   
@@ -3068,34 +3068,76 @@
 %0A%0A            %7D%0A
-  
+%0A            // Servlet API 3.0 unsupported%0A
           catch 
@@ -3122,32 +3122,34 @@
 orted%0A          
+  
 catch (ClassNotF
@@ -3187,73 +3187,20 @@
     
-// Servlet API 3.0 unsupported%0A                System.err.println
+logger.error
 (%22Se
@@ -3216,32 +3216,35 @@
  3.0 not found.%22
+, e
 );%0A            %7D
@@ -3298,35 +3298,46 @@
                 
-// 
+logger.error(%22
 Servlet API 3.0 
@@ -3340,56 +3340,67 @@
 3.0 
-unsupported%0A                System.err.println(%22
+found, but incomplete.%22, e);%0A            %7D%0A%0A            // 
 Serv
@@ -3415,35 +3415,36 @@
 3.0 
-not 
 found
-.%22);%0A            %7D
+, but errors during use
 %0A   
@@ -3479,32 +3479,109 @@
 sException e) %7B%0A
+                logger.error(%22Unable to load WebSocket tunnel servlet.%22, e);%0A
             %7D%0A  
@@ -3644,63 +3644,80 @@
     
-%7D%0A%0A
     
-    %7D%0A        catch (ClassNotFoundException e) %7B
+logger.error(%22Internal error loading WebSocket tunnel servlet.%22, e);
 %0A   
@@ -3725,21 +3725,30 @@
         
-%0A    
+%7D%0A%0A        %7D%0A%0A
         
@@ -3818,144 +3818,259 @@
     
-    System.err.println(%22WebSocket support not found.%22);%0A%0A        %7D%0A        catch (GuacamoleException e) %7B%0A            e.printStackTrace(
+catch (ClassNotFoundException e) %7B%0A            logger.info(%22WebSocket support not found.%22);%0A        %7D%0A%0A        // Log all GuacamoleExceptions%0A        catch (GuacamoleException e) %7B%0A            logger.error(%22Unable to load/detect WebSocket support.%22, e
 );%0A 

Use logger, fix JavaDoc.