Move netconf-dom-api
[netconf.git] / netconf / netconf-util / src / main / java / org / opendaylight / netconf / util / mapping / AbstractNetconfOperation.java
1 /*
2  * Copyright (c) 2013 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.util.mapping;
9
10 import java.util.Map;
11 import java.util.Optional;
12 import org.opendaylight.netconf.api.DocumentedException;
13 import org.opendaylight.netconf.api.xml.XmlElement;
14 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
15 import org.opendaylight.netconf.api.xml.XmlUtil;
16 import org.opendaylight.netconf.mapping.api.HandlingPriority;
17 import org.opendaylight.netconf.mapping.api.NetconfOperation;
18 import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
19 import org.w3c.dom.Attr;
20 import org.w3c.dom.Document;
21 import org.w3c.dom.Element;
22 import org.w3c.dom.NodeList;
23
24 public abstract class AbstractNetconfOperation implements NetconfOperation {
25     private final String netconfSessionIdForReporting;
26
27     protected AbstractNetconfOperation(final String netconfSessionIdForReporting) {
28         this.netconfSessionIdForReporting = netconfSessionIdForReporting;
29     }
30
31     public final String getNetconfSessionIdForReporting() {
32         return netconfSessionIdForReporting;
33     }
34
35     @Override
36     public HandlingPriority canHandle(final Document message) throws DocumentedException {
37         OperationNameAndNamespace operationNameAndNamespace = null;
38         operationNameAndNamespace = new OperationNameAndNamespace(message);
39         return canHandle(operationNameAndNamespace.getOperationName(), operationNameAndNamespace.getNamespace());
40     }
41
42     protected HandlingPriority canHandle(final String operationName, final String operationNamespace) {
43         return operationName.equals(getOperationName()) && operationNamespace.equals(getOperationNamespace())
44                 ? getHandlingPriority()
45                 : HandlingPriority.CANNOT_HANDLE;
46     }
47
48     public static final class OperationNameAndNamespace {
49         private final String operationName;
50         private final String namespace;
51
52         private final XmlElement operationElement;
53
54         public OperationNameAndNamespace(final Document message) throws DocumentedException {
55             XmlElement requestElement = null;
56             requestElement = getRequestElementWithCheck(message);
57             operationElement = requestElement.getOnlyChildElement();
58             operationName = operationElement.getName();
59             namespace = operationElement.getNamespace();
60         }
61
62         public String getOperationName() {
63             return operationName;
64         }
65
66         public String getNamespace() {
67             return namespace;
68         }
69
70         public XmlElement getOperationElement() {
71             return operationElement;
72         }
73
74     }
75
76     protected static XmlElement getRequestElementWithCheck(final Document message) throws DocumentedException {
77         return XmlElement.fromDomElementWithExpected(message.getDocumentElement(), XmlNetconfConstants.RPC_KEY,
78                 XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
79     }
80
81     protected HandlingPriority getHandlingPriority() {
82         return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
83     }
84
85     protected String getOperationNamespace() {
86         return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
87     }
88
89     protected abstract String getOperationName();
90
91     @Override
92     public Document handle(final Document requestMessage,
93             final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
94
95         XmlElement requestElement = getRequestElementWithCheck(requestMessage);
96
97         Document document = XmlUtil.newDocument();
98
99         XmlElement operationElement = requestElement.getOnlyChildElement();
100         Map<String, Attr> attributes = requestElement.getAttributes();
101
102         Element response = handle(document, operationElement, subsequentOperation);
103         Element rpcReply = XmlUtil.createElement(document, XmlNetconfConstants.RPC_REPLY_KEY,
104                 Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
105
106         if (XmlElement.fromDomElement(response).hasNamespace()) {
107             rpcReply.appendChild(response);
108         } else {
109             Element responseNS = XmlUtil.createElement(document, response.getNodeName(),
110                     Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
111             NodeList list = response.getChildNodes();
112             while (list.getLength() != 0) {
113                 responseNS.appendChild(list.item(0));
114             }
115             rpcReply.appendChild(responseNS);
116         }
117
118         for (Attr attribute : attributes.values()) {
119             rpcReply.setAttributeNode((Attr) document.importNode(attribute, true));
120         }
121         document.appendChild(rpcReply);
122         return document;
123     }
124
125     protected abstract Element handle(Document document, XmlElement message,
126                                       NetconfOperationChainedExecution subsequentOperation)
127             throws DocumentedException;
128
129     @Override
130     public String toString() {
131         final StringBuilder sb = new StringBuilder(getClass().getName());
132         try {
133             sb.append("{name=").append(getOperationName());
134         } catch (UnsupportedOperationException e) {
135             // no problem
136         }
137         sb.append(", namespace=").append(getOperationNamespace());
138         sb.append(", session=").append(netconfSessionIdForReporting);
139         sb.append('}');
140         return sb.toString();
141     }
142 }