001: /* Copyright 2001 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.utils;
007:
008: /**
009: * This utility provides a simple way of escaping the special or
010: * reserved characters in XML that serve as delimiters so that
011: * a string of characters can be left untouched by an XML parser.
012: * See http://www.w3.org/TR/2000/REC-xml-20001006#syntax
013: * and http://www.w3.org/TR/2000/REC-xml-20001006#sec-predefined-ent
014: * and http://www.w3.org/TR/2000/REC-xml-20001006#sec-entexpand
015: * Most of the code was borrowed from Xerces serializer classes.
016: * If anyone finds a useable method in a standard XML API
017: * that escapes XML strings, we should use it in place of this class.
018: * @author Ken Weiner, kweiner@unicon.net
019: * @version $Revision: 34797 $
020: */
021: public class XMLEscaper {
022: /**
023: * Escapes an XML string
024: * @param source a String to be escaped
025: * @return an escaped String
026: */
027: public static String escape(String source) {
028: String result = null;
029:
030: if (source != null) {
031: StringBuffer sb = new StringBuffer(source.length() + 256);
032:
033: for (int i = 0; i < source.length(); i++)
034: sb.append(escape(source.charAt(i)));
035:
036: result = sb.toString();
037:
038: }
039:
040: return (result);
041: }
042:
043: /**
044: * Escapes an XML character
045: * @param ch a char to be escaped
046: * @return an escaped char
047: */
048: public static String escape(char ch) {
049: StringBuffer sb = new StringBuffer(10);
050: String charRef;
051:
052: // If there is a suitable entity reference for this character, print it.
053: charRef = getEntityRef(ch);
054:
055: if (charRef != null) {
056: sb.append('&');
057: sb.append(charRef);
058: sb.append(';');
059: } else if ((ch >= ' ' && ch <= 0x7E && ch != 0xF7)
060: || ch == '\n' || ch == '\r' || ch == '\t') {
061: // If the character is not printable, print as character reference.
062: // Non printables are below ASCII space but not tab or line
063: // terminator, ASCII delete, or above a certain Unicode threshold.
064: sb.append(ch);
065: } else {
066: sb.append("&#");
067: sb.append(Integer.toString(ch));
068: sb.append(';');
069: }
070:
071: return sb.toString();
072: }
073:
074: private static String getEntityRef(char ch) {
075: // Encode special XML characters into the equivalent character references.
076: // These five are defined by default for all XML documents.
077: switch (ch) {
078: case '<':
079: return "lt";
080: case '>':
081: return "gt";
082: case '"':
083: return "quot";
084: case '\'':
085: return "apos";
086: case '&':
087: return "amp";
088: }
089: return null;
090: }
091:
092: /**
093: * This method is provided to test out the escape method.
094: * @param args the command line arguments
095: */
096: public static void main(String args[]) {
097: if (args.length < 1) {
098: System.out
099: .println("Usage: XMLEscaper \"<string to escape>\"");
100: } else {
101: String before = args[0];
102: String after = escape(before);
103: System.out.println("Before escaping: " + before);
104: System.out.println(" After escaping: " + after);
105: }
106: }
107: }
|