/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: QName.java 468655 2006-10-28 07:12:06Z minchau $
 */
package org.apache.xml.utils;

import java.util.Stack;
import java.util.StringTokenizer;

import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;

import org.w3c.dom.Element;

/**
 * Class to represent a qualified name: "The name of an internal XSLT object,
 * specifically a named template (see [7 Named Templates]), a mode (see [6.7 Modes]),
 * an attribute set (see [8.1.4 Named Attribute Sets]), a key (see [14.2 Keys]),
 * a locale (see [14.3 Number Formatting]), a variable or a parameter (see
 * [12 Variables and Parameters]) is specified as a QName. If it has a prefix,
 * then the prefix is expanded into a URI reference using the namespace declarations
 * in effect on the attribute in which the name occurs. The expanded name
 * consisting of the local part of the name and the possibly null URI reference
 * is used as the name of the object. The default namespace is not used for
 * unprefixed names."
 * @xsl.usage general
 */
public class QName implements java.io.Serializable
{
    static final long serialVersionUID = 467434581652829920L;

  /**
   * The local name.
   * @serial
   */
  protected String _localName;

  /**
   * The namespace URI.
   * @serial
   */
  protected String _namespaceURI;

  /**
   * The namespace prefix.
   * @serial
   */
  protected String _prefix;

  /**
   * The XML namespace.
   */
  public static final String S_XMLNAMESPACEURI =
    "http://www.w3.org/XML/1998/namespace";

  /**
   * The cached hashcode, which is calculated at construction time.
   * @serial
   */
  private int m_hashCode;

  /**
   * Constructs an empty QName.
   * 20001019: Try making this public, to support Serializable? -- JKESS
   */
  public QName(){}

  /**
   * Constructs a new QName with the specified namespace URI and
   * local name.
   *
   * @param namespaceURI The namespace URI if known, or null
   * @param localName The local name
   */
  public QName(String namespaceURI, String localName)
  {
    this(namespaceURI, localName, false); 
  }

  /**
   * Constructs a new QName with the specified namespace URI and
   * local name.
   *
   * @param namespaceURI The namespace URI if known, or null
   * @param localName The local name
   * @param validate If true the new QName will be validated and an IllegalArgumentException will
   *                 be thrown if it is invalid.
   */
  public QName(String namespaceURI, String localName, boolean validate) 
  {

    // This check was already here.  So, for now, I will not add it to the validation
    // that is done when the validate parameter is true.
    if (localName == null)
      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");

    if (validate) 
    {
        if (!XML11Char.isXML11ValidNCName(localName))
        {
            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
        }
    }
    
    _namespaceURI = namespaceURI;
    _localName = localName;
    m_hashCode = toString().hashCode();
  }
  
  /**
   * Constructs a new QName with the specified namespace URI, prefix
   * and local name.
   *
   * @param namespaceURI The namespace URI if known, or null
   * @param prefix The namespace prefix is known, or null
   * @param localName The local name
   * 
   */
  public QName(String namespaceURI, String prefix, String localName)
  {
     this(namespaceURI, prefix, localName, false);
  }
  
