From 64ca1306b4e0d55a8b15b8da982bc1d37bc8b63c Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 16:51:07 +0200 Subject: [PATCH] Rewrite XML serialization avoiding string concats --- .../java/org/z3950/zing/cql/CQLBooleanNode.java | 29 +++++------ src/main/java/org/z3950/zing/cql/CQLNode.java | 45 ++++++++-------- src/main/java/org/z3950/zing/cql/CQLParser.java | 2 +- .../java/org/z3950/zing/cql/CQLPrefixNode.java | 4 +- src/main/java/org/z3950/zing/cql/CQLRelation.java | 5 +- src/main/java/org/z3950/zing/cql/CQLSortNode.java | 4 +- src/main/java/org/z3950/zing/cql/CQLTermNode.java | 19 +++---- src/main/java/org/z3950/zing/cql/Modifier.java | 25 ++++----- src/main/java/org/z3950/zing/cql/ModifierSet.java | 33 ++++++------ src/main/java/org/z3950/zing/cql/Utils.java | 46 ----------------- src/main/java/org/z3950/zing/cql/XCQLBuilder.java | 54 ++++++++++++++++++++ 11 files changed, 132 insertions(+), 134 deletions(-) delete mode 100644 src/main/java/org/z3950/zing/cql/Utils.java create mode 100644 src/main/java/org/z3950/zing/cql/XCQLBuilder.java diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index 19f96c7..d5a81e8 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -4,9 +4,6 @@ package org.z3950.zing.cql; import java.util.List; import java.util.Properties; -import static org.z3950.zing.cql.Utils.*; - - /** * Represents a boolean node in a CQL parse-tree. * @@ -47,19 +44,19 @@ public abstract class CQLBooleanNode extends CQLNode { } @Override - public String toXCQL(int level, List prefixes, - List sortkeys) { - return (indent(level) + "\n" + - renderPrefixes(level+1, prefixes) + - ms.toXCQL(level+1, "boolean") + - indent(level+1) + "\n" + - left.toXCQL(level+2) + - indent(level+1) + "\n" + - indent(level+1) + "\n" + - right.toXCQL(level+2) + - indent(level+1) + "\n" + - renderSortKeys(level+1, sortkeys) + - indent(level) + "\n"); + void toXCQLInternal(XCQLBuilder b, int level, + List prefixes, List sortkeys) { + b.indent(level).append("\n"); + renderPrefixes(b, level + 1, prefixes); + ms.toXCQLInternal(b, level + 1, "boolean"); + b.indent(level + 1).append("\n"); + left.toXCQLInternal(b, level + 2); + b.indent(level + 1).append("\n"); + b.indent(level + 1).append("\n"); + right.toXCQLInternal(b, level + 2); + b.indent(level + 1).append("\n"); + renderSortKeys(b, level + 1, sortkeys); + b.indent(level).append("\n"); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index 88b50ca..afaa892 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Map; import java.util.Properties; -import static org.z3950.zing.cql.Utils.*; /** @@ -41,43 +40,47 @@ public abstract class CQLNode { * A String containing an XCQL document equivalent to the * parse-tree whose root is this node. */ - public String toXCQL(int level) { - return toXCQL(level, null); + public String toXCQL() { + StringBuilder sb = new StringBuilder(); + toXCQLInternal(new XCQLBuilder(sb), 0); + return sb.toString(); } - public String toXCQL(int level, List prefixes) { - return toXCQL(level, prefixes, null); + void toXCQLInternal(XCQLBuilder b, int level) { + toXCQLInternal(b, level, null, null); } - abstract public String toXCQL(int level, List prefixes, - List sortkeys); + abstract void toXCQLInternal(XCQLBuilder b, int level, + List prefixes, List sortkeys); - protected static String renderPrefixes(int level, List prefixes) { + static void renderPrefixes(XCQLBuilder b, + int level, List prefixes) { if (prefixes == null || prefixes.size() == 0) - return ""; - String res = indent(level) + "\n"; + return; + b.indent(level).append("\n"); for (int i = 0; i < prefixes.size(); i++) { CQLPrefix p = prefixes.get(i); - res += indent(level+1) + "\n"; + b.indent(level+1).append("\n"); if (p.name != null) - res += indent(level+2) + "" + p.name + "\n"; - res += indent(level+2) + - "" + p.identifier + "\n"; - res += indent(level+1) + "\n"; + b.indent(level + 2).append(""). + append(p.name).append("\n"); + b.indent(level + 2).append("").append(p.identifier). + append("\n"); + b.indent(level+1).append("\n"); } - return res + indent(level) + "\n"; + b.indent(level).append("\n"); } - protected static String renderSortKeys(int level, + static void renderSortKeys(XCQLBuilder b, int level, List sortkeys) { if (sortkeys == null || sortkeys.size() == 0) - return ""; - String res = indent(level) + "\n"; + return; + b.indent(level).append("\n"); for (int i = 0; i < sortkeys.size(); i++) { ModifierSet key = sortkeys.get(i); - res += key.sortKeyToXCQL(level+1); + b.append(key.sortKeyToXCQL(level+1)); } - return res + indent(level) + "\n"; + b.indent(level).append("\n"); } /** diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 7ed9f59..be365de 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -443,7 +443,7 @@ public class CQLParser { f.close(); System.out.println(root.toPQF(config)); } else { - System.out.print(root.toXCQL(0)); + System.out.print(root.toXCQL()); } } catch (IOException ex) { System.err.println("Can't render query: " + ex.getMessage()); diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index c793d2f..eed3d34 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -42,13 +42,13 @@ public class CQLPrefixNode extends CQLNode { } @Override - public String toXCQL(int level, List prefixes, + void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { List tmp = (prefixes == null ? new ArrayList() : new ArrayList(prefixes)); tmp.add(prefix); - return subtree.toXCQL(level, tmp, sortkeys); + subtree.toXCQLInternal(b, level, tmp, sortkeys); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 44a55e6..351d8d4 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -44,12 +44,11 @@ public class CQLRelation extends CQLNode { } @Override - public String toXCQL(int level, List prefixes, + void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { if (sortkeys != null) throw new Error("CQLRelation.toXCQL() called with sortkeys"); - - return ms.toXCQL(level, "relation"); + ms.toXCQLInternal(b, level, "relation"); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 55e69d5..68a4ea9 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -43,11 +43,11 @@ public class CQLSortNode extends CQLNode { } @Override - public String toXCQL(int level, List prefixes, + void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { if (sortkeys != null) throw new Error("CQLSortNode.toXCQL() called with sortkeys"); - return subtree.toXCQL(level, prefixes, keys); + subtree.toXCQLInternal(b, level, prefixes, keys); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index cdb62f7..dfd0e63 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -5,9 +5,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; -import static org.z3950.zing.cql.Utils.*; - - /** * Represents a terminal node in a CQL parse-tree. * A term node consists of the term String itself, together with, @@ -55,15 +52,15 @@ public class CQLTermNode extends CQLNode { } @Override - public String toXCQL(int level, List prefixes, + void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { - return (indent(level) + "\n" + - renderPrefixes(level+1, prefixes) + - indent(level+1) + "" + xq(index) + "\n" + - relation.toXCQL(level+1) + - indent(level+1) + "" + xq(term) + "\n" + - renderSortKeys(level+1, sortkeys) + - indent(level) + "\n"); + b.indent(level).append("\n"); + renderPrefixes(b, level + 1, prefixes); + b.indent(level + 1).append("").xq(index).append("\n"); + relation.toXCQLInternal(b, level + 1); + b.indent(level + 1).append("").xq(term).append("\n"); + renderSortKeys(b, level + 1, sortkeys); + b.indent(level).append("\n"); } @Override diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index d85c8a1..8c5cef7 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -2,8 +2,6 @@ package org.z3950.zing.cql; -import static org.z3950.zing.cql.Utils.*; - /** * Represents a single modifier, consisting of three elements: a type, * a comparision and a value. For example, "distance", "<", "3". The @@ -60,22 +58,17 @@ public class Modifier { return value; } - public String toXCQL(int level, String relationElement) { - StringBuilder buf = new StringBuilder(); - - buf.append(indent(level)).append("\n"). - append(indent(level + 1)).append(""). - append(xq(type)).append("\n"); + protected XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, String relationElement) { + b.indent(level).append("\n"); + b.indent(level + 1).append(""); + b.xq(type).append("\n"); if (value != null) { - buf.append(indent(level + 1)).append("<"). - append(relationElement).append(">"). - append(xq(comparison)).append("\n"). - append(indent(level + 1)).append(""). - append(xq(value)).append("\n"); + b.indent(level + 1).append("<").append(relationElement).append(">"); + b.xq(comparison).append("\n"); + b.indent(level + 1).append(""); + b.xq(value).append("\n"); } - buf.append(indent(level)).append("\n"); - return buf.toString(); + return b.indent(level).append("\n"); } public String toCQL() { diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index 213f199..c04bb88 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -4,8 +4,6 @@ package org.z3950.zing.cql; import java.util.ArrayList; import java.util.List; -import static org.z3950.zing.cql.Utils.*; - /** * Represents a base String and a set of Modifiers. *

@@ -80,30 +78,33 @@ public class ModifierSet { } public String toXCQL(int level, String topLevelElement) { - return underlyingToXCQL(level, topLevelElement, "value"); + return "";//underlyingToXCQL(level, topLevelElement, "value"); } public String sortKeyToXCQL(int level) { - return underlyingToXCQL(level, "key", "index"); + return "";//underlyingToXCQL(level, "key", "index"); + } + + protected XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, + String topLevelElement) { + return toXCQLInternal(b, level, topLevelElement, "value"); } - private String underlyingToXCQL(int level, String topLevelElement, - String valueElement) { - StringBuilder buf = new StringBuilder(); - buf.append(indent(level)).append("<").append(topLevelElement). - append(">\n").append(indent(level + 1)).append("<"). - append(valueElement).append(">").append(xq(base)).append("\n").indent(level + 1).append("<"). + append(valueElement).append(">").xq(base).append("\n"); if (modifiers.size() > 0) { - buf.append(indent(level + 1)).append("\n"); + b.indent(level + 1).append("\n"); for (int i = 0; i < modifiers.size(); i++) { - buf.append(modifiers.get(i).toXCQL(level+2, "comparison")); + modifiers.get(i).toXCQLInternal(b, level+2, "comparison"); } - buf.append(indent(level + 1)).append("\n"); + b.indent(level + 1).append("\n"); } - buf.append(indent(level)).append("\n"); - return buf.toString(); + b.indent(level).append("\n"); + return b; } public String toCQL() { diff --git a/src/main/java/org/z3950/zing/cql/Utils.java b/src/main/java/org/z3950/zing/cql/Utils.java deleted file mode 100644 index 9224d36..0000000 --- a/src/main/java/org/z3950/zing/cql/Utils.java +++ /dev/null @@ -1,46 +0,0 @@ -// $Id: Utils.java,v 1.2 2002-11-06 00:05:58 mike Exp $ - -package org.z3950.zing.cql; - - -/** - * Utility functions for the org.z3950.zing.cql package. - * Not intended for use outside this package. - * - * @version $Id: Utils.java,v 1.2 2002-11-06 00:05:58 mike Exp $ - */ -class Utils { - static String indent(int level) { - String x = ""; - while (level-- > 0) { - x += " "; - } - return x; - } - - // XML Quote -- - // s/&/&/g; - // s//>/g; - static String xq(String str) { - StringBuilder sb = new StringBuilder(); - for(int i = 0; i': - sb.append(">"); - break; - case '&': - sb.append("&"); - break; - default: - sb.append(c); - } - } - return sb.toString(); - } - -} diff --git a/src/main/java/org/z3950/zing/cql/XCQLBuilder.java b/src/main/java/org/z3950/zing/cql/XCQLBuilder.java new file mode 100644 index 0000000..d59ce89 --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/XCQLBuilder.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1995-2011, Index Data + * All rights reserved. + * See the file LICENSE for details. + */ +package org.z3950.zing.cql; + +/** + * + * @author jakub + */ +class XCQLBuilder { + private StringBuilder sb; + + XCQLBuilder(StringBuilder sb) { + this.sb = sb; + } + + XCQLBuilder indent(int level) { + while (level-- > 0) { + sb.append(" "); + } + return this; + } + + XCQLBuilder xq(String str) { + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + switch (c) { + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + case '&': + sb.append("&"); + break; + default: + sb.append(c); + } + } + return this; + } + + XCQLBuilder append(String str) { + sb.append(str); + return this; + } + + public String toString() { + return sb.toString(); + } +} \ No newline at end of file -- 1.7.10.4