Fix warnings in mdsal-netconf-connector
[netconf.git] / netconf / mdsal-netconf-connector / src / main / java / org / opendaylight / netconf / mdsal / connector / ops / get / UniversalNamespaceContextImpl.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies 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
9 package org.opendaylight.netconf.mdsal.connector.ops.get;
10
11 import java.util.HashMap;
12 import java.util.Iterator;
13 import java.util.Map;
14 import javax.xml.XMLConstants;
15 import javax.xml.namespace.NamespaceContext;
16 import org.w3c.dom.Attr;
17 import org.w3c.dom.Document;
18 import org.w3c.dom.NamedNodeMap;
19 import org.w3c.dom.Node;
20 import org.w3c.dom.NodeList;
21
22 public class UniversalNamespaceContextImpl implements NamespaceContext {
23     private static final String DEFAULT_NS = "DEFAULT";
24     private final Map<String, String> prefix2Uri = new HashMap<>();
25     private final Map<String, String> uri2Prefix = new HashMap<>();
26
27     /**
28      * This constructor parses the document and stores all namespaces it can
29      * find. If toplevelOnly is true, only namespaces in the root are used.
30      *
31      * @param document     source document
32      * @param toplevelOnly restriction of the search to enhance performance
33      */
34     public UniversalNamespaceContextImpl(final Document document, final boolean toplevelOnly) {
35         readNode(document.getFirstChild(), toplevelOnly);
36     }
37
38     /**
39      * A single node is read, the namespace attributes are extracted and stored.
40      *
41      * @param node            to examine
42      * @param attributesOnly  if true no recursion happens
43      */
44     private void readNode(final Node node, final boolean attributesOnly) {
45         final NamedNodeMap attributes = node.getAttributes();
46         for (int i = 0; i < attributes.getLength(); i++) {
47             final Node attribute = attributes.item(i);
48             storeAttr((Attr) attribute);
49         }
50
51         if (!attributesOnly) {
52             final NodeList chields = node.getChildNodes();
53             for (int i = 0; i < chields.getLength(); i++) {
54                 final Node chield = chields.item(i);
55                 if (chield.getNodeType() == Node.ELEMENT_NODE) {
56                     readNode(chield, false);
57                 }
58             }
59         }
60     }
61
62     /**
63      * This method looks at an attribute and stores it, if it is a namespace
64      * attribute.
65      *
66      * @param attribute to examine
67      */
68     private void storeAttr(final Attr attribute) {
69         // examine the attributes in namespace xmlns
70         if (attribute.getNamespaceURI() != null
71                 && attribute.getNamespaceURI().equals(
72                 XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
73             // Default namespace xmlns="uri goes here"
74             if (attribute.getNodeName().equals(XMLConstants.XMLNS_ATTRIBUTE)) {
75                 putInCache(DEFAULT_NS, attribute.getNodeValue());
76             } else {
77                 // The defined prefixes are stored here
78                 putInCache(attribute.getLocalName(), attribute.getNodeValue());
79             }
80         }
81
82     }
83
84     private void putInCache(final String prefix, final String uri) {
85         prefix2Uri.put(prefix, uri);
86         uri2Prefix.put(uri, prefix);
87     }
88
89     /**
90      * This method is called by XPath. It returns the default namespace, if the
91      * prefix is null or "".
92      *
93      * @param prefix to search for
94      * @return uri
95      */
96     @Override
97     public String getNamespaceURI(final String prefix) {
98         if (prefix == null || prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
99             return prefix2Uri.get(DEFAULT_NS);
100         } else {
101             return prefix2Uri.get(prefix);
102         }
103     }
104
105     /**
106      * This method is not needed in this context, but can be implemented in a
107      * similar way.
108      */
109     @Override
110     public String getPrefix(final String namespaceURI) {
111         return uri2Prefix.get(namespaceURI);
112     }
113
114     @Override
115     public Iterator<String> getPrefixes(final String namespaceURI) {
116         // Not implemented
117         return null;
118     }
119
120 }