Clover coverage report - QedeqKernelSe Coverage Report
Coverage timestamp: Do Jan 11 2007 09:03:50 CET
file stats: LOC: 290   Methods: 8
NCLOC: 165   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
SaxParser.java 45% 74,1% 75% 68,8%
coverage coverage
 1    /* $Id: SaxParser.java,v 1.13 2006/10/20 20:23:04 m31 Exp $
 2    *
 3    * This file is part of the project "Hilbert II" - http://www.qedeq.org
 4    *
 5    * Copyright 2000-2006, Michael Meyling <mime@qedeq.org>.
 6    *
 7    * "Hilbert II" is free software; you can redistribute
 8    * it and/or modify it under the terms of the GNU General Public
 9    * License as published by the Free Software Foundation; either
 10    * version 2 of the License, or (at your option) any later version.
 11    *
 12    * This program is distributed in the hope that it will be useful,
 13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15    * GNU General Public License for more details.
 16    */
 17    package org.qedeq.kernel.xml.parser;
 18   
 19    import java.io.BufferedReader;
 20    import java.io.File;
 21    import java.io.IOException;
 22    import java.io.InputStream;
 23    import java.io.InputStreamReader;
 24    import java.net.URL;
 25   
 26    import javax.xml.parsers.ParserConfigurationException;
 27    import javax.xml.parsers.SAXParser;
 28    import javax.xml.parsers.SAXParserFactory;
 29   
 30    import org.qedeq.kernel.log.Trace;
 31    import org.xml.sax.InputSource;
 32    import org.xml.sax.SAXException;
 33    import org.xml.sax.SAXNotRecognizedException;
 34    import org.xml.sax.XMLReader;
 35    import org.xml.sax.helpers.DefaultHandler;
 36   
 37   
 38    /**
 39    * Parser for XML files. This class uses features specific for Xerces.
 40    *
 41    * @version $Revision: 1.13 $
 42    * @author Michael Meyling
 43    */
 44    public final class SaxParser {
 45   
 46    /** Namespaces feature id (http://xml.org/sax/features/namespaces). */
 47    private static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
 48   
 49    /** Validation feature id (http://xml.org/sax/features/validation). */
 50    private static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
 51   
 52    /** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
 53    private static final String SCHEMA_VALIDATION_FEATURE_ID
 54    = "http://apache.org/xml/features/validation/schema";
 55   
 56    /** Schema full checking feature id
 57    * (http://apache.org/xml/features/validation/schema-full-checking). */
 58    protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID
 59    = "http://apache.org/xml/features/validation/schema-full-checking";
 60   
 61    /** Handler which deals with the XML contents. */
 62    private SaxDefaultHandler handler;
 63   
 64    /** SAX parser. */
 65    private XMLReader reader;
 66   
 67    /** Default handler for validation purpose only. */
 68    private final DefaultHandler deflt;
 69   
 70    /** Saved errors of parsing. */
 71    private ExceptionList exceptionList;
 72   
 73    /**
 74    * Constructor.
 75    *
 76    * @param handler Default handler for this application.
 77    * @throws ParserConfigurationException Severe parser configuration problem.
 78    * @throws SAXException
 79    */
 80  110 public SaxParser(final SaxDefaultHandler handler) throws ParserConfigurationException,
 81    SAXException {
 82  110 super();
 83   
 84  110 this.handler = handler;
 85  110 this.deflt = new DefaultHandler();
 86   
 87  110 final String factoryImpl = System.getProperty("javax.xml.parsers.SAXParserFactory");
 88  110 if (factoryImpl == null) {
 89  1 System.setProperty("javax.xml.parsers.SAXParserFactory",
 90    "org.apache.xerces.jaxp.SAXParserFactoryImpl");
 91    }
 92  110 SAXParserFactory factory = SAXParserFactory.newInstance();
 93  110 factory.setNamespaceAware(true);
 94  110 factory.setValidating(true);
 95   
 96  110 factory.setFeature(NAMESPACES_FEATURE_ID, true);
 97  110 factory.setFeature(VALIDATION_FEATURE_ID, true);
 98  110 try {
 99  110 factory.setFeature(SCHEMA_VALIDATION_FEATURE_ID, true);
 100    } catch (SAXNotRecognizedException e) {
 101  0 Trace.trace(this, "constructor", e);
 102    // ignore
 103    }
 104  110 try {
 105  110 factory.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true);
 106    } catch (SAXNotRecognizedException e) {
 107  0 Trace.trace(this, "constructor", e);
 108    // ignore
 109    }
 110   
 111  110 final SAXParser parser = factory.newSAXParser();
 112  110 if (!parser.isNamespaceAware()) {
 113  0 throw new ParserConfigurationException(
 114    "Current XML parser doesn't support namespaces.");
 115    }
 116  110 if (!parser.isValidating()) {
 117  0 throw new ParserConfigurationException(
 118    "Current XML parser doesn't support schema validation.");
 119    }
 120   
 121  110 reader = parser.getXMLReader();
 122  110 reader.setEntityResolver(new SaxEntityResolver());
 123   
 124    // set parser features
 125  110 reader.setFeature(NAMESPACES_FEATURE_ID, true);
 126  110 reader.setFeature(VALIDATION_FEATURE_ID, true);
 127  110 try {
 128  110 reader.setFeature(SCHEMA_VALIDATION_FEATURE_ID, true);
 129    } catch (SAXNotRecognizedException e) {
 130  0 Trace.trace(this, "constructor", e);
 131    // ignore
 132    }
 133  110 try {
 134  110 reader.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true);
 135    } catch (SAXNotRecognizedException e) {
 136  0 Trace.trace(this, "constructor", e);
 137    // ignore
 138    }
 139    }
 140   
 141    /**
 142    * Parse input source.
 143    *
 144    * @param url Parse data from this source.
 145    * @param validateOnly validate with {@link #deflt} or parse with {@link #handler}.
 146    * @throws SAXException Syntactical or semantical problem occurred.
 147    * @throws IOException Technical problem occurred.
 148    */
 149  216 private void parse(final URL url, final boolean validateOnly)
 150    throws SAXException, IOException {
 151  216 final String method = "parse(URL, boolean)";
 152  216 Trace.param(this, method, "url", url);
 153   
 154  216 InputStream in = null;
 155  216 try {
 156  216 in = url.openStream();
 157  216 parse(url, validateOnly, in);
 158    } catch (SAXException e) {
 159  0 Trace.trace(this, "parse", e);
 160  0 if (exceptionList.size() == 0) { // should not occur, exception must be already here
 161  0 exceptionList.add(e);
 162    }
 163    } finally {
 164  216 if (in != null) {
 165  216 try {
 166  216 in.close();
 167    } catch (Exception e) {
 168  0 Trace.trace(this, method, e);
 169    }
 170    }
 171    }
 172  216 if (exceptionList.size() > 0) {
 173  0 throw new SAXException(exceptionList.toString(), (Exception) exceptionList.get(0));
 174    }
 175    }
 176   
 177    /**
 178    * Parse input source.
 179    *
 180    * @param url Source URL. Only for information.
 181    * @param validateOnly validate with {@link #deflt} or parse with {@link #handler}.
 182    * @param in Parse data from this source.
 183    * @throws SAXException Syntactical or semantical problem occurred.
 184    * @throws IOException Technical problem occurred.
 185    */
 186  216 private void parse(final URL url, final boolean validateOnly, final InputStream in)
 187    throws IOException, SAXException {
 188  216 final String method = "parse(URL, boolean, InputStream)";
 189  216 BufferedReader dis = null;
 190  216 try {
 191  216 dis = new BufferedReader(new InputStreamReader(in));
 192  216 final InputSource input = new InputSource(dis);
 193  216 exceptionList = new ExceptionList();
 194  216 reader.setErrorHandler(new SaxErrorHandler(url, exceptionList));
 195  216 if (validateOnly) {
 196  108 reader.setContentHandler(deflt);
 197  108 reader.parse(input);
 198    } else {
 199  108 handler.setExceptionList(exceptionList);
 200  108 reader.setContentHandler(handler);
 201  108 handler.setUrl(url);
 202  108 reader.parse(input);
 203    }
 204    } finally {
 205  216 if (dis != null) {
 206  216 try {
 207  216 dis.close();
 208    } catch (Exception e) {
 209  0 Trace.trace(this, method, e);
 210    }
 211    }
 212    }
 213    }
 214   
 215    /**
 216    * Parses XML file.
 217    *
 218    * @param fileName File name.
 219    * @throws SAXException Syntactical or semantical problem occurred.
 220    * @throws IOException Technical problem occurred.
 221    */
 222  2 public final void parse(final String fileName) throws SAXException,
 223    IOException {
 224  2 final File file = new File(fileName);
 225  2 parse(file.getAbsoluteFile());
 226    }
 227   
 228    /**
 229    * Parses the XML file.
 230    *
 231    * @param file File to parse.
 232    * @throws SAXException Syntactical or semantical problem occurred.
 233    * @throws IOException Technical problem occurred.
 234    */
 235  27 public final void parse(final File file) throws SAXException,
 236    IOException {
 237  27 final URL url = file.getAbsoluteFile().toURI().toURL();
 238  27 parse(url, true);
 239  27 parse(url, false);
 240    }
 241   
 242    /**
 243    * Parses the XML file.
 244    *
 245    * @param url URL with File to parse.
 246    * @throws SAXException Syntactical or semantical problem occurred.
 247    * @throws IOException Technical problem occurred.
 248    */
 249  81 public final void parse(final URL url) throws SAXException,
 250    IOException {
 251  81 parse(url, true);
 252  81 parse(url, false);
 253    }
 254   
 255    /**
 256    * Parse input source.
 257    *
 258    * @param in Parse data from this source.
 259    * @param validateOnly Validate or parse with handler.
 260    * @throws SAXException Syntactical or semantical problem occurred.
 261    * @throws IOException Technical problem occurred.
 262    */
 263  0 public void parse(final InputStream in, final boolean validateOnly)
 264    throws SAXException, IOException {
 265  0 final String method = "parse(InputStream, boolean)";
 266   
 267    // validateOnly validate with {@link #deflt} or parse with {@link #handler}.
 268  0 try {
 269  0 parse(null, validateOnly, in);
 270    } catch (SAXException e) {
 271  0 Trace.trace(this, method, e);
 272  0 if (exceptionList.size() == 0) { // should not occur, exception must be already here
 273  0 exceptionList.add(e);
 274    }
 275    }
 276  0 if (exceptionList.size() > 0) {
 277  0 throw new SAXException(exceptionList.toString(), (Exception) exceptionList.get(0));
 278    }
 279    }
 280   
 281    /**
 282    * Get errors that occurred during last parsing.
 283    *
 284    * @return List with collected Exceptions.
 285    */
 286  0 public ExceptionList getExceptionList() {
 287  0 return exceptionList;
 288    }
 289   
 290    }