 /**
   * Constructs a new QName with the specified namespace URI, prefix
   * and local name.
   *
   * @param namespaceURI The namespace URI if known, or null
   * @param prefix The namespace prefix is known, or null
   * @param localName The local name
   * @param validate If true the new QName will be validated and an IllegalArgumentException will
   *                 be thrown if it is invalid.
   */
  public QName(String namespaceURI, String prefix, String localName, boolean validate)
  {

    // This check was already here.  So, for now, I will not add it to the validation
    // that is done when the validate parameter is true.
    if (localName == null)
      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");

    if (validate)
    {    
        if (!XML11Char.isXML11ValidNCName(localName))
        {
            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
        }

        if ((null != prefix) && (!XML11Char.isXML11ValidNCName(prefix)))
        {
            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_PREFIX_INVALID,null )); //"Argument 'prefix' not a valid NCName");
        }

    }
    _namespaceURI = namespaceURI;
    _prefix = prefix;
    _localName = localName;
    m_hashCode = toString().hashCode();
  }  

  /**
   * Construct a QName from a string, without namespace resolution.  Good
   * for a few odd cases.
   *
   * @param localName Local part of qualified name
   * 
   */
  public QName(String localName)
  {
    this(localName, false);
  }
  
  /**
   * Construct a QName from a string, without namespace resolution.  Good
   * for a few odd cases.
   *
   * @param localName Local part of qualified name
   * @param validate If true the new QName will be validated and an IllegalArgumentException will
   *                 be thrown if it is invalid.
   */
  public QName(String localName, boolean validate)
  {

    // This check was already here.  So, for now, I will not add it to the validation
    // that is done when the validate parameter is true.
    if (localName == null)
      throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");

    if (validate)
    {    
        if (!XML11Char.isXML11ValidNCName(localName))
        {
            throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
        }
    }
    _namespaceURI = null;
    _localName = localName;
    m_hashCode = toString().hashCode();
  }  

  /**
   * Construct a QName from a string, resolving the prefix
   * using the given namespace stack. The default namespace is
   * not resolved.
   *
   * @param qname Qualified name to resolve
   * @param namespaces Namespace stack to use to resolve namespace
   */
  public QName(String qname, Stack namespaces)
  {
    this(qname, namespaces, false);
  }

  /**
   * Construct a QName from a string, resolving the prefix
   * using the given namespace stack. The default namespace is
   * not resolved.
   *
   * @param qname Qualified name to resolve
   * @param namespaces Namespace stack to use to resolve namespace
   * @param validate If true the new QName will be validated and an IllegalArgumentException will
   *                 be thrown if it is invalid.
   */
  public QName(String qname, Stack namespaces, boolean validate)
  {

    String namespace = null;
    String prefix = null;
    int indexOfNSSep = qname.indexOf(':');

    if (indexOfNSSep > 0)
    {
      prefix = qname.substring(0, indexOfNSSep);

      if (prefix.equals("xml"))
      {
        namespace = S_XMLNAMESPACEURI;
      }
      // Do we want this?
      else if (prefix.equals("xmlns"))
      {
        return;
      }
      else
      {
        int depth = namespaces.size();

        for (int i = depth - 1; i >= 0; i--)
        {
          NameSpace ns = (NameSpace) namespaces.elementAt(i);

          while (null != ns)
          {
            if ((null != ns.m_prefix) && prefix.equals(ns.m_prefix))
            {
              namespace = ns.m_uri;
              i = -1;

              break;
            }

            ns = ns.m_next;
          }
        }
      }

      if (null == namespace)
      {
        throw new RuntimeException(
          XMLMessages.createXMLMessage(
            XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
            new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
      }
    }

    _localName = (indexOfNSSep < 0)
                 ? qname : qname.substring(indexOfNSSep + 1);
                 
    if (validate)
    {
        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
        {
           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
        }
    }                 
    _namespaceURI = namespace;
    _prefix = prefix;
    m_hashCode = toString().hashCode();
  }

  /**
   * Construct a QName from a string, resolving the prefix
   * using the given namespace context and prefix resolver. 
   * The default namespace is not resolved.
   * 
   * @param qname Qualified name to resolve
   * @param namespaceContext Namespace Context to use
   * @param resolver Prefix resolver for this context
   */
  public QName(String qname, Element namespaceContext,
               PrefixResolver resolver)
  {
      this(qname, namespaceContext, resolver, false);
  }

  /**
   * Construct a QName from a string, resolving the prefix
   * using the given namespace context and prefix resolver. 
   * The default namespace is not resolved.
   * 
   * @param qname Qualified name to resolve
   * @param namespaceContext Namespace Context to use
   * @param resolver Prefix resolver for this context
   * @param validate If true the new QName will be validated and an IllegalArgumentException will
   *                 be thrown if it is invalid.
   */
  public QName(String qname, Element namespaceContext,
               PrefixResolver resolver, boolean validate)
  {

    _namespaceURI = null;

    int indexOfNSSep = qname.indexOf(':');

    if (indexOfNSSep > 0)
    {
      if (null != namespaceContext)
      {
        String prefix = qname.substring(0, indexOfNSSep);

        _prefix = prefix;

        if (prefix.equals("xml"))
        {
          _namespaceURI = S_XMLNAMESPACEURI;
        }
        
        // Do we want this?
        else if (prefix.equals("xmlns"))
        {
          return;
        }
        else
        {
          _namespaceURI = resolver.getNamespaceForPrefix(prefix,
                  namespaceContext);
        }

        if (null == _namespaceURI)
        {
          throw new RuntimeException(
            XMLMessages.createXMLMessage(
              XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
              new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
        }
      }
      else
      {

        // TODO: error or warning...
      }
    }

    _localName = (indexOfNSSep < 0)
                 ? qname : qname.substring(indexOfNSSep + 1);

    if (validate)
    {
        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
        {
           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
        }
    }                 
                 
    m_hashCode = toString().hashCode();
  }


  /**
   * Construct a QName from a string, resolving the prefix
   * using the given namespace stack. The default namespace is
   * not resolved.
   *
   * @param qname Qualified name to resolve
   * @param resolver Prefix resolver for this context
   */
  public QName(String qname, PrefixResolver resolver)
  {
    this(qname, resolver, false);
  }

  /**
   * Construct a QName from a string, resolving the prefix
   * using the given namespace stack. The default namespace is
   * not resolved.
   *
   * @param qname Qualified name to resolve
   * @param resolver Prefix resolver for this context
   * @param validate If true the new QName will be validated and an IllegalArgumentException will
   *                 be thrown if it is invalid.
   */
  public QName(String qname, PrefixResolver resolver, boolean validate)
  {

	String prefix = null;
    _namespaceURI = null;

    int indexOfNSSep = qname.indexOf(':');

    if (indexOfNSSep > 0)
    {
      prefix = qname.substring(0, indexOfNSSep);

      if (prefix.equals("xml"))
      {
        _namespaceURI = S_XMLNAMESPACEURI;
      }
      else
      {
        _namespaceURI = resolver.getNamespaceForPrefix(prefix);
      }

      if (null == _namespaceURI)
      {
        throw new RuntimeException(
          XMLMessages.createXMLMessage(
            XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
            new Object[]{ prefix }));  //"Prefix must resolve to a namespace: "+prefix);
      }
      _localName = qname.substring(indexOfNSSep + 1);
    }
    else if (indexOfNSSep == 0) 
    {
      throw new RuntimeException(
         XMLMessages.createXMLMessage(
           XMLErrorResources.ER_NAME_CANT_START_WITH_COLON,
           null));
    }
    else
    {
      _localName = qname;
    }   
                 
    if (validate)
    {
        if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName))) 
        {
           throw new IllegalArgumentException(XMLMessages.createXMLMessage(
            XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
        }
    }                 

              
    m_hashCode = toString().hashCode();
    _prefix = prefix;
  }

  /**
   * Returns the namespace URI. Returns null if the namespace URI
   * is not known.
   *
   * @return The namespace URI, or null
   */
  public String getNamespaceURI()
  {
    return _namespaceURI;
  }

  /**
   * Returns the namespace prefix. Returns null if the namespace
   * prefix is not known.
   *
   * @return The namespace prefix, or null
   */
  public String getPrefix()
  {
    return _prefix;
  }

  /**
   * Returns the local part of the qualified name.
   *
   * @return The local part of the qualified name
   */
  public String getLocalName()
  {
    return _localName;
  }

  /**
   * Return the string representation of the qualified name, using the 
   * prefix if available, or the '{ns}foo' notation if not. Performs
   * string concatenation, so beware of performance issues.
   *
   * @return the string representation of the namespace
   */
  public String toString()
  {

    return _prefix != null
           ? (_prefix + ":" + _localName)
           : (_namespaceURI != null
              ? ("{"+_namespaceURI + "}" + _localName) : _localName);
  }
  
  /**
   * Return the string representation of the qualified name using the 
   * the '{ns}foo' notation. Performs
   * string concatenation, so beware of performance issues.
   *
   * @return the string representation of the namespace
   */
  public String toNamespacedString()
  {

    return (_namespaceURI != null
              ? ("{"+_namespaceURI + "}" + _localName) : _localName);
  }


  /**
   * Get the namespace of the qualified name.
   *
   * @return the namespace URI of the qualified name
   */
  public String getNamespace()
  {
    return getNamespaceURI();
  }

  /**
   * Get the local part of the qualified name.
   *
   * @return the local part of the qualified name
   */
  public String getLocalPart()
  {
    return getLocalName();
  }

  /**
   * Return the cached hashcode of the qualified name.
   *
   * @return the cached hashcode of the qualified name
   */
  public int hashCode()
  {
    return m_hashCode;
  }

  /**
   * Override equals and agree that we're equal if
   * the passed object is a string and it matches
   * the name of the arg.
   *
   * @param ns Namespace URI to compare to
   * @param localPart Local part of qualified name to compare to 
   *
   * @return True if the local name and uri match 
   */
  public boolean equals(String ns, String localPart)
  {

    String thisnamespace = getNamespaceURI();

    return getLocalName().equals(localPart)
           && (((null != thisnamespace) && (null != ns))
               ? thisnamespace.equals(ns)
               : ((null == thisnamespace) && (null == ns)));
  }

  /**
   * Override equals and agree that we're equal if
   * the passed object is a QName and it matches
   * the name of the arg.
   *
   * @return True if the qualified names are equal
   */
  public boolean equals(Object object)
  {

    if (object == this)
      return true;

    if (object instanceof QName) {
      QName qname = (QName) object;
      String thisnamespace = getNamespaceURI();
      String thatnamespace = qname.getNamespaceURI();

      return getLocalName().equals(qname.getLocalName())
             && (((null != thisnamespace) && (null != thatnamespace))
                 ? thisnamespace.equals(thatnamespace)
                 : ((null == thisnamespace) && (null == thatnamespace)));
    }
    else
      return false;
  }

  /**
   * Given a string, create and return a QName object  
   *
   *
   * @param name String to use to create QName
   *
   * @return a QName object
   */
  public static QName getQNameFromString(String name)
  {

    StringTokenizer tokenizer = new StringTokenizer(name, "{}", false);
    QName qname;
    String s1 = tokenizer.nextToken();
    String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;

    if (null == s2)
      qname = new QName(null, s1);
    else
      qname = new QName(s1, s2);

    return qname;
  }

  /**
   * This function tells if a raw attribute name is a
   * xmlns attribute.
   *
   * @param attRawName Raw name of attribute
   *
   * @return True if the attribute starts with or is equal to xmlns 
   */
  public static boolean isXMLNSDecl(String attRawName)
  {

    return (attRawName.startsWith("xmlns")
            && (attRawName.equals("xmlns")
                || attRawName.startsWith("xmlns:")));
  }

  /**
   * This function tells if a raw attribute name is a
   * xmlns attribute.
   *
   * @param attRawName Raw name of attribute
   *
   * @return Prefix of attribute
   */
  public static String getPrefixFromXMLNSDecl(String attRawName)
  {

    int index = attRawName.indexOf(':');

    return (index >= 0) ? attRawName.substring(index + 1) : "";
  }

  /**
   * Returns the local name of the given node.
   *
   * @param qname Input name
   *
   * @return Local part of the name if prefixed, or the given name if not
   */
  public static String getLocalPart(String qname)
  {

    int index = qname.indexOf(':');

    return (index < 0) ? qname : qname.substring(index + 1);
  }

  /**
   * Returns the local name of the given node.
   *
   * @param qname Input name 
   *
   * @return Prefix of name or empty string if none there   
   */
  public static String getPrefixPart(String qname)
  {

    int index = qname.indexOf(':');

    return (index >= 0) ? qname.substring(0, index) : "";
  }
}
