aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.bind; aoqi@0: aoqi@0: /** aoqi@0: * Processes white space normalization. aoqi@0: * aoqi@0: * @since 1.0 aoqi@0: */ aoqi@0: public abstract class WhiteSpaceProcessor { aoqi@0: aoqi@0: // benchmarking (see test/src/ReplaceTest.java in the CVS Attic) aoqi@0: // showed that this code is slower than the current code. aoqi@0: // aoqi@0: // public static String replace(String text) { aoqi@0: // final int len = text.length(); aoqi@0: // StringBuffer result = new StringBuffer(len); aoqi@0: // aoqi@0: // for (int i = 0; i < len; i++) { aoqi@0: // char ch = text.charAt(i); aoqi@0: // if (isWhiteSpace(ch)) aoqi@0: // result.append(' '); aoqi@0: // else aoqi@0: // result.append(ch); aoqi@0: // } aoqi@0: // aoqi@0: // return result.toString(); aoqi@0: // } aoqi@0: aoqi@0: public static String replace(String text) { aoqi@0: return replace( (CharSequence)text ).toString(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * @since 2.0 aoqi@0: */ aoqi@0: public static CharSequence replace(CharSequence text) { aoqi@0: int i=text.length()-1; aoqi@0: aoqi@0: // look for the first whitespace char. aoqi@0: while( i>=0 && !isWhiteSpaceExceptSpace(text.charAt(i)) ) aoqi@0: i--; aoqi@0: aoqi@0: if( i<0 ) aoqi@0: // no such whitespace. replace(text)==text. aoqi@0: return text; aoqi@0: aoqi@0: // we now know that we need to modify the text. aoqi@0: // allocate a char array to do it. aoqi@0: StringBuilder buf = new StringBuilder(text); aoqi@0: aoqi@0: buf.setCharAt(i--,' '); aoqi@0: for( ; i>=0; i-- ) aoqi@0: if( isWhiteSpaceExceptSpace(buf.charAt(i))) aoqi@0: buf.setCharAt(i,' '); aoqi@0: aoqi@0: return new String(buf); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Equivalent of {@link String#trim()}. aoqi@0: * @since 2.0 aoqi@0: */ aoqi@0: public static CharSequence trim(CharSequence text) { aoqi@0: int len = text.length(); aoqi@0: int start = 0; aoqi@0: aoqi@0: while( startstart && isWhiteSpace(text.charAt(end)) ) aoqi@0: end--; aoqi@0: aoqi@0: if(start==0 && end==len-1) aoqi@0: return text; // no change aoqi@0: else aoqi@0: return text.subSequence(start,end+1); aoqi@0: } aoqi@0: aoqi@0: public static String collapse(String text) { aoqi@0: return collapse( (CharSequence)text ).toString(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * This is usually the biggest processing bottleneck. aoqi@0: * aoqi@0: * @since 2.0 aoqi@0: */ aoqi@0: public static CharSequence collapse(CharSequence text) { aoqi@0: int len = text.length(); aoqi@0: aoqi@0: // most of the texts are already in the collapsed form. aoqi@0: // so look for the first whitespace in the hope that we will aoqi@0: // never see it. aoqi@0: int s=0; aoqi@0: while(s 0 && result.charAt(len - 1) == ' ') aoqi@0: result.setLength(len - 1); aoqi@0: // whitespaces are already collapsed, aoqi@0: // so all we have to do is to remove the last one character aoqi@0: // if it's a whitespace. aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns true if the specified string is all whitespace. aoqi@0: */ aoqi@0: public static boolean isWhiteSpace(CharSequence s) { aoqi@0: for( int i=s.length()-1; i>=0; i-- ) aoqi@0: if(!isWhiteSpace(s.charAt(i))) aoqi@0: return false; aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: /** returns true if the specified char is a white space character. */ aoqi@0: public static boolean isWhiteSpace(char ch) { aoqi@0: // most of the characters are non-control characters. aoqi@0: // so check that first to quickly return false for most of the cases. aoqi@0: if( ch>0x20 ) return false; aoqi@0: aoqi@0: // other than we have to do four comparisons. aoqi@0: return ch == 0x9 || ch == 0xA || ch == 0xD || ch == 0x20; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns true if the specified char is a white space character aoqi@0: * but not 0x20. aoqi@0: */ aoqi@0: protected static boolean isWhiteSpaceExceptSpace(char ch) { aoqi@0: // most of the characters are non-control characters. aoqi@0: // so check that first to quickly return false for most of the cases. aoqi@0: if( ch>=0x20 ) return false; aoqi@0: aoqi@0: // other than we have to do four comparisons. aoqi@0: return ch == 0x9 || ch == 0xA || ch == 0xD; aoqi@0: } aoqi@0: }