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