14
14
*/
15
15
package io .fixprotocol .xml ;
16
16
17
+ import static io .fixprotocol .xml .XmlDiffListener .Event .Pos .append ;
17
18
import java .io .IOException ;
18
19
import java .io .OutputStream ;
19
20
import java .io .OutputStreamWriter ;
20
21
import java .nio .charset .StandardCharsets ;
21
22
import java .util .concurrent .atomic .AtomicBoolean ;
22
-
23
23
import javax .xml .parsers .DocumentBuilder ;
24
24
import javax .xml .parsers .DocumentBuilderFactory ;
25
25
import javax .xml .parsers .ParserConfigurationException ;
29
29
import javax .xml .transform .TransformerFactory ;
30
30
import javax .xml .transform .dom .DOMSource ;
31
31
import javax .xml .transform .stream .StreamResult ;
32
-
33
32
import org .w3c .dom .Attr ;
34
33
import org .w3c .dom .Document ;
35
34
import org .w3c .dom .Element ;
36
35
import org .w3c .dom .Node ;
37
36
import org .w3c .dom .Text ;
38
37
39
- import static io .fixprotocol .xml .XmlDiffListener .Event .Pos .*;
40
-
41
38
/**
42
39
* Writes XML diffs as patch operations specified by IETF RFC 5261
43
- *
40
+ *
44
41
* @author Don Mendelson
45
42
* @see <a href="https://tools.ietf.org/html/rfc5261">An Extensible Markup Language (XML) Patch
46
43
* Operations Framework Utilizing XML Path Language (XPath) Selectors</a>
@@ -54,41 +51,42 @@ public class PatchOpsListener implements XmlDiffListener {
54
51
55
52
/**
56
53
* Constructs a listener with an output stream
54
+ *
57
55
* @throws IOException if an IO error occurs
58
56
* @throws ParserConfigurationException if a configuration error occurs
59
57
* @throws TransformerConfigurationException if a configuration error occurs
60
- *
58
+ *
61
59
*/
62
60
public PatchOpsListener (OutputStream out )
63
61
throws IOException , ParserConfigurationException , TransformerConfigurationException {
64
62
writer = new OutputStreamWriter (out , StandardCharsets .UTF_8 );
65
63
66
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory .newInstance ();
64
+ final DocumentBuilderFactory dbFactory = DocumentBuilderFactory .newInstance ();
67
65
dbFactory .setNamespaceAware (true );
68
- DocumentBuilder dBuilder = dbFactory .newDocumentBuilder ();
66
+ final DocumentBuilder dBuilder = dbFactory .newDocumentBuilder ();
69
67
document = dBuilder .newDocument ();
70
68
rootElement = document .createElement ("diff" );
71
69
document .appendChild (rootElement );
72
70
}
73
71
74
72
/*
75
73
* (non-Javadoc)
76
- *
74
+ *
77
75
* @see java.util.function.Consumer#accept(java.lang.Object)
78
76
*/
79
77
@ Override
80
78
public void accept (Event t ) {
81
79
82
80
switch (t .getDifference ()) {
83
81
case ADD :
84
- Element addElement = document .createElement ("add" );
82
+ final Element addElement = document .createElement ("add" );
85
83
rootElement .appendChild (addElement );
86
84
87
85
if (t .getValue () instanceof Attr ) {
88
86
// add attribute
89
87
addElement .setAttribute ("sel" , t .getXpath ());
90
88
addElement .setAttribute ("type" , "@" + t .getValue ().getNodeName ());
91
- Text textNode = document .createTextNode (t .getValue ().getNodeValue ());
89
+ final Text textNode = document .createTextNode (t .getValue ().getNodeValue ());
92
90
addElement .appendChild (textNode );
93
91
} else if (t .getValue () instanceof Element ) {
94
92
// add element
@@ -97,30 +95,30 @@ public void accept(Event t) {
97
95
addElement .setAttribute ("pos" , t .getPos ().toString ());
98
96
}
99
97
// will import child text node if it exists (deep copy)
100
- Element newValue = (Element ) document .importNode (t .getValue (), true );
98
+ final Element newValue = (Element ) document .importNode (t .getValue (), true );
101
99
addElement .appendChild (newValue );
102
100
}
103
101
104
102
break ;
105
103
case REPLACE :
106
- Element replaceElement = document .createElement ("replace" );
104
+ final Element replaceElement = document .createElement ("replace" );
107
105
rootElement .appendChild (replaceElement );
108
106
109
107
if (t .getValue () instanceof Attr ) {
110
108
// replace attribute
111
109
replaceElement .setAttribute ("sel" , t .getXpath ());
112
- Text textNode = document .createTextNode (t .getValue ().getNodeValue ());
110
+ final Text textNode = document .createTextNode (t .getValue ().getNodeValue ());
113
111
replaceElement .appendChild (textNode );
114
112
} else {
115
113
// replace element
116
114
replaceElement .setAttribute ("sel" , t .getXpath ());
117
115
// will import child text node if it exists
118
- Node newValue = document .importNode (t .getValue (), true );
116
+ final Node newValue = document .importNode (t .getValue (), true );
119
117
replaceElement .appendChild (newValue );
120
118
}
121
119
break ;
122
120
case REMOVE :
123
- Element removeElement = document .createElement ("remove" );
121
+ final Element removeElement = document .createElement ("remove" );
124
122
rootElement .appendChild (removeElement );
125
123
removeElement .setAttribute ("sel" , t .getXpath ());
126
124
break ;
@@ -131,18 +129,18 @@ public void accept(Event t) {
131
129
132
130
/*
133
131
* (non-Javadoc)
134
- *
132
+ *
135
133
* @see java.lang.AutoCloseable#close()
136
134
*/
137
135
@ Override
138
136
public void close () throws Exception {
139
137
// Idempotent - only close once
140
138
if (isClosed .compareAndSet (false , true )) {
141
- TransformerFactory transformerFactory = TransformerFactory .newInstance ();
142
- Transformer transformer = transformerFactory .newTransformer ();
139
+ final TransformerFactory transformerFactory = TransformerFactory .newInstance ();
140
+ final Transformer transformer = transformerFactory .newTransformer ();
143
141
transformer .setOutputProperty (OutputKeys .INDENT , "yes" );
144
- DOMSource source = new DOMSource (document );
145
- StreamResult result = new StreamResult (writer );
142
+ final DOMSource source = new DOMSource (document );
143
+ final StreamResult result = new StreamResult (writer );
146
144
transformer .transform (source , result );
147
145
writer .close ();
148
146
}
0 commit comments