Introduce restconf.server.{api,spi,mdsal}
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / server / mdsal / streams / dtcl / XMLDataTreeCandidateFormatter.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.restconf.server.mdsal.streams.dtcl;
9
10 import java.io.IOException;
11 import java.io.StringWriter;
12 import java.time.Instant;
13 import java.util.List;
14 import javax.xml.XMLConstants;
15 import javax.xml.stream.XMLStreamException;
16 import javax.xml.xpath.XPathExpressionException;
17 import org.opendaylight.restconf.server.spi.TextParameters;
18 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
19 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
20
21 final class XMLDataTreeCandidateFormatter extends DataTreeCandidateFormatter {
22     private static final XMLDataTreeCandidateFormatter EMPTY = new XMLDataTreeCandidateFormatter(TextParameters.EMPTY);
23
24     static final DataTreeCandidateFormatterFactory FACTORY = new DataTreeCandidateFormatterFactory(EMPTY) {
25         @Override
26         public XMLDataTreeCandidateFormatter getFormatter(final TextParameters textParams, final String xpathFilter)
27                 throws XPathExpressionException {
28             return new XMLDataTreeCandidateFormatter(textParams, xpathFilter);
29         }
30
31         @Override
32         public XMLDataTreeCandidateFormatter newFormatter(final TextParameters textParams) {
33             return new XMLDataTreeCandidateFormatter(textParams);
34         }
35     };
36
37     private XMLDataTreeCandidateFormatter(final TextParameters textParams) {
38         super(textParams);
39     }
40
41     private XMLDataTreeCandidateFormatter(final TextParameters textParams, final String xpathFilter)
42             throws XPathExpressionException {
43         super(textParams, xpathFilter);
44     }
45
46     @Override
47     protected String createText(final TextParameters params, final EffectiveModelContext schemaContext,
48             final List<DataTreeCandidate> input, final Instant now) throws Exception {
49         final var writer = new StringWriter();
50         boolean nonEmpty = false;
51         try {
52             final var xmlStreamWriter = createStreamWriterWithNotification(writer, now);
53             xmlStreamWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, DATA_CHANGED_NOTIFICATION_ELEMENT,
54                 DATA_CHANGED_NOTIFICATION_NS);
55             xmlStreamWriter.writeDefaultNamespace(DATA_CHANGED_NOTIFICATION_NS);
56
57             final var serializer = new XMLDataTreeCandidateSerializer(schemaContext, xmlStreamWriter);
58             for (var candidate : input) {
59                 nonEmpty |= serializer.serialize(candidate, params);
60             }
61
62             // data-changed-notification
63             xmlStreamWriter.writeEndElement();
64
65             // notification
66             xmlStreamWriter.writeEndElement();
67             xmlStreamWriter.close();
68         } catch (XMLStreamException e) {
69             throw new IOException("Failed to write notification content", e);
70         }
71
72         return nonEmpty ? writer.toString() : null;
73     }
74 }