// URLStreamHandler.java - Superclass of all stream protocol handlers.

/* Copyright (C) 1999  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.net;

/**
 * @author Warren Levy <warrenl@cygnus.com>
 * @date March 4, 1999.
 */

/**
 * Written using on-line Java Platform 1.2 API Specification, as well
 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
 * Status:  Believed complete and correct.
 */

public abstract class URLStreamHandler
{
  protected abstract URLConnection openConnection(URL u)
    throws java.io.IOException;

  protected void parseURL(URL u, String spec, int start, int limit)
  {
    String host = u.getHost();
    int port = u.getPort();
    String file = u.getFile();
    
    /* TBD: The JDK 1.2 doc specifically says that limit is the position
     * to stop parsing at and that it will be either the end of the string
     * or the position of '#'; thus the doc infers that this method does
     * not set the ref.
     */
    if (spec.regionMatches (start, "//", 0, 2))
      {
	int hostEnd;
	int colon;

	start += 2;
	int slash = spec.indexOf('/', start);
	if (slash >= 0) 
	  hostEnd = slash;
        else
	  hostEnd = limit;

	host = spec.substring (start, hostEnd);
	
	// Look for optional port number.  It is valid for the non-port
	// part of the host name to be null (e.g. a URL "http://:80").
	// TBD: JDK 1.2 in this case sets host to null rather than "";
	// this is undocumented and likely an unintended side effect in 1.2
	// so we'll be simple here and stick with "". Note that
	// "http://" or "http:///" produce a "" host in JDK 1.2.
	if ((colon = host.indexOf(':')) >= 0)
	  {
	    try
	      {
		port = Integer.parseInt(host.substring(colon + 1));
	      }
	    catch (NumberFormatException e)
	      {
		; // Ignore invalid port values; port is already set to u's
		  // port.
	      }
	    host = host.substring(0, colon);
	  }
	file = null;
	start = hostEnd;
      } 
    else if (host == null) 
      host = "";

    if (start < limit && spec.charAt(start) == '/') 
      {
	// This is an absolute path name; ignore any file context.
	file = spec.substring(start, limit);
      } 
    else if (file == null || file.length() <= 0)
      {
	// No file context available; just spec for file.
	file = "/" + spec.substring(start, limit);
      }
    else if (start < limit)
      {
	// Context is available, but only override it if there is a new file.
        // FIXME: unsure to what extent `/` and File.separatorChar
	//        can mix in URLs.  Ignore File.separatorChar for now.
	file = file.substring(0, file.lastIndexOf('/'))
		+ "/" + spec.substring(start, limit);
      }

    int index;

    // Replace "/./" with "/".  This probably isn't very efficient in
    // the general case, but it's probably not bad most of the time.
    while ((index = file.indexOf("/./")) >= 0)
      file = file.substring(0, index) + file.substring(index + 2);

    // Process "/../" correctly.  This probably isn't very efficient in
    // the general case, but it's probably not bad most of the time.
    while ((index = file.indexOf("/../")) >= 0)
      {
	// Strip of the previous directory - if it exists.
	int previous = file.lastIndexOf('/', index - 1);
	if (previous >= 0)
	  file = file.substring(0, previous) + file.substring(index + 3);
	else
	  break;
      }
    
    u.set(u.getProtocol(), host, port, file, u.getRef());
  }
  
  protected void setURL(URL u, String protocol, String host, int port,
			String file, String ref)
  {
    u.set(protocol, host, port, file, ref);
  }

  protected String toExternalForm(URL u)
  {
    String resStr, host, file, ref;
    int port;

    resStr = u.getProtocol() + ":";
    host = u.getHost();
    port = u.getPort();
    file = u.getFile();
    ref = u.getRef();

    // JDK 1.2 online doc infers that host could be null because it
    // explicitly states that file cannot be null, but is silent on host.
    //
    // Note that this produces different results from JDK 1.2 as JDK 1.2
    // ignores a non-default port if host is null or "".  That is inconsistent
    // with the spec since the result of this method is spec'ed so it can be
    // used to construct a new URL that is equivalent to the original.
    if (host == null)
      host = "";
    if (port >= 0 || ! (host.length() == 0))
      resStr = resStr + "//" + host + (port < 0 ? "" : ":" + port);

    resStr = resStr + file;

    if (ref != null)
      resStr = resStr + "#" + ref;

    return resStr;
  }
}
