001: /*
002: * Copyright (C) 2007, 2008 XStream Committers.
003: * All rights reserved.
004: *
005: * The software in this package is published under the terms of the BSD
006: * style license a copy of which has been included with this distribution in
007: * the LICENSE.txt file.
008: *
009: * Created on 13. September 2007 by Joerg Schaible
010: */
011: package com.thoughtworks.xstream.benchmark.xmlfriendly.product;
012:
013: import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
014:
015: /**
016: * Abstract base class for the XmlFriendlyReplacer with all kind of implementations.
017: *
018: * @author Jörg Schaible
019: * @since 1.3
020: */
021: public abstract class AbstractXmlFriendlyReplacer extends
022: XmlFriendlyReplacer {
023:
024: private final String dollarReplacement;
025: private final String underscoreReplacement;
026: private final int bufferIncrement;
027:
028: /**
029: * Creates an XmlFriendlyReplacer with custom replacements
030: *
031: * @param dollarReplacement the replacement for '$'
032: * @param underscoreReplacement the replacement for '_'
033: * @param bufferIncrement buffer increment for preallocation
034: */
035: public AbstractXmlFriendlyReplacer(final String dollarReplacement,
036: final String underscoreReplacement,
037: final int bufferIncrement) {
038: this .dollarReplacement = dollarReplacement;
039: this .underscoreReplacement = underscoreReplacement;
040: this .bufferIncrement = bufferIncrement;
041: }
042:
043: /**
044: * Escapes name substituting '$' and '_' with replacement strings
045: *
046: * @param name the name of attribute or node
047: * @return The String with the escaped name
048: */
049: public abstract String escapeName(String name);
050:
051: /**
052: * Escapes name substituting '$' and '_' with replacement strings
053: *
054: * @param name the name of attribute or node
055: * @return The String with the escaped name
056: */
057: public abstract String unescapeName(String name);
058:
059: protected String escapeNoName(final String name) {
060: return name;
061: }
062:
063: protected String unescapeNoName(final String name) {
064: return name;
065: }
066:
067: protected String escapeIterativelyAppending(final String name) {
068: final int length = name.length();
069: final StringBuffer result = bufferIncrement == 0 ? new StringBuffer()
070: : new StringBuffer(length + bufferIncrement);
071: for (int i = 0; i < length; i++) {
072: final char c = name.charAt(i);
073: if (c == '$') {
074: result.append(dollarReplacement);
075: } else if (c == '_') {
076: result.append(underscoreReplacement);
077: } else {
078: result.append(c);
079: }
080: }
081: return result.toString();
082: }
083:
084: protected String unescapeIterativelyAppending(final String name) {
085: final int underscoreReplacementInc = underscoreReplacement
086: .length() - 1;
087: final int dollarReplacementInc = dollarReplacement.length() - 1;
088: final int length = name.length();
089: final StringBuffer result = bufferIncrement == 0 ? new StringBuffer()
090: : new StringBuffer(length + bufferIncrement);
091: for (int i = 0; i < length; i++) {
092: final char c = name.charAt(i);
093: if (name.startsWith(dollarReplacement, i)) {
094: i += dollarReplacementInc;
095: result.append('$');
096: } else if (name.startsWith(underscoreReplacement, i)) {
097: i += underscoreReplacementInc;
098: result.append('_');
099: } else {
100: result.append(c);
101: }
102: }
103: return result.toString();
104: }
105:
106: protected String escapeByCombinedLookupAppending(final String name) {
107: final int length = name.length();
108: final StringBuffer result = bufferIncrement == 0 ? new StringBuffer()
109: : new StringBuffer(length + bufferIncrement);
110: int posDollar = 0;
111: int posUnderscore = 0;
112: for (int i = 0; i < length;) {
113: if (posUnderscore >= 0) {
114: posUnderscore = name.indexOf('_', i);
115: }
116: if (posDollar >= 0) {
117: posDollar = name.indexOf('$', i);
118: }
119: if (posDollar == -1 && posUnderscore == -1) {
120: if (i < length) {
121: result.append(name.substring(i));
122: }
123: break;
124: } else if (posDollar >= 0
125: && (posUnderscore == -1 || posUnderscore >= posDollar)) {
126: result.append(name.substring(i, posDollar));
127: result.append(dollarReplacement);
128: i = posDollar + 1;
129: } else if (posUnderscore >= 0) {
130: result.append(name.substring(i, posUnderscore));
131: result.append(underscoreReplacement);
132: i = posUnderscore + 1;
133: }
134: }
135: return result.toString();
136: }
137:
138: protected String unescapeByCombinedLookupAppending(final String name) {
139: final int underscoreReplacementLength = underscoreReplacement
140: .length();
141: final int dollarReplacementLength = dollarReplacement.length();
142: final int length = name.length();
143: final StringBuffer result = bufferIncrement == 0 ? new StringBuffer()
144: : new StringBuffer(length + bufferIncrement);
145: int posDollar = 0;
146: int posUnderscore = 0;
147: for (int i = 0; i < length;) {
148: if (posUnderscore >= 0) {
149: posUnderscore = name.indexOf(underscoreReplacement, i);
150: }
151: if (posDollar >= 0) {
152: posDollar = name.indexOf(dollarReplacement, i);
153: }
154: if (posDollar == -1 && posUnderscore == -1) {
155: if (i < length) {
156: result.append(name.substring(i));
157: }
158: break;
159: } else if (posDollar >= 0
160: && (posUnderscore == -1 || posUnderscore >= posDollar)) {
161: result.append(name.substring(i, posDollar));
162: result.append('$');
163: i = posDollar + dollarReplacementLength;
164: } else if (posUnderscore >= 0) {
165: result.append(name.substring(i, posUnderscore));
166: result.append('_');
167: i = posUnderscore + underscoreReplacementLength;
168: }
169: }
170: return result.toString();
171: }
172:
173: protected String escapeByCombinedLookupReplacing(final String name) {
174: final int underscoreReplacementLength = underscoreReplacement
175: .length();
176: final int dollarReplacementLength = dollarReplacement.length();
177: final StringBuffer result;
178: if (bufferIncrement == 0) {
179: result = new StringBuffer(name);
180: } else {
181: result = new StringBuffer(name.length() + bufferIncrement);
182: result.append(name);
183: }
184: int posDollar = 0;
185: int posUnderscore = 0;
186: int i = 0;
187: while (true) {
188: if (posUnderscore >= 0) {
189: posUnderscore = result.indexOf("_", i);
190: }
191: if (posDollar >= 0) {
192: posDollar = result.indexOf("$", i);
193: }
194: if (posDollar == -1 && posUnderscore == -1) {
195: break;
196: } else if (posDollar >= 0
197: && (posUnderscore == -1 || posUnderscore > posDollar)) {
198: result.replace(posDollar, posDollar + 1,
199: dollarReplacement);
200: i = posDollar + dollarReplacementLength;
201: } else if (posUnderscore >= 0) {
202: result.replace(posUnderscore, posUnderscore + 1,
203: underscoreReplacement);
204: i = posUnderscore + underscoreReplacementLength;
205: }
206: }
207: return result.toString();
208: }
209:
210: protected String unescapeByCombinedLookupReplacing(final String name) {
211: final int underscoreReplacementLength = underscoreReplacement
212: .length();
213: final int dollarReplacementLength = dollarReplacement.length();
214: final StringBuffer result;
215: if (bufferIncrement == 0) {
216: result = new StringBuffer(name);
217: } else {
218: result = new StringBuffer(name.length() + bufferIncrement);
219: result.append(name);
220: }
221: int posDollar = 0;
222: int posUnderscore = 0;
223: int i = 0;
224: while (true) {
225: if (posUnderscore >= 0) {
226: posUnderscore = result
227: .indexOf(underscoreReplacement, i);
228: }
229: if (posDollar >= 0) {
230: posDollar = result.indexOf(dollarReplacement, i);
231: }
232: if (posDollar == -1 && posUnderscore == -1) {
233: break;
234: } else if (posDollar >= 0
235: && (posUnderscore == -1 || posUnderscore >= posDollar)) {
236: result.replace(posDollar, posDollar
237: + dollarReplacementLength, "$");
238: i = posDollar + 1;
239: } else if (posUnderscore >= 0) {
240: result.replace(posUnderscore, posUnderscore
241: + underscoreReplacementLength, "_");
242: i = posUnderscore + 1;
243: }
244: }
245: return result.toString();
246: }
247:
248: protected String escapeBySeparateLookupReplacing(final String name) {
249: final StringBuffer result;
250: if (bufferIncrement == 0) {
251: result = new StringBuffer(name);
252: } else {
253: result = new StringBuffer(name.length() + bufferIncrement);
254: result.append(name);
255: }
256: final int underscoreReplacementInc = underscoreReplacement
257: .length();
258: final int dollarReplacementInc = dollarReplacement.length();
259: int inc = 0;
260: int pos = 0;
261:
262: while ((pos = result.indexOf("_", pos + inc)) != -1) {
263: result.replace(pos, pos + 1, underscoreReplacement);
264: inc = underscoreReplacementInc;
265: }
266:
267: inc = 0;
268: pos = 0;
269: while ((pos = result.indexOf("$", pos + inc)) != -1) {
270: result.replace(pos, pos + 1, dollarReplacement);
271: inc = dollarReplacementInc;
272: }
273: return result.toString();
274: }
275:
276: protected String unescapeBySeparateLookupReplacing(final String name) {
277: final StringBuffer result;
278: if (bufferIncrement == 0) {
279: result = new StringBuffer(name);
280: } else {
281: result = new StringBuffer(name.length() + bufferIncrement);
282: result.append(name);
283: }
284: int dollarReplacementLength = dollarReplacement.length();
285: int pos = -dollarReplacementLength;
286: while ((pos = result.indexOf(dollarReplacement, pos + 1)) != -1) {
287: result.replace(pos, pos + dollarReplacementLength, "$");
288: }
289:
290: int underscoreReplacementLength = underscoreReplacement
291: .length();
292: pos = -underscoreReplacementLength;
293:
294: while ((pos = result.indexOf(underscoreReplacement, pos + 1)) != -1) {
295: result.replace(pos, pos + underscoreReplacementLength, "_");
296: }
297:
298: return result.toString();
299: }
300:
301: protected String escapeIterativelyReplacing(final String name) {
302: int length = name.length();
303: final int underscoreReplacementInc = underscoreReplacement
304: .length() - 1;
305: final int dollarReplacementInc = dollarReplacement.length() - 1;
306: final StringBuffer result;
307: if (bufferIncrement == 0) {
308: result = new StringBuffer(name);
309: } else {
310: result = new StringBuffer(length + bufferIncrement);
311: result.append(name);
312: }
313: for (int i = 0; i < length; i++) {
314: final char c = result.charAt(i);
315: if (c == '$') {
316: result.replace(i, i + 1, dollarReplacement);
317: length += dollarReplacementInc;
318: i += dollarReplacementInc;
319: } else if (c == '_') {
320: result.replace(i, i + 1, underscoreReplacement);
321: length += underscoreReplacementInc;
322: i += underscoreReplacementInc;
323: }
324: }
325: return result.toString();
326: }
327:
328: protected String unescapeIterativelyReplacing(final String name) {
329: final char dollarChar = dollarReplacement.charAt(0);
330: final char underscoreChar = underscoreReplacement.charAt(0);
331: final int underscoreReplacementLength = underscoreReplacement
332: .length();
333: final int dollarReplacementLength = dollarReplacement.length();
334: int length = name.length();
335: final StringBuffer result;
336: if (bufferIncrement == 0) {
337: result = new StringBuffer(name);
338: } else {
339: result = new StringBuffer(length + bufferIncrement);
340: result.append(name);
341: }
342: for (int i = 0; i < length; ++i) {
343: final char c = result.charAt(i);
344: if (c == dollarChar
345: && i + dollarReplacementLength <= length
346: && result.substring(i, i + dollarReplacementLength)
347: .equals(dollarReplacement)) {
348: result.replace(i, i + dollarReplacementLength, "$");
349: length -= dollarReplacementLength - 1;
350: } else if (c == underscoreChar
351: && i + underscoreReplacementLength <= length
352: && result.substring(i,
353: i + underscoreReplacementLength).equals(
354: underscoreReplacement)) {
355: result.replace(i, i + underscoreReplacementLength, "_");
356: length -= underscoreReplacementLength - 1;
357: }
358: }
359: return result.toString();
360: }
361:
362: }
|