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