31a4b85212ea434cef116b2c8453aa837b8e6c5f
[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 static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.MoreObjects;
13 import com.google.common.collect.Interner;
14 import com.google.common.collect.Interners;
15 import java.io.Serializable;
16 import java.net.URI;
17 import java.net.URISyntaxException;
18 import java.util.Objects;
19 import java.util.Optional;
20 import javax.annotation.Nullable;
21 import org.opendaylight.yangtools.concepts.Immutable;
22
23 public final class QNameModule implements Immutable, Serializable {
24     private static final Interner<QNameModule> INTERNER = Interners.newWeakInterner();
25     private static final long serialVersionUID = 3L;
26
27     private final URI namespace;
28
29     //Nullable
30     private final Revision revision;
31
32     private transient int hash;
33
34     private QNameModule(final URI namespace, final Revision revision) {
35         this.namespace = requireNonNull(namespace);
36         this.revision = revision;
37     }
38
39     /**
40      * Return an interned reference to a equivalent QNameModule.
41      *
42      * @return Interned reference, or this object if it was interned.
43      */
44     public QNameModule intern() {
45         return INTERNER.intern(this);
46     }
47
48     /**
49      * Create a new QName module instance with specified namespace/revision.
50      *
51      * @param namespace Module namespace
52      * @param revision Module revision
53      * @return A new, potentially shared, QNameModule instance
54      */
55     public static QNameModule create(final URI namespace, final Optional<Revision> revision) {
56         return new QNameModule(namespace, revision.orElse(null));
57     }
58
59     /**
60      * Create a new QName module instance with specified namespace and norevision.
61      *
62      * @param namespace Module namespace
63      * @return A new, potentially shared, QNameModule instance
64      */
65     public static QNameModule create(final URI namespace) {
66         return new QNameModule(namespace, null);
67     }
68
69     /**
70      * Create a new QName module instance with specified namespace/revision.
71      *
72      * @param namespace Module namespace
73      * @param revision Module revision
74      * @return A new, potentially shared, QNameModule instance
75      */
76     public static QNameModule create(final URI namespace, @Nullable final Revision revision) {
77         return new QNameModule(namespace, revision);
78     }
79
80     public String getFormattedRevision() {
81         return revision == null ? null : revision.toString();
82     }
83
84     /**
85      * Returns the namespace of the module which is specified as argument of
86      * YANG Module <b><font color="#00FF00">namespace</font></b> keyword.
87      *
88      * @return URI format of the namespace of the module
89      */
90     public URI getNamespace() {
91         return namespace;
92     }
93
94     /**
95      * Returns the revision date for the module.
96      *
97      * @return date of the module revision which is specified as argument of
98      *         YANG Module <b><font color="#339900">revison</font></b> keyword
99      */
100     public Optional<Revision> getRevision() {
101         return Optional.ofNullable(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://tools.ietf.org/html/rfc6020}, for example
126      * {@code http://example.acme.com/system?revision=2008-04-01}.
127      *
128      * @return Namespace in form defined by section 5.6.4. of {@link https://tools.ietf.org/html/rfc6020}.
129      * @throws URISyntaxException on incorrect namespace definition
130      *
131      */
132     URI getRevisionNamespace() throws URISyntaxException {
133         final String query = revision == null ? "" : "revision=" + revision.toString();
134         return new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(), namespace.getPort(),
135             namespace.getPath(), query, namespace.getFragment());
136     }
137
138     @Override
139     public String toString() {
140         return MoreObjects.toStringHelper(QNameModule.class).omitNullValues().add("ns", getNamespace())
141             .add("rev", revision).toString();
142     }
143 }