View Javadoc

1   /*
2    * Copyright 2015 Data Archiving and Networked Services (an institute of
3    * Koninklijke Nederlandse Akademie van Wetenschappen), King's College London,
4    * Georg-August-Universitaet Goettingen Stiftung Oeffentlichen Rechts
5    *
6    * Licensed under the EUPL, Version 1.1 or – as soon they will be approved by
7    * the European Commission - subsequent versions of the EUPL (the "Licence");
8    * You may not use this work except in compliance with the Licence.
9    * You may obtain a copy of the Licence at:
10   *
11   * https://joinup.ec.europa.eu/software/page/eupl
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the Licence is distributed on an "AS IS" basis,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the Licence for the specific language governing
17   * permissions and limitations under the Licence.
18   */
19  
20  package eu.ehri.project.exporters.xml;
21  
22  import com.google.common.base.Preconditions;
23  import com.google.common.collect.ImmutableList;
24  import com.google.common.collect.Maps;
25  
26  import javax.xml.stream.XMLStreamException;
27  import javax.xml.stream.XMLStreamWriter;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.regex.Pattern;
31  
32  /**
33   * A helper base class for writing XML as a stream, using
34   * lambdas for hierarchical nesting of elements.
35   */
36  public abstract class StreamingXmlDsl {
37      private static final Pattern cDataReplace = Pattern.compile("\\]\\]>");
38  
39      protected static Map<String, String> attrs(Object... kv) {
40          Preconditions.checkArgument(kv.length % 2 == 0,
41                  "Attrs must be pairs of key/value");
42          Map<String, String> m = Maps.newHashMap();
43          for (int i = 0; i < kv.length; i += 2) {
44              if (kv[i + 1] != null) {
45                  m.put(String.valueOf(kv[i]), String.valueOf(kv[i + 1]));
46              }
47          }
48          return m;
49      }
50  
51      protected static Map<String, String> namespaces(Object... kv) {
52          Preconditions.checkArgument(kv.length % 2 == 0,
53                  "Namespaces must be pairs of key/value");
54          return attrs(kv);
55      }
56  
57      protected void attribute(XMLStreamWriter sw, String ns, String key, String value) {
58          try {
59              sw.writeAttribute(ns, key, value);
60          } catch (XMLStreamException e) {
61              throw new RuntimeException(e);
62          }
63      }
64  
65      protected void doc(XMLStreamWriter sw, Runnable runnable) {
66          try {
67              sw.writeStartDocument();
68              sw.writeCharacters("\n");
69              runnable.run();
70              sw.writeEndDocument();
71          } catch (XMLStreamException e) {
72              throw new RuntimeException(e);
73          }
74      }
75  
76      protected void root(XMLStreamWriter sw, String tag, String defaultNamespace,
77              Map<String, String> attrs, Map<String, String> namespaces,
78              Runnable runnable) {
79          try {
80              sw.writeStartElement(tag);
81              if (defaultNamespace != null) {
82                  sw.writeDefaultNamespace(defaultNamespace);
83              }
84              for (Map.Entry<String, String> ns : namespaces.entrySet()) {
85                  sw.writeNamespace(ns.getKey(), ns.getValue());
86              }
87              for (Map.Entry<String, String> attr : attrs.entrySet()) {
88                  sw.writeAttribute(attr.getKey(), attr.getValue());
89              }
90              runnable.run();
91              sw.writeEndElement();
92          } catch (XMLStreamException e) {
93              throw new RuntimeException(e);
94          }
95      }
96  
97      protected void tag(XMLStreamWriter sw, String tag, Runnable runnable) {
98          tag(sw, tag, attrs(), runnable);
99      }
100 
101     protected void tag(XMLStreamWriter sw, String tag, Map<String, String> attrs, Runnable runnable) {
102         tag(sw, ImmutableList.of(tag), attrs, runnable);
103     }
104 
105     protected void tag(XMLStreamWriter sw, List<String> tags, Runnable runnable) {
106         tag(sw, tags, attrs(), runnable);
107     }
108 
109     protected void tag(XMLStreamWriter sw, List<String> tags, Map<String, String> attrs, Runnable runnable) {
110         try {
111             for (String tag : tags) {
112                 sw.writeStartElement(tag);
113             }
114             attributes(sw, attrs);
115             runnable.run();
116             for (int i = 0; i < tags.size(); i++) {
117                 sw.writeEndElement();
118             }
119         } catch (XMLStreamException e) {
120             throw new RuntimeException(e);
121         }
122     }
123 
124     protected void tag(XMLStreamWriter sw, String key, String value) {
125         tag(sw, key, value, attrs());
126     }
127 
128     protected void tag(XMLStreamWriter sw, String key, String value, Map<String, String> attrs) {
129         tag(sw, ImmutableList.of(key), value, attrs);
130     }
131 
132     protected void tag(XMLStreamWriter sw, List<String> keys, String value) {
133         tag(sw, keys, value, attrs());
134     }
135 
136     protected void tag(XMLStreamWriter sw, List<String> keys, String value, Map<String, String> attrs) {
137         try {
138             for (String key : keys) {
139                 sw.writeStartElement(key);
140             }
141             attributes(sw, attrs);
142             if (value != null) {
143                 sw.writeCharacters(value);
144             }
145             for (int i = 0; i < keys.size(); i++) {
146                 sw.writeEndElement();
147             }
148         } catch (XMLStreamException e) {
149             throw new RuntimeException(e);
150         }
151     }
152 
153     protected void comment(XMLStreamWriter sw, String comment) {
154         try {
155             sw.writeComment(comment);
156         } catch (XMLStreamException e) {
157             throw new RuntimeException(e);
158         }
159     }
160 
161     protected void characters(XMLStreamWriter sw, String chars) {
162         try {
163             sw.writeCharacters(chars);
164         } catch (XMLStreamException e) {
165             throw new RuntimeException(e);
166         }
167     }
168 
169     protected void cData(XMLStreamWriter sw, String chars) {
170         try {
171             sw.writeCData(cDataReplace.matcher(chars).replaceAll(""));
172         } catch (XMLStreamException e) {
173             throw new RuntimeException(e);
174         }
175     }
176 
177     protected void attributes(XMLStreamWriter sw, Map<String, String> attrs) {
178         try {
179             for (Map.Entry<String, String> attr : attrs.entrySet()) {
180                 if (attr.getValue() != null) {
181                     sw.writeAttribute(attr.getKey(), attr.getValue());
182                 }
183             }
184         } catch (XMLStreamException e) {
185             throw new RuntimeException(e);
186         }
187     }
188 }