XML Properties : Properties « Development Class « Java






XML Properties

     
// XMLProperties.java
// $Id: XMLProperties.java,v 1.5 2000/08/16 21:37:58 ylafon Exp $
// (c) COPYRIGHT MIT, INRIA and Keio, 1999.
// Please first read the full copyright statement in file COPYRIGHT.html

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Properties;

import org.xml.sax.AttributeList;
import org.xml.sax.DocumentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.Parser;
import org.xml.sax.SAXException;

/**
 * The <code>Properties</code> class represents a persistent set of
 * properties. The <code>Properties</code> can be saved to a stream or loaded
 * from a stream. Each key and its corresponding value in the property list is a
 * string.
 * <p>
 * A property list can contain another property list as its "defaults"; this
 * second property list is searched if the property key is not found in the
 * original property list. Because Properties inherits from Hashtable, the put
 * and putAll methods can be applied to a Properties object. Their use is
 * strongly discouraged as they allow the caller to insert entries whose keys or
 * values are not Strings. The setProperty method should be used instead. If the
 * store or save method is called on a "compromised" Properties object that
 * contains a non-String key or value, the call will fail.
 * <p>
 * This is a special implementation for XML :
 * 
 * <pre>
 *    &lt;properties&gt;
 *       &lt;key name=&quot;My_key1&quot;&gt;My_Value1&lt;/key&gt;
 *       &lt;key name=&quot;My_key2&quot;&gt;My_Value2&lt;/key&gt;
 *    &lt;/properties&gt;
 * </pre>
 * 
 * @version $Revision: 1.5 $
 * @author Philippe Le Hgaret (plh@w3.org)
 * @author Benot Mah (bmahe@w3.org)
 */
public class XMLProperties extends Properties {

  public static final String PARSER_P = "com.jclark.xml.sax.Driver";

  public boolean debug = false;

  class XMLParser implements DocumentHandler {

    final int IN_NOTHING = 0;

    final int IN_DOCUMENT = 1;

    final int IN_KEY = 2;

    int state = IN_NOTHING;

    String key;

    StringBuffer value;

    Parser parser;

    XMLParser(InputStream in) throws IOException, SAXException {
      state = IN_NOTHING;
      value = new StringBuffer();
      try {
        parser = getParser();
        parser.setDocumentHandler(this);
      } catch (Exception e) {
        e.printStackTrace();
        throw new SAXException("can't create parser ");
      }
      parser.parse(new InputSource(in));
    }

    public void startElement(String name, AttributeList atts) throws SAXException {
      if (state == IN_NOTHING) {
        if (name.equals("properties")) {
          state = IN_DOCUMENT;
        } else {
          throw new SAXException("attempt to find root properties");
        }
      } else if (state == IN_DOCUMENT) {
        if (name.equals("key")) {
          state = IN_KEY;
          key = atts.getValue("name");

          if (key == null) {
            throw new SAXException("no name for key " + atts);
          }
        } else {
          throw new SAXException("attempt to find keys");
        }
      } else {
        throw new SAXException("invalid element " + name);
      }
    }

    public void endElement(String name) throws SAXException {
      if (state == IN_KEY) {
        setProperty(key, value.toString());
        if (debug) {
          System.out.print("<key name=\"" + key + "\">");
          System.out.println(value.toString() + "</key>\n");
        }
        state = IN_DOCUMENT;
        name = null;
        value = new StringBuffer();
      } else if (state == IN_DOCUMENT) {
        state = IN_NOTHING;
      }
    }

    public void characters(char ch[], int start, int length) throws SAXException {
      if (state == IN_KEY) {
        compute(ch, start, length);
      }
    }

    public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
      // nothing to do
    }

    public void startDocument() throws SAXException {
      // nothing to do
    }

    public void endDocument() throws SAXException {
      // nothing to do
    }

    public void processingInstruction(String target, String data) throws SAXException {
      // nothing to do
    }

    public void setDocumentLocator(Locator locator) {
      // nothing to do
    }

