Revert "Revert "Bug 3874: Support of yang modeled AnyXML - API""
[yangtools.git] / yang / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / QNameModule.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 com.google.common.base.MoreObjects;
11 import com.google.common.collect.Interner;
12 import com.google.common.collect.Interners;
13 import java.io.Serializable;
14 import java.net.URI;
15 import java.net.URISyntaxException;
16 import java.util.Date;
17 import java.util.Objects;
18 import org.opendaylight.yangtools.concepts.Immutable;
19 import org.opendaylight.yangtools.objcache.ObjectCache;
20 import org.opendaylight.yangtools.objcache.ObjectCacheFactory;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 public final class QNameModule implements Immutable, Serializable {
25     private static final Interner<QNameModule> INTERNER = Interners.newWeakInterner();
26     private static final ObjectCache CACHE = ObjectCacheFactory.getObjectCache(QNameModule.class);
27     private static final Logger LOG = LoggerFactory.getLogger(QNameModule.class);
28     private static final QNameModule NULL_INSTANCE = new QNameModule(null, null);
29     private static final long serialVersionUID = 1L;
30
31     //Nullable
32     private final URI namespace;
33
34     //Nullable
35     private final Date revision;
36
37     //Nullable
38     private volatile String formattedRevision;
39
40     private QNameModule(final URI namespace, final Date revision) {
41         this.namespace = namespace;
42         this.revision = revision;
43     }
44
45     /**
46      * Look up specified module in the global cache and return a shared reference.
47      *
48      * @param module Module instance
49      * @return Cached instance, according to {@link ObjectCache} policy.
50      *
51      * @deprecated Use {@link #intern()} instead.
52      */
53     @Deprecated
54     public static QNameModule cachedReference(final QNameModule module) {
55         return CACHE.getReference(module);
56     }
57
58     /**
59      * Return an interned reference to a equivalent QNameModule.
60      *
61      * @return Interned reference, or this object if it was interned.
62      */
63     public QNameModule intern() {
64         return INTERNER.intern(this);
65     }
66
67     /**
68      * Create a new QName module instance with specified namespace/revision.
69      *
70      * @param namespace Module namespace
71      * @param revision Module revision
72      * @return A new, potentially shared, QNameModule instance
73      */
74     public static QNameModule create(final URI namespace, final Date revision) {
75         if (namespace == null && revision == null) {
76             return NULL_INSTANCE;
77         }
78
79         return new QNameModule(namespace, revision);
80     }
81
82     public String getFormattedRevision() {
83         if (revision == null) {
84             return null;
85         }
86
87         String ret = formattedRevision;
88         if (ret == null) {
89             ret = SimpleDateFormatUtil.getRevisionFormat().format(revision);
90             formattedRevision = ret;
91         }
92
93         return ret;
94     }
95
96     /**
97      * Returns the namespace of the module which is specified as argument of
98      * YANG Module <b><font color="#00FF00">namespace</font></b> keyword.
99      *
100      * @return URI format of the namespace of the module
101      */
102     public URI getNamespace() {
103         return namespace;
104     }
105
106     /**
107      * Returns the revision date for the module.
108      *
109      * @return date of the module revision which is specified as argument of
110      *         YANG Module <b><font color="#339900">revison</font></b> keyword
111      */
112     public Date getRevision() {
113         return revision;
114     }
115
116     @Override
117     public int hashCode() {
118         final int prime = 31;
119         int result = Objects.hashCode(namespace);
120         result = prime * result + Objects.hashCode(revision);
121         return result;
122     }
123
124     @Override
125     public boolean equals(final Object obj) {
126         if (this == obj) {
127             return true;
128         }
129         if (!(obj instanceof QNameModule)) {
130             return false;
131         }
132         final QNameModule other = (QNameModule) obj;
133         if (!Objects.equals(revision, other.revision)) {
134             return false;
135         }
136         if (!Objects.equals(namespace, other.namespace)) {
137             return false;
138         }
139         return true;
140     }
141
142     /**
143      * Returns a namespace in form defined by section 5.6.4. of {@link https
144      * ://tools.ietf.org/html/rfc6020}, if namespace is not correctly defined,
145      * the method will return <code>null</code> <br>
146      * example "http://example.acme.com/system?revision=2008-04-01"
147      *
148      * @return namespace in form defined by section 5.6.4. of {@link https
149      *         ://tools.ietf.org/html/rfc6020}, if namespace is not correctly
150      *         defined, the method will return <code>null</code>
151      *
152      */
153     URI getRevisionNamespace() {
154
155         if (namespace == null) {
156             return null;
157         }
158
159         String query = "";
160         if (revision != null) {
161             query = "revision=" + getFormattedRevision();
162         }
163
164         URI compositeURI = null;
165         try {
166             compositeURI = new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(),
167                     namespace.getPort(), namespace.getPath(), query, namespace.getFragment());
168         } catch (final URISyntaxException e) {
169             LOG.error("", e);
170         }
171         return compositeURI;
172     }
173
174     @Override
175     public String toString() {
176         return MoreObjects.toStringHelper(this).omitNullValues().add("ns", getNamespace()).add("rev", getFormattedRevision()).toString();
177     }
178 }