You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by bo...@apache.org on 2012/05/17 14:43:52 UTC
svn commit: r1339576 - in
/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal:
util/ webapp/
Author: bommel
Date: Thu May 17 12:43:51 2012
New Revision: 1339576
URL: http://svn.apache.org/viewvc?rev=1339576&view=rev
Log:
(TOBAGO-1138) Avoid using String.replace inside ResponseWriter
Added:
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JavascriptWriterUtils.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonWriterUtils.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/WriterUtils.java
Modified:
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/HtmlWriterUtils.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/HtmlResponseWriter.java
myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/JsonResponseWriter.java
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/HtmlWriterUtils.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/HtmlWriterUtils.java?rev=1339576&r1=1339575&r2=1339576&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/HtmlWriterUtils.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/HtmlWriterUtils.java Thu May 17 12:43:51 2012
@@ -20,7 +20,7 @@ package org.apache.myfaces.tobago.intern
import java.io.IOException;
import java.io.Writer;
-public final class HtmlWriterUtils {
+public final class HtmlWriterUtils extends WriterUtils {
private static final char[][] CHARS_TO_ESCAPE;
@@ -28,9 +28,8 @@ public final class HtmlWriterUtils {
// init lookup table
CHARS_TO_ESCAPE = new char[0xA0][];
- final char[] empty = "".toCharArray();
for (int i = 0; i < 0x20; i++) {
- CHARS_TO_ESCAPE[i] = empty; // Control characters
+ CHARS_TO_ESCAPE[i] = EMPTY; // Control characters
}
CHARS_TO_ESCAPE['\t'] = "	".toCharArray(); // Horizontal tabulator
@@ -42,44 +41,22 @@ public final class HtmlWriterUtils {
CHARS_TO_ESCAPE['<'] = "<".toCharArray();
CHARS_TO_ESCAPE['>'] = ">".toCharArray();
- CHARS_TO_ESCAPE[0x7F] = empty; // Delete
+ CHARS_TO_ESCAPE[0x7F] = EMPTY; // Delete
for (int i = 0x80; i < 0xA0; i++) {
- CHARS_TO_ESCAPE[i] = empty; // Control characters
+ CHARS_TO_ESCAPE[i] = EMPTY; // Control characters
}
// all "normal" character positions contains null
}
- private final Writer out;
-
- private final ResponseWriterBuffer buffer;
-
- private final boolean utf8;
-
public HtmlWriterUtils(final Writer out, final String characterEncoding) {
- this.out = out;
- utf8 = "utf-8".equalsIgnoreCase(characterEncoding);
- buffer = new ResponseWriterBuffer(out);
+ super(out, characterEncoding);
}
- public void writeAttributeValue(final String text)
- throws IOException {
- writeEncodedValue(text.toCharArray(), 0, text.length(), true);
- }
-
- public void writeText(final String text) throws IOException {
- writeEncodedValue(text.toCharArray(), 0, text.length(), false);
- }
-
- public void writeText(final char[] text, final int start, final int length)
- throws IOException {
- writeEncodedValue(text, start, length, false);
- }
-
- private void writeEncodedValue(final char[] text, final int start,
- final int length, final boolean isAttribute)
- throws IOException {
+ @Override
+ protected void writeEncodedValue(final char[] text, final int start,
+ final int length, final boolean isAttribute) throws IOException {
int localIndex = -1;
@@ -91,6 +68,7 @@ public final class HtmlWriterUtils {
break;
}
}
+ final Writer out = getOut();
if (localIndex == -1) {
// no need to escape
@@ -99,6 +77,8 @@ public final class HtmlWriterUtils {
// write until localIndex and then encode the remainder
out.write(text, start, localIndex);
+ final ResponseWriterBuffer buffer = getBuffer();
+
for (int i = localIndex; i < end; i++) {
final char ch = text[i];
@@ -113,7 +93,7 @@ public final class HtmlWriterUtils {
} else {
buffer.addToBuffer(ch);
}
- } else if (utf8) {
+ } else if (isUtf8()) {
buffer.addToBuffer(ch);
} else if (ch <= 0xff) {
// ISO-8859-1 entities: encode as needed
@@ -137,186 +117,4 @@ public final class HtmlWriterUtils {
buffer.flushBuffer();
}
}
-
-
- /**
- * Writes a character as a decimal escape. Hex escapes are smaller than
- * the decimal version, but Netscape didn't support hex escapes until
- * 4.7.4.
- */
- private void writeDecRef(final char ch) throws IOException {
- if (ch == '\u20ac') {
- out.write("€");
- return;
- }
- out.write("&#");
- // Formerly used String.valueOf(). This version tests out
- // about 40% faster in a microbenchmark (and on systems where GC is
- // going gonzo, it should be even better)
- int i = (int) ch;
- if (i > 10000) {
- out.write('0' + (i / 10000));
- i = i % 10000;
- out.write('0' + (i / 1000));
- i = i % 1000;
- out.write('0' + (i / 100));
- i = i % 100;
- out.write('0' + (i / 10));
- i = i % 10;
- out.write('0' + i);
- } else if (i > 1000) {
- out.write('0' + (i / 1000));
- i = i % 1000;
- out.write('0' + (i / 100));
- i = i % 100;
- out.write('0' + (i / 10));
- i = i % 10;
- out.write('0' + i);
- } else {
- out.write('0' + (i / 100));
- i = i % 100;
- out.write('0' + (i / 10));
- i = i % 10;
- out.write('0' + i);
- }
-
- out.write(';');
- }
-
- public static boolean attributeValueMustEscaped(final String name) {
- // this is 30% faster then the .equals(name) version
- // tested with 100 loops over 19871 names
- // (extracted from logfile over all demo pages)
-
- try {
- switch (name.charAt(0)) {
- case 'i': // 'id'
- if (name.length() == 2 && name.charAt(1) == 'd') {
- return false;
- }
- break;
- case 'n': // 'name'
- if (name.length() == 4 && name.charAt(1) == 'a' && name.charAt(2) == 'm'
- && name.charAt(3) == 'e') {
- return false;
- }
- break;
- case 'c': // 'class'
- if (name.length() == 5 && name.charAt(1) == 'l' && name.charAt(2) == 'a'
- && name.charAt(3) == 's' && name.charAt(4) == 's') {
- return false;
- }
- break;
- default:
- return true;
- }
- } catch (NullPointerException e) {
- // ignore
- } catch (StringIndexOutOfBoundsException e) {
- // ignore
- }
- return true;
- }
-
- //
- // Entities from HTML 4.0, section 24.2.1; character codes 0xA0 to 0xFF
- //
- private static final char [][] ISO8859_1_ENTITIES = new char [][]{
- "nbsp".toCharArray(),
- "iexcl".toCharArray(),
- "cent".toCharArray(),
- "pound".toCharArray(),
- "curren".toCharArray(),
- "yen".toCharArray(),
- "brvbar".toCharArray(),
- "sect".toCharArray(),
- "uml".toCharArray(),
- "copy".toCharArray(),
- "ordf".toCharArray(),
- "laquo".toCharArray(),
- "not".toCharArray(),
- "shy".toCharArray(),
- "reg".toCharArray(),
- "macr".toCharArray(),
- "deg".toCharArray(),
- "plusmn".toCharArray(),
- "sup2".toCharArray(),
- "sup3".toCharArray(),
- "acute".toCharArray(),
- "micro".toCharArray(),
- "para".toCharArray(),
- "middot".toCharArray(),
- "cedil".toCharArray(),
- "sup1".toCharArray(),
- "ordm".toCharArray(),
- "raquo".toCharArray(),
- "frac14".toCharArray(),
- "frac12".toCharArray(),
- "frac34".toCharArray(),
- "iquest".toCharArray(),
- "Agrave".toCharArray(),
- "Aacute".toCharArray(),
- "Acirc".toCharArray(),
- "Atilde".toCharArray(),
- "Auml".toCharArray(),
- "Aring".toCharArray(),
- "AElig".toCharArray(),
- "Ccedil".toCharArray(),
- "Egrave".toCharArray(),
- "Eacute".toCharArray(),
- "Ecirc".toCharArray(),
- "Euml".toCharArray(),
- "Igrave".toCharArray(),
- "Iacute".toCharArray(),
- "Icirc".toCharArray(),
- "Iuml".toCharArray(),
- "ETH".toCharArray(),
- "Ntilde".toCharArray(),
- "Ograve".toCharArray(),
- "Oacute".toCharArray(),
- "Ocirc".toCharArray(),
- "Otilde".toCharArray(),
- "Ouml".toCharArray(),
- "times".toCharArray(),
- "Oslash".toCharArray(),
- "Ugrave".toCharArray(),
- "Uacute".toCharArray(),
- "Ucirc".toCharArray(),
- "Uuml".toCharArray(),
- "Yacute".toCharArray(),
- "THORN".toCharArray(),
- "szlig".toCharArray(),
- "agrave".toCharArray(),
- "aacute".toCharArray(),
- "acirc".toCharArray(),
- "atilde".toCharArray(),
- "auml".toCharArray(),
- "aring".toCharArray(),
- "aelig".toCharArray(),
- "ccedil".toCharArray(),
- "egrave".toCharArray(),
- "eacute".toCharArray(),
- "ecirc".toCharArray(),
- "euml".toCharArray(),
- "igrave".toCharArray(),
- "iacute".toCharArray(),
- "icirc".toCharArray(),
- "iuml".toCharArray(),
- "eth".toCharArray(),
- "ntilde".toCharArray(),
- "ograve".toCharArray(),
- "oacute".toCharArray(),
- "ocirc".toCharArray(),
- "otilde".toCharArray(),
- "ouml".toCharArray(),
- "divide".toCharArray(),
- "oslash".toCharArray(),
- "ugrave".toCharArray(),
- "uacute".toCharArray(),
- "ucirc".toCharArray(),
- "uuml".toCharArray(),
- "yacute".toCharArray(),
- "thorn".toCharArray(),
- "yuml".toCharArray()
- };
}
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JavascriptWriterUtils.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JavascriptWriterUtils.java?rev=1339576&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JavascriptWriterUtils.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JavascriptWriterUtils.java Thu May 17 12:43:51 2012
@@ -0,0 +1,118 @@
+package org.apache.myfaces.tobago.internal.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.Writer;
+
+public final class JavascriptWriterUtils extends WriterUtils {
+
+ private static final char[][] CHARS_TO_ESCAPE;
+
+ static {
+ // init lookup table
+ CHARS_TO_ESCAPE = new char[0xA0][];
+
+ for (int i = 0; i < 0x20; i++) {
+ CHARS_TO_ESCAPE[i] = EMPTY; // Control characters
+ }
+
+ CHARS_TO_ESCAPE['\t'] = "	".toCharArray(); // Horizontal tabulator
+ CHARS_TO_ESCAPE['\n'] = " ".toCharArray(); // Line feed
+ CHARS_TO_ESCAPE['\r'] = " ".toCharArray(); // Carriage return
+
+ CHARS_TO_ESCAPE['"'] = """.toCharArray();
+ CHARS_TO_ESCAPE['\\'] = "\\\\".toCharArray();
+
+ CHARS_TO_ESCAPE[0x7F] = EMPTY; // Delete
+
+ for (int i = 0x80; i < 0xA0; i++) {
+ CHARS_TO_ESCAPE[i] = EMPTY; // Control characters
+ }
+
+ // all "normal" character positions contains null
+ }
+
+ public JavascriptWriterUtils(final Writer out, final String characterEncoding) {
+ super(out, characterEncoding);
+ }
+
+ @Override
+ protected void writeEncodedValue(final char[] text, final int start,
+ final int length, final boolean isAttribute) throws IOException {
+
+ int localIndex = -1;
+
+ final int end = start + length;
+ for (int i = start; i < end; i++) {
+ char ch = text[i];
+ if (ch >= CHARS_TO_ESCAPE.length || CHARS_TO_ESCAPE[ch] != null) {
+ localIndex = i;
+ break;
+ }
+ }
+ final Writer out = getOut();
+
+ if (localIndex == -1) {
+ // no need to escape
+ out.write(text, start, length);
+ } else {
+ // write until localIndex and then encode the remainder
+ out.write(text, start, localIndex);
+
+ final ResponseWriterBuffer buffer = getBuffer();
+
+ for (int i = localIndex; i < end; i++) {
+ final char ch = text[i];
+
+ // Tilde or less...
+ if (ch < CHARS_TO_ESCAPE.length) {
+ if (isAttribute && ch == '&' && (i + 1 < end) && text[i + 1] == '{') {
+ // HTML 4.0, section B.7.1: ampersands followed by
+ // an open brace don't get escaped
+ buffer.addToBuffer('&');
+ } else if (CHARS_TO_ESCAPE[ch] != null) {
+ buffer.addToBuffer(CHARS_TO_ESCAPE[ch]);
+ } else {
+ buffer.addToBuffer(ch);
+ }
+ } else if (isUtf8()) {
+ buffer.addToBuffer(ch);
+ } else if (ch <= 0xff) {
+ // ISO-8859-1 entities: encode as needed
+ buffer.flushBuffer();
+
+ out.write('&');
+ char[] chars = ISO8859_1_ENTITIES[ch - 0xA0];
+ out.write(chars, 0, chars.length);
+ out.write(';');
+ } else {
+ buffer.flushBuffer();
+
+ // Double-byte characters to encode.
+ // PENDING: when outputting to an encoding that
+ // supports double-byte characters (UTF-8, for example),
+ // we should not be encoding
+ writeDecRef(ch);
+ }
+ }
+
+ buffer.flushBuffer();
+ }
+ }
+}
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonWriterUtils.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonWriterUtils.java?rev=1339576&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonWriterUtils.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonWriterUtils.java Thu May 17 12:43:51 2012
@@ -0,0 +1,122 @@
+package org.apache.myfaces.tobago.internal.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.Writer;
+
+
+public final class JsonWriterUtils extends WriterUtils {
+
+ private static final char[][] CHARS_TO_ESCAPE;
+
+ static {
+ // init lookup table
+ CHARS_TO_ESCAPE = new char[0xA0][];
+
+ for (int i = 0; i < 0x20; i++) {
+ CHARS_TO_ESCAPE[i] = EMPTY; // Control characters
+ }
+
+ CHARS_TO_ESCAPE['\t'] = "	".toCharArray(); // Horizontal tabulator
+ CHARS_TO_ESCAPE['\n'] = " ".toCharArray(); // Line feed
+ CHARS_TO_ESCAPE['\r'] = " ".toCharArray(); // Carriage return
+
+ CHARS_TO_ESCAPE['"'] = """.toCharArray();
+ CHARS_TO_ESCAPE['&'] = "&".toCharArray();
+ CHARS_TO_ESCAPE['<'] = "<".toCharArray();
+ CHARS_TO_ESCAPE['>'] = ">".toCharArray();
+ CHARS_TO_ESCAPE['\\'] = "\\\\".toCharArray();
+
+ CHARS_TO_ESCAPE[0x7F] = EMPTY; // Delete
+
+ for (int i = 0x80; i < 0xA0; i++) {
+ CHARS_TO_ESCAPE[i] = EMPTY; // Control characters
+ }
+
+ // all "normal" character positions contains null
+ }
+
+ public JsonWriterUtils(final Writer out, final String characterEncoding) {
+ super(out, characterEncoding);
+ }
+
+ @Override
+ protected void writeEncodedValue(final char[] text, final int start,
+ final int length, final boolean isAttribute) throws IOException {
+
+ int localIndex = -1;
+
+ final int end = start + length;
+ for (int i = start; i < end; i++) {
+ char ch = text[i];
+ if (ch >= CHARS_TO_ESCAPE.length || CHARS_TO_ESCAPE[ch] != null) {
+ localIndex = i;
+ break;
+ }
+ }
+ final Writer out = getOut();
+
+ if (localIndex == -1) {
+ // no need to escape
+ out.write(text, start, length);
+ } else {
+ // write until localIndex and then encode the remainder
+ out.write(text, start, localIndex);
+
+ final ResponseWriterBuffer buffer = getBuffer();
+
+ for (int i = localIndex; i < end; i++) {
+ final char ch = text[i];
+
+ // Tilde or less...
+ if (ch < CHARS_TO_ESCAPE.length) {
+ if (isAttribute && ch == '&' && (i + 1 < end) && text[i + 1] == '{') {
+ // HTML 4.0, section B.7.1: ampersands followed by
+ // an open brace don't get escaped
+ buffer.addToBuffer('&');
+ } else if (CHARS_TO_ESCAPE[ch] != null) {
+ buffer.addToBuffer(CHARS_TO_ESCAPE[ch]);
+ } else {
+ buffer.addToBuffer(ch);
+ }
+ } else if (isUtf8()) {
+ buffer.addToBuffer(ch);
+ } else if (ch <= 0xff) {
+ // ISO-8859-1 entities: encode as needed
+ buffer.flushBuffer();
+
+ out.write('&');
+ char[] chars = ISO8859_1_ENTITIES[ch - 0xA0];
+ out.write(chars, 0, chars.length);
+ out.write(';');
+ } else {
+ buffer.flushBuffer();
+
+ // Double-byte characters to encode.
+ // PENDING: when outputting to an encoding that
+ // supports double-byte characters (UTF-8, for example),
+ // we should not be encoding
+ writeDecRef(ch);
+ }
+ }
+
+ buffer.flushBuffer();
+ }
+ }
+}
Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/WriterUtils.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/WriterUtils.java?rev=1339576&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/WriterUtils.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/WriterUtils.java Thu May 17 12:43:51 2012
@@ -0,0 +1,209 @@
+package org.apache.myfaces.tobago.internal.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.Writer;
+
+public abstract class WriterUtils {
+ protected static final char[] EMPTY = new char[0];
+ //
+ // Entities from HTML 4.0, section 24.2.1; character codes 0xA0 to 0xFF
+ //
+ protected static final char[][] ISO8859_1_ENTITIES = new char[][]{
+ "nbsp".toCharArray(),
+ "iexcl".toCharArray(),
+ "cent".toCharArray(),
+ "pound".toCharArray(),
+ "curren".toCharArray(),
+ "yen".toCharArray(),
+ "brvbar".toCharArray(),
+ "sect".toCharArray(),
+ "uml".toCharArray(),
+ "copy".toCharArray(),
+ "ordf".toCharArray(),
+ "laquo".toCharArray(),
+ "not".toCharArray(),
+ "shy".toCharArray(),
+ "reg".toCharArray(),
+ "macr".toCharArray(),
+ "deg".toCharArray(),
+ "plusmn".toCharArray(),
+ "sup2".toCharArray(),
+ "sup3".toCharArray(),
+ "acute".toCharArray(),
+ "micro".toCharArray(),
+ "para".toCharArray(),
+ "middot".toCharArray(),
+ "cedil".toCharArray(),
+ "sup1".toCharArray(),
+ "ordm".toCharArray(),
+ "raquo".toCharArray(),
+ "frac14".toCharArray(),
+ "frac12".toCharArray(),
+ "frac34".toCharArray(),
+ "iquest".toCharArray(),
+ "Agrave".toCharArray(),
+ "Aacute".toCharArray(),
+ "Acirc".toCharArray(),
+ "Atilde".toCharArray(),
+ "Auml".toCharArray(),
+ "Aring".toCharArray(),
+ "AElig".toCharArray(),
+ "Ccedil".toCharArray(),
+ "Egrave".toCharArray(),
+ "Eacute".toCharArray(),
+ "Ecirc".toCharArray(),
+ "Euml".toCharArray(),
+ "Igrave".toCharArray(),
+ "Iacute".toCharArray(),
+ "Icirc".toCharArray(),
+ "Iuml".toCharArray(),
+ "ETH".toCharArray(),
+ "Ntilde".toCharArray(),
+ "Ograve".toCharArray(),
+ "Oacute".toCharArray(),
+ "Ocirc".toCharArray(),
+ "Otilde".toCharArray(),
+ "Ouml".toCharArray(),
+ "times".toCharArray(),
+ "Oslash".toCharArray(),
+ "Ugrave".toCharArray(),
+ "Uacute".toCharArray(),
+ "Ucirc".toCharArray(),
+ "Uuml".toCharArray(),
+ "Yacute".toCharArray(),
+ "THORN".toCharArray(),
+ "szlig".toCharArray(),
+ "agrave".toCharArray(),
+ "aacute".toCharArray(),
+ "acirc".toCharArray(),
+ "atilde".toCharArray(),
+ "auml".toCharArray(),
+ "aring".toCharArray(),
+ "aelig".toCharArray(),
+ "ccedil".toCharArray(),
+ "egrave".toCharArray(),
+ "eacute".toCharArray(),
+ "ecirc".toCharArray(),
+ "euml".toCharArray(),
+ "igrave".toCharArray(),
+ "iacute".toCharArray(),
+ "icirc".toCharArray(),
+ "iuml".toCharArray(),
+ "eth".toCharArray(),
+ "ntilde".toCharArray(),
+ "ograve".toCharArray(),
+ "oacute".toCharArray(),
+ "ocirc".toCharArray(),
+ "otilde".toCharArray(),
+ "ouml".toCharArray(),
+ "divide".toCharArray(),
+ "oslash".toCharArray(),
+ "ugrave".toCharArray(),
+ "uacute".toCharArray(),
+ "ucirc".toCharArray(),
+ "uuml".toCharArray(),
+ "yacute".toCharArray(),
+ "thorn".toCharArray(),
+ "yuml".toCharArray()
+ };
+ private final Writer out;
+ private final ResponseWriterBuffer buffer;
+ private final boolean utf8;
+
+ public WriterUtils(final Writer out, final String characterEncoding) {
+ this.out = out;
+ buffer = new ResponseWriterBuffer(out);
+ utf8 = "utf-8".equalsIgnoreCase(characterEncoding);
+ }
+
+ public void writeAttributeValue(final String text)
+ throws IOException {
+ writeEncodedValue(text.toCharArray(), 0, text.length(), true);
+ }
+
+ public void writeText(final String text) throws IOException {
+ writeEncodedValue(text.toCharArray(), 0, text.length(), false);
+ }
+
+ public void writeText(final char[] text, final int start, final int length)
+ throws IOException {
+ writeEncodedValue(text, start, length, false);
+ }
+
+ protected abstract void writeEncodedValue(char[] text, int start,
+ int length, boolean isAttribute)
+ throws IOException;
+
+ /**
+ * Writes a character as a decimal escape. Hex escapes are smaller than
+ * the decimal version, but Netscape didn't support hex escapes until
+ * 4.7.4.
+ */
+ protected void writeDecRef(final char ch) throws IOException {
+ if (ch == '\u20ac') {
+ out.write("€");
+ return;
+ }
+ out.write("&#");
+ // Formerly used String.valueOf(). This version tests out
+ // about 40% faster in a microbenchmark (and on systems where GC is
+ // going gonzo, it should be even better)
+ int i = (int) ch;
+ if (i > 10000) {
+ out.write('0' + (i / 10000));
+ i = i % 10000;
+ out.write('0' + (i / 1000));
+ i = i % 1000;
+ out.write('0' + (i / 100));
+ i = i % 100;
+ out.write('0' + (i / 10));
+ i = i % 10;
+ out.write('0' + i);
+ } else if (i > 1000) {
+ out.write('0' + (i / 1000));
+ i = i % 1000;
+ out.write('0' + (i / 100));
+ i = i % 100;
+ out.write('0' + (i / 10));
+ i = i % 10;
+ out.write('0' + i);
+ } else {
+ out.write('0' + (i / 100));
+ i = i % 100;
+ out.write('0' + (i / 10));
+ i = i % 10;
+ out.write('0' + i);
+ }
+
+ out.write(';');
+ }
+
+ protected final Writer getOut() {
+ return out;
+ }
+
+ protected final ResponseWriterBuffer getBuffer() {
+ return buffer;
+ }
+
+ protected final boolean isUtf8() {
+ return utf8;
+ }
+}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/HtmlResponseWriter.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/HtmlResponseWriter.java?rev=1339576&r1=1339575&r2=1339576&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/HtmlResponseWriter.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/HtmlResponseWriter.java Thu May 17 12:43:51 2012
@@ -19,6 +19,8 @@ package org.apache.myfaces.tobago.intern
import org.apache.myfaces.tobago.component.Attributes;
import org.apache.myfaces.tobago.internal.util.HtmlWriterUtils;
+import org.apache.myfaces.tobago.internal.util.JsonWriterUtils;
+import org.apache.myfaces.tobago.internal.util.WriterUtils;
import org.apache.myfaces.tobago.renderkit.css.Style;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
import org.apache.myfaces.tobago.util.FacesVersion;
@@ -35,15 +37,19 @@ public class HtmlResponseWriter extends
private static final String HTML_DOCTYPE =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">";
- private final HtmlWriterUtils helper;
+ private final WriterUtils helper;
public HtmlResponseWriter(
Writer writer, String contentType, String characterEncoding) {
super(writer, contentType, characterEncoding);
- this.helper = new HtmlWriterUtils(writer, characterEncoding);
+ if ("application/json".equals(contentType)) {
+ this.helper = new JsonWriterUtils(writer, characterEncoding);
+ } else {
+ this.helper = new HtmlWriterUtils(writer, characterEncoding);
+ }
}
- public final HtmlWriterUtils getHelper() {
+ public final WriterUtils getHelper() {
return helper;
}
Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/JsonResponseWriter.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/JsonResponseWriter.java?rev=1339576&r1=1339575&r2=1339576&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/JsonResponseWriter.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/JsonResponseWriter.java Thu May 17 12:43:51 2012
@@ -18,8 +18,8 @@ package org.apache.myfaces.tobago.intern
*/
import org.apache.commons.lang.StringUtils;
-import org.apache.myfaces.tobago.internal.ajax.AjaxInternalUtils;
import org.apache.myfaces.tobago.internal.util.FastStringWriter;
+import org.apache.myfaces.tobago.internal.util.JavascriptWriterUtils;
import org.apache.myfaces.tobago.util.FacesVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,26 +34,35 @@ public class JsonResponseWriter extends
private static final Logger LOG = LoggerFactory.getLogger(JsonResponseWriter.class);
private Writer javascriptWriter;
- private boolean javascriptMode;
+ private boolean javascriptBlock;
+ private JavascriptWriterUtils encodeInJavascriptBlock;
+ private JavascriptWriterUtils encodeOutsideJavascriptBlock;
public JsonResponseWriter(Writer writer, String contentType, String characterEncoding) {
super(writer, contentType, characterEncoding);
this.javascriptWriter = new FastStringWriter();
+ this.encodeOutsideJavascriptBlock = new JavascriptWriterUtils(writer, characterEncoding);
+ this.encodeInJavascriptBlock = new JavascriptWriterUtils(javascriptWriter, characterEncoding);
}
@Override
public void endJavascript() throws IOException {
- javascriptMode = false;
+ javascriptBlock = false;
}
@Override
public void startJavascript() throws IOException {
- javascriptMode = true;
+ javascriptBlock = true;
}
@Override
public void write(String string) throws IOException {
- writeInternal(javascriptMode ? javascriptWriter : getWriter(), AjaxInternalUtils.encodeJavaScriptString(string));
+ closeOpenTag();
+ if (javascriptBlock) {
+ encodeInJavascriptBlock.writeText(string);
+ } else {
+ encodeOutsideJavascriptBlock.writeText(string);
+ }
}
@Override
@@ -74,7 +83,8 @@ public class JsonResponseWriter extends
@Override
public void writeJavascript(String script) throws IOException {
- writeInternal(javascriptWriter, AjaxInternalUtils.encodeJavaScriptString(script));
+ closeOpenTag();
+ encodeInJavascriptBlock.writeText(script);
}
public String getJavascript() {
@@ -133,10 +143,7 @@ public class JsonResponseWriter extends
writer.write(' ');
writer.write(name);
writer.write("=\\\"");
- // todo: optimize for performance: replace
- if (value.contains("\\")) {
- value = value.replace("\\", "\\\\");
- }
+
if (escape) {
getHelper().writeAttributeValue(value);
} else {
@@ -149,11 +156,7 @@ public class JsonResponseWriter extends
public void writeText(final Object text, final String property)
throws IOException {
closeOpenTag();
- // todo: optimize for performance: replace
String value = findValue(text, property);
- if (value.contains("\\")) {
- value = value.replace("\\", "\\\\");
- }
getHelper().writeText(value);
}