jdk/src/share/classes/java/util/Properties.java
changeset 14029 c684694164c2
parent 12448 b95438b17098
child 14187 9e193f8bab66
equal deleted inserted replaced
14028:5f3d5ae5f1ea 14029:c684694164c2
    32 import java.io.OutputStream;
    32 import java.io.OutputStream;
    33 import java.io.Reader;
    33 import java.io.Reader;
    34 import java.io.Writer;
    34 import java.io.Writer;
    35 import java.io.OutputStreamWriter;
    35 import java.io.OutputStreamWriter;
    36 import java.io.BufferedWriter;
    36 import java.io.BufferedWriter;
    37 import java.lang.reflect.*;
    37 import java.security.AccessController;
       
    38 import java.security.PrivilegedAction;
       
    39 
       
    40 import sun.util.spi.XmlPropertiesProvider;
    38 
    41 
    39 /**
    42 /**
    40  * The {@code Properties} class represents a persistent set of
    43  * The {@code Properties} class represents a persistent set of
    41  * properties. The {@code Properties} can be saved to a stream
    44  * properties. The {@code Properties} can be saved to a stream
    42  * or loaded from a stream. Each key and its corresponding value in
    45  * or loaded from a stream. Each key and its corresponding value in
   864     public synchronized void loadFromXML(InputStream in)
   867     public synchronized void loadFromXML(InputStream in)
   865         throws IOException, InvalidPropertiesFormatException
   868         throws IOException, InvalidPropertiesFormatException
   866     {
   869     {
   867         if (in == null)
   870         if (in == null)
   868             throw new NullPointerException();
   871             throw new NullPointerException();
   869         XMLUtils.load(this, in);
   872         XmlSupport.load(this, in);
   870         in.close();
   873         in.close();
   871     }
   874     }
   872 
   875 
   873     /**
   876     /**
   874      * Emits an XML document representing all of the properties contained
   877      * Emits an XML document representing all of the properties contained
   932     public void storeToXML(OutputStream os, String comment, String encoding)
   935     public void storeToXML(OutputStream os, String comment, String encoding)
   933         throws IOException
   936         throws IOException
   934     {
   937     {
   935         if (os == null)
   938         if (os == null)
   936             throw new NullPointerException();
   939             throw new NullPointerException();
   937         XMLUtils.save(this, os, comment, encoding);
   940         XmlSupport.save(this, os, comment, encoding);
   938     }
   941     }
   939 
   942 
   940     /**
   943     /**
   941      * Searches for the property with the specified key in this property list.
   944      * Searches for the property with the specified key in this property list.
   942      * If the key is not found in this property list, the default property list,
   945      * If the key is not found in this property list, the default property list,
  1111     /** A table of hex digits */
  1114     /** A table of hex digits */
  1112     private static final char[] hexDigit = {
  1115     private static final char[] hexDigit = {
  1113         '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
  1116         '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
  1114     };
  1117     };
  1115 
  1118 
  1116 
  1119     /**
  1117     private static class XMLUtils {
  1120      * Supporting class for loading/storing properties in XML format.
  1118         private static Method load = null;
  1121      *
  1119         private static Method save = null;
  1122      * <p> The {@code load} and {@code store} methods defined here delegate to a
  1120         static {
  1123      * system-wide {@code XmlPropertiesProvider}. On first invocation of either
       
  1124      * method then the system-wide provider is located as follows: </p>
       
  1125      *
       
  1126      * <ol>
       
  1127      *   <li> If the system property {@code sun.util.spi.XmlPropertiesProvider}
       
  1128      *   is defined then it is taken to be the full-qualified name of a concrete
       
  1129      *   provider class. The class is loaded with the system class loader as the
       
  1130      *   initiating loader. If it cannot be loaded or instantiated using a zero
       
  1131      *   argument constructor then an unspecified error is thrown. </li>
       
  1132      *
       
  1133      *   <li> If the system property is not defined then the service-provider
       
  1134      *   loading facility defined by the {@link ServiceLoader} class is used to
       
  1135      *   locate a provider with the system class loader as the initiating
       
  1136      *   loader and {@code sun.util.spi.XmlPropertiesProvider} as the service
       
  1137      *   type. If this process fails then an unspecified error is thrown. If
       
  1138      *   there is more than one service provider installed then it is
       
  1139      *   not specified as to which provider will be used. </li>
       
  1140      *
       
  1141      *   <li> If the provider is not found by the above means then a system
       
  1142      *   default provider will be instantiated and used. </li>
       
  1143      * </ol>
       
  1144      */
       
  1145     private static class XmlSupport {
       
  1146 
       
  1147         private static XmlPropertiesProvider loadProviderFromProperty(ClassLoader cl) {
       
  1148             String cn = System.getProperty("sun.util.spi.XmlPropertiesProvider");
       
  1149             if (cn == null)
       
  1150                 return null;
  1121             try {
  1151             try {
  1122                 // reference sun.util.xml.Utils reflectively
  1152                 Class<?> c = Class.forName(cn, true, cl);
  1123                 // to allow the Properties class be compiled in
  1153                 return (XmlPropertiesProvider)c.newInstance();
  1124                 // the absence of XML
  1154             } catch (ClassNotFoundException |
  1125                 Class<?> c = Class.forName("sun.util.xml.XMLUtils", true, null);
  1155                      IllegalAccessException |
  1126                 load = c.getMethod("load", Properties.class, InputStream.class);
  1156                      InstantiationException x) {
  1127                 save = c.getMethod("save", Properties.class, OutputStream.class,
  1157                 throw new ServiceConfigurationError(null, x);
  1128                                    String.class, String.class);
  1158             }
  1129             } catch (ClassNotFoundException cnf) {
  1159         }
  1130                 throw new AssertionError(cnf);
  1160 
  1131             } catch (NoSuchMethodException e) {
  1161         private static XmlPropertiesProvider loadProviderAsService(ClassLoader cl) {
  1132                 throw new AssertionError(e);
  1162             Iterator<XmlPropertiesProvider> iterator =
  1133             }
  1163                  ServiceLoader.load(XmlPropertiesProvider.class, cl).iterator();
  1134         }
  1164             return iterator.hasNext() ? iterator.next() : null;
  1135 
  1165         }
  1136         static void invoke(Method m, Object... args) throws IOException {
  1166 
  1137             try {
  1167         private static XmlPropertiesProvider loadProvider() {
  1138                 m.invoke(null, args);
  1168             return AccessController.doPrivileged(
  1139             } catch (IllegalAccessException e) {
  1169                 new PrivilegedAction<XmlPropertiesProvider>() {
  1140                 throw new AssertionError(e);
  1170                     public XmlPropertiesProvider run() {
  1141             } catch (InvocationTargetException e) {
  1171                         ClassLoader cl = ClassLoader.getSystemClassLoader();
  1142                 Throwable t = e.getCause();
  1172                         XmlPropertiesProvider provider = loadProviderFromProperty(cl);
  1143                 if (t instanceof RuntimeException)
  1173                         if (provider != null)
  1144                     throw (RuntimeException)t;
  1174                             return provider;
  1145 
  1175                         provider = loadProviderAsService(cl);
  1146                 if (t instanceof IOException) {
  1176                         if (provider != null)
  1147                     throw (IOException)t;
  1177                             return provider;
  1148                 } else {
  1178                         throw new InternalError("No fallback");
  1149                     throw new AssertionError(t);
  1179                 }});
  1150                 }
  1180         }
  1151             }
  1181 
  1152         }
  1182         private static final XmlPropertiesProvider PROVIDER = loadProvider();
  1153 
  1183 
  1154         static void load(Properties props, InputStream in)
  1184         static void load(Properties props, InputStream in)
  1155             throws IOException, InvalidPropertiesFormatException
  1185             throws IOException, InvalidPropertiesFormatException
  1156         {
  1186         {
  1157             if (load == null)
  1187             PROVIDER.load(props, in);
  1158                 throw new InternalError("sun.util.xml.XMLUtils not found");
       
  1159             invoke(load, props, in);
       
  1160         }
  1188         }
  1161 
  1189 
  1162         static void save(Properties props, OutputStream os, String comment,
  1190         static void save(Properties props, OutputStream os, String comment,
  1163                          String encoding)
  1191                          String encoding)
  1164             throws IOException
  1192             throws IOException
  1165         {
  1193         {
  1166             if (save == null)
  1194             PROVIDER.store(props, os, comment, encoding);
  1167                 throw new InternalError("sun.util.xml.XMLUtils not found");
       
  1168             invoke(save, props, os, comment, encoding);
       
  1169         }
  1195         }
  1170     }
  1196     }
  1171 }
  1197 }