Class RequestProcessor

  • All Implemented Interfaces:
    java.lang.Runnable

    public class RequestProcessor
    extends java.lang.Thread
    Processes HTTP "remote control" requests.
    • Nested Class Summary

      • Nested classes/interfaces inherited from class java.lang.Thread

        java.lang.Thread.State, java.lang.Thread.UncaughtExceptionHandler
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private static java.util.Map<java.lang.String,​java.lang.Class<? extends RequestHandler>> handlers
      Collection of request handlers.
      static java.lang.String JOSM_REMOTE_CONTROL
      The string "JOSM RemoteControl"
      private static java.util.concurrent.locks.ReentrantLock ORDER_LOCK
      This is purely used to ensure that remote control commands are executed in the order in which they are received
      static java.lang.String PROTOCOLVERSION
      RemoteControl protocol version.
      private java.net.Socket request
      The socket this processor listens on
      private static java.nio.charset.Charset RESPONSE_CHARSET  
      private static java.lang.String RESPONSE_TEMPLATE  
      • Fields inherited from class java.lang.Thread

        MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
    • Constructor Summary

      Constructors 
      Constructor Description
      RequestProcessor​(java.net.Socket request)
      Constructor
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static void addRequestHandlerClass​(java.lang.String command, java.lang.Class<? extends RequestHandler> handler)
      Add external request handler.
      private static void addRequestHandlerClass​(java.lang.String command, java.lang.Class<? extends RequestHandler> handler, boolean silent)
      Add external request handler.
      private static void callHandler​(java.lang.String url, java.lang.String command, java.io.Writer out, java.lang.String sender)
      Call the handler for the command
      static RequestHandler getHandlerInfo​(java.lang.String cmd)
      Returns the information for a given handler.
      static java.util.stream.Stream<RequestHandler> getHandlersInfo​(java.util.Collection<java.lang.String> handlers)
      Returns the information for the given (if null: all) handlers.
      static java.lang.String getUsageAsHtml()
      Reports HTML message with the description of all available commands
      static void initialize()
      Force the class to initialize and load the handlers
      private static java.util.Map<java.lang.String,​java.lang.String> parseHeaders​(java.io.BufferedReader in)
      Parse the headers from the request
      private static java.lang.String parseSender​(java.util.Map<java.lang.String,​java.lang.String> headers, java.net.Socket request)
      Attempt to figure out who sent the request
      static void processRequest​(java.net.Socket request)
      Spawns a new thread for the request
      private static void realRun​(java.io.BufferedReader in, java.io.Writer out, java.net.Socket request)
      Perform the actual commands
      void run()
      The work is done here.
      private static void sendBadGateway​(java.io.Writer out, java.lang.String help)
      Sends a 502 error: bad gateway
      private static void sendBadRequest​(java.io.Writer out, java.lang.String help)
      Sends a 400 error: bad request
      private static void sendError​(java.io.Writer out, int errorCode, java.lang.String errorName, java.lang.String help)  
      private static void sendErrorHtml​(java.io.Writer out, int errorCode, java.lang.String errorName, java.lang.String helpHtml)  
      private static void sendForbidden​(java.io.Writer out, java.lang.String help)
      Sends a 403 error: forbidden
      private static void sendHeader​(java.io.Writer out, java.lang.String status, java.lang.String contentType, boolean endHeaders)
      Send common HTTP headers to the client.
      private static void sendInternalError​(java.io.Writer out, java.lang.String help)
      Sends a 500 error: internal server error
      private static void sendNotImplemented​(java.io.Writer out)
      Sends a 501 error: not implemented
      • Methods inherited from class java.lang.Thread

        activeCount, checkAccess, clone, countStackFrames, currentThread, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, onSpinWait, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, suspend, toString, yield
      • Methods inherited from class java.lang.Object

        equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • ORDER_LOCK

        private static final java.util.concurrent.locks.ReentrantLock ORDER_LOCK
        This is purely used to ensure that remote control commands are executed in the order in which they are received
      • RESPONSE_CHARSET

        private static final java.nio.charset.Charset RESPONSE_CHARSET
      • PROTOCOLVERSION

        public static final java.lang.String PROTOCOLVERSION
        RemoteControl protocol version. Change minor number for compatible interface extensions. Change major number in case of incompatible changes.
      • request

        private final java.net.Socket request
        The socket this processor listens on
      • handlers

        private static final java.util.Map<java.lang.String,​java.lang.Class<? extends RequestHandler>> handlers
        Collection of request handlers. Will be initialized with default handlers here. Other plug-ins can extend this list by using @see addRequestHandler
    • Constructor Detail

      • RequestProcessor

        public RequestProcessor​(java.net.Socket request)
        Constructor
        Parameters:
        request - A socket to read the request.
    • Method Detail

      • processRequest

        public static void processRequest​(java.net.Socket request)
        Spawns a new thread for the request
        Parameters:
        request - The request to process
      • addRequestHandlerClass

        public static void addRequestHandlerClass​(java.lang.String command,
                                                  java.lang.Class<? extends RequestHandler> handler)
        Add external request handler. Can be used by other plug-ins that want to use remote control.
        Parameters:
        command - The command to handle.
        handler - The additional request handler.
      • addRequestHandlerClass

        private static void addRequestHandlerClass​(java.lang.String command,
                                                   java.lang.Class<? extends RequestHandler> handler,
                                                   boolean silent)
        Add external request handler. Message can be suppressed. (for internal use)
        Parameters:
        command - The command to handle.
        handler - The additional request handler.
        silent - Don't show message if true.
      • initialize

        public static void initialize()
        Force the class to initialize and load the handlers
      • run

        public void run()
        The work is done here.
        Specified by:
        run in interface java.lang.Runnable
        Overrides:
        run in class java.lang.Thread
      • realRun

        private static void realRun​(java.io.BufferedReader in,
                                    java.io.Writer out,
                                    java.net.Socket request)
                             throws java.io.IOException
        Perform the actual commands
        Parameters:
        in - The reader for incoming data
        out - The writer for outgoing data
        request - The actual request
        Throws:
        java.io.IOException - Usually occurs if one of the Writer methods has problems.
      • parseHeaders

        private static java.util.Map<java.lang.String,​java.lang.String> parseHeaders​(java.io.BufferedReader in)
                                                                                    throws java.io.IOException
        Parse the headers from the request
        Parameters:
        in - The request reader
        Returns:
        The map of headers
        Throws:
        java.io.IOException - See BufferedReader.readLine()
      • parseSender

        private static java.lang.String parseSender​(java.util.Map<java.lang.String,​java.lang.String> headers,
                                                    java.net.Socket request)
        Attempt to figure out who sent the request
        Parameters:
        headers - The headers (we currently look for Referer)
        request - The request to look at
        Returns:
        The sender (or "localhost" if none could be found)
      • callHandler

        private static void callHandler​(java.lang.String url,
                                        java.lang.String command,
                                        java.io.Writer out,
                                        java.lang.String sender)
                                 throws java.lang.ReflectiveOperationException,
                                        java.io.IOException
        Call the handler for the command
        Parameters:
        url - The request URL
        command - The command we are using
        out - The writer to use for indicating success or failure
        sender - The sender of the request
        Throws:
        java.lang.ReflectiveOperationException - If the handler class has an issue
        java.io.IOException - If one of the Writer methods has issues
      • sendError

        private static void sendError​(java.io.Writer out,
                                      int errorCode,
                                      java.lang.String errorName,
                                      java.lang.String help)
                               throws java.io.IOException
        Throws:
        java.io.IOException
      • sendErrorHtml

        private static void sendErrorHtml​(java.io.Writer out,
                                          int errorCode,
                                          java.lang.String errorName,
                                          java.lang.String helpHtml)
                                   throws java.io.IOException
        Throws:
        java.io.IOException
      • sendInternalError

        private static void sendInternalError​(java.io.Writer out,
                                              java.lang.String help)
                                       throws java.io.IOException
        Sends a 500 error: internal server error
        Parameters:
        out - The writer where the error is written
        help - Optional HTML help content to display, can be null
        Throws:
        java.io.IOException - If the error can not be written
      • sendNotImplemented

        private static void sendNotImplemented​(java.io.Writer out)
                                        throws java.io.IOException
        Sends a 501 error: not implemented
        Parameters:
        out - The writer where the error is written
        Throws:
        java.io.IOException - If the error can not be written
      • sendBadGateway

        private static void sendBadGateway​(java.io.Writer out,
                                           java.lang.String help)
                                    throws java.io.IOException
        Sends a 502 error: bad gateway
        Parameters:
        out - The writer where the error is written
        help - Optional HTML help content to display, can be null
        Throws:
        java.io.IOException - If the error can not be written
      • sendForbidden

        private static void sendForbidden​(java.io.Writer out,
                                          java.lang.String help)
                                   throws java.io.IOException
        Sends a 403 error: forbidden
        Parameters:
        out - The writer where the error is written
        help - Optional HTML help content to display, can be null
        Throws:
        java.io.IOException - If the error can not be written
      • sendBadRequest

        private static void sendBadRequest​(java.io.Writer out,
                                           java.lang.String help)
                                    throws java.io.IOException
        Sends a 400 error: bad request
        Parameters:
        out - The writer where the error is written
        help - Optional help content to display, can be null
        Throws:
        java.io.IOException - If the error can not be written
      • sendHeader

        private static void sendHeader​(java.io.Writer out,
                                       java.lang.String status,
                                       java.lang.String contentType,
                                       boolean endHeaders)
                                throws java.io.IOException
        Send common HTTP headers to the client.
        Parameters:
        out - The Writer
        status - The status string ("200 OK", "500", etc)
        contentType - The content type of the data sent
        endHeaders - If true, adds a new line, ending the headers.
        Throws:
        java.io.IOException - When error
      • getHandlersInfo

        public static java.util.stream.Stream<RequestHandlergetHandlersInfo​(java.util.Collection<java.lang.String> handlers)
        Returns the information for the given (if null: all) handlers.
        Parameters:
        handlers - the handlers
        Returns:
        the information for the given (if null: all) handlers
      • getHandlerInfo

        public static RequestHandler getHandlerInfo​(java.lang.String cmd)
        Returns the information for a given handler.
        Parameters:
        cmd - handler key
        Returns:
        the information for the given handler
      • getUsageAsHtml

        public static java.lang.String getUsageAsHtml()
                                               throws java.lang.ReflectiveOperationException
        Reports HTML message with the description of all available commands
        Returns:
        HTML message with the description of all available commands
        Throws:
        java.lang.ReflectiveOperationException - if a reflective operation fails for one handler class