/* Properties.java -- a set of persistent properties
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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 java.util;

import gnu.java.lang.CPStringBuilder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Element;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;

/**
 * A set of persistent properties, which can be saved or loaded from a stream.
 * A property list may also contain defaults, searched if the main list
 * does not contain a property for a given key.
 *
 * An example of a properties file for the german language is given
 * here.  This extends the example given in ListResourceBundle.
 * Create a file MyResource_de.properties with the following contents
 * and put it in the CLASSPATH.  (The character
 * <code>\</code><code>u00e4</code> is the german umlaut)
 *
 *
<pre>s1=3
s2=MeineDisk
s3=3. M\<code></code>u00e4rz 96
s4=Die Diskette ''{1}'' enth\<code></code>u00e4lt {0} in {2}.
s5=0
s6=keine Dateien
s7=1
s8=eine Datei
s9=2
s10={0,number} Dateien
s11=Das Formatieren schlug fehl mit folgender Exception: {0}
s12=FEHLER
s13=Ergebnis
s14=Dialog
s15=Auswahlkriterium
s16=1,3</pre>
 *
 * <p>Although this is a sub class of a hash table, you should never
 * insert anything other than strings to this property, or several
 * methods, that need string keys and values, will fail.  To ensure
 * this, you should use the <code>get/setProperty</code> method instead
 * of <code>get/put</code>.
 *
 * Properties are saved in ISO 8859-1 encoding, using Unicode escapes with
 * a single <code>u</code> for any character which cannot be represented.
 *
 * @author Jochen Hoenicke
 * @author Eric Blake (ebb9@email.byu.edu)
 * @see PropertyResourceBundle
 * @status updated to 1.4
 */
public class Properties extends Hashtable<Object, Object>
{
  // WARNING: Properties is a CORE class in the bootstrap cycle. See the
  // comments in vm/reference/java/lang/Runtime for implications of this fact.

  /**
   * The property list that contains default values for any keys not
   * in this property list.
   *
   * @serial the default properties
   */
  protected Properties defaults;

  /**
   * Compatible with JDK 1.0+.
   */
  private static final long serialVersionUID = 4112578634029874840L;

  /**
   * Creates a new empty property list with no default values.
   */
  public Properties()
  {
  }

  /**
   * Create a new empty property list with the specified default values.
   *
   * @param defaults a Properties object containing the default values
   */
  public Properties(Properties defaults)
  {
    this.defaults = defaults;
  }

  /**
   * Adds the given key/value pair to this properties.  This calls
   * the hashtable method put.
   *
   * @param key the key for this property
   * @param value the value for this property
   * @return The old value for the given key
   * @see #getProperty(String)
   * @since 1.2
   */
  public Object setProperty(String key, String value)
  {
    return put(key, value);
  }

