001: /*
002: * Copyright (C) 2006 Joe Walnes.
003: * Copyright (C) 2006, 2007 XStream Committers.
004: * All rights reserved.
005: *
006: * The software in this package is published under the terms of the BSD
007: * style license a copy of which has been included with this distribution in
008: * the LICENSE.txt file.
009: *
010: * Created on 22. April 2006 by Mauro Talevi
011: */
012: package com.thoughtworks.xstream.io.xml;
013:
014: /**
015: * Allows replacement of Strings in xml-friendly drivers to provide compatibility with XStream 1.1 format
016: *
017: * @author Mauro Talevi
018: * @since 1.2
019: */
020: public class XStream11XmlFriendlyReplacer extends XmlFriendlyReplacer {
021:
022: private char dollarReplacementInClass = '-';
023: private String dollarReplacementInField = "_DOLLAR_";
024: private String underscoreReplacementInField = "__";
025: private String noPackagePrefix = "default";
026:
027: /**
028: * Default constructor.
029: */
030: public XStream11XmlFriendlyReplacer() {
031: }
032:
033: /**
034: * Noop implementation that does not unescape name. Used for XStream 1.1 compatibility.
035: * @param name the name of attribute or node
036: * @return The String with unescaped name
037: */
038: public String unescapeName(String name) {
039: return name;
040: }
041:
042: protected String escapeClassName(String className) {
043: // the $ used in inner class names is illegal as an xml element getNodeName
044: className = className.replace('$', dollarReplacementInClass);
045:
046: // special case for classes named $Blah with no package; <-Blah> is illegal XML
047: if (className.charAt(0) == dollarReplacementInClass) {
048: className = noPackagePrefix + className;
049: }
050:
051: return className;
052: }
053:
054: protected String escapeFieldName(String fieldName) {
055: StringBuffer result = new StringBuffer();
056: int length = fieldName.length();
057: for (int i = 0; i < length; i++) {
058: char c = fieldName.charAt(i);
059: if (c == '$') {
060: result.append(dollarReplacementInField);
061: } else if (c == '_') {
062: result.append(underscoreReplacementInField);
063: } else {
064: result.append(c);
065: }
066: }
067: return result.toString();
068: }
069:
070: protected String unescapeClassName(String className) {
071: // special case for classes named $Blah with no package; <-Blah> is illegal XML
072: if (className.startsWith(noPackagePrefix
073: + dollarReplacementInClass)) {
074: className = className.substring(noPackagePrefix.length());
075: }
076:
077: // the $ used in inner class names is illegal as an xml element getNodeName
078: className = className.replace(dollarReplacementInClass, '$');
079:
080: return className;
081: }
082:
083: protected String unescapeFieldName(String xmlName) {
084: StringBuffer result = new StringBuffer();
085: int length = xmlName.length();
086: for (int i = 0; i < length; i++) {
087: char c = xmlName.charAt(i);
088: if (stringFoundAt(xmlName, i, underscoreReplacementInField)) {
089: i += underscoreReplacementInField.length() - 1;
090: result.append('_');
091: } else if (stringFoundAt(xmlName, i,
092: dollarReplacementInField)) {
093: i += dollarReplacementInField.length() - 1;
094: result.append('$');
095: } else {
096: result.append(c);
097: }
098: }
099: return result.toString();
100: }
101:
102: private boolean stringFoundAt(String name, int i, String replacement) {
103: if (name.length() >= i + replacement.length()
104: && name.substring(i, i + replacement.length()).equals(
105: replacement)) {
106: return true;
107: }
108: return false;
109: }
110:
111: }
|