TextUtilsCompat.java revision 77f6bada6f88acea9025afce3eb0127d45411798
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v4.text;
18
19import android.support.v4.view.ViewCompat;
20
21import java.util.Locale;
22
23public class TextUtilsCompat {
24
25    /**
26     * Html-encode the string.
27     * @param s the string to be encoded
28     * @return the encoded string
29     */
30    public static String htmlEncode(String s) {
31        StringBuilder sb = new StringBuilder();
32        char c;
33        for (int i = 0; i < s.length(); i++) {
34            c = s.charAt(i);
35            switch (c) {
36                case '<':
37                    sb.append("&lt;"); //$NON-NLS-1$
38                    break;
39                case '>':
40                    sb.append("&gt;"); //$NON-NLS-1$
41                    break;
42                case '&':
43                    sb.append("&amp;"); //$NON-NLS-1$
44                    break;
45                case '\'':
46                    //http://www.w3.org/TR/xhtml1
47                    // The named character reference &apos; (the apostrophe, U+0027) was introduced in
48                    // XML 1.0 but does not appear in HTML. Authors should therefore use &#39; instead
49                    // of &apos; to work as expected in HTML 4 user agents.
50                    sb.append("&#39;"); //$NON-NLS-1$
51                    break;
52                case '"':
53                    sb.append("&quot;"); //$NON-NLS-1$
54                    break;
55                default:
56                    sb.append(c);
57            }
58        }
59        return sb.toString();
60    }
61
62    /**
63     * Return the layout direction for a given Locale
64     *
65     * @param locale the Locale for which we want the layout direction. Can be null.
66     * @return the layout direction. This may be one of:
67     * {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
68     * {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
69     *
70     * Be careful: this code will need to be updated when vertical scripts will be supported
71     */
72    public static int getLayoutDirectionFromLocale(Locale locale) {
73        if (locale != null && !locale.equals(ROOT)) {
74            final String scriptSubtag = ICUCompat.getScript(
75                    ICUCompat.addLikelySubtags(locale.toString()));
76            if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
77
78            if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
79                    scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
80                return ViewCompat.LAYOUT_DIRECTION_RTL;
81            }
82        }
83
84        return ViewCompat.LAYOUT_DIRECTION_LTR;
85    }
86
87    /**
88     * Fallback algorithm to detect the locale direction. Rely on the fist char of the
89     * localized locale name. This will not work if the localized locale name is in English
90     * (this is the case for ICU 4.4 and "Urdu" script)
91     *
92     * @param locale
93     * @return the layout direction. This may be one of:
94     * {@link ViewCompat#LAYOUT_DIRECTION_LTR} or
95     * {@link ViewCompat#LAYOUT_DIRECTION_RTL}.
96     *
97     * Be careful: this code will need to be updated when vertical scripts will be supported
98     *
99     * @hide
100     */
101    private static int getLayoutDirectionFromFirstChar(Locale locale) {
102        switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
103            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
104            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
105                return ViewCompat.LAYOUT_DIRECTION_RTL;
106
107            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
108            default:
109                return ViewCompat.LAYOUT_DIRECTION_LTR;
110        }
111    }
112
113    public static final Locale ROOT = new Locale("", "");
114
115    private static String ARAB_SCRIPT_SUBTAG = "Arab";
116    private static String HEBR_SCRIPT_SUBTAG = "Hebr";
117}
118