  /**
   * Reads a property list from a character stream.  The stream should
   * have the following format: <br>
   *
   * An empty line or a line starting with <code>#</code> or
   * <code>!</code> is ignored.  An backslash (<code>\</code>) at the
   * end of the line makes the line continueing on the next line
   * (but make sure there is no whitespace after the backslash).
   * Otherwise, each line describes a key/value pair. <br>
   *
   * The chars up to the first whitespace, = or : are the key.  You
   * can include this caracters in the key, if you precede them with
   * a backslash (<code>\</code>). The key is followed by optional
   * whitespaces, optionally one <code>=</code> or <code>:</code>,
   * and optionally some more whitespaces.  The rest of the line is
   * the resource belonging to the key. <br>
   *
   * Escape sequences <code>\t, \n, \r, \\, \", \', \!, \#, \ </code>(a
   * space), and unicode characters with the
   * <code>\\u</code><em>xxxx</em> notation are detected, and
   * converted to the corresponding single character. <br>
   *
   *
<pre># This is a comment
key     = value
k\:5      \ a string starting with space and ending with newline\n
# This is a multiline specification; note that the value contains
# no white space.
weekdays: Sunday,Monday,Tuesday,Wednesday,\\
          Thursday,Friday,Saturday
# The safest way to include a space at the end of a value:
label   = Name:\\u0020</pre>
   *
   * @param inReader the input {@link java.io.Reader}.
   * @throws IOException if an error occurred when reading the input
   * @throws NullPointerException if in is null
   * @since 1.6
   */
  public void load(Reader inReader) throws IOException
  {
    BufferedReader reader = new BufferedReader(inReader);
    String line;

    while ((line = reader.readLine()) != null)
      {
        char c = 0;
        int pos = 0;
        // Leading whitespaces must be deleted first.
        while (pos < line.length()
               && Character.isWhitespace(c = line.charAt(pos)))
          pos++;

        // If empty line or begins with a comment character, skip this line.
        if ((line.length() - pos) == 0
            || line.charAt(pos) == '#' || line.charAt(pos) == '!')
          continue;

        // The characters up to the next Whitespace, ':', or '='
        // describe the key.  But look for escape sequences.
        // Try to short-circuit when there is no escape char.
        int start = pos;
        boolean needsEscape = line.indexOf('\\', pos) != -1;
        CPStringBuilder key = needsEscape ? new CPStringBuilder() : null;
        while (pos < line.length()
               && ! Character.isWhitespace(c = line.charAt(pos++))
               && c != '=' && c != ':')
          {
            if (needsEscape && c == '\\')
              {
                if (pos == line.length())
                  {
                    // The line continues on the next line.  If there
                    // is no next line, just treat it as a key with an
                    // empty value.
                    line = reader.readLine();
                    if (line == null)
                      line = "";
                    pos = 0;
                    while (pos < line.length()
                           && Character.isWhitespace(c = line.charAt(pos)))
                      pos++;
                  }
                else
                  {
                    c = line.charAt(pos++);
                    switch (c)
                      {
                      case 'n':
                        key.append('\n');
                        break;
                      case 't':
                        key.append('\t');
                        break;
                      case 'r':
                        key.append('\r');
                        break;
                      case 'u':
                        if (pos + 4 <= line.length())
                          {
                            char uni = (char) Integer.parseInt
                              (line.substring(pos, pos + 4), 16);
                            key.append(uni);
                            pos += 4;
                          }        // else throw exception?
                        break;
                      default:
                        key.append(c);
                        break;
                      }
                  }
              }
            else if (needsEscape)
              key.append(c);
          }

        boolean isDelim = (c == ':' || c == '=');

        String keyString;
        if (needsEscape)
          keyString = key.toString();
        else if (isDelim || Character.isWhitespace(c))
          keyString = line.substring(start, pos - 1);
        else
          keyString = line.substring(start, pos);

        while (pos < line.length()
               && Character.isWhitespace(c = line.charAt(pos)))
          pos++;

        if (! isDelim && (c == ':' || c == '='))
          {
            pos++;
            while (pos < line.length()
                   && Character.isWhitespace(c = line.charAt(pos)))
              pos++;
          }

        // Short-circuit if no escape chars found.
        if (!needsEscape)
          {
            put(keyString, line.substring(pos));
            continue;
          }

        // Escape char found so iterate through the rest of the line.
        StringBuilder element = new StringBuilder(line.length() - pos);
        while (pos < line.length())
          {
            c = line.charAt(pos++);
            if (c == '\\')
              {
                if (pos == line.length())
                  {
                    // The line continues on the next line.
                    line = reader.readLine();

                    // We might have seen a backslash at the end of
                    // the file.  The JDK ignores the backslash in
                    // this case, so we follow for compatibility.
                    if (line == null)
                      break;

                    pos = 0;
                    while (pos < line.length()
                           && Character.isWhitespace(c = line.charAt(pos)))
                      pos++;
                    element.ensureCapacity(line.length() - pos +
                                           element.length());
                  }
                else
                  {
                    c = line.charAt(pos++);
                    switch (c)
                      {
                      case 'n':
                        element.append('\n');
                        break;
                      case 't':
                        element.append('\t');
                        break;
                      case 'r':
                        element.append('\r');
                        break;
                      case 'u':
                        if (pos + 4 <= line.length())
                          {
                            char uni = (char) Integer.parseInt
                              (line.substring(pos, pos + 4), 16);
                            element.append(uni);
                            pos += 4;
                          }        // else throw exception?
                        break;
                      default:
                        element.append(c);
                        break;
                      }
                  }
              }
            else
              element.append(c);
          }
        put(keyString, element.toString());
      }
  }

  /**
   * Reads a property list from the supplied input stream.
   * This method has the same functionality as {@link #load(Reader)}
   * but the character encoding is assumed to be ISO-8859-1.
   * Unicode characters not within the Latin1 set supplied by
   * ISO-8859-1 should be escaped using '\\uXXXX' where XXXX
   * is the UTF-16 code unit in hexadecimal.
   *
   * @param inStream the byte stream to read the property list from.
   * @throws IOException if an I/O error occurs.
   * @see #load(Reader)
   * @since 1.2
   */
  public void load(InputStream inStream) throws IOException
  {
    load(new InputStreamReader(inStream, "ISO-8859-1"));
  }

