Project

General

Profile

1
package eu.dnetlib.miscutils.functional.xml;
2

    
3
import java.io.*;
4
import javax.xml.parsers.DocumentBuilder;
5
import javax.xml.parsers.DocumentBuilderFactory;
6
import javax.xml.parsers.ParserConfigurationException;
7
import javax.xml.transform.*;
8
import javax.xml.transform.dom.DOMResult;
9
import javax.xml.transform.dom.DOMSource;
10
import javax.xml.transform.stream.StreamResult;
11

    
12
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
13
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
14
import eu.dnetlib.miscutils.functional.UnaryFunction;
15
import org.w3c.dom.Document;
16
import org.xml.sax.InputSource;
17
import org.xml.sax.SAXException;
18

    
19
/**
20
 * The Class IndentXmlString.
21
 */
22
public class IndentXmlString implements UnaryFunction<String, String> {
23

    
24
	/*
25
	 * (non-Javadoc)
26
	 * 
27
	 * @see eu.dnetlib.miscutils.functional.UnaryFunction#evaluate(java.lang.Object)
28
	 */
29
	@Override
30
	public String evaluate(final String unformattedXml) {
31
		try {
32
			return doIndent(unformattedXml);
33
		} catch (IOException e) {
34
			throw new RuntimeException(e);
35
		}
36
	}
37

    
38
	/**
39
	 * Do indent.
40
	 * 
41
	 * @param unformattedXml
42
	 *            the unformatted xml
43
	 * @return the string
44
	 * @throws IOException
45
	 *             Signals that an I/O exception has occurred.
46
	 */
47
	protected String doIndent(final String unformattedXml) throws IOException {
48
		final Document document = parseXmlString(unformattedXml);
49

    
50
		OutputFormat format = new OutputFormat(document);
51
		format.setIndenting(true);
52
		format.setIndent(2);
53
		Writer out = new StringWriter();
54
		XMLSerializer serializer = new XMLSerializer(out, format);
55
		serializer.serialize(document);
56

    
57
		return out.toString();
58
	}
59

    
60
	/**
61
	 * Parses the xml string.
62
	 * 
63
	 * @param in
64
	 *            the in
65
	 * @return the document
66
	 */
67
	protected Document parseXmlString(final String in) {
68
		try {
69
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
70
			DocumentBuilder db = dbf.newDocumentBuilder();
71
			db.setErrorHandler(null);
72
			InputSource is = new InputSource(new StringReader(in));
73
			return db.parse(is);
74
		} catch (ParserConfigurationException e) {
75
			throw new RuntimeException(e);
76
		} catch (SAXException e) {
77
			throw new RuntimeException(e);
78
		} catch (IOException e) {
79
			throw new RuntimeException(e);
80
		}
81
	}
82

    
83
	private String doIndent(final Document document) throws TransformerException, UnsupportedEncodingException {
84

    
85
		final Transformer transformer = getTransformer();
86
		final ByteArrayOutputStream out = new ByteArrayOutputStream();
87
		transformer.transform(new DOMSource(document), new StreamResult(out));
88

    
89
		return out.toString("utf-8");
90
	}
91

    
92
	private Transformer getTransformer() throws TransformerConfigurationException {
93
		TransformerFactory tf = TransformerFactory.newInstance();
94
		Transformer transformer = tf.newTransformer();
95
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
96
		transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
97
		transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
98
		return transformer;
99
	}
100

    
101
	private Document doIndentDocument(final Document document) throws TransformerException, UnsupportedEncodingException {
102

    
103
		final Transformer transformer = getTransformer();
104

    
105
		final DOMResult out = new DOMResult();
106
		transformer.transform(new DOMSource(document), out);
107

    
108
		return (Document) out.getNode();
109
	}
110

    
111
	/**
112
	 * Static helper Apply.
113
	 * 
114
	 * @param xml
115
	 *            the xml
116
	 * @return the indented xml string
117
	 */
118
	public static String apply(final String xml) {
119
		return new IndentXmlString().evaluate(xml);
120
	}
121

    
122
	/**
123
	 * Static helper Apply.
124
	 *
125
	 * @param xml
126
	 *            the xml
127
	 * @return the indented xml string
128
	 */
129
	public static Document apply(final Document xml) throws TransformerException, UnsupportedEncodingException {
130
		return new IndentXmlString().doIndentDocument(xml);
131
	}
132

    
133
}
(6-6/8)