// Copyright (c) 2003-2012, Jodd Team (jodd.org). All Rights Reserved.
package jodd.servlet;
import jodd.util.StringPool;
/**
* Encodes text and URL strings in various ways resulting HTML-safe text.
* All methods are <code>null</code> safe.
*/
public class HtmlEncoder {
protected static final char[][] TEXT = new char[64][];
protected static final char[][] BLOCK = new char[64][];
private static final String NBSP = " ";
/**
* Creates HTML lookup tables for faster encoding.
*/
static {
for (int i = 0; i < 64; i++) {
TEXT[i] = new char[] {(char) i};
}
// special HTML characters
TEXT['\''] = "'".toCharArray(); // apostrophe (''' doesn't work - it is not by the w3 specs)
TEXT['"'] = """.toCharArray(); // double quote
TEXT['&'] = "&".toCharArray(); // ampersand
TEXT['<'] = "<".toCharArray(); // lower than
TEXT['>'] = ">".toCharArray(); // greater than
// text table
System.arraycopy(TEXT, 0, BLOCK, 0, 64);
BLOCK['\n'] = "<br/>".toCharArray(); // ascii 10, new line
BLOCK['\r'] = "<br/>".toCharArray(); // ascii 13, carriage return
}
// ---------------------------------------------------------------- encode text
/**
* Encodes a string to HTML-safe text. The following characters are replaced:
* <ul>
* <li>' with &#039; (&apos; doesn't work in HTML4)</li>
* <li>" with &quot;</li>
* <li>& with &amp;</li>
* <li>< with &lt;</li>
* <li>> with &gt;</li>
* </ul>
* @see #block(String)
*/
public static String text(String text) {
int len;
if ((text == null) || ((len = text.length()) == 0)) {
return StringPool.EMPTY;
}
StringBuilder buffer = new StringBuilder(len + (len >> 2));
for (int i = 0; i < len; i++) {
char c = text.charAt(i);
if (c < 64) {
buffer.append(TEXT[c]);
} else {
buffer.append(c);
}
}
return buffer.toString();
}
// ---------------------------------------------------------------- encode text block
/**
* Encodes text into HTML-safe block preserving paragraphs. Besides the {@link #text(String) default
* special characters} the following are replaced, too:
* <ul>
* <li>\n with <br></li>
* <li>\r with <br></li>
* </ul>
* <p>
* Method accepts any of CR, LF, or CR+LF as a line terminator.
*/
public static String block(String text) {
int len;
if ((text == null) || ((len = text.length()) == 0)) {
return StringPool.EMPTY;
}
StringBuilder buffer = new StringBuilder(len + (len >> 2));
char c, prev = 0;
for (int i = 0; i < len; i++, prev = c) {
c = text.charAt(i);
if ((c == '\n') && (prev == '\r')) {
continue; // previously '\r' (CR) was encoded, so skip '\n' (LF)
}
if (c < 64) {
buffer.append(BLOCK[c]);
} else {
buffer.append(c);
}
}
return buffer.toString();
}
// ---------------------------------------------------------------- encode text strict
/**
* Encodes text int HTML-safe <b>block</b> and preserves format using smart spaces.
* Additionally to {@link #block(String)}, the following characters are replaced:
*
* <ul>
* <li>\n with <br></li>
* <li>\r with <br></li>
* </ul>
* <p>
* This method preserves the format as much as possible, using the combination of
* not-breakable and common spaces.
*/
public static String strict(String text) {
int len;
if ((text == null) || ((len = text.length()) == 0)) {
return StringPool.EMPTY;
}
StringBuilder buffer = new StringBuilder(len + (len >> 2));
char c, prev = 0;
boolean prevSpace = false;
for (int i = 0; i < len; i++, prev = c) {
c = text.charAt(i);
if (c == ' ') {
if (prev != ' ') {
prevSpace = false;
}
if (prevSpace == false) {
buffer.append(' ');
} else {
buffer.append(NBSP);
}
prevSpace = !prevSpace;
continue;
}
if ((c == '\n') && (prev == '\r')) {
continue; // previously '\r' (CR) was encoded, so skip '\n' (LF)
}
if (c < 64) {
buffer.append(BLOCK[c]);
} else {
buffer.append(c);
}
}
return buffer.toString();
}
}
|