### Eclipse Workspace Patch 1.0 #P groovy-core Index: src/main/groovy/xml/MarkupBuilder.java =================================================================== --- src/main/groovy/xml/MarkupBuilder.java (revision 14839) +++ src/main/groovy/xml/MarkupBuilder.java (working copy) @@ -26,7 +26,7 @@ /** *
A helper class for creating XML or HTML markup. This implementation outputs * markup in a 'pretty printed' format.
- * + * *Example:
*new MarkupBuilder().root {
* a( a1:'one' ) {
@@ -34,13 +34,13 @@
* c( a2:'two', 'blah' )
* }
* }
- * Will print the following to System.out:
+ * Will print the following to System.out:
* <root> * <a a1='one'> * <b>3 < 5</b> * <c a2='two'>blah</c> * </a> - * </root>+ * </root> * * @author James Strachan * @author Stefan Matthias Aust @@ -66,7 +66,7 @@ } /** - * Sends markup to the given PrintWriter + * Sends markup to the given PrintWriter * @see IndentPrinter#IndentPrinter(PrintWriter) */ public MarkupBuilder(PrintWriter writer) { @@ -74,7 +74,7 @@ } /** - * Sends markup to the given PrintWriter + * Sends markup to the given PrintWriter * @see IndentPrinter#IndentPrinter(PrintWriter) */ public MarkupBuilder(Writer writer) { @@ -83,7 +83,7 @@ /** * Sends markup to the given IndentPrinter. Use this option if you want - * to customize the indent used. + * to customize the indent used. */ public MarkupBuilder(IndentPrinter out) { this.out = out; @@ -160,8 +160,8 @@ protected void setParent(Object parent, Object child) { } /** - * Property that may be called from within your builder closure to access - * helper methods, namely {@link #yield(String)} and + * Property that may be called from within your builder closure to access + * helper methods, namely {@link #yield(String)} and * {@link #yieldUnescaped(String)}. * @return this MarkupBuilder */ @@ -306,7 +306,7 @@ * @see #escapeXmlValue(String, boolean) */ private String escapeAttributeValue(String value) { - return escapeXmlValue(value, true); + return escapeXmlValue(value, true, useDoubleQuotes); } /** @@ -318,7 +318,7 @@ * @see #escapeXmlValue(String, boolean) */ private String escapeElementContent(String value) { - return escapeXmlValue(value, false); + return escapeXmlValue(value, false, useDoubleQuotes); } /** @@ -337,57 +337,47 @@ * * @param value The string to escape. * @param isAttrValue
true if the string is to be used
- * as an attribute value, otherwise false.
+ * as an attribute value, otherwise false.
+ * @param useDoubleQuotes true if double quotes are used
+ * as attribute delimiter, or false otherwise.
* @return A new string in which all characters that require escaping
* have been replaced with the corresponding XML entities.
*/
- private String escapeXmlValue(String value, boolean isAttrValue) {
- StringBuffer buffer = new StringBuffer(value);
- for (int i = 0, n = buffer.length(); i < n; i++) {
- switch (buffer.charAt(i)) {
+ private static String escapeXmlValue(String value,
+ boolean isAttrValue,
+ boolean useDoubleQuotes)
+ {
+ if (value == null)
+ throw new IllegalArgumentException();
+
+ StringBuffer buffer = null;
+
+ for (int i = 0, len = value.length(); i < len; i++) {
+ final char ch = value.charAt(i);
+ final String replacement;
+
+ switch (ch)
+ {
case '&':
- buffer.replace(i, i + 1, "&");
-
- // We're replacing a single character by a string of
- // length 5, so we need to update the index variable
- // and the total length.
- i += 4;
- n += 4;
+ replacement = "&";
break;
case '<':
- buffer.replace(i, i + 1, "<");
-
- // We're replacing a single character by a string of
- // length 4, so we need to update the index variable
- // and the total length.
- i += 3;
- n += 3;
+ replacement = "<";
break;
case '>':
- buffer.replace(i, i + 1, ">");
-
- // We're replacing a single character by a string of
- // length 4, so we need to update the index variable
- // and the total length.
- i += 3;
- n += 3;
+ replacement = ">";
break;
case '"':
// The double quote is only escaped if the value is for
// an attribute and the builder is configured to output
// attribute values inside double quotes.
- if (isAttrValue && this.useDoubleQuotes) {
- buffer.replace(i, i + 1, """);
-
- // We're replacing a single character by a string of
- // length 6, so we need to update the index variable
- // and the total length.
- i += 5;
- n += 5;
- }
+ if (isAttrValue && useDoubleQuotes)
+ replacement = """;
+ else
+ replacement = null;
break;
case '\'':
@@ -395,25 +385,37 @@
// attribute, as opposed to element content, and if the
// builder is configured to surround attribute values with
// single quotes.
- if (isAttrValue && !this.useDoubleQuotes){
- buffer.replace(i, i + 1, "'");
-
- // We're replacing a single character by a string of
- // length 6, so we need to update the index variable
- // and the total length.
- i += 5;
- n += 5;
- }
+ if (isAttrValue && !useDoubleQuotes)
+ replacement = "'";
+ else
+ replacement = null;
break;
default:
+ replacement = null;
break;
}
+
+ if (replacement != null) {
+ // output differs from input; we write to our local buffer
+ if (buffer == null) {
+ buffer = new StringBuffer((int)(1.1 * len));
+ buffer.append(value.substring(0, i));
+ }
+
+ buffer.append(replacement);
+ } else if (buffer != null) {
+ // output differs from input; we write to our local buffer
+ buffer.append(ch);
+ } else {
+ // nothing to do
+ }
}
- return buffer.toString();
+ return buffer == null ? value : buffer.toString();
}
+
private void toState(int next, Object name) {
switch (state) {
case 0:
@@ -456,7 +458,7 @@
if (!nodeIsEmpty) {
out.println();
out.incrementIndent();
- out.printIndent();
+ out.printIndent();
}
out.print("<");
print(name);