001/*
002 * #%L
003 * Netarchivesuite - harvester
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023package dk.netarkivet.common.xml;
024
025import java.io.StringWriter;
026
027import javax.xml.parsers.DocumentBuilder;
028import javax.xml.parsers.DocumentBuilderFactory;
029import javax.xml.parsers.ParserConfigurationException;
030import javax.xml.transform.OutputKeys;
031import javax.xml.transform.Transformer;
032import javax.xml.transform.TransformerException;
033import javax.xml.transform.TransformerFactory;
034import javax.xml.transform.dom.DOMSource;
035import javax.xml.transform.stream.StreamResult;
036
037import org.w3c.dom.Document;
038
039public abstract class XmlBuilder {
040    protected final Document xmlDoc;
041    private static DocumentBuilder builder;
042
043    public XmlBuilder() {
044        xmlDoc = getParser().newDocument();
045    }
046
047    public XmlBuilder(Document xmlDoc) {
048        this.xmlDoc = xmlDoc;
049    }
050
051    public org.dom4j.Document getDoc() {
052        org.dom4j.io.DOMReader reader = new org.dom4j.io.DOMReader();
053        return reader.read(xmlDoc);
054    }
055
056    protected static synchronized DocumentBuilder getParser() {
057        if (builder == null) {
058            try {
059                DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
060                documentBuilderFactory.setNamespaceAware(true);
061                builder = documentBuilderFactory.newDocumentBuilder();
062            } catch (ParserConfigurationException e) {
063                throw new RuntimeException(e);
064            }
065        }
066        return builder;
067    }
068
069    /**
070     * Creates a default XmlDoc based on the order.xml file on the classpath.
071     * @return The loaded default XmlDoc.
072     */
073    protected static synchronized Document parseFile(String name) {
074        try {
075            return getParser().parse(XmlBuilder.class.getClassLoader().getResourceAsStream(name));
076        } catch (Exception e) {
077            throw new RuntimeException("Failed to read " +  name + " from path " +
078                    XmlBuilder.class.getClassLoader().getResource(name), e);
079        }
080    }
081
082    @Override
083    public String toString() {
084        try {
085            DOMSource domSource = new DOMSource(xmlDoc);
086            StringWriter writer = new StringWriter();
087            StreamResult result = new StreamResult(writer);
088            TransformerFactory tf = TransformerFactory.newInstance();
089            Transformer transformer = null;
090            transformer = tf.newTransformer();
091            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
092            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
093            transformer.transform(domSource, result);
094            writer.flush();
095            return writer.toString();
096        } catch (TransformerException e) {
097            throw new RuntimeException(e);
098        }
099    }
100}