  /**
   * Calls <code>store(OutputStream out, String header)</code> and
   * ignores the IOException that may be thrown.
   *
   * @param out the stream to write to
   * @param header a description of the property list
   * @throws ClassCastException if this property contains any key or
   *         value that are not strings
   * @deprecated use {@link #store(OutputStream, String)} instead
   */
  @Deprecated
  public void save(OutputStream out, String header)
  {
    try
      {
        store(out, header);
      }
    catch (IOException ex)
      {
      }
  }

  /**
   * Writes the key/value pairs to the given output stream, in a format
   * suitable for <code>load</code>.<br>
   *
   * If header is not null, this method writes a comment containing
   * the header as first line to the stream.  The next line (or first
   * line if header is null) contains a comment with the current date.
   * Afterwards the key/value pairs are written to the stream in the
   * following format.<br>
   *
   * Each line has the form <code>key = value</code>.  Newlines,
   * Returns and tabs are written as <code>\n,\t,\r</code> resp.
   * The characters <code>\, !, #, =</code> and <code>:</code> are
   * preceeded by a backslash.  Spaces are preceded with a backslash,
   * if and only if they are at the beginning of the key.  Characters
   * that are not in the ascii range 33 to 127 are written in the
   * <code>\</code><code>u</code>xxxx Form.<br>
   *
   * Following the listing, the output stream is flushed but left open.
   *
   * @param out the output stream
   * @param header the header written in the first line, may be null
   * @throws ClassCastException if this property contains any key or
   *         value that isn't a string
   * @throws IOException if writing to the stream fails
   * @throws NullPointerException if out is null
   * @since 1.2
   */
  public void store(OutputStream out, String header) throws IOException
  {
    // The spec says that the file must be encoded using ISO-8859-1.
    PrintWriter writer
      = new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1"));
    if (header != null)
      writer.println("#" + header);
    writer.println ("#" + Calendar.getInstance ().getTime ());

    Iterator iter = entrySet ().iterator ();
    int i = size ();
    CPStringBuilder s = new CPStringBuilder (); // Reuse the same buffer.
    while (--i >= 0)
      {
        Map.Entry entry = (Map.Entry) iter.next ();
        formatForOutput ((String) entry.getKey (), s, true);
        s.append ('=');
        formatForOutput ((String) entry.getValue (), s, false);
        writer.println (s);
      }

    writer.flush ();
  }

  /**
   * Gets the property with the specified key in this property list.
   * If the key is not found, the default property list is searched.
   * If the property is not found in the default, null is returned.
   *
   * @param key The key for this property
   * @return the value for the given key, or null if not found
   * @throws ClassCastException if this property contains any key or
   *         value that isn't a string
   * @see #defaults
   * @see #setProperty(String, String)
   * @see #getProperty(String, String)
   */
  public String getProperty(String key)
  {
    Properties prop = this;
    // Eliminate tail recursion.
    do
      {
        String value = (String) prop.get(key);
        if (value != null)
          return value;
        prop = prop.defaults;
      }
    while (prop != null);
    return null;
  }

  /**
   * Gets the property with the specified key in this property list.  If
   * the key is not found, the default property list is searched.  If the
   * property is not found in the default, the specified defaultValue is
   * returned.
   *
   * @param key The key for this property
   * @param defaultValue A default value
   * @return The value for the given key
   * @throws ClassCastException if this property contains any key or
   *         value that isn't a string
   * @see #defaults
   * @see #setProperty(String, String)
   */
  public String getProperty(String key, String defaultValue)
  {
    String prop = getProperty(key);
    if (prop == null)
      prop = defaultValue;
    return prop;
  }

  /**
   * Returns an enumeration of all keys in this property list, including
   * the keys in the default property list.
   *
   * @return an Enumeration of all defined keys
   */
  public Enumeration<?> propertyNames()
  {
    // We make a new Set that holds all the keys, then return an enumeration
    // for that. This prevents modifications from ruining the enumeration,
    // as well as ignoring duplicates.
    Properties prop = this;
    Set s = new HashSet();
    // Eliminate tail recursion.
    do
      {
        s.addAll(prop.keySet());
        prop = prop.defaults;
      }
    while (prop != null);
    return Collections.enumeration(s);
  }

