001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015:
016: package org.griphyn.common.util;
017:
018: /**
019: * This class tries to define an interface to deal with quoting, escaping,
020: * and the way back. The quoting algorithm is safe to only itself. Thus,
021: *
022: * <pre>
023: * unescape( escape( s ) ) === s
024: * </pre>
025: *
026: * holds true, but
027: *
028: * <pre>
029: * escape( unescape( s ) ) =?= s
030: * </pre>
031: *
032: * does not necessarily hold.
033: *
034: * @author Gaurang Mehta
035: * @author Karan Vahi
036: * @author Jens-S. Vöckler
037: * @version $Revision: 50 $
038: */
039: public class Escape {
040: /**
041: * Defines the character used to escape characters.
042: */
043: private char m_escape;
044:
045: /**
046: * Defines the set of characters that require escaping.
047: */
048: private String m_escapable;
049:
050: /**
051: * Defines the default quoting and escaping rules, escaping the
052: * apostrophe, double quote and backslash. The escape character
053: * is the backslash.
054: *
055: */
056: public Escape() {
057: m_escapable = "\"'\\";
058: m_escape = '\\';
059: }
060:
061: /**
062: * Constructs arbitrary escaping rules.
063: *
064: * @param escapable is the set of characters that require escaping
065: * @param escape is the escape character itself.
066: */
067: public Escape(String escapable, char escape) {
068: m_escape = escape;
069: m_escapable = escapable;
070:
071: // ensure that the escape character is part of the escapable char set
072: if (escapable.indexOf(escape) == -1)
073: m_escapable += m_escape;
074: }
075:
076: /**
077: * Transforms a given string by escaping all characters inside the
078: * quotable characters set with the escape character. The escape
079: * character itself is also escaped.
080: *
081: * @param s is the string to escape.
082: * @return the quoted string
083: * @see #unescape( String )
084: */
085: public String escape(String s) {
086: // sanity check
087: if (s == null)
088: return null;
089:
090: StringBuffer result = new StringBuffer(s.length());
091: for (int i = 0; i < s.length(); ++i) {
092: char ch = s.charAt(i);
093: if (m_escapable.indexOf(ch) != -1)
094: result.append(m_escape);
095: result.append(ch);
096: }
097: return result.toString();
098: }
099:
100: /**
101: * Transforms a given string by unescaping all characters that
102: * are prefixed with the escape character.
103: *
104: * @param s is the string to remove escapes from.
105: * @return the quoted string
106: * @see #unescape( String )
107: */
108: public String unescape(String s) {
109: // sanity check
110: if (s == null)
111: return null;
112:
113: StringBuffer result = new StringBuffer(s.length());
114: int state = 0;
115: for (int i = 0; i < s.length(); ++i) {
116: char ch = s.charAt(i);
117: if (state == 0) {
118: // default state
119: if (ch == m_escape)
120: state = 1;
121: else
122: result.append(ch);
123: } else {
124: // "found escape" state
125: if (m_escapable.indexOf(ch) == -1)
126: result.append(m_escape);
127: result.append(ch);
128: state = 0;
129: }
130: }
131:
132: return result.toString();
133: }
134:
135: /**
136: * Test program.
137: *
138: * @param args are command-line arguments
139: */
140: public static void main(String args[]) {
141: Escape me = new Escape(); // defaults
142:
143: for (int i = 0; i < args.length; ++i) {
144: String e = me.escape(args[i]);
145: String u = me.unescape(args[i]);
146: System.out.println("raw s > " + args[i]);
147: System.out.println("e(s) > " + e);
148: System.out.println("u(e(s))> " + me.unescape(e));
149: System.out.println("u(s) > " + u);
150: System.out.println("e(u(s))> " + me.escape(u));
151: System.out.println();
152: }
153: }
154: }
|