Skip to content

Commit fb8a21c

Browse files
committed
Add standardized logging #3
1 parent 441ddce commit fb8a21c

File tree

5 files changed

+132
-32
lines changed

5 files changed

+132
-32
lines changed

pom.xml

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<groupId>io.fixprotocol.xml</groupId>
66
<artifactId>diff-merge</artifactId>
77
<description>Diff/merge tool for XML files</description>
8-
<version>1.4.0-RC5-SNAPSHOT</version>
8+
<version>1.4.1-SNAPSHOT</version>
99
<name>${project.groupId}:${project.artifactId}</name>
1010

1111
<prerequisites>
@@ -16,7 +16,8 @@
1616
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1717
<java.version>11</java.version>
1818
<junit.version>5.5.1</junit.version>
19-
<saxon.version>9.9.1-4</saxon.version>
19+
<log4j.version>2.12.1</log4j.version>
20+
<saxon.version>9.9.1-5</saxon.version>
2021
<ignoreSigningInformation>true</ignoreSigningInformation>
2122
</properties>
2223

@@ -63,6 +64,16 @@
6364
<artifactId>Saxon-HE</artifactId>
6465
<version>${saxon.version}</version>
6566
</dependency>
67+
<dependency>
68+
<groupId>org.apache.logging.log4j</groupId>
69+
<artifactId>log4j-api</artifactId>
70+
<version>${log4j.version}</version>
71+
</dependency>
72+
<dependency>
73+
<groupId>org.apache.logging.log4j</groupId>
74+
<artifactId>log4j-core</artifactId>
75+
<version>${log4j.version}</version>
76+
</dependency>
6677
<dependency>
6778
<groupId>org.junit.jupiter</groupId>
6879
<artifactId>junit-jupiter-engine</artifactId>
@@ -121,7 +132,7 @@
121132
<plugin>
122133
<groupId>org.moditect</groupId>
123134
<artifactId>moditect-maven-plugin</artifactId>
124-
<version>1.0.0.Beta2</version>
135+
<version>1.0.0-SNAPSHOT</version>
125136
<executions>
126137
<execution>
127138
<id>add-module-infos</id>
@@ -168,11 +179,37 @@
168179
<outputDirectory>
169180
${project.build.directory}/jlink-image
170181
</outputDirectory>
171-
<!-- apparently only one launcher can be provided, so merge requires command line -->
172-
<launcher>
173-
<name>xmldiff</name>
174-
<module>diff.merge/io.fixprotocol.xml.XmlDiff</module>
175-
</launcher>
182+
<launchers>
183+
<launcher>
184+
<name>xmldiff</name>
185+
<module>diff.merge</module>
186+
<mainClass>io.fixprotocol.xml.XmlDiff</mainClass>
187+
</launcher>
188+
<launcher>
189+
<name>xmlmerge</name>
190+
<module>diff.merge</module>
191+
<mainClass>io.fixprotocol.xml.XmlMerge</mainClass>
192+
</launcher>
193+
</launchers>
194+
</configuration>
195+
</execution>
196+
</executions>
197+
</plugin>
198+
<plugin>
199+
<groupId>org.apache.maven.plugins</groupId>
200+
<artifactId>maven-dependency-plugin</artifactId>
201+
<version>3.1.1</version>
202+
<executions>
203+
<execution>
204+
<id>copy-dependencies</id>
205+
<phase>verify</phase>
206+
<goals>
207+
<goal>copy-dependencies</goal>
208+
</goals>
209+
<configuration>
210+
<outputDirectory>${project.build.directory}/modules</outputDirectory>
211+
<overWriteIfNewer>true</overWriteIfNewer>
212+
<includeGroupIds>org.apache.logging.log4j</includeGroupIds>
176213
</configuration>
177214
</execution>
178215
</executions>

src/main/java/io/fixprotocol/xml/XmlDiff.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
import javax.xml.xpath.XPath;
3535
import javax.xml.xpath.XPathConstants;
3636
import javax.xml.xpath.XPathFactory;
37-
37+
import org.apache.logging.log4j.LogManager;
38+
import org.apache.logging.log4j.Logger;
3839
import org.w3c.dom.Attr;
3940
import org.w3c.dom.DOMException;
4041
import org.w3c.dom.Document;
@@ -81,6 +82,8 @@ public int compare(Element n1, Element n2) {
8182
}
8283
}
8384

