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 } |