/*
* © Copyright IBM Corp. 2012
*
* Licensed 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 com.ibm.commons.xml.drivers;
import java.io.InputStream;
import java.io.Reader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSParser;
import org.w3c.dom.ls.LSParserFilter;
import org.w3c.dom.traversal.NodeFilter;
import com.ibm.commons.util.ObjectPool;
import com.ibm.commons.xml.XMLException;
/**
* XERCES driver feturing DOM level 3.
*/
public class XercesDriverL3 extends AbstractXercesDriver {
private DOMImplementationLS domImplementationLS;
private ParserPool parserPool;
private static class ParserPool extends ObjectPool {
private DOMImplementationLS domImplementationLS;
ParserPool(DOMImplementationLS domImplementationLS) {
super(8); // Use a parameter here?
this.domImplementationLS = domImplementationLS;
}
protected Object createObject() throws Exception {
LSParser parser = domImplementationLS.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
return parser;
}
}
// Filter to ignore blanks
private static class BlankFilter implements LSParserFilter {
public short acceptNode(Node node) {
if( node instanceof Text ) {
Text t = (Text)node;
String data = t.getData();
int length = data.length();
int first=0;
for( ; first<length; first++ ) {
char c = data.charAt(first);
if( c!=' ' && c!='\t' && c!='\n' && c!='\r' ) {
return FILTER_ACCEPT;
}
}
return FILTER_SKIP;
}
return FILTER_ACCEPT;
}
public int getWhatToShow() {
return NodeFilter.SHOW_TEXT;
}
public short startElement(Element elt) {
return FILTER_ACCEPT;
}
};
private static BlankFilter BLANK_FILTER = new BlankFilter();
public XercesDriverL3() {
this.domImplementationLS = (DOMImplementationLS)getDOMImplementation();
this.parserPool = new ParserPool(domImplementationLS);
}
private LSParser getParser() throws Exception {
//TODO: Use a cache for the parsers?
LSParser parser = (LSParser)parserPool.get();
return parser;
}
private void recycleParser(LSParser parser) {
parser.setFilter(null);
parserPool.recycle(parser);
}
public Document parse(InputStream is, boolean ignoreBlanks) throws XMLException {
try {
LSParser parser = getParser();
try {
if(ignoreBlanks) {
parser.setFilter(BLANK_FILTER);
}
LSInput ip = domImplementationLS.createLSInput();
ip.setByteStream(is);
Document doc = parser.parse(ip);
return doc;
} finally {
recycleParser(parser);
}
} catch(Exception e) {
throw new XMLException(e,"Error parsing XML input stream"); // $NLS-XercesDriverL3.ErrorwhileparsingXMLinputstream-1$
}
}
public Document parse(Reader reader, boolean ignoreBlanks) throws XMLException {
try {
LSParser parser = getParser();
try {
if(ignoreBlanks) {
parser.setFilter(BLANK_FILTER);
}
LSInput ip = domImplementationLS.createLSInput();
ip.setCharacterStream(reader);
Document doc = parser.parse(ip);
return doc;
} finally {
recycleParser(parser);
}
} catch(Exception e) {
throw new XMLException(e,"Error parsing XML character stream"); // $NLS-XercesDriverL3.ErrorwhileparsingXMLchracterstrea-1$
}
}
/* (non-Javadoc)
* @see com.ibm.commons.xml.drivers.XMLParserDriver#parse(java.io.InputStream, boolean, boolean)
*/
public Document parse(InputStream is, boolean ignoreBlanks, boolean validate) throws XMLException {
// TODO set validate
return parse(is, ignoreBlanks);
}
/* (non-Javadoc)
* @see com.ibm.commons.xml.drivers.XMLParserDriver#parse(java.io.Reader, boolean, boolean)
*/
public Document parse(Reader reader, boolean ignoreBlanks, boolean validate) throws XMLException {
// TODO set validate
return parse(reader, ignoreBlanks);
}
}