/* CompositeName.java --
   Copyright (C) 2001, 2005, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.naming;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.Vector;

/**
 * Represents names that may span over several namespaces. For instance,
 * the composite name http://www.gnu.org/software/classpath/index.html spans
 * over three namespaces (the protocol http, the web server location
 * (www.gnu.org) and the index.html location on the server).
 * 
 * @author Tom Tromey (tromey@redhat.com)
 */
public class CompositeName implements Name, Cloneable, Serializable
{
  private static final long serialVersionUID = 1667768148915813118L;
  
  private transient Vector elts;  

  public CompositeName ()
  {
    elts = new Vector ();
  }

  protected CompositeName (Enumeration comps)
  {
    elts = new Vector ();
    try
      {
	while (comps.hasMoreElements ())
	  elts.add (comps.nextElement ());
      }
    catch (NoSuchElementException ignore)
      {
      }
  }

  public CompositeName (String n) throws InvalidNameException
  {
    elts = new Vector ();
    // Parse the string into its components.
    final char no_quote = 'x';	// Use 'x' to mean no quoting.
    char quote = no_quote;
    boolean escaped = false;
    StringBuffer new_element = new StringBuffer ();
    for (int i = 0; i < n.length (); ++i)
      {
	char c = n.charAt (i);
	if (escaped)
	  escaped = false;
	else if (c == '\\')
	  {
	    escaped = true;
	    continue;
	  }
	else if (quote != no_quote)
	  {
	    if (quote == c)
	      {
		// The quotes must surround a complete component.
		if (i + 1 < n.length () && n.charAt (i + 1) != '/')
		  throw new InvalidNameException ("close quote before end of component");
		elts.add (new_element.toString ());
		new_element.setLength (0);
		quote = no_quote;
		continue;
	      }
	    // Otherwise, fall through.
	  }
	// Quotes are only special at the start of a component.
	else if (new_element.length () == 0
		 && (c == '\'' || c == '"'))
	  {
	    quote = c;
	    continue;
	  }
	else if (c == '/')
	  {
	    elts.add (new_element.toString ());
	    new_element.setLength (0);
	    continue;
	  }

	new_element.append (c);
      }

    if (new_element.length () != 0)
      elts.add (new_element.toString ());

    // Error checking.
    if (quote != no_quote)
      throw new InvalidNameException ("unterminated quote");
    if (escaped)
      throw new InvalidNameException ("trailing escape character");
  }

  public Name add (int posn, String comp) throws InvalidNameException
  {
    elts.add (posn, comp);
    return this;
  }

  public Name add (String comp) throws InvalidNameException
  {
    elts.add (comp);
    return this;
  }

  public Name addAll (int posn, Name n) throws InvalidNameException
  {
    Enumeration e = n.getAll ();
    try
      {
	while (e.hasMoreElements ())
	  {
	    elts.add (posn, e.nextElement ());
	    ++posn;
	  }
      }
    catch (NoSuchElementException ignore)
      {
      }
    return this;
  }

  public Name addAll (Name suffix) throws InvalidNameException
  {
    Enumeration e = suffix.getAll ();
    try
      {
	while (e.hasMoreElements ())
	  elts.add (e.nextElement ());
      }
    catch (NoSuchElementException ignore)
      {
      }
    return this;
  }

  public Object clone ()
  {
    return new CompositeName (elts.elements ());
  }

  public int compareTo (Object obj)
  {
    if (obj == null || ! (obj instanceof CompositeName))
      throw new ClassCastException ("CompositeName.compareTo() expected CompositeName");
    CompositeName cn = (CompositeName) obj;
    int last = Math.min (cn.elts.size (), elts.size ());
    for (int i = 0; i < last; ++i)
      {
	String f = (String) elts.get (i);
	int comp = f.compareTo ((String) cn.elts.get (i));
	if (comp != 0)
	  return comp;
      }
    return elts.size () - cn.elts.size ();
  }

  public boolean endsWith (Name n)
  {
    if (! (n instanceof CompositeName))
      return false;
    CompositeName cn = (CompositeName) n;
    if (cn.elts.size () > elts.size ())
      return false;
    int delta = elts.size () - cn.elts.size ();
    for (int i = 0; i < cn.elts.size (); ++i)
      {
	if (! cn.elts.get (i).equals (elts.get (delta + i)))
	  return false;
      }
    return true;
  }

  public boolean equals (Object obj)
  {
    if (! (obj instanceof CompositeName))
      return false;
    CompositeName cn = (CompositeName) obj;
    return elts.equals (cn.elts);
  }

  public String get (int posn)
  {
    return (String) elts.get (posn);
  }

  public Enumeration getAll ()
  {
    return elts.elements ();
  }

  public Name getPrefix (int posn)
  {
    CompositeName cn = new CompositeName ();
    for (int i = 0; i < posn; ++i)
      cn.elts.add ((String) elts.get (i));
    return cn;
  }

  public Name getSuffix (int posn)
  {
    if (posn > elts.size ())
      throw new ArrayIndexOutOfBoundsException (posn);
    CompositeName cn = new CompositeName ();
    for (int i = posn; i < elts.size (); ++i)
      cn.elts.add ((String) elts.get (i));
    return cn;
  }

  public int hashCode ()
  {
    // Specified in documentation.
    int h = 0;
    for (int i = 0; i < elts.size (); ++i)
      h += elts.get (i).hashCode ();
    return h;
  }

  public boolean isEmpty ()
  {
    return elts.isEmpty ();
  }

  public Object remove (int posn) throws InvalidNameException
  {
    return elts.remove (posn);
  }

  public int size ()
  {
    return elts.size ();
  }

  public boolean startsWith (Name n)
  {
    if (! (n instanceof CompositeName))
      return false;
    CompositeName cn = (CompositeName) n;
    if (cn.elts.size () > elts.size ())
      return false;
    for (int i = 0; i < cn.elts.size (); ++i)
      {
	if (! cn.elts.get (i).equals (elts.get (i)))
	  return false;
      }
    return true;
  }

  public String toString ()
  {
    StringBuffer result = new StringBuffer ();
    for (int i = 0; i < elts.size (); ++i)
      {
	// For simplicity we choose to always quote using escapes and
	// never quotes.
	String elt = (String) elts.get (i);
	if (i > 0
	    || (i == elts.size () - 1 && elt.equals ("")))
	  result.append ('/');
	for (int k = 0; k < elt.length (); ++k)
	  {
	    char c = elt.charAt (k);
	    // We must quote
	    //     ... a leading quote,
	    if ((k == 0 && (c == '"' || c == '\''))
		// ... an escape preceding a meta character,
		//     or at the end of a component,
		|| (c == '\\'
		    && (k == elt.length () - 1
			|| "\\'\"/".indexOf (elt.charAt (k + 1)) != -1))
		// ... or a component separator.
		|| c == '/')
	      result.append ('\\');
	    result.append (c);
	  }
      }
    return result.toString ();
  }
  
  private void readObject(ObjectInputStream s) 
    throws IOException, ClassNotFoundException
  {
    int size = s.readInt();
    elts = new Vector(size);
    for (int i = 0; i < size; i++)
      elts.add(s.readObject());
  }

  private void writeObject(ObjectOutputStream s) throws IOException
  {
    s.writeInt(elts.size());
    for (int i = 0; i < elts.size(); i++)
      s.writeObject(elts.get(i));
  }
}
