charinfo.java

来自「JAVA 所有包」· Java 代码 · 共 745 行 · 第 1/2 页

JAVA
745
字号
     * but additional mappings defined through calls to defineChar2String()     * are possible. Such entity reference mappings could be over-ridden.     *     * This is reusing a stored key object, in an effort to avoid     * heap activity. Unfortunately, that introduces a threading risk.     * Simplest fix for now is to make it a synchronized method, or to give     * up the reuse; I see very little performance difference between them.     * Long-term solution would be to replace the hashtable with a sparse array     * keyed directly from the character's integer value; see DTM's     * string pool for a related solution.     *     * @param value The character that should be resolved to     * a String, e.g. resolve '>' to  "&lt;".     *     * @return The String that the character is mapped to, or null if not found.     * @xsl.usage internal     */    synchronized String getOutputStringForChar(char value)    {        // CharKey m_charKey = new CharKey(); //Alternative to synchronized        m_charKey.setChar(value);        return (String) m_charToString.get(m_charKey);    }        /**     * Tell if the character argument that is from     * an attribute value should have special treatment.     *      * @param value the value of a character that is in an attribute value     * @return true if the character should have any special treatment,      * such as when writing out attribute values,      * or entity references.     * @xsl.usage internal     */    final boolean isSpecialAttrChar(int value)    {        // for performance try the values in the boolean array first,        // this is faster access than the BitSet for common ASCII values        if (value < ASCII_MAX)            return isSpecialAttrASCII[value];        // rather than java.util.BitSet, our private        // implementation is faster (and less general).        return get(value);    }        /**     * Tell if the character argument that is from a      * text node should have special treatment.     *      * @param value the value of a character that is in a text node     * @return true if the character should have any special treatment,      * such as when writing out attribute values,      * or entity references.     * @xsl.usage internal     */    final boolean isSpecialTextChar(int value)    {        // for performance try the values in the boolean array first,        // this is faster access than the BitSet for common ASCII values        if (value < ASCII_MAX)            return isSpecialTextASCII[value];        // rather than java.util.BitSet, our private        // implementation is faster (and less general).        return get(value);    }        /**     * This method is used to determine if an ASCII character in     * a text node (not an attribute value) is "clean".     * @param value the character to check (0 to 127).     * @return true if the character can go to the writer as-is     * @xsl.usage internal     */    final boolean isTextASCIIClean(int value)    {        return isCleanTextASCII[value];    }    //  In the future one might want to use the array directly and avoid//  the method call, but I think the JIT alreay inlines this well enough//  so don't do it (for now) - bjm    //    public final boolean[] getASCIIClean()//    {//        return isCleanTextASCII;//    }         private static CharInfo getCharInfoBasedOnPrivilege(        final String entitiesFileName, final String method,         final boolean internal){            return (CharInfo) AccessController.doPrivileged(                new PrivilegedAction() {                        public Object run() {                            return new CharInfo(entitiesFileName,                               method, internal);}            });                }         /**     * Factory that reads in a resource file that describes the mapping of     * characters to entity references.     *     * Resource files must be encoded in UTF-8 and have a format like:     * <pre>     * # First char # is a comment     * Entity numericValue     * quot 34     * amp 38     * </pre>     * (Note: Why don't we just switch to .properties files? Oct-01 -sc)     *     * @param entitiesResource Name of entities resource file that should     * be loaded, which describes that mapping of characters to entity references.     * @param method the output method type, which should be one of "xml", "html", "text"...     *      * @xsl.usage internal     */    static CharInfo getCharInfo(String entitiesFileName, String method)    {        CharInfo charInfo = (CharInfo) m_getCharInfoCache.get(entitiesFileName);        if (charInfo != null) {            return charInfo;        }        // try to load it internally - cache        try {            charInfo = getCharInfoBasedOnPrivilege(entitiesFileName,                                         method, true);            m_getCharInfoCache.put(entitiesFileName, charInfo);            return charInfo;        } catch (Exception e) {}        // try to load it externally - do not cache        try {            return getCharInfoBasedOnPrivilege(entitiesFileName,                                 method, false);        } catch (Exception e) {}        String absoluteEntitiesFileName;        if (entitiesFileName.indexOf(':') < 0) {            absoluteEntitiesFileName =                SystemIDResolver.getAbsoluteURIFromRelative(entitiesFileName);        } else {            try {                absoluteEntitiesFileName =                    SystemIDResolver.getAbsoluteURI(entitiesFileName, null);            } catch (TransformerException te) {                throw new WrappedRuntimeException(te);            }        }        return getCharInfoBasedOnPrivilege(entitiesFileName,                                 method, false);    }    /** Table of user-specified char infos. */    private static Hashtable m_getCharInfoCache = new Hashtable();    /**     * Returns the array element holding the bit value for the     * given integer     * @param i the integer that might be in the set of integers     *      */    private static int arrayIndex(int i) {        return (i >> SHIFT_PER_WORD);    }    /**     * For a given integer in the set it returns the single bit     * value used within a given word that represents whether     * the integer is in the set or not.     */    private static int bit(int i) {        int ret = (1 << (i & LOW_ORDER_BITMASK));        return ret;    }    /**     * Creates a new empty set of integers (characters)     * @param max the maximum integer to be in the set.     */    private int[] createEmptySetOfIntegers(int max) {        firstWordNotUsed = 0; // an optimization         int[] arr = new int[arrayIndex(max - 1) + 1];            return arr;     }    /**     * Adds the integer (character) to the set of integers.     * @param i the integer to add to the set, valid values are      * 0, 1, 2 ... up to the maximum that was specified at     * the creation of the set.     */    private final void set(int i) {           setASCIIdirty(i);                     int j = (i >> SHIFT_PER_WORD); // this word is used        int k = j + 1;                       if(firstWordNotUsed < k) // for optimization purposes.            firstWordNotUsed = k;                    array_of_bits[j] |= (1 << (i & LOW_ORDER_BITMASK));    }    /**     * Return true if the integer (character)is in the set of integers.     *      * This implementation uses an array of integers with 32 bits per     * integer.  If a bit is set to 1 the corresponding integer is      * in the set of integers.     *      * @param i an integer that is tested to see if it is the     * set of integers, or not.     */    private final boolean get(int i) {        boolean in_the_set = false;        int j = (i >> SHIFT_PER_WORD); // wordIndex(i)        // an optimization here, ... a quick test to see        // if this integer is beyond any of the words in use        if(j < firstWordNotUsed)            in_the_set = (array_of_bits[j] &                           (1 << (i & LOW_ORDER_BITMASK))            ) != 0;  // 0L for 64 bit words        return in_the_set;    }        // record if there are any entities other than    // quot, amp, lt, gt  (probably user defined)    /**     * @return true if the entity      * @param code The value of the character that has an entity defined     * for it.     */    private boolean extraEntity(int entityValue)    {        boolean extra = false;        if (entityValue < 128)        {            switch (entityValue)            {                case 34 : // quot                case 38 : // amp                case 60 : // lt                case 62 : // gt                    break;                default : // other entity in range 0 to 127                      extra = true;            }        }        return extra;    }            /**     * If the character is a printable ASCII character then     * mark it as not clean and needing replacement with     * a String on output.     * @param ch     */    private void setASCIIdirty(int j)     {        if (0 <= j && j < ASCII_MAX)         {            isCleanTextASCII[j] = false;            isSpecialTextASCII[j] = true;        }     }    /**     * If the character is a printable ASCII character then     * mark it as and not needing replacement with     * a String on output.     * @param ch     */        private void setASCIIclean(int j)    {        if (0 <= j && j < ASCII_MAX)         {                    isCleanTextASCII[j] = true;            isSpecialTextASCII[j] = false;        }    }        private void defineChar2StringMapping(String outputString, char inputChar)     {        CharKey character = new CharKey(inputChar);        m_charToString.put(character, outputString);        set(inputChar);            }    /**     * Simple class for fast lookup of char values, when used with     * hashtables.  You can set the char, then use it as a key.     *      * This class is a copy of the one in com.sun.org.apache.xml.internal.utils.      * It exists to cut the serializers dependancy on that package.     *       * @xsl.usage internal     */    private static class CharKey extends Object    {      /** String value          */      private char m_char;      /**       * Constructor CharKey       *       * @param key char value of this object.       */      public CharKey(char key)      {        m_char = key;      }        /**       * Default constructor for a CharKey.       *       * @param key char value of this object.       */      public CharKey()      {      }        /**       * Get the hash value of the character.         *       * @return hash value of the character.       */      public final void setChar(char c)      {        m_char = c;      }      /**       * Get the hash value of the character.         *       * @return hash value of the character.       */      public final int hashCode()      {        return (int)m_char;      }      /**       * Override of equals() for this object        *       * @param obj to compare to       *       * @return True if this object equals this string value        */      public final boolean equals(Object obj)      {        return ((CharKey)obj).m_char == m_char;      }    }   }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?