/******************************************************************************* * Copyright (c) 2004, 2008 John Krasnay and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * John Krasnay - initial API and implementation *******************************************************************************/ package net.sf.vex.dom; import java.io.CharArrayReader; import java.io.IOException; import java.io.Reader; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.URL; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.ContentHandler; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.ext.LexicalHandler; /** * Class for creating documents given a URL. */ public class DocumentReader { /** * Returns the debugging flag. */ public boolean isDebugging() { return debugging; } /** * Returns the entity resolver for this reader. */ public EntityResolver getEntityResolver() { return entityResolver; } /** * Returns the whitespace policy factory for this reader. */ public IWhitespacePolicyFactory getWhitespacePolicyFactory() { return whitespacePolicyFactory; } /** * Reads a document given a URL. * * @param url URL from which to load the document. */ public Document read(URL url) throws IOException, ParserConfigurationException, SAXException { return read(new InputSource(url.toString())); } /** * Reads a document from a string. This is mainly used for short documents * in unit tests. * @param s String containing the document to be read. */ public Document read(String s) throws IOException, ParserConfigurationException, SAXException { Reader reader = new CharArrayReader(s.toCharArray()); return this.read(new InputSource(reader)); } /** * Reads a document given a SAX InputSource. * * @param is SAX InputSource from which to load the document. */ public Document read(InputSource is) throws IOException, ParserConfigurationException, SAXException { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(false); // TODO: experimental--SWT implementation XMLReader xmlReader = factory.newSAXParser().getXMLReader(); // XXX validation ausgeschaltet, cp xmlReader.setFeature("http://xml.org/sax/features/validation", false); final net.sf.vex.dom.DocumentBuilder builder = new net.sf.vex.dom.DocumentBuilder(this.getWhitespacePolicyFactory()); ContentHandler contentHandler = builder; LexicalHandler lexicalHandler = builder; if (this.isDebugging()) { Object proxy = Proxy.newProxyInstance( this.getClass().getClassLoader(), new Class[] { ContentHandler.class, LexicalHandler.class }, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { return method.invoke(builder, args); } catch (InvocationTargetException ex) { ex.getCause().printStackTrace(); throw ex.getCause(); } } }); contentHandler = (ContentHandler) proxy; lexicalHandler = (LexicalHandler) proxy; } xmlReader.setContentHandler(contentHandler); xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", lexicalHandler); if (this.getEntityResolver() != null) { xmlReader.setEntityResolver(this.getEntityResolver()); } xmlReader.parse(is); return builder.getDocument(); } /** * Sets the debugging flag. * @param debugging true if the component should log debugging info to stdout. */ public void setDebugging(boolean debugging) { this.debugging = debugging; } /** * Sets the entity resolver for this reader. * @param entityResolver The entityResolver to set. */ public void setEntityResolver(EntityResolver entityResolver) { this.entityResolver = entityResolver; } /** * Sets the whitespace policy factory for this reader. This factory is used * to obtain a whitespace policy once the public ID of the document is * known. * @param whitespacePolicyFactory The whitespacePolicyFactory to set. */ public void setWhitespacePolicyFactory( IWhitespacePolicyFactory whitespacePolicyFactory) { this.whitespacePolicyFactory = whitespacePolicyFactory; } //======================================================= PRIVATE private boolean debugging; private EntityResolver entityResolver; private IWhitespacePolicyFactory whitespacePolicyFactory; }