85+
private static final Logger parentLogger = LogManager.getLogger();
86+
8487
/**
8588
* Compares two XML files. By default, report is sent to console.
8689
*
@@ -111,6 +114,9 @@ public static void main(String[] args) throws Exception {
111114
PatchOpsListener aListener = new PatchOpsListener(out);
112115
tool.setListener(aListener);
113116
tool.diff(is1, is2);
117+
} catch (Exception e) {
118+
parentLogger.fatal("XmlDiff failed", e);
119+
throw e;
114120
}
115121
}
116122
}
@@ -151,11 +157,12 @@ public void diff(InputStream is1, InputStream is2) throws Exception {
151157
final Element root2 = doc2.getDocumentElement();
152158

153159
if (!diffElements(root1, root2)) {
154-
System.err.format("Not comparing same root nodes; %s %s%n", XpathUtil.getFullXPath(root1),
155-
XpathUtil.getFullXPath(root2));
160+
parentLogger.fatal("XmlDiff failed; not comparing same root nodes; {} {}",
161+
XpathUtil.getFullXPath(root1), XpathUtil.getFullXPath(root2));
156162
System.exit(1);
157163
}
158164
listener.close();
165+
parentLogger.info("XmlDiff complete");
159166
}
160167
}
161168

@@ -176,7 +183,7 @@ public void diff(InputStream is1, String xpathString1, InputStream is2, String x
176183
Objects.requireNonNull(is2, "Second input stream cannot be null");
177184
Objects.requireNonNull(xpathString2, "Second expression cannot be null");
178185

179-
try {
186+
try (is1; is2) {
180187
XPathFactory factory = XPathFactory.newInstance();
181188
XPath xpath1 = factory.newXPath();
182189
Object node1 = xpath1.evaluate(xpathString1, new InputSource(is1), XPathConstants.NODE);
@@ -190,8 +197,6 @@ public void diff(InputStream is1, String xpathString1, InputStream is2, String x
190197
}
191198
} finally {
192199
listener.close();
193-
is1.close();
194-
is2.close();
195200
}
196201
}
197202

@@ -250,9 +255,9 @@ private boolean diffAttributes(NamedNodeMap attributes1, NamedNodeMap attributes
250255

251256
switch (difference) {
252257
case ADD:
253-
listener.accept(new Event(ADD,
254-
XpathUtil.getFullXPath(attributesArray2.get(index2).getOwnerElement()),
255-
attributesArray2.get(index2)));
258+
listener.accept(
259+
new Event(ADD, XpathUtil.getFullXPath(attributesArray2.get(index2).getOwnerElement()),
260+
attributesArray2.get(index2)));
256261
index2 = Math.min(index2 + 1, attributesArray2.size());
257262
isEqual = false;
258263
break;

src/main/java/io/fixprotocol/xml/XmlMerge.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import javax.xml.xpath.XPathExpression;
3434
import javax.xml.xpath.XPathExpressionException;
3535
import javax.xml.xpath.XPathFactory;
36+
import org.apache.logging.log4j.LogManager;
37+
import org.apache.logging.log4j.Logger;
3638
import org.w3c.dom.DOMException;
3739
import org.w3c.dom.Document;
3840
import org.w3c.dom.Element;
@@ -65,12 +67,19 @@ public static void main(String[] args) throws Exception {
6567
if (args.length < 3) {
6668
usage();
6769
} else {
68-
XmlMerge tool = new XmlMerge();
69-
tool.merge(new FileInputStream(args[0]), new FileInputStream(args[1]),
70-
new FileOutputStream(args[2]));
70+
try {
71+
XmlMerge tool = new XmlMerge();
72+
tool.merge(new FileInputStream(args[0]), new FileInputStream(args[1]),
73+
new FileOutputStream(args[2]));
74+
} catch (Exception e) {
75+
parentLogger.fatal("XmlMerge failed", e);
76+
throw e;
77+
}
7178
}
7279
}
7380

81+
private static final Logger parentLogger = LogManager.getLogger();
82+
7483
/**
7584
* Prints application usage
7685
*/
@@ -92,7 +101,7 @@ public void merge(InputStream baseline, InputStream diff, OutputStream out) thro
92101
Objects.requireNonNull(out, "Output stream cannot be null");
93102

94103
final Document baselineDoc = parse(baseline);
95-
104+
96105
// XPath implementation supplied with Java 8 fails so using Saxon
97106
final XPathFactory factory = new net.sf.saxon.xpath.XPathFactoryImpl();
98107
final XPath xpathEvaluator = factory.newXPath();
@@ -123,11 +132,12 @@ public void merge(InputStream baseline, InputStream diff, OutputStream out) thro
123132
replace(baselineDoc, xpathEvaluator, patchOpElement);
124133
break;
125134
default:
126-
System.err.format("Invalid operation '%s'%n", tag);
135+
throw new IllegalArgumentException(String.format("Invalid merge operation %s", tag));
127136
}
128137
}
129138

130139
write(baselineDoc, out);
140+
parentLogger.info("XmlMerge complete");
131141
}
132142

133143
private void add(Document doc, XPath xpathEvaluator, Element patchOpElement)
@@ -136,12 +146,12 @@ private void add(Document doc, XPath xpathEvaluator, Element patchOpElement)
136146
String attribute = patchOpElement.getAttribute("type");
137147

