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