1
2
3
4
5
6
7
8 package au.com.acegi.xmlformat;
9
10 import static java.io.File.createTempFile;
11 import static java.nio.file.Files.copy;
12 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
13
14 import static au.com.acegi.xmlformat.IOUtil.hash;
15
16 import java.io.File;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.io.StringReader;
21 import java.io.UnsupportedEncodingException;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24
25 import org.dom4j.Document;
26 import org.dom4j.DocumentException;
27 import org.dom4j.io.SAXReader;
28 import org.dom4j.io.XMLWriter;
29 import org.xml.sax.EntityResolver;
30 import org.xml.sax.InputSource;
31 import org.xml.sax.SAXException;
32
33
34
35
36 final class FormatUtil {
37
38 private static final String TMP_FILE_PREFIX = FormatUtil.class.getSimpleName();
39
40 private FormatUtil() {
41 }
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 static void format(final InputStream in, final OutputStream out, final XmlOutputFormat fmt)
61 throws DocumentException, IOException {
62 final SAXReader reader = new SAXReader();
63 reader.setEntityResolver(new EntityResolver() {
64 @Override
65 public InputSource resolveEntity(final String publicId, final String systemId)
66 throws SAXException, IOException {
67 return new InputSource(new StringReader(""));
68 }
69 });
70 final Document xmlDoc = reader.read(in);
71
72 final XMLWriter xmlWriter = getXmlWriter(out, fmt);
73 xmlWriter.write(xmlDoc);
74 xmlWriter.flush();
75 }
76
77 private static XMLWriter getXmlWriter(final OutputStream out, final XmlOutputFormat fmt)
78 throws UnsupportedEncodingException {
79 final XMLWriter xmlWriter;
80 if (fmt.isKeepBlankLines()) {
81 xmlWriter = new BlankLinesWriter(out, fmt);
82 } else {
83 xmlWriter = new XMLWriter(out, fmt);
84 }
85 return xmlWriter;
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 static boolean formatInPlace(final File file, final XmlOutputFormat fmt) throws DocumentException, IOException {
104 if (file.length() == 0) {
105 return false;
106 }
107
108 final File tmpFile = createTempFile(TMP_FILE_PREFIX, ".xml");
109 tmpFile.deleteOnExit();
110
111 try (InputStream in = Files.newInputStream(file.toPath());
112 OutputStream out = Files.newOutputStream(tmpFile.toPath())) {
113 format(in, out, fmt);
114 }
115
116 final long hashFile = hash(file);
117 final long hashTmp = hash(tmpFile);
118 if (hashFile == hashTmp) {
119 return false;
120 }
121
122 final Path source = tmpFile.toPath();
123 final Path target = file.toPath();
124 copy(source, target, REPLACE_EXISTING);
125 return true;
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 static boolean needsFormatting(final File file, final XmlOutputFormat fmt) throws DocumentException, IOException {
144 if (file.length() == 0) {
145 return false;
146 }
147
148 final File tmpFile = createTempFile(TMP_FILE_PREFIX, ".xml");
149 tmpFile.deleteOnExit();
150
151 try (InputStream in = Files.newInputStream(file.toPath());
152 OutputStream out = Files.newOutputStream(tmpFile.toPath())) {
153 format(in, out, fmt);
154 }
155
156 final long hashFile = hash(file);
157 final long hashTmp = hash(tmpFile);
158 return hashFile != hashTmp;
159 }
160
161 }