JMU
Protocol Handlers
An Introduction with Examples in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Motivation
Returning to an Earlier Example

It would be nice if we could do something like...

javaexamples/sfp/ConnectionDriver.java (Fragment: 0)
                  url = new URL("sfp://"+sfpHost+":"+sfpPort+"/");

          connection = (SFPConnection)(url.openConnection());
          connection.connect();

          in  = (SFPInputStream)(connection.getInputStream());
          out = (SFPOutputStream)(connection.getOutputStream());

          // Useful code would go here

        
Returning to an Earlier Example (cont.)

The Relevant Classes in Java

images/custom_urls_java.gif
Returning to an Earlier Example (cont.)

SFPConnection

javaexamples/sfp/SFPConnection.java
        import java.io.*;
import java.net.*;
import java.util.*;



/**
 * A communications link with an SFP host
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James Madison University
 */
public class SFPConnection extends URLConnection
{
    private SFPSocket       s;

    public static final int DEFAULT_PORT = 5190;

    public static final int SIGNON       = 1;
    public static final int DATA         = 2;

    protected static final byte[] sfpon = 
     {(byte)'S',(byte)'F',(byte)'P',(byte)'O',
     (byte)'N',(byte)'\r',(byte)'\n',(byte)'\r',
     (byte)'\n'};


    /**
     * Construct a new SFPConnection
     *
     * @param u   The SFP URL of the host
     */
    public SFPConnection(URL u)
    {
       super(u);
    }

    /**
     * Connect with the SFP server
     */
    public synchronized void connect() throws IOException
    {
       int            port;
       String         host;

       if (!connected) 
       {
          port = url.getPort();
          if (port < 0) port = DEFAULT_PORT;
          host = url.getHost();

          s = new SFPSocket(host, port);

          connected = true;
       }
    }

    /**
     * Gets the content-type for this SFPConnection 
     *
     */
    public String getContentType()
    {
       return "binary/sfp";
    }

    /**
     * Get an InputStream for this SFPConnection 
     *
     * Note: This function will connect first if necessary
     */
    public synchronized InputStream getInputStream() throws IOException
    {
       if (!connected) connect();
       return s.getInputStream();
    }

    /**
     * Get an OutputStream for this SFPConnection 
     *
     * Note: This function will connect first if necessary
     */
    public synchronized OutputStream getOutputStream() throws IOException
    {
       if (!connected) connect();
       return s.getOutputStream();
    }
}
        
Returning to an Earlier Example (cont.)

SFPStreamHandler

javaexamples/sfp/SFPStreamHandler.java
        import java.io.*;
import java.net.*;
import java.util.*;


/**
 * A stream protocol handler for the SFP protocol
 *
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James madison University
 */
public class SFPStreamHandler extends URLStreamHandler
{



     /**
      * Opens a connection to an SFP host
      *
      * @param u   The URL of the SFP host (sfp://host:port/)
      * 
      */
    protected URLConnection openConnection(URL u) throws IOException
    {
        return new SFPConnection(u);
    }



    

     /**
      * Parses an SFP URL
      *
      * @param u      The URL to fill
      * @param spec   The String representation of the URL to parse
      * @param start  The character index at which parsing should start
      * @param limit  The character index at which parsing should stop
      * 
      */
    protected void parseURL(URL u, String spec, int start, int limit)
    {
        int             port;
        String          file, host, protocol, ref;
        StringTokenizer st;


        st = new StringTokenizer(spec.substring(start,limit), "/:");

        protocol = null;
        host = null;
        file = null;
        ref = null;
        port = SFPConnection.DEFAULT_PORT;

        try 
        {
           if (start == 0) protocol = st.nextToken().toLowerCase(); // sfp
            host = st.nextToken();
            port = Integer.parseInt(st.nextToken());
        } 
        catch (Exception e) 
        {
            // Use the default values
        }
        setURL(u, protocol, host, port, file, ref);
    }


     /**
      * Converts an SFP URL to a String
      *
      * @param u      The URL to convert
      * @return       A String representation of the SFP URL
      * 
      */
    protected String toExternalForm(URL u)
    {
        return "sfp://"+u.getHost()+":"+u.getPort();
    }


}
        
Returning to an Earlier Example (cont.)

SFPStreamHandlerFactory

javaexamples/sfp/SFPStreamHandlerFactory.java
        import java.net.*;

/**
 * Creates SFPStreamHandler objects
 *
 * Note: This is a very simple factory.  For example, it does not attempt
 * to re-use SFPStreamHandler objects that have been disposed of.
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James Madison University
 */
public class SFPStreamHandlerFactory implements URLStreamHandlerFactory
{


    /**
     * Create an appropriate URLStreamHandler
     *
     * @param protocol   The protocol to use
     * @return           The URLStreamHandler
     */
    public URLStreamHandler createURLStreamHandler(String protocol)
    {
        if (protocol.equalsIgnoreCase("sfp")) return (new SFPStreamHandler());
        else                                  return null;
    }

}
        
Returning to an Earlier Example (cont.)

Telling the URL Class the Kind of Connection to Create

javaexamples/sfp/ConnectionDriver.java (Fragment: 1)
                  URL.setURLStreamHandlerFactory(new SFPStreamHandlerFactory());

          url = new URL("sfp://"+sfpHost+":"+sfpPort+"/");

          connection = (SFPConnection)(url.openConnection());
          connection.connect();

          in  = (SFPInputStream)(connection.getInputStream());
          out = (SFPOutputStream)(connection.getOutputStream());

          // Useful code would go here

        
Some Observations