1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.util;
20
21 import java.io.IOException;
22 import java.io.Writer;
23 import java.lang.reflect.Field;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class StringCharArrayAccessor
45 {
46
47
48
49
50
51 static volatile boolean enabled = Boolean
52 .getBoolean("oam.stringchararrayaccessor.enabled");
53
54 static Field valueField;
55 static Field countField;
56 static Field offsetField;
57
58 static
59 {
60 if (enabled)
61 {
62 try
63 {
64 valueField = String.class.getDeclaredField("value");
65 valueField.setAccessible(true);
66
67 countField = String.class.getDeclaredField("count");
68 countField.setAccessible(true);
69
70 offsetField = String.class.getDeclaredField("offset");
71 offsetField.setAccessible(true);
72 }
73 catch (Exception e)
74 {
75 enabled = false;
76 System.err
77 .println("Unable to use direct char[] access of java.lang.String");
78 e.printStackTrace();
79 }
80 }
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95 static public void writeStringAsCharArray(Writer writer, String str)
96 throws IOException
97 {
98 writeStringAsCharArray(writer, str, 0, str.length());
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 static public void writeStringAsCharArray(Writer writer, String str,
120 int off, int len) throws IOException
121 {
122 if (!enabled)
123 {
124 writeStringFallback(writer, str, off, len);
125 return;
126 }
127
128 char[] value;
129 int internalOffset;
130 try
131 {
132 value = (char[]) valueField.get(str);
133 internalOffset = offsetField.getInt(str);
134 }
135 catch (Exception e)
136 {
137 handleError(e);
138 writeStringFallback(writer, str, off, len);
139 return;
140 }
141 writer.write(value, internalOffset + off, len);
142 }
143
144 private static void writeStringFallback(Writer writer, String str, int off,
145 int len) throws IOException
146 {
147 writer.write(str, off, len);
148 }
149
150 static char[] getValue(String str)
151 {
152 if (!enabled)
153 {
154 return getValueFallback(str);
155 }
156
157 char[] value = null;
158 int internalOffset = 0;
159 try
160 {
161 value = (char[]) valueField.get(str);
162 internalOffset = offsetField.getInt(str);
163 }
164 catch (Exception e)
165 {
166 handleError(e);
167 }
168 if (value != null && internalOffset == 0)
169 {
170 return value;
171 }
172
173 return getValueFallback(str);
174 }
175
176 static char[] getValueFallback(String str)
177 {
178 return str.toCharArray();
179 }
180
181
182
183
184
185
186
187
188 public static String createString(char[] charBuf)
189 {
190 if (!enabled)
191 {
192 return createStringFallback(charBuf);
193 }
194
195 String str = new String();
196 try
197 {
198
199
200
201 synchronized (str)
202 {
203 valueField.set(str, charBuf);
204 countField.set(str, charBuf.length);
205 }
206 synchronized (str)
207 {
208
209 if (str.length() != charBuf.length)
210 {
211 throw new IllegalStateException(
212 "Fast java.lang.String construction failed.");
213 }
214 }
215 }
216 catch (Exception e)
217 {
218 handleError(e);
219 str = createStringFallback(charBuf);
220 }
221 return str;
222 }
223
224 private static String createStringFallback(char[] charBuf)
225 {
226 return new String(charBuf);
227 }
228
229 private static synchronized void handleError(Exception e)
230 {
231 enabled = false;
232 System.err
233 .println("Unable to use direct char[] access of java.lang.String. Disabling this method.");
234 valueField = null;
235 countField = null;
236 offsetField = null;
237 e.printStackTrace();
238 }
239
240 static public boolean isEnabled()
241 {
242 return enabled;
243 }
244 }