Merge "BUG-1793: make sure we cache QNameModule"
[yangtools.git] / yang / yang-model-api / src / main / java / org / opendaylight / yangtools / yang / model / repo / api / SourceIdentifier.java
1 /*
2  * Copyright (c) 2014 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/eplv10.html
7  */
8 package org.opendaylight.yangtools.yang.model.repo.api;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13
14 import org.opendaylight.yangtools.concepts.Identifier;
15 import org.opendaylight.yangtools.concepts.Immutable;
16 import org.opendaylight.yangtools.objcache.ObjectCache;
17 import org.opendaylight.yangtools.objcache.ObjectCacheFactory;
18
19 /**
20  * YANG Schema source identifier
21  *
22  * Simple transfer object represents identifier of source for YANG schema (module or submodule),
23  * which consists of
24  * <ul>
25  * <li>YANG schema name ({@link #getName()}
26  * <li>Module revision (optional) ({link {@link #getRevision()})
27  * </ul>
28  *
29  * Source identifier is designated to be carry only necessary information
30  * to look-up YANG model source and to be used by {@link AdvancedSchemaSourceProvider}
31  * and similar.
32  *
33  * <b>Note:</b>On source retrieval layer it is impossible to distinguish
34  * between YANG module and/or submodule unless source is present.
35  *
36  * <p>
37  * (For further reference see: http://tools.ietf.org/html/rfc6020#section-5.2 and
38  * http://tools.ietf.org/html/rfc6022#section-3.1 ).
39  */
40 @Beta
41 public final class SourceIdentifier implements Identifier, Immutable {
42     /**
43      * Default revision for sources without specified revision.
44      * Marks the source as oldest.
45      */
46     public static final String NOT_PRESENT_FORMATTED_REVISION = "0000-00-00";
47
48     private static final ObjectCache CACHE = ObjectCacheFactory.getObjectCache(SourceIdentifier.class);
49     private static final long serialVersionUID = 1L;
50     private final String revision;
51     private final String name;
52
53     /**
54      * Creates new YANG Schema source identifier.
55      *
56      * @param name Name of schema
57      * @param formattedRevision Revision of source in format YYYY-mm-dd
58      */
59     public SourceIdentifier(final String name, final String formattedRevision) {
60         this.name = Preconditions.checkNotNull(name);
61         this.revision = Preconditions.checkNotNull(formattedRevision);
62     }
63
64     /**
65      *
66      * Creates new YANG Schema source identifier.
67      *
68      * @param name Name of schema
69      * @param formattedRevision Revision of source in format YYYY-mm-dd. If not present, default value will be used.
70      */
71     public SourceIdentifier(final String name, final Optional<String> formattedRevision) {
72         this(name, formattedRevision.or(NOT_PRESENT_FORMATTED_REVISION));
73     }
74
75     /**
76      * Return a cached reference to an object equal to this object.
77      *
78      * @return A potentially shared reference, not guaranteed to be unique.
79      */
80     public SourceIdentifier cachedReference() {
81         return CACHE.getReference(this);
82     }
83
84     /**
85      *
86      * Creates new YANG Schema source identifier for sources without revision.
87      * {@link SourceIdentifier#NOT_PRESENT_FORMATTED_REVISION} as default revision.
88      *
89      * @param name Name of schema
90      */
91     public SourceIdentifier(final String name) {
92         this(name, NOT_PRESENT_FORMATTED_REVISION);
93     }
94
95     /**
96      * Returns model name
97      *
98      * @return model name
99      */
100     public String getName() {
101         return name;
102     }
103
104     /**
105      * Returns revision of source or null if revision was not supplied.
106      *
107      * @return revision of source or null if revision was not supplied.
108      */
109     public String getRevision() {
110         return revision;
111     }
112
113     @Override
114     public int hashCode() {
115         final int prime = 31;
116         int result = 1;
117         result = prime * result + ((name == null) ? 0 : name.hashCode());
118         result = prime * result + ((revision == null) ? 0 : revision.hashCode());
119         return result;
120     }
121
122     @Override
123     public boolean equals(final Object obj) {
124         if (this == obj) {
125             return true;
126         }
127         if (obj == null) {
128             return false;
129         }
130         if (getClass() != obj.getClass()) {
131             return false;
132         }
133         SourceIdentifier other = (SourceIdentifier) obj;
134         if (name == null) {
135             if (other.name != null) {
136                 return false;
137             }
138         } else if (!name.equals(other.name)) {
139             return false;
140         }
141         if (revision == null) {
142             if (other.revision != null) {
143                 return false;
144             }
145         } else if (!revision.equals(other.revision)) {
146             return false;
147         }
148         return true;
149     }
150
151     public static SourceIdentifier create(final String moduleName, final Optional<String> revision) {
152         return new SourceIdentifier(moduleName, revision);
153     }
154
155     /**
156      * Returns filename for this YANG module as specified in RFC 6020.
157      *
158      * Returns filename in format
159      * <code>name ['@' revision] '.yang'</code>
160      * <p>
161      * Where revision is  date in format YYYY-mm-dd.
162      * <p>
163      *
164      * @see http://tools.ietf.org/html/rfc6020#section-5.2
165      *
166      * @return Filename for this source identifier.
167      */
168     public String toYangFilename() {
169         return toYangFileName(name, Optional.fromNullable(revision));
170     }
171
172     @Override
173     public String toString() {
174         return "SourceIdentifier [name=" + name + "@" + revision + "]";
175     }
176
177     /**
178      * Returns filename for this YANG module as specified in RFC 6020.
179      *
180      * Returns filename in format
181      * <code>moduleName ['@' revision] '.yang'</code>
182      *
183      * Where Where revision-date is in format YYYY-mm-dd.
184      *
185      * <p>
186      * See
187      * http://tools.ietf.org/html/rfc6020#section-5.2
188      *
189      * @return Filename for this source identifier.
190      */
191     public static final String toYangFileName(final String moduleName, final Optional<String> revision) {
192         StringBuilder filename = new StringBuilder(moduleName);
193         if (revision.isPresent()) {
194             filename.append('@');
195             filename.append(revision.get());
196         }
197         filename.append(".yang");
198         return filename.toString();
199     }
200
201 }