001: package net.sf.saxon.value;
002:
003: import net.sf.saxon.functions.NormalizeSpace;
004: import net.sf.saxon.om.FastStringBuffer;
005:
006: /**
007: * This class provides helper methods and constants for handling whitespace
008: */
009: public class Whitespace {
010:
011: private Whitespace() {
012: }
013:
014: /**
015: * The values PRESERVE, REPLACE, and COLLAPSE represent the three options for whitespace
016: * normalization. They are deliberately chosen in ascending strength order; given a number
017: * of whitespace facets, only the strongest needs to be carried out.
018: */
019:
020: public static final int PRESERVE = 0;
021: public static final int REPLACE = 1;
022: public static final int COLLAPSE = 2;
023:
024: /**
025: * The values NONE, IGNORABLE, and ALL identify which kinds of whitespace text node
026: * should be stripped when building a source tree
027: */
028:
029: public static final int NONE = 10;
030: public static final int IGNORABLE = 11;
031: public static final int ALL = 12;
032: public static final int UNSPECIFIED = 13;
033:
034: /**
035: * Apply schema-defined whitespace normalization to a string
036: * @param action the action to be applied: one of PRESERVE, REPLACE, or COLLAPSE
037: * @param value the value to be normalized
038: * @return the value after normalization
039: */
040:
041: public static CharSequence applyWhitespaceNormalization(int action,
042: CharSequence value) {
043: switch (action) {
044: case PRESERVE:
045: return value;
046: case REPLACE:
047: FastStringBuffer sb = new FastStringBuffer(value.length());
048: for (int i = 0; i < value.length(); i++) {
049: char c = value.charAt(i);
050: switch (c) {
051: case '\n':
052: case '\r':
053: case '\t':
054: sb.append(' ');
055: default:
056: sb.append(c);
057: }
058: }
059: return sb;
060: case COLLAPSE:
061: return NormalizeSpace.normalize(value);
062: default:
063: throw new IllegalArgumentException(
064: "Unknown whitespace facet value");
065: }
066: }
067:
068: /**
069: * Remove all whitespace characters from a string
070: */
071:
072: public static CharSequence removeAllWhitespace(CharSequence value) {
073: if (containsWhitespace(value)) {
074: FastStringBuffer sb = new FastStringBuffer(value.length());
075: for (int i = 0; i < value.length(); i++) {
076: char c = value.charAt(i);
077: if (c > 32 || !C0WHITE[c]) {
078: sb.append(c);
079: }
080: }
081: return sb;
082: } else {
083: return value;
084: }
085: }
086:
087: /**
088: * Remove leading whitespace characters from a string
089: */
090:
091: public static CharSequence removeLeadingWhitespace(
092: CharSequence value) {
093: int start = 0;
094: final int len = value.length();
095: for (int i = 0; i < len; i++) {
096: char c = value.charAt(i);
097: if (c > 32 || !C0WHITE[c]) {
098: start = i;
099: break;
100: }
101: }
102: if (start == 0) {
103: return value;
104: } else if (start == len - 1) {
105: return "";
106: } else {
107: return value.subSequence(start, len);
108: }
109: }
110:
111: /**
112: * Determine if a string contains any whitespace
113: */
114:
115: public static boolean containsWhitespace(CharSequence value) {
116: final int len = value.length();
117: for (int i = 0; i < len;) {
118: char c = value.charAt(i++);
119: if (c <= 32 && C0WHITE[c]) {
120: return true;
121: }
122: }
123: return false;
124: }
125:
126: /**
127: * Determine if a string is all-whitespace
128: *
129: * @param content the string to be tested
130: * @return true if the supplied string contains no non-whitespace
131: * characters
132: */
133:
134: public static final boolean isWhite(CharSequence content) {
135: final int len = content.length();
136: for (int i = 0; i < len;) {
137: // all valid XML 1.0 whitespace characters, and only whitespace characters, are <= 0x20
138: // But XML 1.1 allows non-white characters that are also < 0x20, so we need a specific test for these
139: char c = content.charAt(i++);
140: if (c > 32 || !C0WHITE[c]) {
141: return false;
142: }
143: }
144: return true;
145: }
146:
147: private static boolean[] C0WHITE = { false, false, false, false,
148: false, false, false, false, // 0-7
149: false, true, true, false, false, true, false, false, // 8-15
150: false, false, false, false, false, false, false, false, // 16-23
151: false, false, false, false, false, false, false, false, // 24-31
152: true // 32
153: };
154: }
155: //
156: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
157: // you may not use this file except in compliance with the License. You may obtain a copy of the
158: // License at http://www.mozilla.org/MPL/
159: //
160: // Software distributed under the License is distributed on an "AS IS" basis,
161: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
162: // See the License for the specific language governing rights and limitations under the License.
163: //
164: // The Original Code is: all this file
165: //
166: // The Initial Developer of the Original Code is Michael H. Kay.
167: //
168: // Contributor(s):
169: //
|