Fix eclipse/checkstyle warnings
[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.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 public final class QNameModule implements Immutable, Serializable {
23     private static final Interner<QNameModule> INTERNER = Interners.newWeakInterner();
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 = 2L;
27
28     //Nullable
29     private final URI namespace;
30
31     //Nullable
32     private final Date revision;
33
34     //Nullable
35     private transient volatile String formattedRevision;
36
37     private transient int hash;
38
39     private QNameModule(final URI namespace, final Date revision) {
40         // FIXME: 2.0.0: Preconditions.checkNotNull(namespace)
41         this.namespace = namespace;
42         this.revision = revision;
43     }
44
45     /**
46      * Return an interned reference to a equivalent QNameModule.
47      *
48      * @return Interned reference, or this object if it was interned.
49      */
50     public QNameModule intern() {
51         return INTERNER.intern(this);
52     }
53
54     /**
55      * Create a new QName module instance with specified namespace/revision.
56      *
57      * @param namespace Module namespace
58      * @param revision Module revision
59      * @return A new, potentially shared, QNameModule instance
60      */
61     public static QNameModule create(final URI namespace, final Date revision) {
62         if (namespace == null && revision == null) {
63             return NULL_INSTANCE;
64         }
65
66         return new QNameModule(namespace, revision);
67     }
68
69     public String getFormattedRevision() {
70         if (revision == null) {
71             return null;
72         }
73
74         String ret = formattedRevision;
75         if (ret == null) {
76             ret = SimpleDateFormatUtil.getRevisionFormat().format(revision);
77             formattedRevision = ret;
78         }
79
80         return ret;
81     }
82
83     /**
84      * Returns the namespace of the module which is specified as argument of
85      * YANG Module <b><font color="#00FF00">namespace</font></b> keyword.
86      *
87      * @return URI format of the namespace of the module
88      */
89     public URI getNamespace() {
90         return namespace;
91     }
92
93     /**
94      * Returns the revision date for the module.
95      *
96      * @return date of the module revision which is specified as argument of
97      *         YANG Module <b><font color="#339900">revison</font></b> keyword
98      */
99     // FIXME: BUG-4688: should return Optional<Revision>
100     public Date getRevision() {
101         return revision;
102     }
103
104     @Override
105     public int hashCode() {
106         if (hash == 0) {
107             hash = Objects.hash(namespace, revision);
108         }
109         return hash;
110     }
111
112     @Override
113     public boolean equals(final Object obj) {
114         if (this == obj) {
115             return true;
116         }
117         if (!(obj instanceof QNameModule)) {
118             return false;
119         }
120         final QNameModule other = (QNameModule) obj;
121         return Objects.equals(revision, other.revision) && Objects.equals(namespace, other.namespace);
122     }
123
124     /**
125      * Returns a namespace in form defined by section 5.6.4. of {@link https
126      * ://tools.ietf.org/html/rfc6020}, if namespace is not correctly defined,
127      * the method will return <code>null</code> <br>
128      * example "http://example.acme.com/system?revision=2008-04-01"
129      *
130      * @return namespace in form defined by section 5.6.4. of {@link https
131      *         ://tools.ietf.org/html/rfc6020}, if namespace is not correctly
132      *         defined, the method will return <code>null</code>
133      *
134      */
135     URI getRevisionNamespace() {
136         if (namespace == null) {
137             return null;
138         }
139
140         final String query = revision == null ? "" : "revision=" + getFormattedRevision();
141         try {
142             return new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(),
143                     namespace.getPort(), namespace.getPath(), query, namespace.getFragment());
144         } catch (final URISyntaxException e) {
145             LOG.error("Failed to construct URI for {}", this, e);
146             return null;
147         }
148     }
149
150     @Override
151     public String toString() {
152         return MoreObjects.toStringHelper(QNameModule.class).omitNullValues().add("ns", getNamespace())
153             .add("rev", getFormattedRevision()).toString();
154     }
155 }