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