  /**
   * Prints the key/value pairs to the given print stream.  This is
   * mainly useful for debugging purposes.
   *
   * @param out the print stream, where the key/value pairs are written to
   * @throws ClassCastException if this property contains a key or a
   *         value that isn't a string
   * @see #list(PrintWriter)
   */
  public void list(PrintStream out)
  {
    PrintWriter writer = new PrintWriter (out);
    list (writer);
  }

  /**
   * Prints the key/value pairs to the given print writer.  This is
   * mainly useful for debugging purposes.
   *
   * @param out the print writer where the key/value pairs are written to
   * @throws ClassCastException if this property contains a key or a
   *         value that isn't a string
   * @see #list(PrintStream)
   * @since 1.1
   */
  public void list(PrintWriter out)
  {
    out.println ("-- listing properties --");

    Iterator iter = entrySet ().iterator ();
    int i = size ();
    while (--i >= 0)
      {
        Map.Entry entry = (Map.Entry) iter.next ();
        out.print ((String) entry.getKey () + "=");

        // JDK 1.3/1.4 restrict the printed value, but not the key,
        // to 40 characters, including the truncating ellipsis.
        String s = (String ) entry.getValue ();
        if (s != null && s.length () > 40)
          out.println (s.substring (0, 37) + "...");
        else
          out.println (s);
      }
    out.flush ();
  }

  /**
   * Formats a key or value for output in a properties file.
   * See store for a description of the format.
   *
   * @param str the string to format
   * @param buffer the buffer to add it to
   * @param key true if all ' ' must be escaped for the key, false if only
   *        leading spaces must be escaped for the value
   * @see #store(OutputStream, String)
   */
  private void formatForOutput(String str, CPStringBuilder buffer, boolean key)
  {
    if (key)
      {
        buffer.setLength(0);
        buffer.ensureCapacity(str.length());
      }
    else
      buffer.ensureCapacity(buffer.length() + str.length());
    boolean head = true;
    int size = str.length();
    for (int i = 0; i < size; i++)
      {
        char c = str.charAt(i);
        switch (c)
          {
          case '\n':
            buffer.append("\\n");
            break;
          case '\r':
            buffer.append("\\r");
            break;
          case '\t':
            buffer.append("\\t");
            break;
          case ' ':
            buffer.append(head ? "\\ " : " ");
            break;
          case '\\':
          case '!':
          case '#':
          case '=':
          case ':':
            buffer.append('\\').append(c);
            break;
          default:
            if (c < ' ' || c > '~')
              {
                String hex = Integer.toHexString(c);
                buffer.append("\\u0000".substring(0, 6 - hex.length()));
                buffer.append(hex);
              }
            else
              buffer.append(c);
          }
        if (c != ' ')
          head = key;
      }
  }

  /**
   * <p>
   * Encodes the properties as an XML file using the UTF-8 encoding.
   * The format of the XML file matches the DTD
   * <a href="http://java.sun.com/dtd/properties.dtd">
   * http://java.sun.com/dtd/properties.dtd</a>.
   * </p>
   * <p>
   * Invoking this method provides the same behaviour as invoking
   * <code>storeToXML(os, comment, "UTF-8")</code>.
   * </p>
   *
   * @param os the stream to output to.
   * @param comment a comment to include at the top of the XML file, or
   *                <code>null</code> if one is not required.
   * @throws IOException if the serialization fails.
   * @throws NullPointerException if <code>os</code> is null.
   * @since 1.5
   */
  public void storeToXML(OutputStream os, String comment)
    throws IOException
  {
    storeToXML(os, comment, "UTF-8");
  }

