Fixing sonar issues 3
[yangtools.git] / yang / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / QName.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.yangtools.yang.common;
9
10 import java.net.URI;
11 import java.net.URISyntaxException;
12
13 import java.text.SimpleDateFormat;
14 import java.util.Date;
15
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 /**
20  * The QName from XML consists of local name of element and XML namespace, but
21  * for our use, we added module revision to it.
22  * 
23  * In YANG context QName is full name of defined node, type, procedure or
24  * notification. QName consists of XML namespace, YANG model revision and local
25  * name of defined type. It is used to prevent name clashes between nodes with
26  * same local name, but from different schemas.
27  * 
28  * <ul>
29  * <li><b>XMLNamespace</b> - the namespace assigned to the YANG module which
30  * defined element, type, procedure or notification.</li>
31  * <li><b>Revision</b> - the revision of the YANG module which describes the
32  * element</li>
33  * <li><b>LocalName</b> - the YANG schema identifier which were defined for this
34  * node in the YANG module</li>
35  * </ul>
36  * 
37  * 
38  */
39 public final class QName {
40     protected static final Logger LOGGER = LoggerFactory.getLogger(QName.class);
41
42     private SimpleDateFormat revisionFormat = new SimpleDateFormat("yyyy-MM-dd");
43
44     private final URI namespace;
45     private final String localName;
46     private final String prefix;
47     private final Date revision;
48
49     /**
50      * QName Constructor.
51      * 
52      * @param namespace
53      *            the namespace assigned to the YANG module
54      * @param revision
55      *            the revision of the YANG module
56      * @param prefix
57      *            locally defined prefix assigned to local name
58      * @param localName
59      *            YANG schema identifier
60      */
61     public QName(URI namespace, Date revision, String prefix, String localName) {
62         this.namespace = namespace;
63         this.localName = localName;
64         this.revision = revision;
65         this.prefix = prefix;
66     }
67
68     /**
69      * QName Constructor.
70      * 
71      * @param namespace
72      *            the namespace assigned to the YANG module
73      * @param localName
74      *            YANG schema identifier
75      */
76     public QName(URI namespace, String localName) {
77         this(namespace, null, "", localName);
78     }
79
80     /**
81      * QName Constructor.
82      * 
83      * @param namespace
84      *            the namespace assigned to the YANG module
85      * @param revision
86      *            the revision of the YANG module
87      * @param localName
88      *            YANG schema identifier
89      */
90     public QName(URI namespace, Date revision, String localName) {
91         this(namespace, revision, null, localName);
92     }
93
94     public QName(QName base, String localName) {
95         this(base.getNamespace(), base.getRevision(), base.getPrefix(), localName);
96     }
97
98     /**
99      * Returns XMLNamespace assigned to the YANG module.
100      * 
101      * @return XMLNamespace assigned to the YANG module.
102      */
103     public URI getNamespace() {
104         return namespace;
105     }
106
107     /**
108      * Returns YANG schema identifier which were defined for this node in the
109      * YANG module
110      * 
111      * @return YANG schema identifier which were defined for this node in the
112      *         YANG module
113      */
114     public String getLocalName() {
115         return localName;
116     }
117
118     /**
119      * Returns revision of the YANG module if the module has defined revision,
120      * otherwise returns <code>null</code>
121      * 
122      * @return revision of the YANG module if the module has defined revision,
123      *         otherwise returns <code>null</code>
124      */
125     public Date getRevision() {
126         return revision;
127     }
128
129     /**
130      * Returns locally defined prefix assigned to local name
131      * 
132      * @return locally defined prefix assigned to local name
133      */
134     public String getPrefix() {
135         return prefix;
136     }
137
138     @Override
139     public int hashCode() {
140         final int prime = 31;
141         int result = 1;
142         result = prime * result + ((localName == null) ? 0 : localName.hashCode());
143         result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
144         result = prime * result + ((revision == null) ? 0 : revision.hashCode());
145         return result;
146     }
147
148     @Override
149     public boolean equals(Object obj) {
150         if (this == obj) {
151             return true;
152         }
153         if (obj == null) {
154             return false;
155         }
156         if (getClass() != obj.getClass()) {
157             return false;
158         }
159         QName other = (QName) obj;
160         if (localName == null) {
161             if (other.localName != null) {
162                 return false;
163             }
164         } else if (!localName.equals(other.localName)) {
165             return false;
166         }
167         if (namespace == null) {
168             if (other.namespace != null) {
169                 return false;
170             }
171         } else if (!namespace.equals(other.namespace)) {
172             return false;
173         }
174         if (revision == null) {
175             if (other.revision != null) {
176                 return false;
177             }
178         } else if (!revision.equals(other.revision)) {
179             return false;
180         }
181         return true;
182     }
183
184     @Override
185     public String toString() {
186         StringBuilder sb = new StringBuilder();
187         if (namespace != null) {
188             sb.append("(" + namespace);
189
190             if (revision != null) {
191                 sb.append("?revision=" + revisionFormat.format(revision));
192             }
193             sb.append(")");
194         }
195         sb.append(localName);
196         return sb.toString();
197     }
198
199     /**
200      * Returns a namespace in form defined by section 5.6.4. of {@link https
201      * ://tools.ietf.org/html/rfc6020}, if namespace is not correctly defined,
202      * the method will return <code>null</code> <br>
203      * example "http://example.acme.com/system?revision=2008-04-01"
204      * 
205      * @return namespace in form defined by section 5.6.4. of {@link https
206      *         ://tools.ietf.org/html/rfc6020}, if namespace is not correctly
207      *         defined, the method will return <code>null</code>
208      * 
209      */
210     URI getRevisionNamespace() {
211
212         if (namespace == null) {
213             return null;
214         }
215
216         String query = "";
217         if (revision != null) {
218             query = "revision=" + revisionFormat.format(revision);
219         }
220
221         URI compositeURI = null;
222         try {
223             compositeURI = new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(),
224                     namespace.getPort(), namespace.getPath(), query, namespace.getFragment());
225         } catch (URISyntaxException e) {
226             LOGGER.error("", e);
227         }
228         return compositeURI;
229     }
230 }