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