/* 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 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 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
{
  // 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 an input 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 inStream the input stream
   * @throws IOException if an error occurred when reading the input
   * @throws NullPointerException if in is null
   */
  public void load(InputStream inStream) throws IOException
  {
    // The spec says that the file must be encoded using ISO-8859-1.
    BufferedReader reader =
      new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1"));
    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;
        StringBuilder key = needsEscape ? new StringBuilder() : 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());
      }
  }

  /**
   * 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
   */
  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 ();
    StringBuilder s = new StringBuilder (); // 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, StringBuilder 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;
        StringBuffer 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 StringBuffer();
                  }
                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
