KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jodd > servlet > HtmlEncode


1 // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
2

3 package jodd.servlet;
4
5 import javax.servlet.http.HttpServletRequest JavaDoc;
6 import javax.servlet.http.HttpServletResponse JavaDoc;
7 import javax.servlet.jsp.PageContext JavaDoc;
8 import java.io.UnsupportedEncodingException JavaDoc;
9 import java.net.URLEncoder JavaDoc;
10
11 /**
12  * Encodes text and URL strings in various ways resulting HTML-safe text.
13  * All methods are <code>null</code> safe.
14  */

15 public class HtmlEncode {
16
17     protected static String JavaDoc EMPTY_STRING = "";
18
19     protected static final char[][] TEXT = new char[64][];
20     protected static final char[][] BLOCK = new char[64][];
21     protected static final char[][] URL = new char[256][];
22
23     /**
24      * Creates HTML lookup tables for faster encoding.
25      */

26     static {
27         for (int i = 0; i < 64; i++) {
28             TEXT[i] = new char[] {(char) i};
29         }
30         for (char c = 0; c < 256; c++) {
31             try {
32                 URL[c] = URLEncoder.encode(String.valueOf(c), "ISO-8859-1").toCharArray();
33             } catch (UnsupportedEncodingException JavaDoc ueex) {
34                 ueex.printStackTrace();
35             }
36         }
37
38         // special HTML characters
39
TEXT['\''] = "&#039;".toCharArray(); // apostrophe ('&apos;' doesn't work - it is not by the w3 specs)
40
TEXT['"'] = "&quot;".toCharArray(); // double quote
41
TEXT['&'] = "&amp;".toCharArray(); // ampersand
42
TEXT['<'] = "&lt;".toCharArray(); // lower than
43
TEXT['>'] = "&gt;".toCharArray(); // greater than
44

45         // text table
46
System.arraycopy(TEXT, 0, BLOCK, 0, 64);
47         BLOCK['\n'] = "<br>".toCharArray(); // ascii 10, new line
48
BLOCK['\r'] = "<br>".toCharArray(); // ascii 13, carriage return
49
}
50
51     // ---------------------------------------------------------------- encode
52

53     public static String JavaDoc text(Object JavaDoc object) {
54         if (object == null) {
55             return EMPTY_STRING;
56         }
57         return text(object.toString());
58     }
59
60     /**
61      * Encodes a string to HTML-safe text. The following characters are replaced:
62      * <ul>
63      * <li>' with &amp;#039; (&amp;apos; doesn't work)</li>
64      * <li>" with &amp;quot;</li>
65      * <li>&amp; with &amp;amp;</li>
66      * <li>&lt; with &amp;lt;</li>
67      * <li>&gt; with &amp;gt;</li>
68      * </ul>
69      * @see #block(String)
70      */

71     public static String JavaDoc text(String JavaDoc text) {
72         int len;
73         if ((text == null) || ((len = text.length()) == 0)) {
74             return EMPTY_STRING;
75         }
76         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(len + (len >> 2));
77         for (int i = 0; i < len; i++) {
78             char c = text.charAt(i);
79             if (c < 64) {
80                 buffer.append(TEXT[c]);
81             } else {
82                 buffer.append(c);
83             }
84         }
85         return buffer.toString();
86     }
87
88     // ---------------------------------------------------------------- enocde text
89

90     public static String JavaDoc block(Object JavaDoc object) {
91         if (object == null) {
92             return EMPTY_STRING;
93         }
94         return block(object.toString());
95     }
96
97
98     /**
99      * Encodes text into HTML-safe block preserving paragraphes. Besides the {@link #text(String) default
100      * special characters} the following are replaced, too:
101      * <ul>
102      * <li>\n with &lt;br&gt;</li>
103      * <li>\r with &lt;br&gt;</li>
104      * </ul>
105      *
106      * <p>
107      * Method accepts any of CR, LF, or CR+LF as a line terminator.
108      */

109     public static String JavaDoc block(String JavaDoc text) {
110         int len;
111         if ((text == null) || ((len = text.length()) == 0)) {
112             return EMPTY_STRING;
113         }
114         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(len + (len >> 2));
115         char c, prev = 0;
116         for (int i = 0; i < len; i++, prev = c) {
117             c = text.charAt(i);
118             if ((c == '\n') && (prev == '\r')) {
119                 continue; // previously '\r' (CR) was encoded, so skip '\n' (LF)
120
}
121             if (c < 64) {
122                 buffer.append(BLOCK[c]);
123             } else {
124                 buffer.append(c);
125             }
126         }
127         return buffer.toString();
128     }
129
130
131     // ---------------------------------------------------------------- encode text strict
132

133     public static String JavaDoc strict(Object JavaDoc object) {
134         if (object == null) {
135             return EMPTY_STRING;
136         }
137         return strict(object.toString());
138     }
139
140
141     /**
142      * Encodes text int HTML-safe block and preserves format using smart spaces.
143      * Additionaly to {@link #block(String)}, the following characters are replaced:
144      *
145      * <ul>
146      * <li>\n with &lt;br&gt;</li>
147      * <li>\r with &lt;br&gt;</li>
148      * </ul>
149      * <p>
150      * This method preserves the format as much as possible, using the combination of
151      * not-breakable and common spaces.
152      */

153     public static String JavaDoc strict(String JavaDoc text) {
154         int len;
155         if ((text == null) || ((len = text.length()) == 0)) {
156             return EMPTY_STRING;
157         }
158         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(len + (len >> 2));
159         char c, prev = 0;
160         boolean prevSpace = false;
161         for (int i = 0; i < len; i++, prev = c) {
162             c = text.charAt(i);
163
164             if (c == ' ') {
165                 if (prev != ' ') {
166                     prevSpace = false;
167                 }
168                 if (prevSpace == false) {
169                     buffer.append(' ');
170                 } else {
171                     buffer.append("&nbsp;");
172                 }
173                 prevSpace = !prevSpace;
174                 continue;
175             }
176             if ((c == '\n') && (prev == '\r')) {
177                 continue; // previously '\r' (CR) was encoded, so skip '\n' (LF)
178
}
179             if (c < 64) {
180                 buffer.append(BLOCK[c]);
181             } else {
182                 buffer.append(c);
183             }
184         }
185         return buffer.toString();
186     }
187
188
189
190     // ---------------------------------------------------------------- urls
191

192     public static String JavaDoc url(String JavaDoc value, PageContext JavaDoc pageContext) {
193         return url(value, "UTF-8", (HttpServletRequest JavaDoc) pageContext.getRequest(), (HttpServletResponse JavaDoc) pageContext.getResponse());
194     }
195     public static String JavaDoc url(String JavaDoc value, String JavaDoc encoding, PageContext JavaDoc pageContext) {
196         return url(value, encoding, (HttpServletRequest JavaDoc) pageContext.getRequest(), (HttpServletResponse JavaDoc) pageContext.getResponse());
197     }
198
199     public static String JavaDoc url(String JavaDoc value, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
200         return url(value, "UTF-8", request, response);
201     }
202
203     public static String JavaDoc url(String JavaDoc value, String JavaDoc encoding, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
204         String JavaDoc result = ServletUtil.resolveUrl(url(value, encoding), request);
205         if (ServletUtil.isAbsoluteUrl(result) == false) {
206             result = response.encodeURL(result); // rewrite relative URLs
207
}
208         return result;
209     }
210
211     public static String JavaDoc url(String JavaDoc url) {
212         return url(url, "UTF-8");
213     }
214
215     /**
216      * Faster smart url encoding. Url is parsed after the '?' sign.
217      * Both parameter name and values are parsed. This method is not 100% correct:
218      * it can't make a difference between '&' char in parameter value and '&' used as
219      * a delimeter.
220      */

221     public static String JavaDoc url(String JavaDoc url, String JavaDoc encoding) {
222         int paramNdx = url.indexOf('?');
223         if (paramNdx == -1) {
224             return url;
225         }
226         StringBuffer JavaDoc result = new StringBuffer JavaDoc(url.length() >> 1);
227         paramNdx++;
228         result.append(url.substring(0, paramNdx));
229         while (true) {
230             int ampNdx = url.indexOf('&', paramNdx);
231             String JavaDoc q;
232             if (ampNdx == -1) {
233                 q = url.substring(paramNdx);
234             } else {
235                 q = url.substring(paramNdx, ampNdx);
236             }
237             int eqNdx = q.indexOf('=');
238             if (eqNdx == -1) {
239                 result.append(q);
240             } else {
241                 String JavaDoc name = q.substring(0, eqNdx);
242                 appendUrl(result, name, encoding);
243                 result.append('=');
244                 String JavaDoc value = q.substring(eqNdx + 1);
245                 if (value.length() > 0) {
246                     appendUrl(result, value, encoding);
247                 }
248             }
249             if (ampNdx == -1) {
250                 break;
251             }
252             result.append('&');
253             paramNdx = ampNdx + 1;
254         }
255         return result.toString();
256     }
257
258
259     private static void appendUrl(StringBuffer JavaDoc result, String JavaDoc value, String JavaDoc encoding) {
260         byte[] bytes;
261         try {
262             bytes = value.getBytes(encoding);
263         } catch (UnsupportedEncodingException JavaDoc ueex) {
264             throw new IllegalArgumentException JavaDoc(ueex.toString());
265         }
266         for (int i = 0; i < bytes.length; i++) {
267             int b = bytes[i];
268             if (b < 0) {
269                 b += 256;
270             }
271             result.append(URL[b]);
272         }
273     }
274
275
276
277
278     // ---------------------------------------------------------------- build url
279

280     public static class UrlBuilder {
281         StringBuffer JavaDoc url;
282         String JavaDoc encoding;
283         HttpServletResponse JavaDoc response;
284         private boolean hasParams = false;
285
286         UrlBuilder(String JavaDoc baseUrl, String JavaDoc encoding, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
287             if (request != null) {
288                 baseUrl = ServletUtil.resolveUrl(baseUrl, request);
289             }
290             url = new StringBuffer JavaDoc(baseUrl);
291             this.encoding = encoding;
292             this.response = response;
293         }
294
295         public UrlBuilder p(String JavaDoc name, String JavaDoc value) {
296             return param(name, value);
297         }
298         public UrlBuilder p(String JavaDoc name, Object JavaDoc value) {
299             return param(name, value);
300         }
301         public UrlBuilder param(String JavaDoc name, Object JavaDoc value) {
302             return param(name, value == null ? null : value.toString());
303         }
304         public UrlBuilder param(String JavaDoc name, String JavaDoc value) {
305             url.append(hasParams ? '&' : '?');
306             hasParams = true;
307             appendUrl(url, name, encoding);
308             if ((value != null) && (value.length() > 0)) {
309                 url.append('=');
310                 appendUrl(url, value, encoding);
311             }
312             return this;
313         }
314
315         public UrlBuilder p(String JavaDoc nameValue) {
316             return param(nameValue);
317         }
318         public UrlBuilder param(String JavaDoc nameValue) {
319             url.append(hasParams ? '&' : '?');
320             hasParams = true;
321             int eqNdx = nameValue.indexOf('=');
322             String JavaDoc name; String JavaDoc value = null;
323             if (eqNdx == -1) {
324                 name = nameValue;
325             } else {
326                 name = nameValue.substring(0, eqNdx);
327                 value = nameValue.substring(eqNdx + 1);
328             }
329
330             appendUrl(url, name, encoding);
331             if ((value != null) && (value.length() > 0)) {
332                 url.append('=');
333                 appendUrl(url, value, encoding);
334             }
335             return this;
336         }
337
338
339         public String JavaDoc toString() {
340             if (response != null) {
341                 return response.encodeURL(url.toString());
342             }
343             return url.toString();
344         }
345     }
346
347     public static UrlBuilder baseUrl(String JavaDoc url) {
348         return new UrlBuilder(url, "UTF-8", null, null);
349     }
350     public static UrlBuilder baseUrl(String JavaDoc url, String JavaDoc encoding) {
351         return new UrlBuilder(url, encoding, null, null);
352     }
353
354     public static UrlBuilder baseUrl(String JavaDoc url, PageContext JavaDoc pageContext) {
355         return new UrlBuilder(url, "UTF-8", (HttpServletRequest JavaDoc) pageContext.getRequest(), (HttpServletResponse JavaDoc) pageContext.getResponse());
356     }
357     public static UrlBuilder baseUrl(String JavaDoc url, String JavaDoc encoding, PageContext JavaDoc pageContext) {
358         return new UrlBuilder(url, encoding, (HttpServletRequest JavaDoc) pageContext.getRequest(), (HttpServletResponse JavaDoc) pageContext.getResponse());
359     }
360
361     public static UrlBuilder baseUrl(String JavaDoc url, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
362         return new UrlBuilder(url, "UTF-8", request, response);
363     }
364     public static UrlBuilder baseUrl(String JavaDoc url, String JavaDoc encoding, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
365         return new UrlBuilder(url, encoding, request, response);
366     }
367
368
369 }
370
Popular Tags