001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.language.markup.xsp;
018:
019: /**
020: * This class is used as a XSLT extension class. It is used by the XSP
021: * generation stylesheet to escape XML characters to make a valid Java strings.
022: *
023: * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
024: * @version CVS $Id: XSLTExtension.java 433543 2006-08-22 06:22:54Z crossley $
025: */
026: public class XSLTExtension {
027:
028: /**
029: * Escapes '"' and '\' characters in a String (add a '\' before them) so that it can
030: * be inserted in java source + quote special characters as UTF-8
031: */
032: public static String escapeJavaString(String string) {
033: char chr[] = string.toCharArray();
034: StringBuffer buffer = new StringBuffer();
035:
036: for (int i = 0; i < chr.length; i++) {
037: char c = chr[i];
038: switch (c) {
039: case '\t':
040: buffer.append("\\t");
041: break;
042: case '\r':
043: buffer.append("\\r");
044: break;
045: case '\n':
046: buffer.append("\\n");
047: break;
048: case '\b':
049: buffer.append("\\b");
050: break;
051: case '\f':
052: buffer.append("\\f");
053: break;
054: case '"':
055: case '\\':
056: buffer.append('\\');
057: buffer.append(c);
058: break;
059: default:
060: if (' ' <= c && c <= 127) {
061: buffer.append(c);
062: } else {
063: buffer.append("\\u");
064: buffer.append(int2digit(c >> 12));
065: buffer.append(int2digit(c >> 8));
066: buffer.append(int2digit(c >> 4));
067: buffer.append(int2digit(c));
068: }
069: break;
070: }
071: }
072:
073: final String encoded = buffer.toString();
074: return encoded;
075: }
076:
077: /**
078: * Quote special characters as UTF-8
079: *
080: * TC: It's code duplication but that way we don't
081: * have to iterate through the StringBuffer twice
082: */
083: public static String escapeString(String string) {
084: char chr[] = string.toCharArray();
085: StringBuffer buffer = new StringBuffer();
086: for (int i = 0; i < chr.length; i++) {
087: char c = chr[i];
088: if (c <= 127) {
089: buffer.append(c);
090: } else {
091: buffer.append("\\u");
092: buffer.append(int2digit(c >> 12));
093: buffer.append(int2digit(c >> 8));
094: buffer.append(int2digit(c >> 4));
095: buffer.append(int2digit(c));
096: }
097: }
098:
099: final String encoded = buffer.toString();
100: return encoded;
101: }
102:
103: private static char int2digit(int x) {
104: x &= 0xF;
105: if (x <= 9)
106: return (char) (x + '0');
107: else
108: return (char) (x - 10 + 'A');
109: }
110:
111: /**
112: * @see #escapeString(String)
113: */
114: public String escape(String string) {
115: return escapeString(string);
116: }
117:
118: /**
119: * This method used by Java XSP core logicsheet.
120: * @see #escapeJavaString(String)
121: */
122: public String escapeJava(String string) {
123: return escapeJavaString(string);
124: }
125:
126: /**
127: * Counts amount of spaces in the input line from the beginning
128: * to the first new line symbol and returns a string with this
129: * amount of spaces.
130: *
131: * Used by the Python XSP core logicsheet.
132: */
133: public String prefix(String string) {
134: char chr[] = string.toCharArray();
135: int i;
136: for (i = 0; i < chr.length; i++) {
137: if (chr[i] == '\n' || chr[i] == '\r')
138: break;
139: }
140: if (i == chr.length) {
141: return "";
142: }
143:
144: int j = 0;
145: for (; i < chr.length; i++) {
146: if (chr[i] == '\n' || chr[i] == '\r') {
147: j = 0;
148: } else if (!Character.isSpaceChar(chr[i])) {
149: break;
150: } else {
151: j++;
152: }
153: }
154:
155: // System.out.println("<" + string + "> prefix:" + j);
156: StringBuffer buffer = new StringBuffer();
157: for (i = 0; i < j; i++) {
158: buffer.append(' ');
159: }
160: return buffer.toString();
161: }
162:
163: /**
164: * Counts amount of spaces in the input line from the end
165: * to the last new line symbol and returns a string with this
166: * amount of spaces.
167: *
168: * Used by the Python XSP core logicsheet.
169: */
170: public String suffix(String string) {
171: char chr[] = string.toCharArray();
172:
173: int j = 0;
174: for (int i = chr.length - 1; i >= 0; i--) {
175: if (chr[i] == '\n' || chr[i] == '\r')
176: break;
177: if (!Character.isSpaceChar(chr[i]))
178: return "";
179: j++;
180: }
181:
182: // System.out.println("<" + string + "> suffix:" + j);
183: StringBuffer buffer = new StringBuffer();
184: for (int i = 0; i < j; i++) {
185: buffer.append(' ');
186: }
187: return buffer.toString();
188: }
189: }
|