OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * Copyright (C) 2004-2009, International Business Machines Corporation and * | 3 * Copyright (C) 2004-2014, International Business Machines Corporation and |
4 * others. All Rights Reserved. * | 4 * others. All Rights Reserved. |
5 ******************************************************************************* | 5 ******************************************************************************* |
6 * | 6 * |
7 * Created on Feb 4, 2004 | 7 * Created on Feb 4, 2004 |
8 * | 8 * |
9 */ | 9 */ |
10 package com.ibm.icu.impl; | 10 package com.ibm.icu.impl; |
11 | 11 |
| 12 import java.io.IOException; |
12 import java.io.InputStream; | 13 import java.io.InputStream; |
13 import java.net.URL; | 14 import java.net.URL; |
14 import java.security.AccessController; | 15 import java.security.AccessController; |
15 import java.security.PrivilegedAction; | 16 import java.security.PrivilegedAction; |
16 import java.util.MissingResourceException; | 17 import java.util.MissingResourceException; |
| 18 import java.util.logging.Logger; |
| 19 |
| 20 import com.ibm.icu.util.VersionInfo; |
17 | 21 |
18 /** | 22 /** |
19 * Provides access to ICU data files as InputStreams. Implements security check
ing. | 23 * Provides access to ICU data files as InputStreams. Implements security check
ing. |
20 */ | 24 */ |
21 public final class ICUData { | 25 public final class ICUData { |
22 /* | 26 /** |
23 * Return a URL to the ICU resource names resourceName. The | 27 * The data path to be used with getBundleInstance API |
24 * resource name should either be an absolute path, or a path relative to | |
25 * com.ibm.icu.impl (e.g., most likely it is 'data/foo'). If required | |
26 * is true, throw an MissingResourceException instead of returning a null re
sult. | |
27 */ | 28 */ |
| 29 static final String ICU_DATA_PATH = "com/ibm/icu/impl/"; |
| 30 /** |
| 31 * The ICU data package name. |
| 32 * This is normally the name of the .dat package, and the prefix (plus '/') |
| 33 * of the package entry names. |
| 34 */ |
| 35 static final String PACKAGE_NAME = "icudt" + VersionInfo.ICU_DATA_VERSION_PA
TH; |
| 36 /** |
| 37 * The data path to be used with Class.getResourceAsStream(). |
| 38 */ |
| 39 public static final String ICU_BUNDLE = "data/" + PACKAGE_NAME; |
| 40 |
| 41 /** |
| 42 * The base name of ICU data to be used with ClassLoader.getResourceAsStream
(), |
| 43 * ICUResourceBundle.getBundleInstance() etc. |
| 44 */ |
| 45 public static final String ICU_BASE_NAME = ICU_DATA_PATH + ICU_BUNDLE; |
| 46 |
| 47 /** |
| 48 * The base name of collation data to be used with getBundleInstance API |
| 49 */ |
| 50 public static final String ICU_COLLATION_BASE_NAME = ICU_BASE_NAME + "/coll"
; |
| 51 |
| 52 /** |
| 53 * The base name of rbbi data to be used with getData API |
| 54 */ |
| 55 public static final String ICU_BRKITR_NAME = "brkitr"; |
| 56 |
| 57 /** |
| 58 * The base name of rbbi data to be used with getBundleInstance API |
| 59 */ |
| 60 public static final String ICU_BRKITR_BASE_NAME = ICU_BASE_NAME + '/' + ICU_
BRKITR_NAME; |
| 61 |
| 62 /** |
| 63 * The base name of rbnf data to be used with getBundleInstance API |
| 64 */ |
| 65 public static final String ICU_RBNF_BASE_NAME = ICU_BASE_NAME + "/rbnf"; |
| 66 |
| 67 /** |
| 68 * The base name of transliterator data to be used with getBundleInstance AP
I |
| 69 */ |
| 70 public static final String ICU_TRANSLIT_BASE_NAME = ICU_BASE_NAME + "/transl
it"; |
| 71 |
| 72 public static final String ICU_LANG_BASE_NAME = ICU_BASE_NAME + "/lang"; |
| 73 public static final String ICU_CURR_BASE_NAME = ICU_BASE_NAME + "/curr"; |
| 74 public static final String ICU_REGION_BASE_NAME = ICU_BASE_NAME + "/region"; |
| 75 public static final String ICU_ZONE_BASE_NAME = ICU_BASE_NAME + "/zone"; |
| 76 |
| 77 /** |
| 78 * For testing (otherwise false): When reading an InputStream from a Class o
r ClassLoader |
| 79 * (that is, not from a file), log when the stream contains ICU binary data. |
| 80 * |
| 81 * This cannot be ICUConfig'ured because ICUConfig calls ICUData.getStream() |
| 82 * to read the properties file, so we would get a circular dependency |
| 83 * in the class initialization. |
| 84 */ |
| 85 private static final boolean logBinaryDataFromInputStream = false; |
| 86 private static final Logger logger = logBinaryDataFromInputStream ? |
| 87 Logger.getLogger(ICUData.class.getName()) : null; |
| 88 |
28 public static boolean exists(final String resourceName) { | 89 public static boolean exists(final String resourceName) { |
29 URL i = null; | 90 URL i = null; |
30 if (System.getSecurityManager() != null) { | 91 if (System.getSecurityManager() != null) { |
31 i = AccessController.doPrivileged(new PrivilegedAction<URL>() { | 92 i = AccessController.doPrivileged(new PrivilegedAction<URL>() { |
32 public URL run() { | 93 public URL run() { |
33 return ICUData.class.getResource(resourceName); | 94 return ICUData.class.getResource(resourceName); |
34 } | 95 } |
35 }); | 96 }); |
36 } else { | 97 } else { |
37 i = ICUData.class.getResource(resourceName); | 98 i = ICUData.class.getResource(resourceName); |
38 } | 99 } |
39 return i != null; | 100 return i != null; |
40 } | 101 } |
41 | 102 |
42 private static InputStream getStream(final Class<?> root, final String resou
rceName, boolean required) { | 103 private static InputStream getStream(final Class<?> root, final String resou
rceName, boolean required) { |
43 InputStream i = null; | 104 InputStream i = null; |
44 ········ | |
45 if (System.getSecurityManager() != null) { | 105 if (System.getSecurityManager() != null) { |
46 i = AccessController.doPrivileged(new PrivilegedAction<InputStream>(
) { | 106 i = AccessController.doPrivileged(new PrivilegedAction<InputStream>(
) { |
47 public InputStream run() { | 107 public InputStream run() { |
48 return root.getResourceAsStream(resourceName); | 108 return root.getResourceAsStream(resourceName); |
49 } | 109 } |
50 }); | 110 }); |
51 } else { | 111 } else { |
52 i = root.getResourceAsStream(resourceName); | 112 i = root.getResourceAsStream(resourceName); |
53 } | 113 } |
54 | 114 |
55 if (i == null && required) { | 115 if (i == null && required) { |
56 throw new MissingResourceException("could not locate data " +resourc
eName, root.getPackage().getName(), resourceName); | 116 throw new MissingResourceException("could not locate data " +resourc
eName, root.getPackage().getName(), resourceName); |
57 } | 117 } |
| 118 checkStreamForBinaryData(i, resourceName); |
58 return i; | 119 return i; |
59 } | 120 } |
60 | 121 |
61 private static InputStream getStream(final ClassLoader loader, final String
resourceName, boolean required) { | 122 /** |
| 123 * Should be called only from ICUBinary.getData() or from convenience overlo
ads here. |
| 124 */ |
| 125 static InputStream getStream(final ClassLoader loader, final String resource
Name, boolean required) { |
62 InputStream i = null; | 126 InputStream i = null; |
63 if (System.getSecurityManager() != null) { | 127 if (System.getSecurityManager() != null) { |
64 i = AccessController.doPrivileged(new PrivilegedAction<InputStream>(
) { | 128 i = AccessController.doPrivileged(new PrivilegedAction<InputStream>(
) { |
65 public InputStream run() { | 129 public InputStream run() { |
66 return loader.getResourceAsStream(resourceName); | 130 return loader.getResourceAsStream(resourceName); |
67 } | 131 } |
68 }); | 132 }); |
69 } else { | 133 } else { |
70 i = loader.getResourceAsStream(resourceName); | 134 i = loader.getResourceAsStream(resourceName); |
71 } | 135 } |
72 if (i == null && required) { | 136 if (i == null && required) { |
73 throw new MissingResourceException("could not locate data", loader.t
oString(), resourceName); | 137 throw new MissingResourceException("could not locate data", loader.t
oString(), resourceName); |
74 } | 138 } |
| 139 checkStreamForBinaryData(i, resourceName); |
75 return i; | 140 return i; |
76 } | 141 } |
77 ···· | 142 |
| 143 @SuppressWarnings("unused") // used if logBinaryDataFromInputStream == true |
| 144 private static void checkStreamForBinaryData(InputStream is, String resource
Name) { |
| 145 if (logBinaryDataFromInputStream && is != null && resourceName.indexOf(P
ACKAGE_NAME) >= 0) { |
| 146 try { |
| 147 is.mark(32); |
| 148 byte[] b = new byte[32]; |
| 149 int len = is.read(b); |
| 150 if (len == 32 && b[2] == (byte)0xda && b[3] == 0x27) { |
| 151 String msg = String.format( |
| 152 "ICU binary data file loaded from Class/ClassLoader
as InputStream " + |
| 153 "from %s: MappedData %02x%02x%02x%02x dataFormat %0
2x%02x%02x%02x", |
| 154 resourceName, |
| 155 b[0], b[1], b[2], b[3], |
| 156 b[12], b[13], b[14], b[15]); |
| 157 logger.info(msg); |
| 158 } |
| 159 is.reset(); |
| 160 } catch (IOException ignored) { |
| 161 } |
| 162 } |
| 163 } |
| 164 |
78 public static InputStream getStream(ClassLoader loader, String resourceName)
{ | 165 public static InputStream getStream(ClassLoader loader, String resourceName)
{ |
79 return getStream(loader,resourceName, false); | 166 return getStream(loader,resourceName, false); |
80 } | 167 } |
81 | 168 |
82 public static InputStream getRequiredStream(ClassLoader loader, String resou
rceName){ | 169 public static InputStream getRequiredStream(ClassLoader loader, String resou
rceName){ |
83 return getStream(loader, resourceName, true); | 170 return getStream(loader, resourceName, true); |
84 } | 171 } |
85 | 172 |
86 /* | 173 /** |
87 * Convenience override that calls getStream(ICUData.class, resourceName, fa
lse); | 174 * Convenience override that calls getStream(ICUData.class, resourceName, fa
lse); |
| 175 * Returns null if the resource could not be found. |
88 */ | 176 */ |
89 public static InputStream getStream(String resourceName) { | 177 public static InputStream getStream(String resourceName) { |
90 return getStream(ICUData.class, resourceName, false); | 178 return getStream(ICUData.class, resourceName, false); |
91 } | 179 } |
92 | 180 |
93 /* | 181 /** |
94 * Convenience method that calls getStream(ICUData.class, resourceName, true
). | 182 * Convenience method that calls getStream(ICUData.class, resourceName, true
). |
| 183 * @throws MissingResourceException if the resource could not be found |
95 */ | 184 */ |
96 public static InputStream getRequiredStream(String resourceName) { | 185 public static InputStream getRequiredStream(String resourceName) { |
97 return getStream(ICUData.class, resourceName, true); | 186 return getStream(ICUData.class, resourceName, true); |
98 } | 187 } |
99 | 188 |
100 /* | 189 /** |
101 * Convenience override that calls getStream(root, resourceName, false); | 190 * Convenience override that calls getStream(root, resourceName, false); |
| 191 * Returns null if the resource could not be found. |
102 */ | 192 */ |
103 public static InputStream getStream(Class<?> root, String resourceName) { | 193 public static InputStream getStream(Class<?> root, String resourceName) { |
104 return getStream(root, resourceName, false); | 194 return getStream(root, resourceName, false); |
105 } | 195 } |
106 | 196 |
107 /* | 197 /** |
108 * Convenience method that calls getStream(root, resourceName, true). | 198 * Convenience method that calls getStream(root, resourceName, true). |
| 199 * @throws MissingResourceException if the resource could not be found |
109 */ | 200 */ |
110 public static InputStream getRequiredStream(Class<?> root, String resourceNa
me) { | 201 public static InputStream getRequiredStream(Class<?> root, String resourceNa
me) { |
111 return getStream(root, resourceName, true); | 202 return getStream(root, resourceName, true); |
112 } | 203 } |
113 } | 204 } |
OLD | NEW |