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