/* * @(#)$Id: WhiteSpaceProcessor.java,v 1.17 2001/10/08 23:58:38 Bear Exp $ * * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * * This software is the proprietary information of Sun Microsystems, Inc. * Use is subject to license terms. * */ package com.sun.msv.datatype.xsd; import java.io.Serializable; import java.io.InvalidObjectException; import org.relaxng.datatype.DatatypeException; /** * processes white space normalization * * @author <a href="mailto:kohsuke.kawaguchi@eng.sun.com">Kohsuke KAWAGUCHI</a> */ public abstract class WhiteSpaceProcessor implements Serializable { /** * returns whitespace normalized text. * behavior varies on what normalization mode is used. */ public abstract String process( String text ); /** higher return value indicates tigher constraint */ abstract int tightness(); /** * gets the name of the white space processing mode. * It is one of "preserve","collapse", or "replace". */ public abstract String getName(); /** * returns a WhiteSpaceProcessor object if "whiteSpace" facet is specified. * Otherwise returns null. */ protected static WhiteSpaceProcessor get( String name ) throws DatatypeException { name = theCollapse.process(name); if( name.equals("preserve") ) return thePreserve; if( name.equals("collapse") ) return theCollapse; if( name.equals("replace") ) return theReplace; throw new DatatypeException( XSDatatypeImpl.localize( XSDatatypeImpl.ERR_INVALID_WHITESPACE_VALUE, name )); } /** returns true if the specified char is a white space character. */ protected static final boolean isWhiteSpace( char ch ) { return ch==0x9 || ch==0xA || ch==0xD || ch==0x20; } protected Object readResolve() throws InvalidObjectException { // return the singleton instead of deserialized object. try { return get(getName()); } catch( DatatypeException bte ) { throw new InvalidObjectException("Unknown Processing Mode"); } } // short-cut methods public static String replace( String str ) { return theReplace.process(str); } public static String collapse( String str ) { return theCollapse.process(str); } /* Actual processor implementation */ public final static WhiteSpaceProcessor thePreserve = new WhiteSpaceProcessor() { public String process( String text ) { return text; } int tightness() { return 0; } public String getName() { return "preserve"; } }; public final static WhiteSpaceProcessor theReplace = new WhiteSpaceProcessor() { public String process( String text ) { final int len = text.length(); StringBuffer result = new StringBuffer(len); for( int i=0; i<len; i++ ) { char ch = text.charAt(i); if( super.isWhiteSpace(ch) ) result.append(' '); else result.append(ch); } return result.toString(); } int tightness() { return 1; } public String getName() { return "replace"; } }; public final static WhiteSpaceProcessor theCollapse= new WhiteSpaceProcessor() { public String process( String text ) { int len = text.length(); StringBuffer result = new StringBuffer(len /**enough size*/ ); boolean inStripMode = true; for( int i=0; i<len; i++ ) { char ch = text.charAt(i); boolean b = WhiteSpaceProcessor.isWhiteSpace(ch); if( inStripMode && b ) continue; // skip this character inStripMode = b; if( inStripMode ) result.append(' '); else result.append(ch); } // remove trailing whitespaces len = result.length(); if( len>0 && result.charAt(len-1)==' ' ) result.setLength(len-1); // whitespaces are already collapsed, // so all we have to do is to remove the last one character // if it's a whitespace. return result.toString(); } int tightness() { return 2; } public String getName() { return "collapse"; } }; }