blob: 76b8fee23fdd5d4f57bd46c018d2d6a8c946b28d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.xml;
import org.apache.cocoon.xml.AbstractXMLPipe;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
/**
* A SAX filter to remove whitespace character, which disturb the
* XML matching process.
*
* @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
* @version CVS $Id$
*/
public class WhitespaceFilter extends AbstractXMLPipe {
private StringBuffer buffer = null;
/**
* Create a new WhitespaceFilter.
*
* @param handler Content handler.
*/
public WhitespaceFilter(ContentHandler handler) {
setContentHandler(handler);
}
/**
* Receive notification of character data.
*/
public void characters(char c[], int start, int len) throws SAXException {
if (contentHandler==null) {
return;
}
if (buffer==null) {
buffer = new StringBuffer();
}
buffer.append(c, start, len);
}
/**
* Receive notification of ignorable whitespace in element content.
*/
public void ignorableWhitespace(char c[], int start,
int len) throws SAXException {
// ignore
}
/**
* Receive notification of the beginning of an element.
*/
public void startElement(String namespaceURI, String localName,
String qName,
Attributes atts) throws SAXException {
pushText();
contentHandler.startElement(namespaceURI, localName, qName, atts);
}
/**
* Receive notification of the end of an element.
*/
public void endElement(String uri, String loc, String raw)
throws SAXException {
pushText();
contentHandler.endElement(uri, loc, raw);
}
/**
* Receive notification of a processing instruction.
*/
public void processingInstruction(String target, String data)
throws SAXException {
pushText();
contentHandler.processingInstruction(target, data);
}
/**
* Report an XML comment anywhere in the document.
*
* @param ch An array holding the characters in the comment.
* @param start The starting position in the array.
* @param len The number of characters to use from the array.
*/
public void comment(char ch[], int start, int len)
throws SAXException {
pushText();
super.comment(ch, start, len);
}
public void pushText() throws SAXException {
if (buffer!=null) {
String text = buffer.toString();
StringBuffer normalized = new StringBuffer();
for(int i=0; i<text.length(); i++) {
if (Character.isWhitespace(text.charAt(i))) {
normalized.append(' ');
while (((i+1)<text.length()) && (Character.isWhitespace(text.charAt(i+1))))
i++;
} else {
normalized.append(text.charAt(i));
}
}
text = normalized.toString().trim();
if (text.length()>0) {
contentHandler.characters(text.toCharArray(), 0,
text.length());
}
buffer = null;
}
}
}