/*
 * Copyright (c) 1998-2010 Caucho Technology -- all rights reserved
 *
 * This file is part of Resin(R) Open Source
 *
 * Each copy or derived work must preserve the copyright notice and this
 * notice unmodified.
 *
 * Resin Open Source 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 of the License, or
 * (at your option) any later version.
 *
 * Resin Open Source 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, or any warranty
 * of NON-INFRINGEMENT.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Resin Open Source; if not, write to the
 *
 *   Free Software Foundation, Inc.
 *   59 Temple Place, Suite 330
 *   Boston, MA 02111-1307  USA
 *
 * @author James David Low
 */

package com.caucho.quercus.lib.simplexml;

import java.util.*;
import javax.xml.*;
import javax.xml.namespace.NamespaceContext;

/**
 * SimpleXMLElementNamespaceContext helper for SimpleXMLElement.
 * Helps with implementation of SimpleXMLElement.registerXPathNamespace.
 * http://download.oracle.com/javase/1.5.0/docs/api/javax/xml/namespace/NamespaceContext.html
 */
public class SimpleXMLElementNamespaceContext implements NamespaceContext
{
  protected Map _namespaces = new HashMap();
  
  
  public SimpleXMLElementNamespaceContext()
  {
  }
  
  /**
   * Add a new namespace to this context.
   * 
   * @param prefix
   * @param ns
   * @return true on success or false on failure.
   */
  public boolean registerNameSpace(String prefix, String ns) {
    if (prefix == null) {
      return false;
    //Commented out so we can set a default namespace
    //} else if (prefix.length == 0) {
    //  return false;
    } else if (ns == null) {
      //PHP Always allows remove, even if wasn't there in the first place
      _namespaces.remove(prefix);
      return true;
    } else if (ns.length() == 0) {
      return false;
    } else {
      _namespaces.put(prefix,ns);
      return true;
    }
  }  
  
  /**
   * Get namespace URI associated with a prefix.
   * 
   * @param prefix
   * @return namespace URI assocaited with the prefix.
   */
  public String getNamespaceURI(String prefix) {
    if (prefix == null) {
      throw new IllegalArgumentException();
    } else if (XMLConstants.XML_NS_PREFIX.compareTo(prefix) == 0) {
      return XMLConstants.XML_NS_URI;
    } else if (XMLConstants.XMLNS_ATTRIBUTE.compareTo(prefix) == 0) {
      return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
    } else {
      String result = (String) _namespaces.get(prefix);
      if (result != null) {
        return result;
      }
      //If prefix not found, or prefix = ""
      return XMLConstants.NULL_NS_URI;
    }
  }
  
  /**
   * Get prefix associated with a namespace URI.
   * 
   * @param prefix
   * @return prefix asssociated with a namespace URI, if there is more than one, a arbitrary one is returned.
   */
  public String getPrefix(String namespaceURI) {
    if (namespaceURI == null) {
      throw new IllegalArgumentException();
    } else if (XMLConstants.XML_NS_URI.compareTo(namespaceURI) == 0) {
      return XMLConstants.XML_NS_PREFIX;
    } else if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.compareTo(namespaceURI) == 0) {
      return XMLConstants.XMLNS_ATTRIBUTE;
    } else {
      Iterator it = _namespaces.keySet().iterator();
      while (it.hasNext()) {
        String key = (String) it.next();
        String value = (String) _namespaces.get(key);
        //Java documentation says we can return any value
        if (namespaceURI.compareTo(value) == 0) {
          return key;
        }
      }
      return null;
    }
  }
  
  /**
   * Get all prefixes associated with a namespace URI.
   * 
   * @param prefix
   * @return prefixes asssociated with a namespace URI.
   */
  public Iterator getPrefixes(String namespaceURI) {
    List results = new ArrayList();
    if (namespaceURI == null) {
      throw new IllegalArgumentException();
    } else if (XMLConstants.XML_NS_URI.compareTo(namespaceURI) == 0) {
      //Documenatation says we must add this
      results.add(XMLConstants.XML_NS_PREFIX);
    } else if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.compareTo(namespaceURI) == 0) {
      //Documenatation says we must add this
      results.add(XMLConstants.XMLNS_ATTRIBUTE);
    }
    
    Iterator it = _namespaces.keySet().iterator();
    while (it.hasNext()) {
      String key = (String) it.next();
      String value = (String) _namespaces.get(it.next());
      if (namespaceURI.compareTo(value) == 0) {
        results.add(key);
      }
    }
    if (results.isEmpty()) {
      return null;
    }
    return results.listIterator();
  }
}
