Subversion Repository Public Repository

litesoft

Diff Revisions 949 vs 950 for /trunk/Java/GWT/Client/src/org/litesoft/GWT/client/util/SafeHtmlizer.java

Diff revisions: vs.
  @@ -1,188 +1,188 @@
1 - package org.litesoft.GWT.client.util;
2 -
3 - import org.litesoft.commonfoundation.html.*;
4 -
5 - import com.google.gwt.safehtml.shared.*;
6 -
7 - public class SafeHtmlizer {
8 - public static SafeHtmlizer getInstance() {
9 - SafeHtmlizer zInstance = sInstance; // Snag the reference
10 - return (zInstance != null) ? zInstance : new SafeHtmlizer(); // Force Registration
11 - }
12 -
13 - /**
14 - * HTML Encode the first line of the input (guaranteed to contains at least a single character).
15 - * <p/>
16 - * Line Breaks are normalized to NewLines. (@see normalizeNewLines)
17 - * Tabs are converted to a space. (@see tabsToSpaces)
18 - * Leading blank lines are removed. (@see eliminateLeadingEmptyLines)
19 - * Escape the HTML Markup and sanitize the text (@see escapeAndSanitize)
20 - *
21 - * @param pText String to be processed.
22 - *
23 - * @return Processed pText as a SafeHtml object.
24 - */
25 - public SafeHtml noEmpty1stLine( String pText ) {
26 - return escapeAndSanitize( insureNotEmpty( only1stLine( eliminateLeadingEmptyLines( tabsToSpaces( normalizeNewLines( deNull( pText ) ) ) ) ) ) );
27 - }
28 -
29 - /**
30 - * HTML Encode the input (guaranteed to contains at least a single character) with New Lines converted to <br />s.
31 - * <p/>
32 - * Line Breaks are normalized to NewLines. (@see normalizeNewLines)
33 - * Tabs are converted to a space. (@see tabsToSpaces)
34 - * Leading blank lines are removed. (@see eliminateLeadingEmptyLines)
35 - * Escape the HTML Markup and sanitize the text (@see escapeAndSanitize)
36 - *
37 - * @param pText String to be processed.
38 - *
39 - * @return Processed pText as a SafeHtml object.
40 - */
41 - public SafeHtml noEmpty( String pText ) {
42 - return escapeAndSanitize( insureNotEmpty( eliminateLeadingEmptyLines( tabsToSpaces( normalizeNewLines( deNull( pText ) ) ) ) ) );
43 - }
44 -
45 - protected String deNull( String pText ) {
46 - return (pText == null) ? "" : pText;
47 - }
48 -
49 - /**
50 - * Line Breaks are normalized to NewLines. (after CR LF combinations are converted to a LF, then both FFs & CRs are converted to LFs).
51 - *
52 - * @param pText !null
53 - */
54 - protected String normalizeNewLines( String pText ) {
55 - // switch "CR LF" -> LF & then switch CR -> LF & then switch FF -> LF
56 - return convertCRNL( pText ).replace( '\r', '\n' ).replace( '\f', '\n' );
57 - }
58 -
59 - /**
60 - * Tabs are converted to a space.
61 - *
62 - * @param pText !null
63 - */
64 - protected String tabsToSpaces( String pText ) {
65 - return pText.replace( '\t', ' ' );
66 - }
67 -
68 - /**
69 - * Leading blank lines are removed.
70 - *
71 - * @param pText !null
72 - */
73 - protected String eliminateLeadingEmptyLines( String pText ) {
74 - Integer justPastNewLine = null;
75 - int at = 0;
76 - while ( at < pText.length() ) {
77 - char c = pText.charAt( at++ );
78 - if ( c != ' ' ) // Leading whitespace
79 - {
80 - if ( c != '\n' ) {
81 - break;
82 - }
83 - justPastNewLine = at;
84 - }
85 - }
86 - return (justPastNewLine == null) ? pText : pText.substring( justPastNewLine );
87 - }
88 -
89 - /**
90 - * Return the Text if no New Lines, otherwise return the Text upto the first New Line.
91 - *
92 - * @param pText !null
93 - */
94 - protected String only1stLine( String pText ) {
95 - int at = pText.indexOf( '\n' );
96 - return (at == -1) ? pText : pText.substring( 0, at );
97 - }
98 -
99 - /**
100 - * Return the text unless it is empty, then return a space.
101 - *
102 - * @param pText !null
103 - */
104 - protected String insureNotEmpty( String pText ) {
105 - return pText.isEmpty() ? " " : pText;
106 - }
107 -
108 - /**
109 - * Convert CR LF (New Line) combinations into just a LF.
110 - *
111 - * @param pText !null
112 - */
113 - protected String convertCRNL( String pText ) {
114 - int at = pText.indexOf( HTMLConstants.CRNL );
115 - if ( at == -1 ) {
116 - return pText;
117 - }
118 - StringBuilder sb = new StringBuilder( pText );
119 - do {
120 - sb.deleteCharAt( at );
121 - }
122 - while ( -1 != (at = pText.indexOf( HTMLConstants.CRNL )) );
123 - return sb.toString();
124 - }
125 -
126 - /**
127 - * Escape and sanitize the text to make if reasonably safe to inject as HTML for display purposes.
128 - * <p/>
129 - * This means that in addition to escaping the standard html special characters ('"', '<', '>', '&'),
130 - * bah blah blah are decimal escaped to eliminate "cdata" sections,
131 - * spaces are converted to "&nbsp;", New Lines are converted to "<br />", all other control characters
132 - * are converted to a period ('.'), and any remaining non-7bit ascii is turned into a decimal entity.
133 - *
134 - * @param pText !null
135 - *
136 - * @return Processed pText as a SafeHtml object.
137 - */
138 - protected SafeHtml escapeAndSanitize( String pText ) {
139 - StringBuilder sb = new StringBuilder();
140 - for ( int i = 0; i < pText.length(); i++ ) {
141 - char c = pText.charAt( i );
142 - switch ( c ) {
143 - case 160: // Hi-bit Space
144 - case ' ':
145 - sb.append( HTMLConstants.NBSP );
146 - break;
147 - case '&':
148 - sb.append( HTMLConstants.AMPERSAND );
149 - break;
150 - case '<':
151 - sb.append( HTMLConstants.LESS_THAN );
152 - break;
153 - case '>':
154 - sb.append( HTMLConstants.GREATER_THAN );
155 - break;
156 - case '"':
157 - sb.append( HTMLConstants.DOUBLE_QUOTE );
158 - break;
159 - case '\n':
160 - sb.append( HTMLConstants.HTML_BR );
161 - break;
162 - default:
163 - if ( (c < ' ') || ((127 <= c) && (c < 160)) ) // Control Character
164 - {
165 - sb.append( '.' );
166 - break;
167 - }
168 - if ( c < 127 ) // Regular 7-bit Ascii
169 - {
170 - sb.append( c );
171 - break;
172 - }
173 - // Decimal Escape It!
174 - sb.append( "&#" );
175 - sb.append( (int) c );
176 - sb.append( ';' );
177 - break;
178 - }
179 - }
180 - return SafeHtmlUtils.fromTrustedString( sb.toString() );
181 - }
182 -
183 - private static volatile SafeHtmlizer sInstance;
184 -
185 - protected SafeHtmlizer() {
186 - sInstance = this;
187 - }
188 - }
1 + package org.litesoft.GWT.client.util;
2 +
3 + import org.litesoft.commonfoundation.html.*;
4 +
5 + import com.google.gwt.safehtml.shared.*;
6 +
7 + public class SafeHtmlizer {
8 + public static SafeHtmlizer getInstance() {
9 + SafeHtmlizer zInstance = sInstance; // Snag the reference
10 + return (zInstance != null) ? zInstance : new SafeHtmlizer(); // Force Registration
11 + }
12 +
13 + /**
14 + * HTML Encode the first line of the input (guaranteed to contains at least a single character).
15 + * <p/>
16 + * Line Breaks are normalized to NewLines. (@see normalizeNewLines)
17 + * Tabs are converted to a space. (@see tabsToSpaces)
18 + * Leading blank lines are removed. (@see eliminateLeadingEmptyLines)
19 + * Escape the HTML Markup and sanitize the text (@see escapeAndSanitize)
20 + *
21 + * @param pText String to be processed.
22 + *
23 + * @return Processed pText as a SafeHtml object.
24 + */
25 + public SafeHtml noEmpty1stLine( String pText ) {
26 + return escapeAndSanitize( insureNotEmpty( only1stLine( eliminateLeadingEmptyLines( tabsToSpaces( normalizeNewLines( deNull( pText ) ) ) ) ) ) );
27 + }
28 +
29 + /**
30 + * HTML Encode the input (guaranteed to contains at least a single character) with New Lines converted to <br />s.
31 + * <p/>
32 + * Line Breaks are normalized to NewLines. (@see normalizeNewLines)
33 + * Tabs are converted to a space. (@see tabsToSpaces)
34 + * Leading blank lines are removed. (@see eliminateLeadingEmptyLines)
35 + * Escape the HTML Markup and sanitize the text (@see escapeAndSanitize)
36 + *
37 + * @param pText String to be processed.
38 + *
39 + * @return Processed pText as a SafeHtml object.
40 + */
41 + public SafeHtml noEmpty( String pText ) {
42 + return escapeAndSanitize( insureNotEmpty( eliminateLeadingEmptyLines( tabsToSpaces( normalizeNewLines( deNull( pText ) ) ) ) ) );
43 + }
44 +
45 + protected String deNull( String pText ) {
46 + return (pText == null) ? "" : pText;
47 + }
48 +
49 + /**
50 + * Line Breaks are normalized to NewLines. (after CR LF combinations are converted to a LF, then both FFs & CRs are converted to LFs).
51 + *
52 + * @param pText !null
53 + */
54 + protected String normalizeNewLines( String pText ) {
55 + // switch "CR LF" -> LF & then switch CR -> LF & then switch FF -> LF
56 + return convertCRNL( pText ).replace( '\r', '\n' ).replace( '\f', '\n' );
57 + }
58 +
59 + /**
60 + * Tabs are converted to a space.
61 + *
62 + * @param pText !null
63 + */
64 + protected String tabsToSpaces( String pText ) {
65 + return pText.replace( '\t', ' ' );
66 + }
67 +
68 + /**
69 + * Leading blank lines are removed.
70 + *
71 + * @param pText !null
72 + */
73 + protected String eliminateLeadingEmptyLines( String pText ) {
74 + Integer justPastNewLine = null;
75 + int at = 0;
76 + while ( at < pText.length() ) {
77 + char c = pText.charAt( at++ );
78 + if ( c != ' ' ) // Leading whitespace
79 + {
80 + if ( c != '\n' ) {
81 + break;
82 + }
83 + justPastNewLine = at;
84 + }
85 + }
86 + return (justPastNewLine == null) ? pText : pText.substring( justPastNewLine );
87 + }
88 +
89 + /**
90 + * Return the Text if no New Lines, otherwise return the Text upto the first New Line.
91 + *
92 + * @param pText !null
93 + */
94 + protected String only1stLine( String pText ) {
95 + int at = pText.indexOf( '\n' );
96 + return (at == -1) ? pText : pText.substring( 0, at );
97 + }
98 +
99 + /**
100 + * Return the text unless it is empty, then return a space.
101 + *
102 + * @param pText !null
103 + */
104 + protected String insureNotEmpty( String pText ) {
105 + return pText.isEmpty() ? " " : pText;
106 + }
107 +
108 + /**
109 + * Convert CR LF (New Line) combinations into just a LF.
110 + *
111 + * @param pText !null
112 + */
113 + protected String convertCRNL( String pText ) {
114 + int at = pText.indexOf( "\r\n" );
115 + if ( at == -1 ) {
116 + return pText;
117 + }
118 + StringBuilder sb = new StringBuilder( pText );
119 + do {
120 + sb.deleteCharAt( at );
121 + }
122 + while ( -1 != (at = pText.indexOf( "\r\n" )) );
123 + return sb.toString();
124 + }
125 +
126 + /**
127 + * Escape and sanitize the text to make if reasonably safe to inject as HTML for display purposes.
128 + * <p/>
129 + * This means that in addition to escaping the standard html special characters ('"', '<', '>', '&'),
130 + * bah blah blah are decimal escaped to eliminate "cdata" sections,
131 + * spaces are converted to "&nbsp;", New Lines are converted to "<br />", all other control characters
132 + * are converted to a period ('.'), and any remaining non-7bit ascii is turned into a decimal entity.
133 + *
134 + * @param pText !null
135 + *
136 + * @return Processed pText as a SafeHtml object.
137 + */
138 + protected SafeHtml escapeAndSanitize( String pText ) {
139 + StringBuilder sb = new StringBuilder();
140 + for ( int i = 0; i < pText.length(); i++ ) {
141 + char c = pText.charAt( i );
142 + switch ( c ) {
143 + case 160: // Hi-bit Space
144 + case ' ':
145 + sb.append( HtmlEntity.NBSP );
146 + break;
147 + case '&':
148 + sb.append( HtmlEntity.AMP.getString() );
149 + break;
150 + case '<':
151 + sb.append( HtmlEntity.LT.getString() );
152 + break;
153 + case '>':
154 + sb.append( HtmlEntity.GT.getString() );
155 + break;
156 + case '"':
157 + sb.append( HtmlEntity.DOUBLE_QUOTE );
158 + break;
159 + case '\n':
160 + sb.append( HtmlEntity.HTML_BR );
161 + break;
162 + default:
163 + if ( (c < ' ') || ((127 <= c) && (c < 160)) ) // Control Character
164 + {
165 + sb.append( '.' );
166 + break;
167 + }
168 + if ( c < 127 ) // Regular 7-bit Ascii
169 + {
170 + sb.append( c );
171 + break;
172 + }
173 + // Decimal Escape It!
174 + sb.append( "&#" );
175 + sb.append( (int) c );
176 + sb.append( ';' );
177 + break;
178 + }
179 + }
180 + return SafeHtmlUtils.fromTrustedString( sb.toString() );
181 + }
182 +
183 + private static volatile SafeHtmlizer sInstance;
184 +
185 + protected SafeHtmlizer() {
186 + sInstance = this;
187 + }
188 + }