    private void compute(char[] ch, int start, int length) {
      int st = start;
      int len = length - 1;
      while (st < length
          && ((ch[st] == '\n') || (ch[st] == '\t') || (ch[st] == ' ') || (ch[st] == '\r'))) {
        st++;
      }
      while (len > 0
          && ((ch[len] == '\n') || (ch[len] == '\t') || (ch[len] == ' ') || (ch[len] == '\r'))) {
        len--;
      }

      while (st <= len) {
        value.append(ch[st]);
        st++;
      }
    }
  } // XMLParser

  private Class parser_class = null;

  /**
   * Reads a property list from an input stream.
   * 
   * @param in
   *          the input stream.
   * @exception IOException
   *              if an error occurred when reading from the input stream.
   * @since JDK1.0
   */
  public synchronized void load(InputStream in) throws IOException {
    XMLParser p = null;
    try {
      p = new XMLParser(in);
    } catch (SAXException e) {
      throw new IOException(e.getMessage());
    }
  }

  /**
   * Reads a property list from an input stream. This method try to load
   * properties with super.load() if the XMLParser failed. Use this method to
   * translate an Property set to an XML Property set.
   * 
   * @param file
   *          the properties file.
   * @exception IOException
   *              if an error occurred when reading from the input stream.
   * @since JDK1.0
   */
  public synchronized void load(File file) throws IOException {
    InputStream in = new BufferedInputStream(new FileInputStream(file));
    XMLParser p = null;
    try {
      p = new XMLParser(in);
    } catch (SAXException e) {
      try {
        in = new BufferedInputStream(new FileInputStream(file));
        super.load(in);
        in.close();
      } catch (IOException ex) {
        throw new IOException(e.getMessage());
      }
    }
  }

  /**
   * Calls the <code>store(OutputStream out, String header)</code> method and
   * suppresses IOExceptions that were thrown.
   * 
   * @deprecated This method does not throw an IOException if an I/O error
   *             occurs while saving the property list. As of JDK 1.2, the
   *             preferred way to save a properties list is via the
   *             <code>store(OutputStream out,
   * String header)</code> method.
   * 
   * @param out
   *          an output stream.
   * @param header
   *          a description of the property list.
   * @exception ClassCastException
   *              if this <code>Properties</code> object contains any keys or
   *              values that are not <code>Strings</code>.
   */
  public synchronized void save(OutputStream out, String header) {
    try {
      store(out, header);
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }

  /**
   * Writes this property list (key and element pairs) in this
   * <code>Properties</code> table to the output stream in a format suitable
   * for loading into a <code>Properties</code> table using the
   * <code>load</code> method.
   * <p>
   * After the entries have been written, the output stream is flushed. The
   * output stream remains open after this method returns.
   * 
   * @param out
   *          an output stream.
   * @param header
   *          a description of the property list.
   * @exception ClassCastException
   *              if this <code>Properties</code> object contains any keys or
   *              values that are not <code>Strings</code>.
   */
  public synchronized void store(OutputStream out, String header) throws IOException {
    PrintWriter wout = new PrintWriter(out);
    wout.println("<?xml version='1.0'?>");
    if (header != null) {
      wout.println("<!--" + header + "-->");
    }

    wout.print("<properties>");
    for (Enumeration e = keys(); e.hasMoreElements();) {
      String key = (String) e.nextElement();
      String val = (String) get(key);
      wout.print("\n <key name=\"" + key + "\">");
      wout.print(encode(val));
      wout.print("</key>");
    }
    wout.print("\n</properties>");
    wout.flush();
  }

  protected StringBuffer encode(String string) {
    int len = string.length();
    StringBuffer buffer = new StringBuffer(len);
    char c;

    for (int i = 0; i < len; i++) {
      switch (c = string.charAt(i)) {
      case '&':
        buffer.append("&amp;");
        break;
      case '<':
        buffer.append("&lt;");
        break;
      case '>':
        buffer.append("&gt;");
        break;
      default:
        buffer.append(c);
      }
    }

    return buffer;
  }

  private Class getParserClass() throws ClassNotFoundException {
    if (parser_class == null)
      parser_class = Class.forName(PARSER_P);
    return parser_class;
  }

  private Parser getParser() {
    try {
      return (Parser) getParserClass().newInstance();
    } catch (Exception ex) {
      throw new RuntimeException("Unable to intantiate : " + PARSER_P);
    }
  }

  /**
   * Creates an empty property list with no default values.
   */
  public XMLProperties() {
    super();
  }

  /**
   * Creates an empty property list with the specified defaults.
   * 
   * @param defaults
   *          the defaults.
   */
  public XMLProperties(Properties defaults) {
    super(defaults);
  }

  /**
   * Creates an empty property list with the specified defaults.
   * 
   * @param parser
   *          the XML Parser classname (default is PARSER_P)
   * @param defaults
   *          the defaults.
   */
  public XMLProperties(String parser, Properties defaults) {
    super(defaults);
    try {
      parser_class = Class.forName(parser);
    } catch (ClassNotFoundException ex) {
      System.err.println("Unable to instanciate parser class: " + parser);
      System.err.println("Using default parser.");
    }
  }

  public void setDebug(boolean debug) {
    this.debug = debug;
  }

}

   
    
    
    
    
  








Related examples in the same category

1.Read a set of properties from the received input stream, strip off any excess white space that exists in those property values,
2.Copy a set of properties from one Property to another.
3.Sorts property list and print out each key=value pair prepended with specific indentation.
4.Sorts a property list and turns the sorted list into a string.
5.A utility class for replacing properties in strings.
6.Property Loader
7.Property access utility methods
8.Represents a persistent set of properties
9.Converts specified map to java.util.Properties
10.A java.util.Properties class that will check a file or URL for changes periodically
11.Encapsulates java.util.Properties to add java primitives and some other java classes
12.Load and save properties to files.
13.Adds new properties to an existing set of properties
14.Extracts a specific property key subset from the known properties
15.Observable Properties
16.Merge Properties Into Map
17.XML configuration management
18.JDOM based XML properties
19.Converts Unicode into something that can be embedded in a java properties file
20.Create Properties from String array
21.Task to overwrite Properties
22.Gets strong-type-value property from a standard Properties
23.The properties iterator iterates over a set of enumerated properties.
24.An utility class to ease up using property-file resource bundles.
25.Sorted Properties
26.A subclass of the java.util.Properties class that must be initialized from a file on disk
27.This class contains a collection of static utility methods for creating, retrieving, saving and loading properties.
28.Simplify routine job with properties
29.Property Manager