
/* **************************************************************************

  $Archive: /njcl_v2/src/com/novell/utility/naming/URLParser.java $
  $Revision: 3 $
  $Modtime: 7/10/02 1:47p $
 
  Copyright (c) 1998 Novell, Inc.  All Rights Reserved.

  THIS WORK IS  SUBJECT  TO  U.S.  AND  INTERNATIONAL  COPYRIGHT  LAWS  AND
  TREATIES.   NO  PART  OF  THIS  WORK MAY BE  USED,  PRACTICED,  PERFORMED
  COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,  ABRIDGED, CONDENSED,
  EXPANDED,  COLLECTED,  COMPILED,  LINKED,  RECAST, TRANSFORMED OR ADAPTED
  WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC. ANY USE OR EXPLOITATION
  OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO
  CRIMINAL AND CIVIL LIABILITY.

****************************************************************************/

package com.novell.utility.naming;


import java.net.MalformedURLException;

import javax.naming.NamingException;


/** @internal
 * Parses URL names into scheme, user, password, host, port, and path
 * See RFC 1738 for details.
 * this has the exception of allowing the scheme and the :// to be optional
 */
public class URLParser
{
//NOTE:  set defaults?
   private String url = null;
   private String scheme = null;
   private String user = null;
   private String password = null;
   private String host = null;
   private int port = 0;
   private String path = null;



   /**
    * Constructor that takes a url.
    * The url may also be set later by calling setURL
    */
   public URLParser (String url)
      throws NamingException
   {
      setURL (url);
   }

   /**
    * Sets the internal url and parses it
    *
    */
   public void setURL (String url)
      throws NamingException
   {
      try
      {
         this.url = url;
         parse ();
      }
      catch (MalformedURLException e)
      {
         NamingException ne = new NamingException ();
         ne.setRootCause (e);
         throw ne;
      }
   }

   /**
    * Returns the raw URL
    *
    */
   public String getURL ()
   {
      return url;
   }

   /**
    * Returns the scheme part of the URL (text before ://).
    * null if no scheme was specified.
    */
   public String getScheme ()
   {
      return scheme;
   }

   /**
    * Returns the user.  null if not specified
    *
    */
   public String getUser ()
   {
      return user;
   }

   /**
    * Returns the password.  null if not specified
    *
    */
   public String getPassword ()
   {
      return password;
   }

   /**
    * Returns the host.  null if not specified
    *
    */
   public String getHost ()
   {
      return host;
   }

   /**
    * Returns the port.  0 if not specified
    *
    */
   public int getPort ()
   {
      return port;
   }

   /**
    * Returns the path.  null if not specified
    *
    */
   public String getPath ()
   {
      return path;
   }

   /**
    * Parses the URL into its atomic componenets
    *
    */
   private void parse ()
      throws MalformedURLException
   {
      int index = 0;
      String temp;

      if (url == null || url.equals (""))
      {
         // Ignore
         setDefaults ();
         return;
      }

      // Parse scheme
      int schemeEnd = url.indexOf ("://");

      if (schemeEnd < 0)
      {
         scheme = null;
      }
      else
      {
         scheme = url.substring (0, schemeEnd);
         index = schemeEnd + 3;
      }

      // Parse user and password
/*

BBerg: Defect #299913 - currently it appears that no provider depends on this feature
       however regression testing is needed to prove that assumption

      int userEnd = url.indexOf ('@');

      if (userEnd < 0)
      {
         user = null;
         password = null;
      }
      else
      {
         // Isolate "user:password"
         temp = url.substring (index, userEnd);

         index = userEnd + 1;

         userEnd = temp.indexOf (':');

         if (userEnd < 0)
         {
            // No password
            user = temp;
            password = null;
         }
         else
         {
            user = temp.substring (0, userEnd);
            password = temp.substring (userEnd + 1);
         }
      }
*/

      // Parse host, port and path
      temp = url.substring (index);

      int hostEnd = temp.indexOf ('/');

      if (hostEnd < 0)
      {
         // No path;
         path = null;
      }
      else
      {
         // Set path
         path = temp.substring (hostEnd + 1);

         // Isolate "host:port"
         temp = temp.substring (0, hostEnd);
      }

      hostEnd = temp.indexOf (':');

      if (hostEnd < 0)
      {
         // No port
         host = temp;
         port = 0;
      }
      else
      {
         host = temp.substring (0, hostEnd);
         try
         {
            port = Integer.parseInt (temp.substring (hostEnd + 1));
         }
         catch (NumberFormatException e)
         {
            throw new MalformedURLException (e.getMessage ());
         }
      }
   }

   /**
    * Dumps the URL both in long form and its atomic parts.
    * This is for debugging.
    */
   public String toString ()
   {
      StringBuffer parts = new StringBuffer ();
      StringBuffer concat = new StringBuffer ();

      if (scheme != null)
      {
         parts.append ("scheme: " + scheme + '\n');
         concat.append (scheme);
         concat.append ("://");
      }

      if (user != null)
      {
         parts.append ("user: " + user + '\n');
         concat.append (user);
      }

      if (password != null)
      {
         parts.append ("password: " + password + '\n');
         concat.append (':');
         concat.append (password);
      }

      if (user != null || password != null)
      {
         concat.append ('@');
      }

      if (host != null)
      {
         parts.append ("host: " + host + '\n');
         concat.append (host);
      }

      if (port != 0)
      {
         parts.append ("port: " + port + '\n');
         concat.append (':');
         concat.append (port);
      }

      if (path != null)
      {
         parts.append ("path: " + path + '\n');
         concat.append ('/');
         concat.append (path);
      }

      return concat.toString () + '\n' + parts.toString ();
   }

   /**
    * Sets all members to default values
    *
    */
   private void setDefaults ()
   {
      url = null;
      scheme = null;
      user = null;
      password = null;
      host = null;
      port = 0;
      path = null;
   }

} // URLParser
