/* 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