138148
final XPathExpression compiled = xpathEvaluator.compile(xpathExpression);
139-
Node parent =
140-
(Node) compiled.evaluate(doc, XPathConstants.NODE);
149+
Node parent = (Node) compiled.evaluate(doc, XPathConstants.NODE);
141150
if (parent == null) {
142-
throw new XPathExpressionException("No target for Xpath expression in 'sel' for add; " + xpathExpression);
151+
throw new XPathExpressionException(
152+
"No target for Xpath expression in 'sel' for add; " + xpathExpression);
143153
}
144-
154+
145155
if (attribute.length() > 0) {
146156
String value = null;
147157
NodeList children = patchOpElement.getChildNodes();
@@ -201,9 +211,10 @@ private void replace(final Document doc, XPath xpathEvaluator, Element patchOpEl
201211

202212
Node node = (Node) xpathEvaluator.compile(xpathExpression).evaluate(doc, XPathConstants.NODE);
203213
if (node == null) {
204-
throw new XPathExpressionException("No target for Xpath expression in 'sel' for replace; " + xpathExpression);
214+
throw new XPathExpressionException(
215+
"No target for Xpath expression in 'sel' for replace; " + xpathExpression);
205216
}
206-
217+
207218
switch (node.getNodeType()) {
208219
case Node.ELEMENT_NODE:
209220
NodeList children = node.getChildNodes();

src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module diff.merge {
22
requires java.xml;
33
requires Saxon.HE;
4+
requires org.apache.logging.log4j;
45
}

src/test/java/io/fixprotocol/xml/XmlDiffTest.java

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,69 @@
1818
import java.io.File;
1919
import java.io.FileInputStream;
2020
import java.io.FileOutputStream;
21+
import java.net.URI;
2122
import javax.xml.parsers.DocumentBuilder;
2223
import javax.xml.parsers.DocumentBuilderFactory;
24+
import org.apache.logging.log4j.Level;
25+
import org.apache.logging.log4j.LogManager;
26+
import org.apache.logging.log4j.core.appender.ConsoleAppender;
27+
import org.apache.logging.log4j.core.config.Configurator;
28+
import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
29+
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
30+
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
31+
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
32+
import org.apache.logging.log4j.spi.LoggerContextFactory;
2333
import org.junit.jupiter.api.BeforeAll;
2434
import org.junit.jupiter.api.BeforeEach;
2535
import org.junit.jupiter.api.Test;
2636
import org.w3c.dom.Document;
2737

38+
class CustomLogFactory implements LoggerContextFactory {
39+
private final org.apache.logging.log4j.spi.LoggerContext ctx;
40+
41+
CustomLogFactory() {
42+
final ConfigurationBuilder<BuiltConfiguration> builder =
43+
ConfigurationBuilderFactory.newConfigurationBuilder();
44+
builder.setStatusLevel(Level.WARN);
45+
final AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE")
46+
.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT)
47+
.add(builder.newLayout("PatternLayout").addAttribute("pattern",
48+
"%date %-5level: %msg%n%throwable"));
49+
builder.add(appenderBuilder);
50+
builder.add(builder.newRootLogger(Level.INFO).add(builder.newAppenderRef("Stdout")));
51+
ctx = Configurator.initialize(builder.build());
52+
}
53+
54+
@Override
55+
public org.apache.logging.log4j.spi.LoggerContext getContext(String fqcn, ClassLoader loader,
56+
Object externalContext, boolean currentContext) {
57+
return ctx;
58+
}
59+
60+
@Override
61+
public org.apache.logging.log4j.spi.LoggerContext getContext(String fqcn, ClassLoader loader,
62+
Object externalContext, boolean currentContext, URI configLocation, String name) {
63+
return ctx;
64+
}
65+
66+
@Override
67+
public void removeContext(org.apache.logging.log4j.spi.LoggerContext context) {
68+
69+
}
70+
}
71+
72+
2873
public class XmlDiffTest {
2974

3075
private static final String MERGED_FILENAME = "target/test/testmerged.xml";
3176
private static final String DIFF_FILENAME = "target/test/testdiff.xml";
3277
private XmlDiff xmlDiff;
3378
private XmlMerge xmlMerge;
34-
79+
3580
@BeforeAll
3681
public static void setupOnce() throws Exception {
3782
new File("target/test").mkdirs();
83+
LogManager.setFactory(new CustomLogFactory());
3884
}
3985

4086
/**
@@ -65,10 +111,10 @@ public void simpleDiffUnordered() throws Exception {
65111
assertEquals(2, doc.getElementsByTagName("add").getLength());
66112
assertEquals(2, doc.getElementsByTagName("replace").getLength());
67113
assertEquals(2, doc.getElementsByTagName("remove").getLength());
68-
114+
69115
try (
70-
final FileInputStream is1Baseline = new FileInputStream(Thread.currentThread()
71-
.getContextClassLoader().getResource("DiffTest1.xml").getFile());
116+
final FileInputStream is1Baseline = new FileInputStream(
117+
Thread.currentThread().getContextClassLoader().getResource("DiffTest1.xml").getFile());
72118
final FileInputStream isDiff = new FileInputStream(DIFF_FILENAME);
73119
final FileOutputStream osMerge = new FileOutputStream(MERGED_FILENAME)) {
74120
xmlMerge.merge(is1Baseline, isDiff, osMerge);

0 commit comments

Comments
 (0)