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

  $Archive: /njcl/src/com/novell/service/file/nw/naming/FileSystemNameParser.java $
  $Revision: 3 $
  $Modtime: 5/11/98 2:06p $
 
  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.service.file.nw.naming;

import java.util.Properties;

import javax.naming.CompoundName;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NamingException;

import com.novell.utility.naming.Syntax;

/** @internal
 * Parses names using the file system naming system naming conventions.
 *
 * <p>A file system name parser returned from a context referencing the
 * file system of server 'x' will be _different_ than a file system name
 * parser returned from a context referencing the file system of server
 * 'y'.
 * </p>
 */
public class FileSystemNameParser implements NameParser
{
   /**
    * FileSystem provider Naming Convention for DIRECTION.
    *
    * <p>(DIRECTION = "left_to_right")
    * </p>
    */
   public static final String DIRECTION = "left_to_right";

   /**
    * FileSystem provider Naming Convention for SEPARATOR.
    *
    * <p>(SEPARATOR = "/")
    * </p>
    */
   public static final String SEPARATOR = "/";

   /**
    * FileSystem provider Naming Convention for IGNORE_CASE.
    *
    * <p>(IGNORE_CASE = "true")
    * </p>
    */
   public static final String IGNORE_CASE = "true";

   /**
    * FileSystem provider Naming Convention for ESCAPE.
    *
    * <p>(ESCAPE = "\\")
    * </p>
    */
   public static final String ESCAPE = "\\";

   /**
    * FileSystem provider Naming Convention for BEGIN_QUOTE.
    *
    * <p>(BEGIN_QUOTE = "\"")
    * </p>
    */
   public static final String BEGIN_QUOTE = "\"";

   /**
    * FileSystem provider Naming Convention for BEGIN_QUOTE2.
    *
    * <p>(BEGIN_QUOTE2 = "'")
    * </p>
    */
   public static final String BEGIN_QUOTE2 = "'";

   /* ***********************************************************************
    * As of 29.Jul.97, this class must exist, and we cannot use
    * com.novell.utility.naming.FlatNameParser for the following reasons:
    *
    * 1) The flat name parser does not have the "jndi.syntax.ignorecase"
    *    option set to true.
    *
    * 2) As per the javadoc on javax.naming.NameParser, the
    *    Object.equals(Object) method must return true if and only if the
    *    argument is a name parser from the same name space as itself.
    ************************************************************************/

   // internal naming convention property set
   private static Properties _compositeSyntax = new Properties ();

   static
   {
      /*
       * Starting around mid-October 97, the JNDI from Sun didn't insert
       * any separators when toString'ing a 'flat' name.  This is a
       * problem when creating references, because we need a separator.
       * So, the direction was changed to 'left_to_right'.
       */
      _compositeSyntax.put(Syntax.DIRECTION, DIRECTION);
      _compositeSyntax.put(Syntax.SEPARATOR, SEPARATOR);
      _compositeSyntax.put(Syntax.IGNORE_CASE, IGNORE_CASE);
      _compositeSyntax.put(Syntax.ESCAPE, ESCAPE);
      _compositeSyntax.put(Syntax.BEGIN_QUOTE, BEGIN_QUOTE);
      _compositeSyntax.put(Syntax.BEGIN_QUOTE2, BEGIN_QUOTE2);
   }

   String serverName;
   boolean schema;

   /**
    * Constructs a file system name parser.
    *
    * <p>It is necessary to do this in order to allow for comparisons across
    * name spaces (in the same naming system).  For example: the file system
    * naming system is the same on two different Netware servers.  But they
    * are two different name spaces.  The schema is also a different name
    * space as the actual file system.
    * </p>
    */
   protected FileSystemNameParser (String serverName, boolean schema)
   {
      this.serverName = serverName;
      this.schema = schema;
   }
   
   /**
    * Parses a name into its components.
    *
    * @param      name           The string name to parse.
    * @return                    A parsed form of the name using the
    *                            naming convention of this parser.
    * @exception NamingException when 'name' contains an unmatched quote
    *                            or is otherwise invalid and cannot be
    *                            parsed.
    */
   public Name parse (String name)
      throws NamingException
   {
      return (new CompoundName (name, _compositeSyntax));
   }

   /**
    * When used to compare two NameParsers, returns true if and only if they
    * serve the same name space.
    *
    * @return                    true if 'o' is a FileSystemNameParser,
    *                            otherwise false
    */
   public boolean equals (Object o)
   {
      if (o instanceof FileSystemNameParser)
      {
         FileSystemNameParser parser = (FileSystemNameParser) o;

         if (parser.serverName.equalsIgnoreCase (this.serverName) &&
             parser.schema == this.schema)
         {
            return true;
         }
      }

      return (false);
   }
}
