|
13 | 13 | */
|
14 | 14 | package com.connexta.replication.adapters.ddf.csw;
|
15 | 15 |
|
16 |
| -import com.connexta.replication.adapters.ddf.DdfMetadata; |
17 |
| -import com.connexta.replication.adapters.ddf.MetacardAttribute; |
18 |
| -import com.connexta.replication.api.AdapterException; |
19 |
| -import com.connexta.replication.api.Replication; |
20 | 16 | import com.connexta.replication.api.data.Metadata;
|
21 |
| -import com.thoughtworks.xstream.converters.ConversionException; |
22 | 17 | import com.thoughtworks.xstream.converters.Converter;
|
23 | 18 | import com.thoughtworks.xstream.converters.MarshallingContext;
|
24 | 19 | import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
25 | 20 | import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
26 | 21 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
27 | 22 | import com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier;
|
28 |
| -import com.thoughtworks.xstream.io.naming.NoNameCoder; |
29 |
| -import com.thoughtworks.xstream.io.xml.CompactWriter; |
30 |
| -import com.thoughtworks.xstream.io.xml.XppReader; |
31 |
| -import java.io.IOException; |
32 |
| -import java.io.InputStreamReader; |
33 |
| -import java.io.StringWriter; |
34 |
| -import java.net.URI; |
35 |
| -import java.net.URISyntaxException; |
36 |
| -import java.nio.charset.StandardCharsets; |
37 |
| -import java.text.DateFormat; |
38 |
| -import java.text.ParseException; |
39 |
| -import java.util.ArrayList; |
40 | 23 | import java.util.Arrays;
|
41 |
| -import java.util.Collections; |
42 |
| -import java.util.Date; |
43 |
| -import java.util.HashMap; |
44 | 24 | import java.util.List;
|
45 | 25 | import java.util.Map;
|
46 |
| -import java.util.Map.Entry; |
47 |
| -import javax.annotation.Nullable; |
48 |
| -import org.apache.commons.io.IOUtils; |
49 |
| -import org.apache.commons.lang.StringUtils; |
50 |
| -import org.joda.time.format.ISODateTimeFormat; |
51 | 26 | import org.slf4j.Logger;
|
52 | 27 | import org.slf4j.LoggerFactory;
|
53 |
| -import org.xmlpull.v1.XmlPullParser; |
54 |
| -import org.xmlpull.v1.XmlPullParserException; |
55 |
| -import org.xmlpull.v1.XmlPullParserFactory; |
56 | 28 |
|
57 | 29 | /**
|
58 | 30 | * Copied from DDF and modified for replication purposes.
|
@@ -89,213 +61,6 @@ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext co
|
89 | 61 | namespaceMap = (Map<String, String>) namespaceObj;
|
90 | 62 | }
|
91 | 63 |
|
92 |
| - return createMetadataFromCswRecord(reader, namespaceMap); |
93 |
| - } |
94 |
| - |
95 |
| - private static void copyElementWithAttributes( |
96 |
| - HierarchicalStreamReader source, |
97 |
| - HierarchicalStreamWriter destination, |
98 |
| - Map<String, String> namespaceMap) { |
99 |
| - destination.startNode(source.getNodeName()); |
100 |
| - int attributeCount = source.getAttributeCount(); |
101 |
| - for (int i = 0; i < attributeCount; i++) { |
102 |
| - destination.addAttribute(source.getAttributeName(i), source.getAttribute(i)); |
103 |
| - } |
104 |
| - if (namespaceMap != null && !namespaceMap.isEmpty()) { |
105 |
| - for (Entry<String, String> entry : namespaceMap.entrySet()) { |
106 |
| - if (StringUtils.isBlank(source.getAttribute(entry.getKey()))) { |
107 |
| - destination.addAttribute(entry.getKey(), entry.getValue()); |
108 |
| - } |
109 |
| - } |
110 |
| - } |
111 |
| - String value = source.getValue(); |
112 |
| - if (value != null && value.length() > 0) { |
113 |
| - destination.setValue(value); |
114 |
| - } |
115 |
| - while (source.hasMoreChildren()) { |
116 |
| - source.moveDown(); |
117 |
| - COPIER.copy(source, destination); |
118 |
| - source.moveUp(); |
119 |
| - } |
120 |
| - destination.endNode(); |
121 |
| - } |
122 |
| - |
123 |
| - /** |
124 |
| - * Copies the entire XML element {@code reader} is currently at into {@code writer} and returns a |
125 |
| - * new reader ready to read the copied element. After the call, {@code reader} will be at the end |
126 |
| - * of the element that was copied. |
127 |
| - * |
128 |
| - * <p>If {@code attributeMap} is provided, the attributes will be added to the copy. |
129 |
| - * |
130 |
| - * @param reader the reader currently at the XML element you want to copy |
131 |
| - * @param writer the writer that the element will be copied into |
132 |
| - * @param attributeMap the map of attribute names to values that will be added as attributes of |
133 |
| - * the copy, may be null |
134 |
| - * @return a new reader ready to read the copied element |
135 |
| - * @throws ConversionException if a parser to use for the new reader can't be created |
136 |
| - */ |
137 |
| - public static HierarchicalStreamReader copyXml( |
138 |
| - HierarchicalStreamReader reader, StringWriter writer, Map<String, String> attributeMap) { |
139 |
| - copyElementWithAttributes(reader, new CompactWriter(writer, new NoNameCoder()), attributeMap); |
140 |
| - |
141 |
| - XmlPullParser parser; |
142 |
| - try { |
143 |
| - parser = XmlPullParserFactory.newInstance().newPullParser(); |
144 |
| - } catch (XmlPullParserException e) { |
145 |
| - throw new ConversionException("Unable to create XmlPullParser, cannot parse XML.", e); |
146 |
| - } |
147 |
| - |
148 |
| - try { |
149 |
| - // NOTE: must specify encoding here, otherwise the platform default |
150 |
| - // encoding will be used which will not always work |
151 |
| - return new XppReader( |
152 |
| - new InputStreamReader( |
153 |
| - IOUtils.toInputStream(writer.toString(), StandardCharsets.UTF_8.name())), |
154 |
| - parser); |
155 |
| - } catch (IOException e) { |
156 |
| - LOGGER.debug("Unable create reader with UTF-8 encoding", e); |
157 |
| - return new XppReader( |
158 |
| - new InputStreamReader(IOUtils.toInputStream(writer.toString(), StandardCharsets.UTF_8)), |
159 |
| - parser); |
160 |
| - } |
161 |
| - } |
162 |
| - |
163 |
| - public static @Nullable Date convertToDate(@Nullable MetacardAttribute value) { |
164 |
| - if (value == null) { |
165 |
| - return null; |
166 |
| - } |
167 |
| - /* Dates are strings and expected to be in ISO8601 format, YYYY-MM-DD'T'hh:mm:ss.sss, |
168 |
| - per annotations in the CSW Record schema. At least the date portion must be present - |
169 |
| - the time zone and time are optional.*/ |
170 |
| - try { |
171 |
| - return ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(value.getValue()).toDate(); |
172 |
| - } catch (IllegalArgumentException e) { |
173 |
| - LOGGER.debug("Failed to convert to date {} from ISO Format: {}", value, e); |
174 |
| - } |
175 |
| - |
176 |
| - // try from java date serialization for the default locale |
177 |
| - try { |
178 |
| - return DateFormat.getDateInstance().parse(value.getValue()); |
179 |
| - } catch (ParseException e) { |
180 |
| - LOGGER.debug("Unable to convert date {} from default locale format {} ", value, e); |
181 |
| - } |
182 |
| - |
183 |
| - // default to current date |
184 |
| - LOGGER.debug("Unable to convert {} to a date object", value); |
185 |
| - return null; |
186 |
| - } |
187 |
| - |
188 |
| - public static Metadata createMetadataFromCswRecord( |
189 |
| - HierarchicalStreamReader hreader, Map<String, String> namespaceMap) { |
190 |
| - |
191 |
| - StringWriter metadataWriter = new StringWriter(); |
192 |
| - HierarchicalStreamReader reader = copyXml(hreader, metadataWriter, namespaceMap); |
193 |
| - |
194 |
| - Map<String, MetacardAttribute> metadataMap = new HashMap<>(); |
195 |
| - String metadataStr = metadataWriter.toString(); |
196 |
| - metadataMap.put( |
197 |
| - Constants.RAW_METADATA_KEY, |
198 |
| - new MetacardAttribute(Constants.RAW_METADATA_KEY, null, metadataStr)); |
199 |
| - String id = reader.getAttribute("gml:id"); |
200 |
| - metadataMap.put(Constants.METACARD_ID, new MetacardAttribute(Constants.METACARD_ID, null, id)); |
201 |
| - // If we want to grab the type we will have to do so below. As you move through the child nodes |
202 |
| - // check if the node name is type and save the value. |
203 |
| - |
204 |
| - parseToMap(reader, metadataMap); |
205 |
| - |
206 |
| - Date metacardModified = convertToDate(metadataMap.get(Constants.METACARD_MODIFIED)); |
207 |
| - if (metadataMap.get(Constants.VERSION_OF_ID) != null |
208 |
| - && metadataMap.get(Constants.VERSION_OF_ID).getValue() != null) { |
209 |
| - // Since we are dealing with a delete revision metacard, we need to make sure the |
210 |
| - // returned metadata has the original metacard id and modified date. |
211 |
| - id = metadataMap.get(Constants.VERSION_OF_ID).getValue(); |
212 |
| - metacardModified = convertToDate(metadataMap.get(Constants.VERSIONED_ON)); |
213 |
| - } |
214 |
| - |
215 |
| - if (metacardModified == null) { |
216 |
| - throw new AdapterException("Can't convert csw metacard without a metacard.modified field"); |
217 |
| - } |
218 |
| - |
219 |
| - DdfMetadata metadata = |
220 |
| - new DdfMetadata(metadataStr, String.class, id, metacardModified, metadataMap); |
221 |
| - metadata.setMetadataSize(metadataStr.length()); |
222 |
| - if (metadataMap.get(Constants.RESOURCE_SIZE) != null) { |
223 |
| - metadata.setResourceSize(Long.parseLong(metadataMap.get(Constants.RESOURCE_SIZE).getValue())); |
224 |
| - metadata.setResourceModified(convertToDate(metadataMap.get(Constants.MODIFIED))); |
225 |
| - |
226 |
| - try { |
227 |
| - metadata.setResourceUri(new URI(metadataMap.get(Constants.RESOURCE_URI).getValue())); |
228 |
| - } catch (URISyntaxException e) { |
229 |
| - LOGGER.warn( |
230 |
| - "Invalid resource URI of {} for {}", |
231 |
| - metadataMap.get(Constants.RESOURCE_URI).getValue(), |
232 |
| - id); |
233 |
| - } |
234 |
| - } |
235 |
| - |
236 |
| - metadataMap.get(Constants.METACARD_TAGS).getValues().forEach(metadata::addTag); |
237 |
| - MetacardAttribute origin = metadataMap.get(Replication.ORIGINS); |
238 |
| - if (origin != null) { |
239 |
| - origin.getValues().forEach(metadata::addLineage); |
240 |
| - } |
241 |
| - MetacardAttribute versionAction = metadataMap.get(Constants.ACTION); |
242 |
| - if (versionAction != null) { |
243 |
| - metadata.setIsDeleted(versionAction.getValue().startsWith("Deleted")); |
244 |
| - } |
245 |
| - metadataMap.remove(Constants.DERIVED_RESOURCE_URI); |
246 |
| - metadataMap.remove(Constants.DERIVED_RESOURCE_DOWNLOAD_URL); |
247 |
| - |
248 |
| - return metadata; |
249 |
| - } |
250 |
| - |
251 |
| - private static void parseToMap( |
252 |
| - HierarchicalStreamReader reader, Map<String, MetacardAttribute> metadataMap) { |
253 |
| - while (reader.hasMoreChildren()) { |
254 |
| - reader.moveDown(); |
255 |
| - |
256 |
| - String entryType = reader.getNodeName(); |
257 |
| - String attributeName = reader.getAttribute("name"); |
258 |
| - List<String> xmlns = new ArrayList<>(); |
259 |
| - int count = reader.getAttributeCount(); |
260 |
| - for (int i = 0; i < count; i++) { |
261 |
| - if (reader.getAttributeName(i).startsWith("xmlns")) { |
262 |
| - xmlns.add(reader.getAttributeName(i) + "=" + reader.getAttribute(i)); |
263 |
| - } |
264 |
| - } |
265 |
| - if (!reader.hasMoreChildren()) { |
266 |
| - metadataMap.put(entryType, new MetacardAttribute(entryType, null, reader.getValue())); |
267 |
| - reader.moveUp(); |
268 |
| - continue; |
269 |
| - } |
270 |
| - |
271 |
| - if (COMPLEX_TYPE.contains(entryType)) { |
272 |
| - reader.moveDown(); |
273 |
| - reader.moveDown(); |
274 |
| - StringWriter xmlWriter = new StringWriter(); |
275 |
| - copyXml(reader, xmlWriter, null); |
276 |
| - metadataMap.put( |
277 |
| - attributeName, |
278 |
| - new MetacardAttribute( |
279 |
| - attributeName, entryType, Collections.singletonList(xmlWriter.toString()), xmlns)); |
280 |
| - reader.moveUp(); |
281 |
| - reader.moveUp(); |
282 |
| - reader.moveUp(); |
283 |
| - continue; |
284 |
| - } |
285 |
| - List<String> values = new ArrayList<>(); |
286 |
| - while (reader.hasMoreChildren()) { |
287 |
| - reader.moveDown(); |
288 |
| - values.add(reader.getValue()); |
289 |
| - reader.moveUp(); |
290 |
| - } |
291 |
| - |
292 |
| - LOGGER.trace("attribute name: {} value: {}.", attributeName, values); |
293 |
| - if (StringUtils.isNotEmpty(attributeName) && !values.isEmpty()) { |
294 |
| - metadataMap.put( |
295 |
| - attributeName, new MetacardAttribute(attributeName, entryType, values, xmlns)); |
296 |
| - } |
297 |
| - |
298 |
| - reader.moveUp(); |
299 |
| - } |
| 64 | + return MetacardMarshaller.unmarshal(reader, namespaceMap); |
300 | 65 | }
|
301 | 66 | }
|
0 commit comments