/* XMLStreamWriterImpl.java -- 
   Copyright (C) 2005  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 gnu.xml.stream;

import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.xml.sax.helpers.NamespaceSupport;

/**
 * Simple XML stream writer.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public class XMLStreamWriterImpl
  implements XMLStreamWriter
{

  /**
   * The underlying character stream to write to.
   */
  protected final Writer writer;

  /**
   * The encoding being used.
   * Note that this must match the encoding of the character stream.
   */
  protected final String encoding;

  /**
   * Whether prefix defaulting is being used.
   * If true and a prefix has not been defined for a namespace specified on
   * an element or an attribute, a new prefix and namespace declaration will
   * be created.
   */
  protected final boolean prefixDefaulting;

  /**
   * The namespace context used to determine the namespace-prefix mappings
   * in scope.
   */
  protected NamespaceContext namespaceContext;
  
  /**
   * The stack of elements in scope.
   * Used to close the remaining elements.
   */
  private LinkedList elements;

  /**
   * Whether a start element has been opened but not yet closed.
   */
  private boolean inStartElement;

  /**
   * Whether we are in an empty element.
   */
  private boolean emptyElement;
  
  private NamespaceSupport namespaces;
  private int count = 0;

  private boolean xml11;
  private boolean hasXML11RestrictedChars;

  /**
   * Constructor.
   * @see #writer
   * @see #encoding
   * @see #prefixDefaulting
   */
  protected XMLStreamWriterImpl(Writer writer, String encoding,
                                boolean prefixDefaulting)
  {
    this.writer = writer;
    this.encoding = encoding;
    this.prefixDefaulting = prefixDefaulting;
    elements = new LinkedList();
    namespaces = new NamespaceSupport();
  }

  /**
   * Write the end of a start-element event.
   * This will close the element if it was defined to be an empty element.
   */
  private void endStartElement()
    throws IOException
  {
    if (!inStartElement)
      return;
    if (emptyElement)
      {
        writer.write('/');
        elements.removeLast();
        namespaces.popContext();
        emptyElement = false;
      }
    writer.write('>');
    inStartElement = false;
  }

  public void writeStartElement(String localName)
    throws XMLStreamException
  {
    try
      {
        if (!isName(localName))
          throw new IllegalArgumentException("illegal Name: " + localName);

        endStartElement();
        namespaces.pushContext();
        
        writer.write('<');
        writer.write(localName);
        
        elements.addLast(new String[] { null, localName });
        inStartElement = true;
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeStartElement(String namespaceURI, String localName)
    throws XMLStreamException
  {
    try
      {
        if (namespaceURI != null && !isURI(namespaceURI))
          throw new IllegalArgumentException("illegal URI: " + namespaceURI);
        if (!isName(localName))
          throw new IllegalArgumentException("illegal Name: " + localName);

        endStartElement();
        namespaces.pushContext();
        
        String prefix = getPrefix(namespaceURI);
        boolean isDeclared = (prefix != null);
        if (!isDeclared)
          {
            if (prefixDefaulting)
              prefix = createPrefix(namespaceURI);
            else
              throw new XMLStreamException("namespace " + namespaceURI +
                                           " has not been declared");
          }
        writer.write('<');
        if (!"".equals(prefix))
          {
            writer.write(prefix);
            writer.write(':');
          }
        writer.write(localName);
        inStartElement = true;
        if (!isDeclared)
          {
            writeNamespaceImpl(prefix, namespaceURI);
          }
        
        elements.addLast(new String[] { prefix, localName });
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  /**
   * Creates a new unique prefix in the document.
   * Subclasses may override this method to provide a suitably unique prefix
   * for the given namespace.
   * @param namespaceURI the namespace URI
   */
  protected String createPrefix(String namespaceURI)
  {
    Set prefixes = new HashSet();
    for (Enumeration e = namespaces.getPrefixes(); e.hasMoreElements(); )
      prefixes.add(e.nextElement());
    String ret;
    do
      {
        ret = "ns" + (count++);
      }
    while (prefixes.contains(ret));
    return ret;
  }

  public void writeStartElement(String prefix, String localName,
                                String namespaceURI)
    throws XMLStreamException
  {
    try
      {
        if (namespaceURI != null && !isURI(namespaceURI))
          throw new IllegalArgumentException("illegal URI: " + namespaceURI);
        if (prefix != null && !isNCName(prefix))
          throw new IllegalArgumentException("illegal NCName: " + prefix);
        if (!isNCName(localName))
          throw new IllegalArgumentException("illegal NCName: " + localName);

        endStartElement();
        namespaces.pushContext();
        
        String currentPrefix = getPrefix(namespaceURI);
        boolean isCurrent = prefix.equals(currentPrefix);
        writer.write('<');
        if (!"".equals(prefix))
          {
            writer.write(prefix);
            writer.write(':');
          }
        writer.write(localName);
        if (prefixDefaulting && !isCurrent)
          {
            writeNamespaceImpl(prefix, namespaceURI);
          }
        
        elements.addLast(new String[] { prefix, localName });
        inStartElement = true;
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeEmptyElement(String namespaceURI, String localName)
    throws XMLStreamException
  {
    writeStartElement(namespaceURI, localName);
    emptyElement = true;
  }

  public void writeEmptyElement(String prefix, String localName,
                                String namespaceURI)
    throws XMLStreamException
  {
    writeStartElement(prefix, localName, namespaceURI);
    emptyElement = true;
  }

  public void writeEmptyElement(String localName)
    throws XMLStreamException
  {
    writeStartElement(localName);
    emptyElement = true;
  }

  public void writeEndElement()
    throws XMLStreamException
  {
    if (elements.isEmpty())
      throw new IllegalStateException("no matching start element");
    try
      {
        endStartElement();
        String[] element = (String[]) elements.removeLast();
        namespaces.popContext();

        writer.write('<');
        writer.write('/');
        if (element[0] != null && !"".equals(element[0]))
          {
            writer.write(element[0]);
            writer.write(':');
          }
        writer.write(element[1]);
        writer.write('>');
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeEndDocument()
    throws XMLStreamException
  {
    while (!elements.isEmpty())
      writeEndElement();
  }

  public void close()
    throws XMLStreamException
  {
    flush();
  }

  public void flush()
    throws XMLStreamException
  {
    try
      {
        writer.flush();
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeAttribute(String localName, String value)
    throws XMLStreamException
  {
    if (!inStartElement)
      throw new IllegalStateException();
    try
      {
        if (!isName(localName))
          throw new IllegalArgumentException("illegal Name: " + localName);
        if (!isChars(value))
          throw new IllegalArgumentException("illegal character: " + value);

        writer.write(' ');
        writer.write(localName);
        writer.write('=');
        writer.write('"');
        if (hasXML11RestrictedChars)
          writeEncodedWithRestrictedChars(value, true);
        else
          writeEncoded(value, true);
        writer.write('"');
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeAttribute(String prefix, String namespaceURI,
                             String localName, String value)
    throws XMLStreamException
  {
    if (!inStartElement)
      throw new IllegalStateException();
    try
      {
        if (namespaceURI != null && !isURI(namespaceURI))
          throw new IllegalArgumentException("illegal URI: " + namespaceURI);
        if (prefix != null && !isNCName(prefix))
          throw new IllegalArgumentException("illegal NCName: " + prefix);
        if (!isNCName(localName))
          throw new IllegalArgumentException("illegal NCName: " + localName);
        if (!isChars(value))
          throw new IllegalArgumentException("illegal character: " + value);

        String currentPrefix = getPrefix(namespaceURI);
        if (currentPrefix == null)
          {
            if (prefixDefaulting)
              writeNamespaceImpl(prefix, namespaceURI);
            else
              throw new XMLStreamException("namespace " + namespaceURI +
                                           " is not bound");
          }
        else if (!currentPrefix.equals(prefix))
          throw new XMLStreamException("namespace " + namespaceURI +
                                       " is bound to prefix " +
                                       currentPrefix);
        writer.write(' ');
        if (!"".equals(prefix))
          {
            writer.write(prefix);
            writer.write(':');
          }
        writer.write(localName);
        writer.write('=');
        writer.write('"');
        if (hasXML11RestrictedChars)
          writeEncodedWithRestrictedChars(value, true);
        else
          writeEncoded(value, true);
        writer.write('"');
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeAttribute(String namespaceURI, String localName,
                             String value)
    throws XMLStreamException
  {
    if (!inStartElement)
      throw new IllegalStateException();
    try
      {
        if (namespaceURI != null && !isURI(namespaceURI))
          throw new IllegalArgumentException("illegal URI: " + namespaceURI);
        if (!isName(localName))
          throw new IllegalArgumentException("illegal Name: " + localName);
        if (!isChars(value))
          throw new IllegalArgumentException("illegal character: " + value);
        
        String prefix = getPrefix(namespaceURI);
        if (prefix == null)
          {
            if (prefixDefaulting)
              {
                prefix = XMLConstants.DEFAULT_NS_PREFIX;
                writeNamespaceImpl(prefix, namespaceURI);
              }
            else
              throw new XMLStreamException("namespace " + namespaceURI +
                                           " is not bound");
          }
        writer.write(' ');
        if (!"".equals(prefix))
          {
            writer.write(prefix);
            writer.write(':');
          }
        writer.write(localName);
        writer.write('=');
        writer.write('"');
        if (hasXML11RestrictedChars)
          writeEncodedWithRestrictedChars(value, true);
        else
          writeEncoded(value, true);
        writer.write('"');
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeNamespace(String prefix, String namespaceURI)
    throws XMLStreamException
  {
    if (!inStartElement)
      throw new IllegalStateException();
    try
      {
        if (!isURI(namespaceURI))
          throw new IllegalArgumentException("illegal URI: " + namespaceURI);
        if (!isNCName(prefix))
          throw new IllegalArgumentException("illegal NCName: " + prefix);
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
    writeNamespaceImpl(prefix, namespaceURI);
  }

  private void writeNamespaceImpl(String prefix, String namespaceURI)
    throws XMLStreamException
  {
    try
      {
        if (prefix == null)
          prefix = XMLConstants.DEFAULT_NS_PREFIX;

        setPrefix(prefix, namespaceURI);
        
        writer.write(' ');
        writer.write("xmlns");
        if (!XMLConstants.DEFAULT_NS_PREFIX.equals(prefix))
          {
            writer.write(':');
            writer.write(prefix);
          }
        writer.write('=');
        writer.write('"');
        writer.write(namespaceURI);
        writer.write('"');
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeDefaultNamespace(String namespaceURI)
    throws XMLStreamException
  {
    if (!inStartElement)
      throw new IllegalStateException();
    if (!isURI(namespaceURI))
      throw new IllegalArgumentException("illegal URI: " + namespaceURI);
    writeNamespaceImpl(XMLConstants.DEFAULT_NS_PREFIX, namespaceURI);
  }

  public void writeComment(String data)
    throws XMLStreamException
  {
    if (data == null)
      return;
    try
      {
        if (!isChars(data))
          throw new IllegalArgumentException("illegal XML character: " + data);
        if (data.indexOf("--") != -1)
          throw new IllegalArgumentException("illegal comment: " + data);

        endStartElement();
        
        writer.write("<!--");
        if (hasXML11RestrictedChars)
          {
            int[] seq = UnicodeReader.toCodePointArray(data);
            for (int i = 0; i < seq.length; i++)
              {
                int c = seq[i];
                if (XMLParser.isXML11RestrictedChar(c))
                  writer.write("&#x" + Integer.toHexString(c) + ";");
                else
                  writer.write(Character.toChars(i));
              }
          }
        else
          writer.write(data);
        writer.write("-->");
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeProcessingInstruction(String target)
    throws XMLStreamException
  {
    writeProcessingInstruction(target, null);
  }

  public void writeProcessingInstruction(String target, String data)
    throws XMLStreamException
  {
    try
      {
        if (!isName(target) || "xml".equalsIgnoreCase(target))
          throw new IllegalArgumentException("illegal PITarget: " + target);
        if (data != null && !isChars(data))
          throw new IllegalArgumentException("illegal XML character: " + data);

        endStartElement();

        writer.write('<');
        writer.write('?');
        writer.write(target);
        if (data != null)
          {
            writer.write(' ');
            if (hasXML11RestrictedChars)
              {
                int[] seq = UnicodeReader.toCodePointArray(data);
                for (int i = 0; i < seq.length; i++)
                  {
                    int c = seq[i];
                    if (XMLParser.isXML11RestrictedChar(c))
                      writer.write("&#x" + Integer.toHexString(c) + ";");
                    else
                      writer.write(Character.toChars(i));
                  }
              }
            else
              writer.write(data);
          }
        writer.write('?');
        writer.write('>');
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeCData(String data)
    throws XMLStreamException
  {
    try
      {
        if (!isChars(data) || hasXML11RestrictedChars)
          throw new IllegalArgumentException("illegal XML character: " + data);
        if (data.indexOf("]]") != -1)
          throw new IllegalArgumentException("illegal CDATA section: " + data);
        
        endStartElement();

        writer.write("<![CDATA[");
        writer.write(data);
        writer.write("]]>");
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeDTD(String dtd)
    throws XMLStreamException
  {
    // Really thoroughly pointless method...
    try
      {
        if (!isName(dtd))
          throw new IllegalArgumentException("illegal Name: " + dtd);

        writer.write("<!DOCTYPE ");
        writer.write(dtd);
        writer.write('>');
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeEntityRef(String name)
    throws XMLStreamException
  {
    try
      {
        if (!isName(name))
          throw new IllegalArgumentException("illegal Name: " + name);

        endStartElement();

        writer.write('&');
        writer.write(name);
        writer.write(';');
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeStartDocument()
    throws XMLStreamException
  {
    writeStartDocument(null, null);
  }

  public void writeStartDocument(String version)
    throws XMLStreamException
  {
    writeStartDocument(null, version);
  }

  public void writeStartDocument(String encoding, String version)
    throws XMLStreamException
  {
    if (version == null)
      version = "1.0";
    else if ("1.1".equals(version))
      xml11 = true;
    encoding = this.encoding; // YES: the parameter must be ignored
    if (encoding == null)
      encoding = "UTF-8";
    if (!"1.0".equals(version) && !"1.1".equals(version))
      throw new IllegalArgumentException(version);
    try
      {
        writer.write("<?xml version=\"");
        writer.write(version);
        writer.write("\" encoding=\"");
        writer.write(encoding);
        writer.write("\"?>");
        writer.write(System.getProperty("line.separator"));
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeCharacters(String text)
    throws XMLStreamException
  {
    if (text == null)
      return;
    try
      {
        if (!isChars(text))
          throw new IllegalArgumentException("illegal XML character: " + text);

        endStartElement();

        if (hasXML11RestrictedChars)
          writeEncodedWithRestrictedChars(text, false);
        else
          writeEncoded(text, false);
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
  }

  public void writeCharacters(char[] text, int start, int len)
    throws XMLStreamException
  {
    writeCharacters(new String(text, start, len));
  }

  public String getPrefix(String uri)
    throws XMLStreamException
  {
    String prefix = namespaces.getPrefix(uri);
    if (prefix == null && namespaceContext != null)
      prefix = namespaceContext.getPrefix(uri);
    return prefix;
  }

  public void setPrefix(String prefix, String uri)
    throws XMLStreamException
  {
    try
      {
        if (!isURI(uri))
          throw new IllegalArgumentException("illegal URI: " + uri);
        if (!isNCName(prefix))
          throw new IllegalArgumentException("illegal NCName: " + prefix);
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException(e);
        e2.initCause(e);
        throw e2;
      }
    if (!namespaces.declarePrefix(prefix, uri))
      throw new XMLStreamException("illegal prefix " + prefix);
  }

  public void setDefaultNamespace(String uri)
    throws XMLStreamException
  {
    if (!isURI(uri))
      throw new IllegalArgumentException("illegal URI: " + uri);
    if (!namespaces.declarePrefix(XMLConstants.DEFAULT_NS_PREFIX, uri))
      throw new XMLStreamException("illegal default namespace prefix");
  }

  public void setNamespaceContext(NamespaceContext context)
    throws XMLStreamException
  {
    namespaceContext = context;
  }

  public NamespaceContext getNamespaceContext()
  {
    return namespaceContext;
  }

  public Object getProperty(String name)
    throws IllegalArgumentException
  {
    throw new IllegalArgumentException(name);
  }

  /**
   * Write the specified text, ensuring that the content is suitably encoded
   * for XML.
   * @param text the text to write
   * @param inAttr whether we are in an attribute value
   */
  private void writeEncoded(String text, boolean inAttr)
    throws IOException
  {
    char[] chars = text.toCharArray();
    int start = 0;
    int end = chars.length;
    int len = 0;
    for (int i = start; i < end; i++)
      {
        char c = chars[i];
        if (c == '<' || c == '>' || c == '&')
          {
            writer.write(chars, start, len);
            if (c == '<')
              writer.write("&lt;");
            else if (c == '>')
              writer.write("&gt;");
            else
              writer.write("&amp;");
            start = i + 1;
            len = 0;
          }
        else if (inAttr && (c == '"' || c == '\''))
          {
            writer.write(chars, start, len);
            if (c == '"')
              writer.write("&quot;");
            else
              writer.write("&apos;");
            start = i + 1;
            len = 0;
          }
        else
          len++;
      }
    if (len > 0)
      writer.write(chars, start, len);
  }

  /**
   * Writes the specified text, in the knowledge that some of the
   * characters are XML 1.1 restricted characters.
   */
  private void writeEncodedWithRestrictedChars(String text, boolean inAttr)
    throws IOException
  {
    int[] seq = UnicodeReader.toCodePointArray(text);
    for (int i = 0; i < seq.length; i++)
      {
        int c = seq[i];
        switch (c)
          {
          case 0x3c: // '<'
            writer.write("&lt;");
            break;
          case 0x3e: // '>'
            writer.write("&gt;");
            break;
          case 0x26: // '&'
            writer.write("&amp;");
            break;
          case 0x22: // '"'
            if (inAttr)
              writer.write("&quot;");
            else
              writer.write(c);
            break;
          case 0x27: // '\''
            if (inAttr)
              writer.write("&apos;");
            else
              writer.write(c);
            break;
          default:
            if (XMLParser.isXML11RestrictedChar(c))
              writer.write("&#x" + Integer.toHexString(c) + ";");
            else
              {
                char[] chars = Character.toChars(c);
                writer.write(chars, 0, chars.length);
              }
          }
      }
  }

  private boolean isName(String text)
    throws IOException
  {
    if (text == null)
      return false;
    int[] seq = UnicodeReader.toCodePointArray(text);
    if (seq.length < 1)
      return false;
    if (!XMLParser.isNameStartCharacter(seq[0], xml11))
      return false;
    for (int i = 1; i < seq.length; i++)
      {
        if (!XMLParser.isNameCharacter(seq[i], xml11))
          return false;
      }
    return true;
  }

  private boolean isNCName(String text)
    throws IOException
  {
    if (text == null)
      return false;
    int[] seq = UnicodeReader.toCodePointArray(text);
    if (seq.length < 1)
      return false;
    if (!XMLParser.isNameStartCharacter(seq[0], xml11) || seq[0] == 0x3a)
      return false;
    for (int i = 1; i < seq.length; i++)
      {
        if (!XMLParser.isNameCharacter(seq[i], xml11) || seq[i] == 0x3a)
          return false;
      }
    return true;
  }

  private boolean isChars(String text)
    throws IOException
  {
    if (text == null)
      return false;
    int[] seq = UnicodeReader.toCodePointArray(text);
    hasXML11RestrictedChars = false;
    if (xml11)
      {
        for (int i = 0; i < seq.length; i++)
          {
            if (!XMLParser.isXML11Char(seq[i]))
              return false;
            if (XMLParser.isXML11RestrictedChar(seq[i]))
              hasXML11RestrictedChars = true;
          }
      }
    else
      {
        for (int i = 0; i < seq.length; i++)
          {
            if (!XMLParser.isChar(seq[i]))
              return false;
          }
      }
    return true;
  }

  private boolean isURI(String text)
  {
    if (text == null)
      return false;
    char[] chars = text.toCharArray();
    if (chars.length < 1)
      return false;
    for (int i = 0; i < chars.length; i++)
      {
        if (chars[i] < 0x20 || chars[i] >= 0x7f)
          return false;
      }
    return true;
  }
  
}