  /**
   * <p>
   * Encodes the properties as an XML file using the supplied encoding.
   * The format of the XML file matches the DTD
   * <a href="http://java.sun.com/dtd/properties.dtd">
   * http://java.sun.com/dtd/properties.dtd</a>.
   * </p>
   *
   * @param os the stream to output to.
   * @param comment a comment to include at the top of the XML file, or
   *                <code>null</code> if one is not required.
   * @param encoding the encoding to use for the XML output.
   * @throws IOException if the serialization fails.
   * @throws NullPointerException if <code>os</code> or <code>encoding</code>
   *                              is null.
   * @since 1.5
   */
  public void storeToXML(OutputStream os, String comment, String encoding)
    throws IOException
  {
    if (os == null)
      throw new NullPointerException("Null output stream supplied.");
    if (encoding == null)
      throw new NullPointerException("Null encoding supplied.");
    try
      {
        DOMImplementationRegistry registry =
          DOMImplementationRegistry.newInstance();
        DOMImplementation domImpl = registry.getDOMImplementation("LS 3.0");
        DocumentType doctype =
          domImpl.createDocumentType("properties", null,
                                     "http://java.sun.com/dtd/properties.dtd");
        Document doc = domImpl.createDocument(null, "properties", doctype);
        Element root = doc.getDocumentElement();
        if (comment != null)
          {
            Element commentElement = doc.createElement("comment");
            commentElement.appendChild(doc.createTextNode(comment));
            root.appendChild(commentElement);
          }
        Iterator iterator = entrySet().iterator();
        while (iterator.hasNext())
          {
            Map.Entry entry = (Map.Entry) iterator.next();
            Element entryElement = doc.createElement("entry");
            entryElement.setAttribute("key", (String) entry.getKey());
            entryElement.appendChild(doc.createTextNode((String)
                                                        entry.getValue()));
            root.appendChild(entryElement);
          }
        DOMImplementationLS loadAndSave = (DOMImplementationLS) domImpl;
        LSSerializer serializer = loadAndSave.createLSSerializer();
        LSOutput output = loadAndSave.createLSOutput();
        output.setByteStream(os);
        output.setEncoding(encoding);
        serializer.write(doc, output);
      }
    catch (ClassNotFoundException e)
      {
        throw (IOException)
          new IOException("The XML classes could not be found.").initCause(e);
      }
    catch (InstantiationException e)
      {
        throw (IOException)
          new IOException("The XML classes could not be instantiated.")
          .initCause(e);
      }
    catch (IllegalAccessException e)
      {
        throw (IOException)
          new IOException("The XML classes could not be accessed.")
          .initCause(e);
      }
  }

  /**
   * <p>
   * Decodes the contents of the supplied <code>InputStream</code> as
   * an XML file, which represents a set of properties.  The format of
   * the XML file must match the DTD
   * <a href="http://java.sun.com/dtd/properties.dtd">
   * http://java.sun.com/dtd/properties.dtd</a>.
   * </p>
   *
   * @param in the input stream from which to receive the XML data.
   * @throws IOException if an I/O error occurs in reading the input data.
   * @throws InvalidPropertiesFormatException if the input data does not
   *                                          constitute an XML properties
   *                                          file.
   * @throws NullPointerException if <code>in</code> is null.
   * @since 1.5
   */
  public void loadFromXML(InputStream in)
    throws IOException, InvalidPropertiesFormatException
  {
    if (in == null)
      throw new NullPointerException("Null input stream supplied.");
    try
      {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        // Don't resolve external entity references
        factory.setProperty("javax.xml.stream.isSupportingExternalEntities",
                            Boolean.FALSE);
        XMLStreamReader reader = factory.createXMLStreamReader(in);
        String name, key = null;
        CPStringBuilder buf = null;
        while (reader.hasNext())
          {
            switch (reader.next())
              {
              case XMLStreamConstants.START_ELEMENT:
                name = reader.getLocalName();
                if (buf == null && "entry".equals(name))
                  {
                    key = reader.getAttributeValue(null, "key");
                    if (key == null)
                      {
                        String msg = "missing 'key' attribute";
                        throw new InvalidPropertiesFormatException(msg);
                      }
                    buf = new CPStringBuilder();
                  }
                else if (!"properties".equals(name) && !"comment".equals(name))
                  {
                    String msg = "unexpected element name '" + name + "'";
                    throw new InvalidPropertiesFormatException(msg);
                  }
                break;
              case XMLStreamConstants.END_ELEMENT:
                name = reader.getLocalName();
                if (buf != null && "entry".equals(name))
                  {
                    put(key, buf.toString());
                    buf = null;
                  }
                else if (!"properties".equals(name) && !"comment".equals(name))
                  {
                    String msg = "unexpected element name '" + name + "'";
                    throw new InvalidPropertiesFormatException(msg);
                  }
                break;
              case XMLStreamConstants.CHARACTERS:
              case XMLStreamConstants.SPACE:
              case XMLStreamConstants.CDATA:
                if (buf != null)
                  buf.append(reader.getText());
                break;
              }
          }
        reader.close();
      }
    catch (XMLStreamException e)
      {
        throw (InvalidPropertiesFormatException)
          new InvalidPropertiesFormatException("Error in parsing XML.").
          initCause(e);
      }
  }

} // class Properties
