1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.apache.commons.xmlio.out;
25
26
27
28
29
30
31
32 public final class XMLEncode {
33
34 private final static int CDATA_BLOCK_THRESHOLD_LENGTH = 12;
35 private final static char DEFAULT_QUOTE_CHAR = '"';
36
37
38
39
40 public final static boolean isWhiteSpace(String text) {
41 for (int i = 0; i < text.length(); i++) {
42 char c = text.charAt(i);
43 if (Character.isWhitespace(c)) {
44 continue;
45 } else {
46 return false;
47 }
48 }
49 return true;
50 }
51
52
53 public final static String xmlEncodeTextForAttribute(String text, char quoteChar) {
54 if (text == null)
55 return null;
56 return xmlEncodeTextAsPCDATA(text, true, quoteChar);
57 }
58
59
60 public final static String xmlEncodeText(String text) {
61 if (text == null)
62 return null;
63 if (!needsEncoding(text)) {
64 return text;
65 } else {
66
67 if (text.length() > CDATA_BLOCK_THRESHOLD_LENGTH) {
68 String cdata = xmlEncodeTextAsCDATABlock(text);
69 if (cdata != null) {
70 return cdata;
71 }
72 }
73 }
74
75 return xmlEncodeTextAsPCDATA(text);
76 }
77
78
79 public final static String xmlEncodeTextAsPCDATA(String text) {
80 if (text == null)
81 return null;
82 return xmlEncodeTextAsPCDATA(text, false);
83 }
84
85
86
87
88
89 public final static String xmlEncodeTextAsPCDATA(String text, boolean forAttribute) {
90 return xmlEncodeTextAsPCDATA(text, forAttribute, DEFAULT_QUOTE_CHAR);
91 }
92
93
94
95
96
97
98 public final static String xmlEncodeTextAsPCDATA(String text, boolean forAttribute, char quoteChar) {
99 if (text == null)
100 return null;
101 char c;
102 StringBuffer n = new StringBuffer(text.length() * 2);
103 for (int i = 0; i < text.length(); i++) {
104 c = text.charAt(i);
105 switch (c) {
106 case '&' :
107 n.append("&");
108 break;
109 case '<' :
110 n.append("<");
111 break;
112 case '>' :
113 n.append(">");
114 break;
115 case '"' :
116 if (forAttribute)
117 n.append(""");
118 else
119 n.append(c);
120 break;
121 case '\'' :
122 if (forAttribute)
123 n.append("'");
124 else
125 n.append(c);
126 break;
127 default :
128 {
129 n.append(c);
130 break;
131 }
132 }
133 }
134
135 if (forAttribute) {
136 n.append(quoteChar);
137 n.insert(0, quoteChar);
138 }
139
140 return n.toString();
141 }
142
143
144 public final static String xmlEncodeTextAsCDATABlock(String text) {
145 if (text == null)
146 return null;
147 if (isCompatibleWithCDATABlock(text)) {
148 return "<![CDATA[" + text + "]]>";
149 } else {
150 return null;
151 }
152 }
153
154
155 public final static boolean needsEncoding(String text) {
156 return needsEncoding(text, false);
157 }
158
159
160
161
162
163
164 public final static boolean needsEncoding(String data, boolean checkForAttr) {
165 if (data == null)
166 return false;
167 char c;
168 for (int i = 0; i < data.length(); i++) {
169 c = data.charAt(i);
170 if (c == '&' || c == '<' || (checkForAttr && (c == '"' || c == '\'')))
171 return true;
172 }
173 return false;
174 }
175
176
177 public final static boolean isCompatibleWithCDATABlock(String text) {
178 if (text == null)
179 return false;
180 return (text.indexOf("]]>") == -1);
181 }
182
183
184
185
186 public final static String xmlDecodeTextToCDATA(String pcdata) {
187 if (pcdata == null)
188 return null;
189 char c, c1, c2, c3, c4, c5;
190 StringBuffer n = new StringBuffer(pcdata.length());
191 for (int i = 0; i < pcdata.length(); i++) {
192 c = pcdata.charAt(i);
193 if (c == '&') {
194 c1 = lookAhead(1, i, pcdata);
195 c2 = lookAhead(2, i, pcdata);
196 c3 = lookAhead(3, i, pcdata);
197 c4 = lookAhead(4, i, pcdata);
198 c5 = lookAhead(5, i, pcdata);
199
200 if (c1 == 'a' && c2 == 'm' && c3 == 'p' && c4 == ';') {
201 n.append("&");
202 i += 4;
203 } else if (c1 == 'l' && c2 == 't' && c3 == ';') {
204 n.append("<");
205 i += 3;
206 } else if (c1 == 'g' && c2 == 't' && c3 == ';') {
207 n.append(">");
208 i += 3;
209 } else if (c1 == 'q' && c2 == 'u' && c3 == 'o' && c4 == 't' && c5 == ';') {
210 n.append("\"");
211 i += 5;
212 } else if (c1 == 'a' && c2 == 'p' && c3 == 'o' && c4 == 's' && c5 == ';') {
213 n.append("'");
214 i += 5;
215 } else
216 n.append("&");
217 } else
218 n.append(c);
219 }
220 return n.toString();
221 }
222
223 private final static char lookAhead(int la, int offset, String data) {
224 try {
225 return data.charAt(offset + la);
226 } catch (StringIndexOutOfBoundsException e) {
227 return 0x0;
228 }
229 }
230
231
232 private final static boolean contains(String text, char[] chars) {
233 if (text == null || chars == null || chars.length == 0) {
234 return false;
235 }
236 for (int i = 0; i < text.length(); i++) {
237 char c = text.charAt(i);
238 for (int j = 0; j < chars.length; j++) {
239 if (chars[j] == c) {
240 return true;
241 }
242 }
243 }
244 return false;
245 }
246
247 }