1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.util; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.OutputStream; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.OutputStreamWriter; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintStream; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintWriter; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.StringReader; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.charset.Charset; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.charset.IllegalCharsetNameException; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.charset.UnsupportedCharsetException; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.AccessController; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport javax.xml.parsers.DocumentBuilder; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport javax.xml.parsers.DocumentBuilderFactory; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport javax.xml.parsers.ParserConfigurationException; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.xml.sax.EntityResolver; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.xml.sax.ErrorHandler; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.xml.sax.InputSource; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.xml.sax.SAXException; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.xml.sax.SAXParseException; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.Document; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.Element; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.NodeList; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-added 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.Node; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.Text; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-added 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-added 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// copied from newer version of Haromny 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.internal.nls.Messages; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-added 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.PriviAction; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A {@code Properties} object is a {@code Hashtable} where the keys and values 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * must be {@code String}s. Each property can have a default 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Properties} list which specifies the default 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * values to be used when a given key is not found in this {@code Properties} 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance. 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see Hashtable 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.lang.System#getProperties 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class Properties extends Hashtable<Object,Object> { 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final long serialVersionUID = 4112578634029874840L; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private transient DocumentBuilder builder = null; 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final String PROP_DTD_NAME 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = "http://java.sun.com/dtd/properties.dtd"; 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final String PROP_DTD 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + " <!ELEMENT properties (comment?, entry*) >" 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + " <!ATTLIST properties version CDATA #FIXED \"1.0\" >" 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + " <!ELEMENT comment (#PCDATA) >" 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + " <!ELEMENT entry (#PCDATA) >" 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + " <!ATTLIST entry key CDATA #REQUIRED >"; 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The default values for keys not found in this {@code Properties} 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance. 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected Properties defaults; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int NONE = 0, SLASH = 1, UNICODE = 2, CONTINUE = 3, 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KEY_DONE = 4, IGNORE = 5; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a new {@code Properties} object. 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Properties() { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a new {@code Properties} object using the specified default 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Properties}. 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param properties 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the default {@code Properties}. 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Properties(Properties properties) { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project defaults = properties; 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void dumpString(StringBuilder buffer, String string, boolean key) { 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = 0; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!key && i < string.length() && string.charAt(i) == ' ') { 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("\\ "); //$NON-NLS-1$ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (; i < string.length(); i++) { 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char ch = string.charAt(i); 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (ch) { 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\t': 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("\\t"); //$NON-NLS-1$ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\n': 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("\\n"); //$NON-NLS-1$ 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\f': 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("\\f"); //$NON-NLS-1$ 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\r': 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("\\r"); //$NON-NLS-1$ 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ("\\#!=:".indexOf(ch) >= 0 || (key && ch == ' ')) { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append('\\'); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ch >= ' ' && ch <= '~') { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(ch); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String hex = Integer.toHexString(ch); 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("\\u"); //$NON-NLS-1$ 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int j = 0; j < 4 - hex.length(); j++) { 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("0"); //$NON-NLS-1$ 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(hex); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Searches for the property with the specified name. If the property is not 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * found, the default {@code Properties} are checked. If the property is not 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * found in the default {@code Properties}, {@code null} is returned. 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param name 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the property to find. 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the named property value, or {@code null} if it can't be found. 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getProperty(String name) { 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object result = super.get(name); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String property = result instanceof String ? (String) result : null; 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (property == null && defaults != null) { 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project property = defaults.getProperty(name); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return property; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Searches for the property with the specified name. If the property is not 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * found, it looks in the default {@code Properties}. If the property is not 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * found in the default {@code Properties}, it returns the specified 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * default. 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param name 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the property to find. 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param defaultValue 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the default value. 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the named property value. 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getProperty(String name, String defaultValue) { 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object result = super.get(name); 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String property = result instanceof String ? (String) result : null; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (property == null && defaults != null) { 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project property = defaults.getProperty(name); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (property == null) { 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return defaultValue; 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return property; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Lists the mappings in this {@code Properties} to the specified 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code PrintStream} in a 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * human readable form. 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param out 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code PrintStream} to write the content to in human readable 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * form. 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void list(PrintStream out) { 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (out == null) { 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(); 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer buffer = new StringBuffer(80); 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Enumeration<?> keys = propertyNames(); 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (keys.hasMoreElements()) { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String key = (String) keys.nextElement(); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(key); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append('='); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String property = (String) super.get(key); 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Properties def = defaults; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (property == null) { 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project property = (String) def.get(key); 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project def = def.defaults; 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (property.length() > 40) { 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(property.substring(0, 37)); 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("..."); //$NON-NLS-1$ 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(property); 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(buffer.toString()); 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.setLength(0); 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Lists the mappings in this {@code Properties} to the specified 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code PrintWriter} in a 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * human readable form. 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param writer 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code PrintWriter} to write the content to in human 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * readable form. 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void list(PrintWriter writer) { 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (writer == null) { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(); 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer buffer = new StringBuffer(80); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Enumeration<?> keys = propertyNames(); 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (keys.hasMoreElements()) { 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String key = (String) keys.nextElement(); 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(key); 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append('='); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String property = (String) super.get(key); 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Properties def = defaults; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (property == null) { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project property = (String) def.get(key); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project def = def.defaults; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (property.length() > 40) { 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(property.substring(0, 37)); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append("..."); //$NON-NLS-1$ 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(property); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.println(buffer.toString()); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.setLength(0); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Loads properties from the specified {@code InputStream}. The encoding is 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ISO8859-1. The {@code Properties} file is interpreted according to the 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * following rules: 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <ul> 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li>Empty lines are ignored.</li> 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li>Lines starting with either a "#" or a "!" are comment lines and are 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ignored.</li> 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li>A backslash at the end of the line escapes the following newline 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * character ("\r", "\n", "\r\n"). If there's a whitespace after the 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * backslash it will just escape that whitespace instead of concatenating 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the lines. This does not apply to comment lines.</li> 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li>A property line consists of the key, the space between the key and 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the value, and the value. The key goes up to the first whitespace, "=" or 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ":" that is not escaped. The space between the key and the value contains 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * either one whitespace, one "=" or one ":" and any number of additional 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * whitespaces before and after that character. The value starts with the 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * first character after the space between the key and the value.</li> 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li>Following escape sequences are recognized: "\ ", "\\", "\r", "\n", 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "\!", "\#", "\t", "\b", "\f", and "\uXXXX" (unicode character).</li> 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </ul> 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param in 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code InputStream}. 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if error occurs during reading from the {@code InputStream}. 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public synchronized void load(InputStream in) throws IOException { 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mode = NONE, unicode = 0, count = 0; 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char nextChar, buf[] = new char[40]; 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset = 0, keyLength = -1; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean firstChar = true; 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] inbuf = new byte[256]; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int inbufCount = 0, inbufPos = 0; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (inbufPos == inbufCount) { 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((inbufCount = in.read(inbuf)) == -1) { 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project inbufPos = 0; 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextChar = (char) (inbuf[inbufPos++] & 0xff); 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset == buf.length) { 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char[] newBuf = new char[buf.length * 2]; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(buf, 0, newBuf, 0, offset); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf = newBuf; 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == UNICODE) { 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int digit = Character.digit(nextChar, 16); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-changed 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // copied from newer version of Harmony 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (digit >= 0) { 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unicode = (unicode << 4) + digit; 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (++count < 4) { 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (count <= 4) { 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // luni.09=Invalid Unicode sequence: illegal character 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(Messages.getString("luni.09")); 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-changed 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = NONE; 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[offset++] = (char) unicode; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nextChar != '\n') { 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == SLASH) { 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = NONE; 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (nextChar) { 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\r': 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = CONTINUE; // Look for a following \n 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\n': 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = IGNORE; // Ignore whitespace on the next line 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'b': 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextChar = '\b'; 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'f': 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextChar = '\f'; 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'n': 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextChar = '\n'; 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'r': 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextChar = '\r'; 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 't': 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextChar = '\t'; 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'u': 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = UNICODE; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unicode = count = 0; 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (nextChar) { 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '#': 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '!': 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (firstChar) { 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (inbufPos == inbufCount) { 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((inbufCount = in.read(inbuf)) == -1) { 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project inbufPos = -1; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project inbufPos = 0; 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextChar = (char) inbuf[inbufPos++]; // & 0xff 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // not 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // required 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nextChar == '\r' || nextChar == '\n') { 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\n': 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == CONTINUE) { // Part of a \r\n sequence 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = IGNORE; // Ignore whitespace on the next line 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // fall into the next case 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\r': 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = NONE; 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstChar = true; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset > 0) { 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (keyLength == -1) { 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project keyLength = offset; 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String temp = new String(buf, 0, offset); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project put(temp.substring(0, keyLength), temp 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .substring(keyLength)); 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project keyLength = -1; 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = 0; 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '\\': 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == KEY_DONE) { 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project keyLength = offset; 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = SLASH; 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ':': 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '=': 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (keyLength == -1) { // if parsing the key 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = NONE; 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project keyLength = offset; 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (Character.isWhitespace(nextChar)) { 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == CONTINUE) { 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = IGNORE; 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // if key length == 0 or value length == 0 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset == 0 || offset == keyLength || mode == IGNORE) { 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (keyLength == -1) { // if parsing the key 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = KEY_DONE; 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == IGNORE || mode == CONTINUE) { 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = NONE; 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstChar = false; 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == KEY_DONE) { 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project keyLength = offset; 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mode = NONE; 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[offset++] = nextChar; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-added 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // copied from a newer version of Harmony 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mode == UNICODE && count <= 4) { 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // luni.08=Invalid Unicode sequence: expected format \\uxxxx 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(Messages.getString("luni.08")); 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-added 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (keyLength >= 0) { 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String temp = new String(buf, 0, offset); 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project put(temp.substring(0, keyLength), temp.substring(keyLength)); 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns all of the property names that this {@code Properties} object 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contains. 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return an {@code Enumeration} containing the names of all properties 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that this {@code Properties} object contains. 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Enumeration<?> propertyNames() { 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (defaults == null) { 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return keys(); 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hashtable<Object, Object> set = new Hashtable<Object, Object>(defaults.size() + size()); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Enumeration<?> keys = defaults.propertyNames(); 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (keys.hasMoreElements()) { 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set.put(keys.nextElement(), set); 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project keys = keys(); 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (keys.hasMoreElements()) { 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set.put(keys.nextElement(), set); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return set.keys(); 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Saves the mappings in this {@code Properties} to the specified {@code 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * OutputStream}, putting the specified comment at the beginning. The output 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from this method is suitable for being read by the 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link #load(InputStream)} method. 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param out the {@code OutputStream} to write to. 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param comment the comment to add at the beginning. 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @exception ClassCastException when the key or value of a mapping is not a 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * String. 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @deprecated This method ignores any {@code IOException} thrown while 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * writing -- use {@link #store} instead for better exception 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * handling. 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Deprecated 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void save(OutputStream out, String comment) { 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project store(out, comment); 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Maps the specified key to the specified value. If the key already exists, 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the old value is replaced. The key and value cannot be {@code null}. 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param name 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the key. 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the value. 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the old value mapped to the key, or {@code null}. 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Object setProperty(String name, String value) { 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return put(name, value); 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static String lineSeparator; 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Stores the mappings in this {@code Properties} to the specified {@code 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * OutputStream}, putting the specified comment at the beginning. The output 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from this method is suitable for being read by the 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link #load(InputStream)} method. 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param out the {@code OutputStream} to write to. 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param comment the comment to put at the beginning. 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException if an error occurs during the write to the {@code 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * OutputStream}. 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @exception ClassCastException when the key or value of a mapping is not a 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code String}. 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public synchronized void store(OutputStream out, String comment) 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (lineSeparator == null) { 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lineSeparator = AccessController 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .doPrivileged(new PriviAction<String>("line.separator")); //$NON-NLS-1$ 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder buffer = new StringBuilder(200); 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OutputStreamWriter writer = new OutputStreamWriter(out, "ISO8859_1"); //$NON-NLS-1$ 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (comment != null) { 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.write("#"); //$NON-NLS-1$ 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.write(comment); 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.write(lineSeparator); 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.write("#"); //$NON-NLS-1$ 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.write(new Date().toString()); 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.write(lineSeparator); 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Map.Entry<Object, Object> entry : entrySet()) { 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String key = (String) entry.getKey(); 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpString(buffer, key, true); 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append('='); 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpString(buffer, (String) entry.getValue(), false); 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.append(lineSeparator); 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.write(buffer.toString()); 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.setLength(0); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project writer.flush(); 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Loads the properties from an {@code InputStream} containing the 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * properties in XML form. The XML document must begin with (and conform to) 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * following DOCTYPE: 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <pre> 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </pre> 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Also the content of the XML data must satisfy the DTD but the xml is not 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * validated against it. The DTD is not loaded from the SYSTEM ID. After 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this method returns the InputStream is not closed. 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param in the InputStream containing the XML document. 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException in case an error occurs during a read operation. 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws InvalidPropertiesFormatException if the XML data is not a valid 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * properties file. 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public synchronized void loadFromXML(InputStream in) 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException, InvalidPropertiesFormatException { 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (in == null) { 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(); 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (builder == null) { 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-removed 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // factory.setValidating(true); 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-removed 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project builder = factory.newDocumentBuilder(); 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (ParserConfigurationException e) { 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new Error(e); 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project builder.setErrorHandler(new ErrorHandler() { 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void warning(SAXParseException e) throws SAXException { 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw e; 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void error(SAXParseException e) throws SAXException { 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw e; 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void fatalError(SAXParseException e) throws SAXException { 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw e; 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project builder.setEntityResolver(new EntityResolver() { 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public InputSource resolveEntity(String publicId, String systemId) 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws SAXException, IOException { 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (systemId.equals(PROP_DTD_NAME)) { 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InputSource result = new InputSource(new StringReader( 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PROP_DTD)); 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.setSystemId(PROP_DTD_NAME); 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SAXException( 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Invalid DOCTYPE declaration: " + systemId); 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Document doc = builder.parse(in); 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NodeList entries = doc.getElementsByTagName("entry"); 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (entries == null) { 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int entriesListLength = entries.getLength(); 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < entriesListLength; i++) { 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Element entry = (Element) entries.item(i); 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String key = entry.getAttribute("key"); 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-removed 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // String value = entry.getTextContent(); 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-removed 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-added 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String value = getTextContent(entry); 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-added 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * key != null & value != null 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * but key or(and) value can be empty String 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project put(key, value); 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw e; 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (SAXException e) { 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new InvalidPropertiesFormatException(e); 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes all properties stored in this instance into the {@code 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * OutputStream} in XML representation. The DOCTYPE is 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <pre> 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </pre> 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the comment is null, no comment is added to the output. UTF-8 is used 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * as the encoding. The {@code OutputStream} is not closed at the end. A 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call to this method is the same as a call to {@code storeToXML(os, 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * comment, "UTF-8")}. 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param os the {@code OutputStream} to write to. 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param comment the comment to add. If null, no comment is added. 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException if an error occurs during writing to the output. 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void storeToXML(OutputStream os, String comment) 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project storeToXML(os, comment, "UTF-8"); 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes all properties stored in this instance into the {@code 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * OutputStream} in XML representation. The DOCTYPE is 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <pre> 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </pre> 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the comment is null, no comment is added to the output. The parameter 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code encoding} defines which encoding should be used. The {@code 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * OutputStream} is not closed at the end. 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param os the {@code OutputStream} to write to. 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param comment the comment to add. If null, no comment is added. 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param encoding the code identifying the encoding that should be used to 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * write into the {@code OutputStream}. 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException if an error occurs during writing to the output. 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public synchronized void storeToXML(OutputStream os, String comment, 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String encoding) throws IOException { 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (os == null || encoding == null) { 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(); 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can write to XML file using encoding parameter but note that some 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * aliases for encodings are not supported by the XML parser. Thus we 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have to know canonical name for encoding used to store data in XML 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * since the XML parser must recognize encoding name used to store data. 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String encodingCanonicalName; 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodingCanonicalName = Charset.forName(encoding).name(); 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IllegalCharsetNameException e) { 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.out.println("Warning: encoding name " + encoding 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + " is illegal, using UTF-8 as default encoding"); 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodingCanonicalName = "UTF-8"; 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (UnsupportedCharsetException e) { 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.out.println("Warning: encoding " + encoding 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + " is not supported, using UTF-8 as default encoding"); 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project encodingCanonicalName = "UTF-8"; 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PrintStream printStream = new PrintStream(os, false, encodingCanonicalName); 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print("<?xml version=\"1.0\" encoding=\""); 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print(encodingCanonicalName); 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.println("\"?>"); 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print("<!DOCTYPE properties SYSTEM \""); 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print(PROP_DTD_NAME); 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.println("\">"); 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.println("<properties>"); 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (comment != null) { 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print("<comment>"); 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print(substitutePredefinedEntries(comment)); 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.println("</comment>"); 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Map.Entry<Object, Object> entry : entrySet()) { 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String keyValue = (String) entry.getKey(); 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String entryValue = (String) entry.getValue(); 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print("<entry key=\""); 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print(substitutePredefinedEntries(keyValue)); 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print("\">"); 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.print(substitutePredefinedEntries(entryValue)); 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.println("</entry>"); 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.println("</properties>"); 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printStream.flush(); 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String substitutePredefinedEntries(String s) { 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * substitution for predefined character entities 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to use them safely in XML 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return s.replaceAll("&", "&") 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .replaceAll("<", "<") 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .replaceAll(">", ">") 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .replaceAll("\u0027", "'") 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .replaceAll("\"", """); 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-added 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String getTextContent(Node node) { 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String result = (node instanceof Text ? ((Text) node).getData() : ""); 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Node child = node.getFirstChild(); 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (child != null) { 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = result + getTextContent(child); 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child = child.getNextSibling(); 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-added 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 803