/* * Copyright (c) 2014 the original author or authors * * 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 io.werval.modules.xml.internal; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.validation.Schema; import io.werval.modules.xml.SAX; import io.werval.modules.xml.UncheckedXMLException; import static io.werval.modules.xml.internal.Internal.LOG; /** * DocumentBuilderFactory implementation for XMLPlugin. * <p> * Factory API that enables applications to obtain a parser that produces DOM object trees from XML documents. * * @see DocumentBuilderFactory */ public final class DocumentBuilderFactoryImpl extends DocumentBuilderFactory { // Xerces private final DocumentBuilderFactory delegate = new org.apache.xerces.jaxp.DocumentBuilderFactoryImpl(); public DocumentBuilderFactoryImpl() throws ParserConfigurationException { super(); delegate.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true ); delegate.setFeature( SAX.Features.EXTERNAL_GENERAL_ENTITIES, Internal.EXTERNAL_ENTITIES.get() ); delegate.setFeature( SAX.Features.EXTERNAL_PARAMETER_ENTITIES, Internal.EXTERNAL_ENTITIES.get() ); try { delegate.setAttribute( XMLConstants.ACCESS_EXTERNAL_DTD, Internal.EXTERNAL_ENTITIES.get() ? Internal.ACCESS_EXTERNAL_ALL : Internal.ACCESS_EXTERNAL_NONE ); } catch( IllegalArgumentException ex ) { LOG.trace( "JAXP<1.5 - {} on {}", ex.getMessage(), delegate ); } try { delegate.setAttribute( XMLConstants.ACCESS_EXTERNAL_SCHEMA, Internal.EXTERNAL_ENTITIES.get() ? Internal.ACCESS_EXTERNAL_ALL : Internal.ACCESS_EXTERNAL_NONE ); } catch( IllegalArgumentException ex ) { LOG.trace( "JAXP<1.5 - {} on {}", ex.getMessage(), delegate ); } setValidating( false ); // No support but should be disabled anyway, belt'n braces delegate.setXIncludeAware( false ); } @Override public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { DocumentBuilder docBuilder = delegate.newDocumentBuilder(); docBuilder.setEntityResolver( Internal.RESOLVER.get() ); docBuilder.setErrorHandler( Errors.INSTANCE ); return docBuilder; } @Override public void setNamespaceAware( boolean awareness ) { delegate.setNamespaceAware( awareness ); } @Override public void setValidating( boolean dtdValidation ) { try { // Xerces delegate.setFeature( "http://apache.org/xml/features/validation/balance-syntax-trees", dtdValidation ); delegate.setFeature( "http://apache.org/xml/features/nonvalidating/load-dtd-grammar", dtdValidation ); delegate.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", dtdValidation && Internal.EXTERNAL_ENTITIES.get() ); delegate.setFeature( "http://apache.org/xml/features/disallow-doctype-decl", !dtdValidation ); } catch( ParserConfigurationException ex ) { throw new UncheckedXMLException( ex ); } delegate.setValidating( dtdValidation ); if( dtdValidation ) { LOG.warn( "DocumentBuilderFactory.setValidating( true ) Unsafe DTD support enabled" ); } } @Override public void setIgnoringElementContentWhitespace( boolean whitespace ) { delegate.setIgnoringElementContentWhitespace( whitespace ); } @Override public void setExpandEntityReferences( boolean expandEntityRef ) { delegate.setExpandEntityReferences( expandEntityRef ); } @Override public void setIgnoringComments( boolean ignoreComments ) { delegate.setIgnoringComments( ignoreComments ); } @Override public void setCoalescing( boolean coalescing ) { delegate.setCoalescing( coalescing ); } @Override public boolean isNamespaceAware() { return delegate.isNamespaceAware(); } @Override public boolean isValidating() { return delegate.isValidating(); } @Override public boolean isIgnoringElementContentWhitespace() { return delegate.isIgnoringElementContentWhitespace(); } @Override public boolean isExpandEntityReferences() { return delegate.isExpandEntityReferences(); } @Override public boolean isIgnoringComments() { return delegate.isIgnoringComments(); } @Override public boolean isCoalescing() { return delegate.isCoalescing(); } @Override public void setAttribute( String name, Object value ) throws IllegalArgumentException { delegate.setAttribute( name, value ); } @Override public Object getAttribute( String name ) throws IllegalArgumentException { return delegate.getAttribute( name ); } @Override public void setFeature( String name, boolean value ) throws ParserConfigurationException { delegate.setFeature( name, value ); } @Override public boolean getFeature( String name ) throws ParserConfigurationException { return delegate.getFeature( name ); } @Override public Schema getSchema() { return delegate.getSchema(); } @Override public void setSchema( Schema schema ) { delegate.setSchema( schema ); } @Override public void setXIncludeAware( boolean state ) { delegate.setXIncludeAware( state ); } @Override public boolean isXIncludeAware() { return delegate.isXIncludeAware(); } }