com.crabshue.commons.xml.XmlDocumentBuilder Maven / Gradle / Ivy
package com.crabshue.commons.xml;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.crabshue.commons.exceptions.ApplicationException;
import com.crabshue.commons.exceptions.SystemException;
import com.crabshue.commons.xml.error.XmlErrorHandler;
import com.crabshue.commons.xml.exceptions.XmlErrorType;
import com.crabshue.commons.xml.inputsource.InputSourceBuilder;
import lombok.NonNull;
import net.sf.saxon.lib.StandardEntityResolver;
/**
* {@link Document} builder from various XML document sources.
*
* Default options for {@link DocumentBuilderFactory} are:
*
*
* - namespaceAware: true
* - validating: false
*
*
* Default {@link ErrorHandler} for {@link DocumentBuilder}: {@link XmlErrorHandler}.
*
*
*/
public class XmlDocumentBuilder {
private InputSource inputSource;
private boolean namespaceAware = true;
private boolean validationEnabled = false;
private ErrorHandler errorHandler = new XmlErrorHandler();
private EntityResolver entityResolver = new StandardEntityResolver();
/**
* Start a {@link XmlDocumentBuilder} based on a {@link InputSource}.
*
* @param inputSource the XML input source.
* @return a new instance of {@link XmlDocumentBuilder}
*/
public static XmlDocumentBuilder of(@NonNull final InputSource inputSource) {
final XmlDocumentBuilder ret = new XmlDocumentBuilder();
ret.inputSource = inputSource;
return ret;
}
/**
* Start a {@link XmlDocumentBuilder} based on an {@link File XML file}.
*
* @param xmlFile the XML file.
* @return a new instance of {@link XmlDocumentBuilder}
*/
public static XmlDocumentBuilder of(@NonNull final File xmlFile) {
return XmlDocumentBuilder.of(InputSourceBuilder.newInputSource(xmlFile));
}
/**
* Start a {@link XmlDocumentBuilder} based on an {@link String XML as a string}.
*
* @param xmlAsString the XML file.
* @return a new instance of {@link XmlDocumentBuilder}
*/
public static XmlDocumentBuilder of(@NonNull final String xmlAsString) {
return XmlDocumentBuilder.of(InputSourceBuilder.newInputSource(xmlAsString));
}
/**
* Set option {@code namespaceAware} of {@link DocumentBuilderFactory}.
*
* @param namespaceAware toggle namespace awareness.
* @return the current {@link XmlDocumentBuilder} instance
*/
public XmlDocumentBuilder withNamespaceAwareness(@NonNull final boolean namespaceAware) {
this.namespaceAware = namespaceAware;
return this;
}
/**
* Set option {@code validating} of {@link DocumentBuilderFactory}.
*
* @param validationEnabled toggle validation.
* @return the current {@link XmlDocumentBuilder} instance
*/
public XmlDocumentBuilder withValidationEnabled(@NonNull final boolean validationEnabled) {
this.validationEnabled = validationEnabled;
return this;
}
/**
* Set {@link ErrorHandler}.
*
* @param errorHandler the error handler.
* @return the current {@link XmlDocumentBuilder} instance
*/
public XmlDocumentBuilder withErrorHandler(@NonNull final ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
return this;
}
public XmlDocumentBuilder withEntityResolver(@NonNull final EntityResolver entityResolver) {
this.entityResolver = entityResolver;
return this;
}
/**
* Build the {@link Document XML document}.
*
* @return the built XML document.
*/
public Document build() {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(this.namespaceAware);
dbf.setValidating(this.validationEnabled);
final DocumentBuilder documentBuilder;
try {
documentBuilder = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new SystemException(XmlErrorType.DOCUMENT_BUILDER_INITIALIZATION_ISSUE, e);
}
documentBuilder.setErrorHandler(this.errorHandler);
documentBuilder.setEntityResolver(this.entityResolver);
final Document ret;
try {
ret = documentBuilder.parse(this.inputSource);
} catch (SAXException e) {
throw new ApplicationException(XmlErrorType.ERROR_PARSING_XML, e);
} catch (IOException e) {
throw new SystemException(XmlErrorType.ERROR_PARSING_XML, e);
}
return ret;
}
private XmlDocumentBuilder() {
}
}