001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * @(#)$Id: WhitespaceStripper.java,v 1.2 2005/04/29 19:56:57 kohsuke Exp $
028: */
029:
030: package com.sun.tools.internal.xjc.reader.internalizer;
031:
032: import com.sun.xml.internal.bind.WhiteSpaceProcessor;
033:
034: import org.xml.sax.Attributes;
035: import org.xml.sax.ContentHandler;
036: import org.xml.sax.EntityResolver;
037: import org.xml.sax.ErrorHandler;
038: import org.xml.sax.SAXException;
039: import org.xml.sax.XMLReader;
040: import org.xml.sax.helpers.XMLFilterImpl;
041:
042: /**
043: * Strips ignorable whitespace from SAX event stream.
044: *
045: * <p>
046: * This filter works only when the event stream doesn't
047: * contain any mixed content.
048: *
049: * @author
050: * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
051: */
052: class WhitespaceStripper extends XMLFilterImpl {
053:
054: private int state = 0;
055:
056: private char[] buf = new char[1024];
057: private int bufLen = 0;
058:
059: private static final int AFTER_START_ELEMENT = 1;
060: private static final int AFTER_END_ELEMENT = 2;
061:
062: public WhitespaceStripper(XMLReader reader) {
063: setParent(reader);
064: }
065:
066: public WhitespaceStripper(ContentHandler handler, ErrorHandler eh,
067: EntityResolver er) {
068: setContentHandler(handler);
069: if (eh != null)
070: setErrorHandler(eh);
071: if (er != null)
072: setEntityResolver(er);
073: }
074:
075: public void characters(char[] ch, int start, int length)
076: throws SAXException {
077: switch (state) {
078: case AFTER_START_ELEMENT:
079: // we have to store the characters here, even if it consists entirely
080: // of whitespaces. This is because successive characters event might
081: // include non-whitespace char, in which case all the whitespaces in
082: // this event may suddenly become significant.
083: if (bufLen + length > buf.length) {
084: // reallocate buffer
085: char[] newBuf = new char[Math.max(bufLen + length,
086: buf.length * 2)];
087: System.arraycopy(buf, 0, newBuf, 0, bufLen);
088: buf = newBuf;
089: }
090: System.arraycopy(ch, start, buf, bufLen, length);
091: bufLen += length;
092: break;
093: case AFTER_END_ELEMENT:
094: // check if this is ignorable.
095: int len = start + length;
096: for (int i = start; i < len; i++)
097: if (!WhiteSpaceProcessor.isWhiteSpace(ch[i])) {
098: super .characters(ch, start, length);
099: return;
100: }
101: // if it's entirely whitespace, ignore it.
102: break;
103: }
104: }
105:
106: public void startElement(String uri, String localName,
107: String qName, Attributes atts) throws SAXException {
108: processPendingText();
109: super .startElement(uri, localName, qName, atts);
110: state = AFTER_START_ELEMENT;
111: bufLen = 0;
112: }
113:
114: public void endElement(String uri, String localName, String qName)
115: throws SAXException {
116: processPendingText();
117: super .endElement(uri, localName, qName);
118: state = AFTER_END_ELEMENT;
119: }
120:
121: /**
122: * Forwars the buffered characters if it contains any non-whitespace
123: * character.
124: */
125: private void processPendingText() throws SAXException {
126: if (state == AFTER_START_ELEMENT) {
127: for (int i = bufLen - 1; i >= 0; i--)
128: if (!WhiteSpaceProcessor.isWhiteSpace(buf[i])) {
129: super .characters(buf, 0, bufLen);
130: return;
131: }
132: }
133: }
134:
135: public void ignorableWhitespace(char[] ch, int start, int length)
136: throws SAXException {
137: // ignore completely.
138: }
139: }
|