src/share/classes/java/util/Properties.java

Print this page




  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util;
  27 
  28 import java.io.IOException;
  29 import java.io.PrintStream;
  30 import java.io.PrintWriter;
  31 import java.io.InputStream;
  32 import java.io.OutputStream;
  33 import java.io.Reader;
  34 import java.io.Writer;
  35 import java.io.OutputStreamWriter;
  36 import java.io.BufferedWriter;
  37 import java.security.AccessController;
  38 import java.security.PrivilegedAction;
  39 
  40 import sun.util.spi.XmlPropertiesProvider;
  41 
  42 /**
  43  * The {@code Properties} class represents a persistent set of
  44  * properties. The {@code Properties} can be saved to a stream
  45  * or loaded from a stream. Each key and its corresponding value in
  46  * the property list is a string.
  47  * <p>
  48  * A property list can contain another property list as its
  49  * "defaults"; this second property list is searched if
  50  * the property key is not found in the original property list.
  51  * <p>
  52  * Because {@code Properties} inherits from {@code Hashtable}, the
  53  * {@code put} and {@code putAll} methods can be applied to a
  54  * {@code Properties} object.  Their use is strongly discouraged as they
  55  * allow the caller to insert entries whose keys or values are not
  56  * {@code Strings}.  The {@code setProperty} method should be used
  57  * instead.  If the {@code store} or {@code save} method is called
  58  * on a "compromised" {@code Properties} object that contains a
  59  * non-{@code String} key or value, the call will fail. Similarly,
  60  * the call to the {@code propertyNames} or {@code list} method


 860      *
 861      * <p>The specified stream is closed after this method returns.
 862      *
 863      * @param in the input stream from which to read the XML document.
 864      * @throws IOException if reading from the specified input stream
 865      *         results in an <tt>IOException</tt>.
 866      * @throws java.io.UnsupportedEncodingException if the document's encoding
 867      *         declaration can be read and it specifies an encoding that is not
 868      *         supported
 869      * @throws InvalidPropertiesFormatException Data on input stream does not
 870      *         constitute a valid XML document with the mandated document type.
 871      * @throws NullPointerException if {@code in} is null.
 872      * @see    #storeToXML(OutputStream, String, String)
 873      * @see    <a href="http://www.w3.org/TR/REC-xml/#charencoding">Character
 874      *         Encoding in Entities</a>
 875      * @since 1.5
 876      */
 877     public synchronized void loadFromXML(InputStream in)
 878         throws IOException, InvalidPropertiesFormatException
 879     {
 880         XmlSupport.load(this, Objects.requireNonNull(in));


 881         in.close();
 882     }
 883 
 884     /**
 885      * Emits an XML document representing all of the properties contained
 886      * in this table.
 887      *
 888      * <p> An invocation of this method of the form <tt>props.storeToXML(os,
 889      * comment)</tt> behaves in exactly the same way as the invocation
 890      * <tt>props.storeToXML(os, comment, "UTF-8");</tt>.
 891      *
 892      * @param os the output stream on which to emit the XML document.
 893      * @param comment a description of the property list, or {@code null}
 894      *        if no comment is desired.
 895      * @throws IOException if writing to the specified output stream
 896      *         results in an <tt>IOException</tt>.
 897      * @throws NullPointerException if {@code os} is null.
 898      * @throws ClassCastException  if this {@code Properties} object
 899      *         contains any keys or values that are not
 900      *         {@code Strings}.


 932      *                  <a href="../lang/package-summary.html#charenc">
 933      *                  character encoding</a>
 934      *
 935      * @throws IOException if writing to the specified output stream
 936      *         results in an <tt>IOException</tt>.
 937      * @throws java.io.UnsupportedEncodingException if the encoding is not
 938      *         supported by the implementation.
 939      * @throws NullPointerException if {@code os} is {@code null},
 940      *         or if {@code encoding} is {@code null}.
 941      * @throws ClassCastException  if this {@code Properties} object
 942      *         contains any keys or values that are not
 943      *         {@code Strings}.
 944      * @see    #loadFromXML(InputStream)
 945      * @see    <a href="http://www.w3.org/TR/REC-xml/#charencoding">Character
 946      *         Encoding in Entities</a>
 947      * @since 1.5
 948      */
 949     public void storeToXML(OutputStream os, String comment, String encoding)
 950         throws IOException
 951     {
 952         XmlSupport.save(this, Objects.requireNonNull(os), comment,
 953                         Objects.requireNonNull(encoding));


 954     }
 955 
 956     /**
 957      * Searches for the property with the specified key in this property list.
 958      * If the key is not found in this property list, the default property list,
 959      * and its defaults, recursively, are then checked. The method returns
 960      * {@code null} if the property is not found.
 961      *
 962      * @param   key   the property key.
 963      * @return  the value in this property list with the specified key value.
 964      * @see     #setProperty
 965      * @see     #defaults
 966      */
 967     public String getProperty(String key) {
 968         Object oval = super.get(key);
 969         String sval = (oval instanceof String) ? (String)oval : null;
 970         return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
 971     }
 972 
 973     /**


1111             Object k = e.nextElement();
1112             Object v = get(k);
1113             if (k instanceof String && v instanceof String) {
1114                 h.put((String) k, (String) v);
1115             }
1116         }
1117     }
1118 
1119     /**
1120      * Convert a nibble to a hex character
1121      * @param   nibble  the nibble to convert.
1122      */
1123     private static char toHex(int nibble) {
1124         return hexDigit[(nibble & 0xF)];
1125     }
1126 
1127     /** A table of hex digits */
1128     private static final char[] hexDigit = {
1129         '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
1130     };
1131 
1132     /**
1133      * Supporting class for loading/storing properties in XML format.
1134      *
1135      * <p> The {@code load} and {@code store} methods defined here delegate to a
1136      * system-wide {@code XmlPropertiesProvider}. On first invocation of either
1137      * method then the system-wide provider is located as follows: </p>
1138      *
1139      * <ol>
1140      *   <li> If the system property {@code sun.util.spi.XmlPropertiesProvider}
1141      *   is defined then it is taken to be the full-qualified name of a concrete
1142      *   provider class. The class is loaded with the system class loader as the
1143      *   initiating loader. If it cannot be loaded or instantiated using a zero
1144      *   argument constructor then an unspecified error is thrown. </li>
1145      *
1146      *   <li> If the system property is not defined then the service-provider
1147      *   loading facility defined by the {@link ServiceLoader} class is used to
1148      *   locate a provider with the system class loader as the initiating
1149      *   loader and {@code sun.util.spi.XmlPropertiesProvider} as the service
1150      *   type. If this process fails then an unspecified error is thrown. If
1151      *   there is more than one service provider installed then it is
1152      *   not specified as to which provider will be used. </li>
1153      *
1154      *   <li> If the provider is not found by the above means then a system
1155      *   default provider will be instantiated and used. </li>
1156      * </ol>
1157      */
1158     private static class XmlSupport {
1159 
1160         private static XmlPropertiesProvider loadProviderFromProperty(ClassLoader cl) {
1161             String cn = System.getProperty("sun.util.spi.XmlPropertiesProvider");
1162             if (cn == null)
1163                 return null;
1164             try {
1165                 Class<?> c = Class.forName(cn, true, cl);
1166                 return (XmlPropertiesProvider)c.newInstance();
1167             } catch (ClassNotFoundException |
1168                      IllegalAccessException |
1169                      InstantiationException x) {
1170                 throw new ServiceConfigurationError(null, x);
1171             }
1172         }
1173 
1174         private static XmlPropertiesProvider loadProviderAsService(ClassLoader cl) {
1175             Iterator<XmlPropertiesProvider> iterator =
1176                  ServiceLoader.load(XmlPropertiesProvider.class, cl).iterator();
1177             return iterator.hasNext() ? iterator.next() : null;
1178         }
1179 
1180         private static XmlPropertiesProvider loadProvider() {
1181             return AccessController.doPrivileged(
1182                 new PrivilegedAction<XmlPropertiesProvider>() {
1183                     public XmlPropertiesProvider run() {
1184                         ClassLoader cl = ClassLoader.getSystemClassLoader();
1185                         XmlPropertiesProvider provider = loadProviderFromProperty(cl);
1186                         if (provider != null)
1187                             return provider;
1188                         provider = loadProviderAsService(cl);
1189                         if (provider != null)
1190                             return provider;
1191                         return new jdk.internal.util.xml.BasicXmlPropertiesProvider();
1192                 }});
1193         }
1194 
1195         private static final XmlPropertiesProvider PROVIDER = loadProvider();
1196 
1197         static void load(Properties props, InputStream in)
1198             throws IOException, InvalidPropertiesFormatException
1199         {
1200             PROVIDER.load(props, in);
1201         }
1202 
1203         static void save(Properties props, OutputStream os, String comment,
1204                          String encoding)
1205             throws IOException
1206         {
1207             PROVIDER.store(props, os, comment, encoding);
1208         }
1209     }
1210 }


  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util;
  27 
  28 import java.io.IOException;
  29 import java.io.PrintStream;
  30 import java.io.PrintWriter;
  31 import java.io.InputStream;
  32 import java.io.OutputStream;
  33 import java.io.Reader;
  34 import java.io.Writer;
  35 import java.io.OutputStreamWriter;
  36 import java.io.BufferedWriter;
  37 import java.security.AccessController;
  38 import java.security.PrivilegedAction;
  39 
  40 import jdk.internal.util.xml.PropertiesDefaultHandler;
  41 
  42 /**
  43  * The {@code Properties} class represents a persistent set of
  44  * properties. The {@code Properties} can be saved to a stream
  45  * or loaded from a stream. Each key and its corresponding value in
  46  * the property list is a string.
  47  * <p>
  48  * A property list can contain another property list as its
  49  * "defaults"; this second property list is searched if
  50  * the property key is not found in the original property list.
  51  * <p>
  52  * Because {@code Properties} inherits from {@code Hashtable}, the
  53  * {@code put} and {@code putAll} methods can be applied to a
  54  * {@code Properties} object.  Their use is strongly discouraged as they
  55  * allow the caller to insert entries whose keys or values are not
  56  * {@code Strings}.  The {@code setProperty} method should be used
  57  * instead.  If the {@code store} or {@code save} method is called
  58  * on a "compromised" {@code Properties} object that contains a
  59  * non-{@code String} key or value, the call will fail. Similarly,
  60  * the call to the {@code propertyNames} or {@code list} method


 860      *
 861      * <p>The specified stream is closed after this method returns.
 862      *
 863      * @param in the input stream from which to read the XML document.
 864      * @throws IOException if reading from the specified input stream
 865      *         results in an <tt>IOException</tt>.
 866      * @throws java.io.UnsupportedEncodingException if the document's encoding
 867      *         declaration can be read and it specifies an encoding that is not
 868      *         supported
 869      * @throws InvalidPropertiesFormatException Data on input stream does not
 870      *         constitute a valid XML document with the mandated document type.
 871      * @throws NullPointerException if {@code in} is null.
 872      * @see    #storeToXML(OutputStream, String, String)
 873      * @see    <a href="http://www.w3.org/TR/REC-xml/#charencoding">Character
 874      *         Encoding in Entities</a>
 875      * @since 1.5
 876      */
 877     public synchronized void loadFromXML(InputStream in)
 878         throws IOException, InvalidPropertiesFormatException
 879     {
 880         Objects.requireNonNull(in);
 881         PropertiesDefaultHandler handler = new PropertiesDefaultHandler();
 882         handler.load(this, in);
 883         in.close();
 884     }
 885 
 886     /**
 887      * Emits an XML document representing all of the properties contained
 888      * in this table.
 889      *
 890      * <p> An invocation of this method of the form <tt>props.storeToXML(os,
 891      * comment)</tt> behaves in exactly the same way as the invocation
 892      * <tt>props.storeToXML(os, comment, "UTF-8");</tt>.
 893      *
 894      * @param os the output stream on which to emit the XML document.
 895      * @param comment a description of the property list, or {@code null}
 896      *        if no comment is desired.
 897      * @throws IOException if writing to the specified output stream
 898      *         results in an <tt>IOException</tt>.
 899      * @throws NullPointerException if {@code os} is null.
 900      * @throws ClassCastException  if this {@code Properties} object
 901      *         contains any keys or values that are not
 902      *         {@code Strings}.


 934      *                  <a href="../lang/package-summary.html#charenc">
 935      *                  character encoding</a>
 936      *
 937      * @throws IOException if writing to the specified output stream
 938      *         results in an <tt>IOException</tt>.
 939      * @throws java.io.UnsupportedEncodingException if the encoding is not
 940      *         supported by the implementation.
 941      * @throws NullPointerException if {@code os} is {@code null},
 942      *         or if {@code encoding} is {@code null}.
 943      * @throws ClassCastException  if this {@code Properties} object
 944      *         contains any keys or values that are not
 945      *         {@code Strings}.
 946      * @see    #loadFromXML(InputStream)
 947      * @see    <a href="http://www.w3.org/TR/REC-xml/#charencoding">Character
 948      *         Encoding in Entities</a>
 949      * @since 1.5
 950      */
 951     public void storeToXML(OutputStream os, String comment, String encoding)
 952         throws IOException
 953     {
 954         Objects.requireNonNull(os);
 955         Objects.requireNonNull(encoding);
 956         PropertiesDefaultHandler handler = new PropertiesDefaultHandler();
 957         handler.store(this, os, comment, encoding);
 958     }
 959 
 960     /**
 961      * Searches for the property with the specified key in this property list.
 962      * If the key is not found in this property list, the default property list,
 963      * and its defaults, recursively, are then checked. The method returns
 964      * {@code null} if the property is not found.
 965      *
 966      * @param   key   the property key.
 967      * @return  the value in this property list with the specified key value.
 968      * @see     #setProperty
 969      * @see     #defaults
 970      */
 971     public String getProperty(String key) {
 972         Object oval = super.get(key);
 973         String sval = (oval instanceof String) ? (String)oval : null;
 974         return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
 975     }
 976 
 977     /**


1115             Object k = e.nextElement();
1116             Object v = get(k);
1117             if (k instanceof String && v instanceof String) {
1118                 h.put((String) k, (String) v);
1119             }
1120         }
1121     }
1122 
1123     /**
1124      * Convert a nibble to a hex character
1125      * @param   nibble  the nibble to convert.
1126      */
1127     private static char toHex(int nibble) {
1128         return hexDigit[(nibble & 0xF)];
1129     }
1130 
1131     /** A table of hex digits */
1132     private static final char[] hexDigit = {
1133         '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
1134     };















































































1135 }