1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cms.util;
35
36 import info.magnolia.cms.core.SystemProperty;
37 import info.magnolia.objectfactory.Components;
38
39 import java.lang.reflect.InvocationTargetException;
40 import java.lang.reflect.Method;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class UnicodeNormalizer {
59 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UnicodeNormalizer.class);
60
61 private static final String JAVA6_NORMALIZER_CLASS = "java.text.Normalizer";
62 private static final String JAVA6_FORMPARAM_CLASS = "java.text.Normalizer$Form";
63 private static final String ICU_NORMALIZER_CLASS = "com.ibm.icu.text.Normalizer";
64
65 private static final Normalizer normalizer = Components.getSingleton(Normalizer.class);
66
67
68
69
70 public static String normalizeNFC(String in) {
71 return normalizer.normalizeNFC(in);
72
73
74
75
76
77
78
79
80
81
82
83 }
84
85
86
87
88 public interface Normalizer {
89 String normalizeNFC(String in);
90 }
91
92
93
94
95
96 public static final class Java6ReflectionNormalizer implements Normalizer {
97 private final Method normalize;
98 private final Object nfc;
99
100 public Java6ReflectionNormalizer() {
101 try {
102 final Class<?> normalizer = Class.forName(JAVA6_NORMALIZER_CLASS);
103 final Class<?> form = Class.forName(JAVA6_FORMPARAM_CLASS);
104 normalize = normalizer.getMethod("normalize", CharSequence.class, form);
105 nfc = form.getField("NFC").get(null);
106 } catch (ClassNotFoundException e) {
107 throw new RuntimeException(e);
108 } catch (IllegalAccessException e) {
109 throw new RuntimeException(e);
110 } catch (NoSuchFieldException e) {
111 throw new RuntimeException(e);
112 } catch (NoSuchMethodException e) {
113 throw new RuntimeException(e);
114 }
115
116 }
117
118 public String normalizeNFC(String in) {
119 try {
120 return (String) normalize.invoke(null, in, nfc);
121 } catch (IllegalAccessException e) {
122 throw new RuntimeException(e);
123 } catch (InvocationTargetException e) {
124 throw new RuntimeException(e);
125 }
126 }
127 }
128
129
130
131
132 public static final class ICUNormalizer implements UnicodeNormalizer.Normalizer {
133 public String normalizeNFC(String in) {
134 return com.ibm.icu.text.Normalizer.normalize(in, com.ibm.icu.text.Normalizer.NFC);
135 }
136 }
137
138
139
140
141 public static final class NonNormalizer implements UnicodeNormalizer.Normalizer {
142 public String normalizeNFC(String in) {
143 return in;
144 }
145 }
146
147
148
149
150 public static final class AutoDetectNormalizer implements Normalizer {
151 private final Normalizer delegate;
152
153 public AutoDetectNormalizer() {
154 Normalizer candidate;
155 if (!SystemProperty.getBooleanProperty(SystemProperty.MAGNOLIA_UTF8_ENABLED)) {
156 candidate = new NonNormalizer();
157 } else {
158 try {
159 Class.forName(JAVA6_NORMALIZER_CLASS);
160 candidate = new Java6ReflectionNormalizer();
161 log.info("Running on Java 6, using {} for unicode form normalization.", candidate.getClass());
162 } catch (ClassNotFoundException e) {
163 log.warn("Not running on Java 6 ({} not found). Attempting to locate the ICU4J library.", JAVA6_NORMALIZER_CLASS);
164 try {
165 Class.forName(ICU_NORMALIZER_CLASS);
166 candidate = new ICUNormalizer();
167 log.info("ICU4J found, using {} for Unicode form normalization.", candidate.getClass());
168 } catch (ClassNotFoundException e2) {
169 log.warn("ICU4J not found ({} not found), Unicode will not be 100% supported; no Unicode form normalization available. If Java 6 is not an option, you can get the ICU4J library from http://www.icu-project.org/.", ICU_NORMALIZER_CLASS);
170 candidate = new NonNormalizer();
171 }
172 }
173 }
174 this.delegate = candidate;
175 }
176
177 public String normalizeNFC(String in) {
178 return delegate.normalizeNFC(in);
179 }
180 }
181
182 }