com.puppycrawl.tools.checkstyle.XmlLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of checkstyle Show documentation
Show all versions of checkstyle Show documentation
Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
/**
* Contains the common implementation of a loader, for loading a configuration
* from an XML file.
*
* The error handling policy can be described as being austere, dead set,
* disciplinary, dour, draconian, exacting, firm, forbidding, grim, hard, hard-
* boiled, harsh, harsh, in line, iron-fisted, no-nonsense, oppressive,
* persnickety, picky, prudish, punctilious, puritanical, rigid, rigorous,
* scrupulous, set, severe, square, stern, stickler, straight, strait-laced,
* stringent, stuffy, stuffy, tough, unpermissive, unsparing and uptight.
*
*
* @noinspection ThisEscapedInObjectConstruction
*/
public class XmlLoader
extends DefaultHandler {
/** Maps public id to resolve to resource name for the DTD. */
private final Map publicIdToResourceNameMap;
/** Parser to read XML files. **/
private final XMLReader parser;
/**
* Creates a new instance.
* @param publicId the public ID for the DTD to resolve
* @param dtdResourceName the resource for the DTD
* @throws SAXException if an error occurs
* @throws ParserConfigurationException if an error occurs
*/
protected XmlLoader(String publicId, String dtdResourceName)
throws SAXException, ParserConfigurationException {
this(new HashMap<>(1));
publicIdToResourceNameMap.put(publicId, dtdResourceName);
}
/**
* Creates a new instance.
* @param publicIdToResourceNameMap maps public IDs to DTD resource names
* @throws SAXException if an error occurs
* @throws ParserConfigurationException if an error occurs
*/
protected XmlLoader(Map publicIdToResourceNameMap)
throws SAXException, ParserConfigurationException {
this.publicIdToResourceNameMap = new HashMap<>(publicIdToResourceNameMap);
final SAXParserFactory factory = SAXParserFactory.newInstance();
FeaturesForVerySecureJavaInstallations.addFeaturesForVerySecureJavaInstallations(factory);
factory.setValidating(true);
factory.setNamespaceAware(true);
parser = factory.newSAXParser().getXMLReader();
parser.setContentHandler(this);
parser.setEntityResolver(this);
parser.setErrorHandler(this);
}
/**
* Parses the specified input source.
* @param inputSource the input source to parse.
* @throws IOException if an error occurs
* @throws SAXException in an error occurs
*/
public void parseInputSource(InputSource inputSource)
throws IOException, SAXException {
parser.parse(inputSource);
}
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
final InputSource inputSource;
if (publicIdToResourceNameMap.keySet().contains(publicId)) {
final String dtdResourceName =
publicIdToResourceNameMap.get(publicId);
final ClassLoader loader =
getClass().getClassLoader();
final InputStream dtdIs =
loader.getResourceAsStream(dtdResourceName);
inputSource = new InputSource(dtdIs);
}
else {
inputSource = super.resolveEntity(publicId, systemId);
}
return inputSource;
}
@Override
public void error(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
throw exception;
}
/**
* Used for setting specific for secure java installations features to SAXParserFactory.
* Pulled out as a separate class in order to suppress Pitest mutations.
*/
public static final class FeaturesForVerySecureJavaInstallations {
/** Feature that enables loading external DTD when loading XML files. */
private static final String LOAD_EXTERNAL_DTD =
"http://apache.org/xml/features/nonvalidating/load-external-dtd";
/** Feature that enables including external general entities in XML files. */
private static final String EXTERNAL_GENERAL_ENTITIES =
"http://xml.org/sax/features/external-general-entities";
/** Stop instances being created. **/
private FeaturesForVerySecureJavaInstallations() {
}
/**
* Configures SAXParserFactory with features required
* for execution on very secured environments.
* @param factory factory to be configured with special features
* @throws SAXException if an error occurs
* @throws ParserConfigurationException if an error occurs
*/
public static void addFeaturesForVerySecureJavaInstallations(SAXParserFactory factory)
throws SAXException, ParserConfigurationException {
factory.setFeature(LOAD_EXTERNAL_DTD, true);
factory.setFeature(EXTERNAL_GENERAL_ENTITIES, true);
}
}
}