import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.HashMap;
import java.util.Map;
/**
* An encoder useful for converting text to be used within XML attribute values.
* The following translations will be performed:
*
*
* Raw (Unencoded)
Character
* Translated (Encoded)
Entity
*
*
* &
* &
*
*
* <
* <
*
*
* >
* >
*
*
* "
* "
*
*
* '
* '
*
*
* All Others
* No Translation
*
*
*
*/
public class XmlValueEncoder {
private static final Map SPECIAL_ENTITIES;
static {
SPECIAL_ENTITIES = new HashMap();
SPECIAL_ENTITIES.put("quot", '"');
SPECIAL_ENTITIES.put("gt", '>');
SPECIAL_ENTITIES.put("lt", '<');
SPECIAL_ENTITIES.put("amp", '&');
}
/**
* {@inheritDoc}
*
* @see org.jboss.dna.common.text.TextEncoder#encode(java.lang.String)
*/
public String encode( String text ) {
if (text == null) return null;
StringBuilder sb = new StringBuilder();
CharacterIterator iter = new StringCharacterIterator(text);
for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
switch (c) {
case '&':
sb.append("&");
break;
case '"':
sb.append(""");
break;
case '<':
sb.append("<");
break;
case '>':
sb.append(">");
break;
case '\'':
sb.append("'");
break;
default:
sb.append(c);
}
}
return sb.toString();
}
/**
* {@inheritDoc}
*
* @see org.jboss.dna.common.text.TextDecoder#decode(java.lang.String)
*/
public String decode( String encodedText ) {
if (encodedText == null) return null;
StringBuilder sb = new StringBuilder();
CharacterIterator iter = new StringCharacterIterator(encodedText);
for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
if (c == '&') {
int index = iter.getIndex();
do {
c = iter.next();
}
while (c != CharacterIterator.DONE && c != ';');
// We found a closing semicolon
if (c == ';') {
String s = encodedText.substring(index + 1, iter.getIndex());
if (SPECIAL_ENTITIES.containsKey(s)) {
sb.append(SPECIAL_ENTITIES.get(s));
continue;
}
if (s.length() > 0 && s.charAt(0) == '#') {
try {
sb.append((char) Short.parseShort(s.substring(1, s.length())));
continue;
}
catch (NumberFormatException nfe) {
// This is possible in malformed encodings, but let it fall through
}
}
}
// Malformed encoding, restore state and pass poorly encoded data back
c = '&';
iter.setIndex(index);
}
sb.append(c);
}
return sb.toString();
}
}