Bump MRI upstreams
[netconf.git] / restconf / restconf-nb-bierman02 / src / main / java / org / opendaylight / netconf / sal / streams / listeners / AbstractNotificationsData.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.sal.streams.listeners;
9
10 import java.io.ByteArrayOutputStream;
11 import java.io.IOException;
12 import java.nio.charset.StandardCharsets;
13 import java.time.Instant;
14 import java.time.OffsetDateTime;
15 import java.time.ZoneId;
16 import java.time.format.DateTimeFormatter;
17 import javax.xml.stream.XMLOutputFactory;
18 import javax.xml.stream.XMLStreamException;
19 import javax.xml.stream.XMLStreamWriter;
20 import javax.xml.transform.OutputKeys;
21 import javax.xml.transform.Transformer;
22 import javax.xml.transform.TransformerException;
23 import javax.xml.transform.TransformerFactory;
24 import javax.xml.transform.dom.DOMResult;
25 import javax.xml.transform.dom.DOMSource;
26 import javax.xml.transform.stream.StreamResult;
27 import org.opendaylight.yangtools.util.xml.UntrustedXML;
28 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
30 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
31 import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
32 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
33 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.w3c.dom.Document;
37 import org.w3c.dom.Element;
38
39 /**
40  * Abstract class for processing and preparing data.
41  *
42  */
43 abstract class AbstractNotificationsData {
44     private static final Logger LOG = LoggerFactory.getLogger(AbstractNotificationsData.class);
45     private static final TransformerFactory TF = TransformerFactory.newInstance();
46     private static final XMLOutputFactory OF = XMLOutputFactory.newFactory();
47
48     /**
49      * Formats data specified by RFC3339.
50      *
51      * @param now time stamp
52      * @return Data specified by RFC3339.
53      */
54     protected static String toRFC3339(final Instant now) {
55         return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(now, ZoneId.systemDefault()));
56     }
57
58     /**
59      * Creates {@link Document} document.
60      *
61      * @return {@link Document} document.
62      */
63     protected static Document createDocument() {
64         return UntrustedXML.newDocumentBuilder().newDocument();
65     }
66
67     /**
68      * Write normalized node to {@link DOMResult}.
69      *
70      * @param normalized
71      *            data
72      * @param context
73      *            actual schema context
74      * @param schemaPath
75      *            schema path of data
76      * @return {@link DOMResult}
77      */
78     protected DOMResult writeNormalizedNode(final NormalizedNode normalized, final EffectiveModelContext context,
79             final SchemaPath schemaPath) throws IOException, XMLStreamException {
80         final Document doc = UntrustedXML.newDocumentBuilder().newDocument();
81         final DOMResult result = new DOMResult(doc);
82         NormalizedNodeWriter normalizedNodeWriter = null;
83         NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
84         XMLStreamWriter writer = null;
85
86         try {
87             writer = OF.createXMLStreamWriter(result);
88             normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, context, schemaPath);
89             normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter);
90
91             normalizedNodeWriter.write(normalized);
92
93             normalizedNodeWriter.flush();
94         } finally {
95             if (normalizedNodeWriter != null) {
96                 normalizedNodeWriter.close();
97             }
98             if (normalizedNodeStreamWriter != null) {
99                 normalizedNodeStreamWriter.close();
100             }
101             if (writer != null) {
102                 writer.close();
103             }
104         }
105
106         return result;
107     }
108
109     /**
110      * Generating base element of every notification.
111      *
112      * @param doc
113      *            base {@link Document}
114      * @return element of {@link Document}
115      */
116     protected Element basePartDoc(final Document doc) {
117         final Element notificationElement =
118                 doc.createElementNS("urn:ietf:params:xml:ns:netconf:notification:1.0", "notification");
119
120         doc.appendChild(notificationElement);
121
122         final Element eventTimeElement = doc.createElement("eventTime");
123         eventTimeElement.setTextContent(toRFC3339(Instant.now()));
124         notificationElement.appendChild(eventTimeElement);
125
126         return notificationElement;
127     }
128
129     /**
130      * Generating of {@link Document} transforming to string.
131      *
132      * @param doc
133      *            {@link Document} with data
134      * @return - string from {@link Document}
135      */
136     protected String transformDoc(final Document doc) {
137         final ByteArrayOutputStream out = new ByteArrayOutputStream();
138
139         try {
140             final Transformer transformer = TF.newTransformer();
141             transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
142             transformer.setOutputProperty(OutputKeys.METHOD, "xml");
143             transformer.setOutputProperty(OutputKeys.INDENT, "yes");
144             transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
145             transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
146             transformer.transform(new DOMSource(doc), new StreamResult(out));
147         } catch (final TransformerException e) {
148             // FIXME: this should raise an exception
149             final String msg = "Error during transformation of Document into String";
150             LOG.error(msg, e);
151             return msg;
152         }
153
154         return new String(out.toByteArray(), StandardCharsets.UTF_8);
155     }
156 }