You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2005/11/22 21:41:33 UTC
svn commit: r348244 [3/3] - in
/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration:
./ plist/
Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/plist/XMLPropertyListConfiguration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/plist/XMLPropertyListConfiguration.java?rev=348244&r1=348243&r2=348244&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/plist/XMLPropertyListConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/plist/XMLPropertyListConfiguration.java Tue Nov 22 12:40:57 2005
@@ -1,521 +1,521 @@
-/*
- * Copyright 2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License")
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.configuration.plist;
-
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.configuration.AbstractHierarchicalFileConfiguration;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.apache.commons.configuration.MapConfiguration;
-import org.apache.commons.digester.AbstractObjectCreationFactory;
-import org.apache.commons.digester.Digester;
-import org.apache.commons.digester.ObjectCreateRule;
-import org.apache.commons.digester.SetNextRule;
-import org.apache.commons.lang.StringEscapeUtils;
-import org.apache.commons.lang.StringUtils;
-import org.xml.sax.Attributes;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-
-/**
- * Mac OS X configuration file (http://www.apple.com/DTDs/PropertyList-1.0.dtd).
- *
- * <p>Example:</p>
- * <pre>
- * <?xml version="1.0"?>
- * <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
- * <plist version="1.0">
- * <dict>
- * <key>string</key>
- * <string>value1</string>
- *
- * <key>integer</key>
- * <integer>12345</integer>
- *
- * <key>real</key>
- * <real>-123.45E-1</real>
- *
- * <key>boolean</key>
- * <true/>
- *
- * <key>date</key>
- * <date>2005-01-01T12:00:00-0700</date>
- *
- * <key>data</key>
- * <data>RHJhY28gRG9ybWllbnMgTnVucXVhbSBUaXRpbGxhbmR1cw==</data>
- *
- * <key>array</key>
- * <array>
- * <string>value1</string>
- * <string>value2</string>
- * <string>value3</string>
- * </array>
- *
- * <key>dictionnary</key>
- * <dict>
- * <key>key1</key>
- * <string>value1</string>
- * <key>key2</key>
- * <string>value2</string>
- * <key>key3</key>
- * <string>value3</string>
- * </dict>
- *
- * <key>nested</key>
- * <dict>
- * <key>node1</key>
- * <dict>
- * <key>node2</key>
- * <dict>
- * <key>node3</key>
- * <string>value</string>
- * </dict>
- * </dict>
- * </dict>
- *
- * </dict>
- * </plist>
- * </pre>
- *
- * @since 1.2
- *
- * @author Emmanuel Bourg
- * @version $Revision$, $Date$
- */
-public class XMLPropertyListConfiguration extends AbstractHierarchicalFileConfiguration
-{
- private static final int INDENT_SIZE = 4;
-
- /**
- * Creates an empty XMLPropertyListConfiguration object which can be
- * used to synthesize a new plist file by adding values and
- * then saving().
- */
- public XMLPropertyListConfiguration() { }
-
- /**
- * Creates and loads the property list from the specified file.
- *
- * @param fileName The name of the plist file to load.
- * @throws org.apache.commons.configuration.ConfigurationException Error while loading the plist file
- */
- public XMLPropertyListConfiguration(String fileName) throws ConfigurationException
- {
- super(fileName);
- }
-
- /**
- * Creates and loads the property list from the specified file.
- *
- * @param file The plist file to load.
- * @throws ConfigurationException Error while loading the plist file
- */
- public XMLPropertyListConfiguration(File file) throws ConfigurationException
- {
- super(file);
- }
-
- /**
- * Creates and loads the property list from the specified URL.
- *
- * @param url The location of the plist file to load.
- * @throws ConfigurationException Error while loading the plist file
- */
- public XMLPropertyListConfiguration(URL url) throws ConfigurationException
- {
- super(url);
- }
-
- public void load(Reader in) throws ConfigurationException
- {
- // set up the digester
- Digester digester = new Digester();
-
- // set up the DTD validation
- digester.setEntityResolver(new EntityResolver()
- {
- public InputSource resolveEntity(String publicId, String systemId)
- {
- return new InputSource(getClass().getClassLoader().getResourceAsStream("PropertyList-1.0.dtd"));
- }
- });
- digester.setValidating(true);
-
- // dictionary rules
- digester.addRule("*/key", new ObjectCreateRule(PListNode.class)
- {
- public void end() throws Exception
- {
- // leave the node on the stack to set the value
- }
- });
-
- digester.addCallMethod("*/key", "setName", 0);
-
- digester.addRule("*/dict/string", new SetNextAndPopRule("addChild"));
- digester.addRule("*/dict/data", new SetNextAndPopRule("addChild"));
- digester.addRule("*/dict/integer", new SetNextAndPopRule("addChild"));
- digester.addRule("*/dict/real", new SetNextAndPopRule("addChild"));
- digester.addRule("*/dict/true", new SetNextAndPopRule("addChild"));
- digester.addRule("*/dict/false", new SetNextAndPopRule("addChild"));
- digester.addRule("*/dict/date", new SetNextAndPopRule("addChild"));
- digester.addRule("*/dict/dict", new SetNextAndPopRule("addChild"));
-
- digester.addCallMethod("*/dict/string", "addValue", 0);
- digester.addCallMethod("*/dict/data", "addDataValue", 0);
- digester.addCallMethod("*/dict/integer", "addIntegerValue", 0);
- digester.addCallMethod("*/dict/real", "addRealValue", 0);
- digester.addCallMethod("*/dict/true", "addTrueValue");
- digester.addCallMethod("*/dict/false", "addFalseValue");
- digester.addCallMethod("*/dict/date", "addDateValue", 0);
-
- // rules for arrays
- digester.addRule("*/dict/array", new SetNextAndPopRule("addChild"));
- digester.addRule("*/dict/array", new ObjectCreateRule(ArrayNode.class));
- digester.addSetNext("*/dict/array", "addList");
-
- digester.addRule("*/array/array", new ObjectCreateRule(ArrayNode.class));
- digester.addSetNext("*/array/array", "addList");
-
- digester.addCallMethod("*/array/string", "addValue", 0);
- digester.addCallMethod("*/array/data", "addDataValue", 0);
- digester.addCallMethod("*/array/integer", "addIntegerValue", 0);
- digester.addCallMethod("*/array/real", "addRealValue", 0);
- digester.addCallMethod("*/array/true", "addTrueValue");
- digester.addCallMethod("*/array/false", "addFalseValue");
- digester.addCallMethod("*/array/date", "addDateValue", 0);
-
- // rule for a dictionary in an array
- digester.addFactoryCreate("*/array/dict", new AbstractObjectCreationFactory()
- {
- public Object createObject(Attributes attributes) throws Exception
- {
- // create the configuration
- XMLPropertyListConfiguration config = new XMLPropertyListConfiguration();
-
- // add it to the ArrayNode
- ArrayNode node = (ArrayNode) getDigester().peek();
- node.addValue(config);
-
- // push the root on the stack
- return config.getRoot();
- }
- });
-
- // parse the file
- digester.push(getRoot());
- try
- {
- digester.parse(in);
- }
- catch (Exception e)
- {
- throw new ConfigurationException("Unable to parse the configuration file", e);
- }
- }
-
- /**
- * Digester rule that sets the object on the stack to the n-1 object
- * and remove both of them from the stack. This rule is used to remove
- * the configuration node from the stack once its value has been parsed.
- */
- private class SetNextAndPopRule extends SetNextRule
- {
- public SetNextAndPopRule(String methodName)
- {
- super(methodName);
- }
-
- public void end(String namespace, String name) throws Exception
- {
- super.end(namespace, name);
- digester.pop();
- }
- }
-
- public void save(Writer out) throws ConfigurationException
- {
- PrintWriter writer = new PrintWriter(out);
-
- if (getEncoding() != null)
- {
- writer.println("<?xml version=\"1.0\" encoding=\"" + getEncoding() + "\"?>");
- }
- else
- {
- writer.println("<?xml version=\"1.0\"?>");
- }
-
- writer.println("<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">");
- writer.println("<plist version=\"1.0\">");
-
- printNode(writer, 1, getRoot());
-
- writer.println("</plist>");
- writer.flush();
- }
-
- /**
- * Append a node to the writer, indented according to a specific level.
- */
- private void printNode(PrintWriter out, int indentLevel, Node node)
- {
- String padding = StringUtils.repeat(" ", indentLevel * INDENT_SIZE);
-
- if (node.getName() != null)
- {
- out.println(padding + "<key>" + StringEscapeUtils.escapeXml(node.getName()) + "</key>");
- }
-
- List children = node.getChildren();
- if (!children.isEmpty())
- {
- out.println(padding + "<dict>");
-
- Iterator it = children.iterator();
- while (it.hasNext())
- {
- Node child = (Node) it.next();
- printNode(out, indentLevel + 1, child);
-
- if (it.hasNext())
- {
- out.println();
- }
- }
-
- out.println(padding + "</dict>");
- }
- else
- {
- Object value = node.getValue();
- printValue(out, indentLevel, value);
- }
- }
-
- /**
- * Append a value to the writer, indented according to a specific level.
- */
- private void printValue(PrintWriter out, int indentLevel, Object value)
- {
- String padding = StringUtils.repeat(" ", indentLevel * INDENT_SIZE);
-
- if (value instanceof Date)
- {
- out.println(padding + "<date>" + PListNode.format.format((Date) value) + "</date>");
- }
- else if (value instanceof Calendar)
- {
- printValue(out, indentLevel, ((Calendar) value).getTime());
- }
- else if (value instanceof Number)
- {
- if (value instanceof Double || value instanceof Float || value instanceof BigDecimal)
- {
- out.println(padding + "<real>" + value.toString() + "</real>");
- }
- else
- {
- out.println(padding + "<integer>" + value.toString() + "</integer>");
- }
- }
- else if (value instanceof Boolean)
- {
- if (((Boolean) value).booleanValue())
- {
- out.println(padding + "<true/>");
- }
- else
- {
- out.println(padding + "<false/>");
- }
- }
- else if (value instanceof List)
- {
- out.println(padding + "<array>");
- Iterator it = ((List) value).iterator();
- while (it.hasNext())
- {
- printValue(out, indentLevel + 1, it.next());
- }
- out.println(padding + "</array>");
- }
- else if (value instanceof HierarchicalConfiguration)
- {
- printNode(out, indentLevel, ((HierarchicalConfiguration) value).getRoot());
- }
- else if (value instanceof Configuration)
- {
- // display a flat Configuration as a dictionary
- out.println(padding + "<dict>");
-
- Configuration config = (Configuration) value;
- Iterator it = config.getKeys();
- while (it.hasNext())
- {
- // create a node for each property
- String key = (String) it.next();
- Node node = new Node(key);
- node.setValue(config.getProperty(key));
-
- // print the node
- printNode(out, indentLevel + 1, node);
-
- if (it.hasNext())
- {
- out.println();
- }
- }
- out.println(padding + "</dict>");
- }
- else if (value instanceof Map)
- {
- // display a Map as a dictionary
- Map map = (Map) value;
- printValue(out, indentLevel, new MapConfiguration(map));
- }
- else if (value instanceof byte[])
- {
- String base64 = new String(Base64.encodeBase64((byte[]) value));
- out.println(padding + "<data>" + StringEscapeUtils.escapeXml(base64) + "</data>");
- }
- else
- {
- out.println(padding + "<string>" + StringEscapeUtils.escapeXml(String.valueOf(value)) + "</string>");
- }
- }
-
-
- /**
- * Node extension with addXXX methods to parse the typed data passed by Digester.
- * <b>Do not use this class !</b> It is used internally by XMLPropertyConfiguration
- * to parse the configuration file, it may be removed at any moment in the future.
- */
- public static class PListNode extends Node
- {
- private static DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
-
- public void addChild(Node child)
- {
- super.addChild(child);
- }
-
- public void setName(String string)
- {
- super.setName(string);
- }
-
- public void addValue(Object value)
- {
- if (getValue() == null)
- {
- setValue(value);
- }
- else if (getValue() instanceof List)
- {
- List list = (List) getValue();
- list.add(value);
- }
- else
- {
- List list = new ArrayList();
- list.add(getValue());
- list.add(value);
- setValue(list);
- }
- }
-
- public void addDateValue(String value)
- {
- try
- {
- addValue(format.parse(value));
- }
- catch (ParseException e)
- {
- e.printStackTrace();
- }
- }
-
- public void addDataValue(String value)
- {
- addValue(Base64.decodeBase64(value.getBytes()));
- }
-
- public void addIntegerValue(String value)
- {
- addValue(new Integer(value));
- }
-
- public void addRealValue(String value)
- {
- addValue(new Double(value));
- }
-
- public void addTrueValue()
- {
- addValue(Boolean.TRUE);
- }
-
- public void addFalseValue()
- {
- addValue(Boolean.FALSE);
- }
-
- public void addList(ArrayNode node)
- {
- addValue(node.getValue());
- }
- }
-
- /**
- * Container for array elements. <b>Do not use this class !</b>
- * It is used internally by XMLPropertyConfiguration to parse the
- * configuration file, it may be removed at any moment in the future.
- */
- public static class ArrayNode extends PListNode
- {
- private List list = new ArrayList();
-
- public void addValue(Object value)
- {
- list.add(value);
- }
-
- public Object getValue()
- {
- return list;
- }
- }
-}
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.configuration.plist;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.configuration.AbstractHierarchicalFileConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.configuration.MapConfiguration;
+import org.apache.commons.digester.AbstractObjectCreationFactory;
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.ObjectCreateRule;
+import org.apache.commons.digester.SetNextRule;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+/**
+ * Mac OS X configuration file (http://www.apple.com/DTDs/PropertyList-1.0.dtd).
+ *
+ * <p>Example:</p>
+ * <pre>
+ * <?xml version="1.0"?>
+ * <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+ * <plist version="1.0">
+ * <dict>
+ * <key>string</key>
+ * <string>value1</string>
+ *
+ * <key>integer</key>
+ * <integer>12345</integer>
+ *
+ * <key>real</key>
+ * <real>-123.45E-1</real>
+ *
+ * <key>boolean</key>
+ * <true/>
+ *
+ * <key>date</key>
+ * <date>2005-01-01T12:00:00-0700</date>
+ *
+ * <key>data</key>
+ * <data>RHJhY28gRG9ybWllbnMgTnVucXVhbSBUaXRpbGxhbmR1cw==</data>
+ *
+ * <key>array</key>
+ * <array>
+ * <string>value1</string>
+ * <string>value2</string>
+ * <string>value3</string>
+ * </array>
+ *
+ * <key>dictionnary</key>
+ * <dict>
+ * <key>key1</key>
+ * <string>value1</string>
+ * <key>key2</key>
+ * <string>value2</string>
+ * <key>key3</key>
+ * <string>value3</string>
+ * </dict>
+ *
+ * <key>nested</key>
+ * <dict>
+ * <key>node1</key>
+ * <dict>
+ * <key>node2</key>
+ * <dict>
+ * <key>node3</key>
+ * <string>value</string>
+ * </dict>
+ * </dict>
+ * </dict>
+ *
+ * </dict>
+ * </plist>
+ * </pre>
+ *
+ * @since 1.2
+ *
+ * @author Emmanuel Bourg
+ * @version $Revision$, $Date$
+ */
+public class XMLPropertyListConfiguration extends AbstractHierarchicalFileConfiguration
+{
+ private static final int INDENT_SIZE = 4;
+
+ /**
+ * Creates an empty XMLPropertyListConfiguration object which can be
+ * used to synthesize a new plist file by adding values and
+ * then saving().
+ */
+ public XMLPropertyListConfiguration() { }
+
+ /**
+ * Creates and loads the property list from the specified file.
+ *
+ * @param fileName The name of the plist file to load.
+ * @throws org.apache.commons.configuration.ConfigurationException Error while loading the plist file
+ */
+ public XMLPropertyListConfiguration(String fileName) throws ConfigurationException
+ {
+ super(fileName);
+ }
+
+ /**
+ * Creates and loads the property list from the specified file.
+ *
+ * @param file The plist file to load.
+ * @throws ConfigurationException Error while loading the plist file
+ */
+ public XMLPropertyListConfiguration(File file) throws ConfigurationException
+ {
+ super(file);
+ }
+
+ /**
+ * Creates and loads the property list from the specified URL.
+ *
+ * @param url The location of the plist file to load.
+ * @throws ConfigurationException Error while loading the plist file
+ */
+ public XMLPropertyListConfiguration(URL url) throws ConfigurationException
+ {
+ super(url);
+ }
+
+ public void load(Reader in) throws ConfigurationException
+ {
+ // set up the digester
+ Digester digester = new Digester();
+
+ // set up the DTD validation
+ digester.setEntityResolver(new EntityResolver()
+ {
+ public InputSource resolveEntity(String publicId, String systemId)
+ {
+ return new InputSource(getClass().getClassLoader().getResourceAsStream("PropertyList-1.0.dtd"));
+ }
+ });
+ digester.setValidating(true);
+
+ // dictionary rules
+ digester.addRule("*/key", new ObjectCreateRule(PListNode.class)
+ {
+ public void end() throws Exception
+ {
+ // leave the node on the stack to set the value
+ }
+ });
+
+ digester.addCallMethod("*/key", "setName", 0);
+
+ digester.addRule("*/dict/string", new SetNextAndPopRule("addChild"));
+ digester.addRule("*/dict/data", new SetNextAndPopRule("addChild"));
+ digester.addRule("*/dict/integer", new SetNextAndPopRule("addChild"));
+ digester.addRule("*/dict/real", new SetNextAndPopRule("addChild"));
+ digester.addRule("*/dict/true", new SetNextAndPopRule("addChild"));
+ digester.addRule("*/dict/false", new SetNextAndPopRule("addChild"));
+ digester.addRule("*/dict/date", new SetNextAndPopRule("addChild"));
+ digester.addRule("*/dict/dict", new SetNextAndPopRule("addChild"));
+
+ digester.addCallMethod("*/dict/string", "addValue", 0);
+ digester.addCallMethod("*/dict/data", "addDataValue", 0);
+ digester.addCallMethod("*/dict/integer", "addIntegerValue", 0);
+ digester.addCallMethod("*/dict/real", "addRealValue", 0);
+ digester.addCallMethod("*/dict/true", "addTrueValue");
+ digester.addCallMethod("*/dict/false", "addFalseValue");
+ digester.addCallMethod("*/dict/date", "addDateValue", 0);
+
+ // rules for arrays
+ digester.addRule("*/dict/array", new SetNextAndPopRule("addChild"));
+ digester.addRule("*/dict/array", new ObjectCreateRule(ArrayNode.class));
+ digester.addSetNext("*/dict/array", "addList");
+
+ digester.addRule("*/array/array", new ObjectCreateRule(ArrayNode.class));
+ digester.addSetNext("*/array/array", "addList");
+
+ digester.addCallMethod("*/array/string", "addValue", 0);
+ digester.addCallMethod("*/array/data", "addDataValue", 0);
+ digester.addCallMethod("*/array/integer", "addIntegerValue", 0);
+ digester.addCallMethod("*/array/real", "addRealValue", 0);
+ digester.addCallMethod("*/array/true", "addTrueValue");
+ digester.addCallMethod("*/array/false", "addFalseValue");
+ digester.addCallMethod("*/array/date", "addDateValue", 0);
+
+ // rule for a dictionary in an array
+ digester.addFactoryCreate("*/array/dict", new AbstractObjectCreationFactory()
+ {
+ public Object createObject(Attributes attributes) throws Exception
+ {
+ // create the configuration
+ XMLPropertyListConfiguration config = new XMLPropertyListConfiguration();
+
+ // add it to the ArrayNode
+ ArrayNode node = (ArrayNode) getDigester().peek();
+ node.addValue(config);
+
+ // push the root on the stack
+ return config.getRoot();
+ }
+ });
+
+ // parse the file
+ digester.push(getRoot());
+ try
+ {
+ digester.parse(in);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("Unable to parse the configuration file", e);
+ }
+ }
+
+ /**
+ * Digester rule that sets the object on the stack to the n-1 object
+ * and remove both of them from the stack. This rule is used to remove
+ * the configuration node from the stack once its value has been parsed.
+ */
+ private class SetNextAndPopRule extends SetNextRule
+ {
+ public SetNextAndPopRule(String methodName)
+ {
+ super(methodName);
+ }
+
+ public void end(String namespace, String name) throws Exception
+ {
+ super.end(namespace, name);
+ digester.pop();
+ }
+ }
+
+ public void save(Writer out) throws ConfigurationException
+ {
+ PrintWriter writer = new PrintWriter(out);
+
+ if (getEncoding() != null)
+ {
+ writer.println("<?xml version=\"1.0\" encoding=\"" + getEncoding() + "\"?>");
+ }
+ else
+ {
+ writer.println("<?xml version=\"1.0\"?>");
+ }
+
+ writer.println("<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">");
+ writer.println("<plist version=\"1.0\">");
+
+ printNode(writer, 1, getRoot());
+
+ writer.println("</plist>");
+ writer.flush();
+ }
+
+ /**
+ * Append a node to the writer, indented according to a specific level.
+ */
+ private void printNode(PrintWriter out, int indentLevel, Node node)
+ {
+ String padding = StringUtils.repeat(" ", indentLevel * INDENT_SIZE);
+
+ if (node.getName() != null)
+ {
+ out.println(padding + "<key>" + StringEscapeUtils.escapeXml(node.getName()) + "</key>");
+ }
+
+ List children = node.getChildren();
+ if (!children.isEmpty())
+ {
+ out.println(padding + "<dict>");
+
+ Iterator it = children.iterator();
+ while (it.hasNext())
+ {
+ Node child = (Node) it.next();
+ printNode(out, indentLevel + 1, child);
+
+ if (it.hasNext())
+ {
+ out.println();
+ }
+ }
+
+ out.println(padding + "</dict>");
+ }
+ else
+ {
+ Object value = node.getValue();
+ printValue(out, indentLevel, value);
+ }
+ }
+
+ /**
+ * Append a value to the writer, indented according to a specific level.
+ */
+ private void printValue(PrintWriter out, int indentLevel, Object value)
+ {
+ String padding = StringUtils.repeat(" ", indentLevel * INDENT_SIZE);
+
+ if (value instanceof Date)
+ {
+ out.println(padding + "<date>" + PListNode.format.format((Date) value) + "</date>");
+ }
+ else if (value instanceof Calendar)
+ {
+ printValue(out, indentLevel, ((Calendar) value).getTime());
+ }
+ else if (value instanceof Number)
+ {
+ if (value instanceof Double || value instanceof Float || value instanceof BigDecimal)
+ {
+ out.println(padding + "<real>" + value.toString() + "</real>");
+ }
+ else
+ {
+ out.println(padding + "<integer>" + value.toString() + "</integer>");
+ }
+ }
+ else if (value instanceof Boolean)
+ {
+ if (((Boolean) value).booleanValue())
+ {
+ out.println(padding + "<true/>");
+ }
+ else
+ {
+ out.println(padding + "<false/>");
+ }
+ }
+ else if (value instanceof List)
+ {
+ out.println(padding + "<array>");
+ Iterator it = ((List) value).iterator();
+ while (it.hasNext())
+ {
+ printValue(out, indentLevel + 1, it.next());
+ }
+ out.println(padding + "</array>");
+ }
+ else if (value instanceof HierarchicalConfiguration)
+ {
+ printNode(out, indentLevel, ((HierarchicalConfiguration) value).getRoot());
+ }
+ else if (value instanceof Configuration)
+ {
+ // display a flat Configuration as a dictionary
+ out.println(padding + "<dict>");
+
+ Configuration config = (Configuration) value;
+ Iterator it = config.getKeys();
+ while (it.hasNext())
+ {
+ // create a node for each property
+ String key = (String) it.next();
+ Node node = new Node(key);
+ node.setValue(config.getProperty(key));
+
+ // print the node
+ printNode(out, indentLevel + 1, node);
+
+ if (it.hasNext())
+ {
+ out.println();
+ }
+ }
+ out.println(padding + "</dict>");
+ }
+ else if (value instanceof Map)
+ {
+ // display a Map as a dictionary
+ Map map = (Map) value;
+ printValue(out, indentLevel, new MapConfiguration(map));
+ }
+ else if (value instanceof byte[])
+ {
+ String base64 = new String(Base64.encodeBase64((byte[]) value));
+ out.println(padding + "<data>" + StringEscapeUtils.escapeXml(base64) + "</data>");
+ }
+ else
+ {
+ out.println(padding + "<string>" + StringEscapeUtils.escapeXml(String.valueOf(value)) + "</string>");
+ }
+ }
+
+
+ /**
+ * Node extension with addXXX methods to parse the typed data passed by Digester.
+ * <b>Do not use this class !</b> It is used internally by XMLPropertyConfiguration
+ * to parse the configuration file, it may be removed at any moment in the future.
+ */
+ public static class PListNode extends Node
+ {
+ private static DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+
+ public void addChild(Node child)
+ {
+ super.addChild(child);
+ }
+
+ public void setName(String string)
+ {
+ super.setName(string);
+ }
+
+ public void addValue(Object value)
+ {
+ if (getValue() == null)
+ {
+ setValue(value);
+ }
+ else if (getValue() instanceof List)
+ {
+ List list = (List) getValue();
+ list.add(value);
+ }
+ else
+ {
+ List list = new ArrayList();
+ list.add(getValue());
+ list.add(value);
+ setValue(list);
+ }
+ }
+
+ public void addDateValue(String value)
+ {
+ try
+ {
+ addValue(format.parse(value));
+ }
+ catch (ParseException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void addDataValue(String value)
+ {
+ addValue(Base64.decodeBase64(value.getBytes()));
+ }
+
+ public void addIntegerValue(String value)
+ {
+ addValue(new Integer(value));
+ }
+
+ public void addRealValue(String value)
+ {
+ addValue(new Double(value));
+ }
+
+ public void addTrueValue()
+ {
+ addValue(Boolean.TRUE);
+ }
+
+ public void addFalseValue()
+ {
+ addValue(Boolean.FALSE);
+ }
+
+ public void addList(ArrayNode node)
+ {
+ addValue(node.getValue());
+ }
+ }
+
+ /**
+ * Container for array elements. <b>Do not use this class !</b>
+ * It is used internally by XMLPropertyConfiguration to parse the
+ * configuration file, it may be removed at any moment in the future.
+ */
+ public static class ArrayNode extends PListNode
+ {
+ private List list = new ArrayList();
+
+ public void addValue(Object value)
+ {
+ list.add(value);
+ }
+
+ public Object getValue()
+ {
+ return list;
+ }
+ }
+}
Propchange: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/plist/XMLPropertyListConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/plist/XMLPropertyListConfiguration.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org