Sonar issues clean-up
[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/epl-v10.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 import java.util.regex.Pattern;
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 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
19
20 /**
21  * YANG Schema source identifier
22  *
23  * Simple transfer object represents identifier of source for YANG schema (module or submodule),
24  * which consists of
25  * <ul>
26  * <li>YANG schema name ({@link #getName()}
27  * <li>Module revision (optional) ({link {@link #getRevision()})
28  * </ul>
29  *
30  * Source identifier is designated to be carry only necessary information
31  * to look-up YANG model source and to be used by various SchemaSourceProviders.
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     /**
49      *
50      * Simplified compiled revision pattern in format YYYY-mm-dd, which checks
51      * only distribution of number elements.
52      * <p>
53      * For checking if supplied string is real date, use {@link SimpleDateFormatUtil}
54      * instead.
55      *
56      */
57     public static final Pattern REVISION_PATTERN = Pattern.compile("\\d\\d\\d\\d-\\d\\d-\\d\\d");
58
59     private static final ObjectCache CACHE = ObjectCacheFactory.getObjectCache(SourceIdentifier.class);
60     private static final long serialVersionUID = 1L;
61     private final String revision;
62     private final String name;
63
64     /**
65      *
66      * Creates new YANG Schema source identifier for sources without revision.
67      * {@link SourceIdentifier#NOT_PRESENT_FORMATTED_REVISION} as default revision.
68      *
69      * @param name Name of schema
70      */
71     public SourceIdentifier(final String name) {
72         this(name, NOT_PRESENT_FORMATTED_REVISION);
73     }
74
75     /**
76      * Creates new YANG Schema source identifier.
77      *
78      * @param name Name of schema
79      * @param formattedRevision Revision of source in format YYYY-mm-dd
80      */
81     public SourceIdentifier(final String name, final String formattedRevision) {
82         this.name = Preconditions.checkNotNull(name);
83         this.revision = Preconditions.checkNotNull(formattedRevision);
84     }
85
86     /**
87      *
88      * Creates new YANG Schema source identifier.
89      *
90      * @param name Name of schema
91      * @param formattedRevision Revision of source in format YYYY-mm-dd. If not present, default value will be used.
92      */
93     public SourceIdentifier(final String name, final Optional<String> formattedRevision) {
94         this(name, formattedRevision.or(NOT_PRESENT_FORMATTED_REVISION));
95     }
96
97     /**
98      * Return a cached reference to an object equal to this object.
99      *
100      * @return A potentially shared reference, not guaranteed to be unique.
101      */
102     public SourceIdentifier cachedReference() {
103         return CACHE.getReference(this);
104     }
105
106     /**
107      * Returns model name
108      *
109      * @return model name
110      */
111     public String getName() {
112         return name;
113     }
114
115     /**
116      * Returns revision of source or null if revision was not supplied.
117      *
118      * @return revision of source or null if revision was not supplied.
119      */
120     public String getRevision() {
121         return revision;
122     }
123
124     @Override
125     public int hashCode() {
126         final int prime = 31;
127         int result = 1;
128         result = prime * result + ((name == null) ? 0 : name.hashCode());
129         result = prime * result + ((revision == null) ? 0 : revision.hashCode());
130         return result;
131     }
132
133     @Override
134     public boolean equals(final Object obj) {
135         if (this == obj) {
136             return true;
137         }
138         if (obj == null) {
139             return false;
140         }
141         if (getClass() != obj.getClass()) {
142             return false;
143         }
144         SourceIdentifier other = (SourceIdentifier) obj;
145         if (name == null) {
146             if (other.name != null) {
147                 return false;
148             }
149         } else if (!name.equals(other.name)) {
150             return false;
151         }
152         if (revision == null) {
153             if (other.revision != null) {
154                 return false;
155             }
156         } else if (!revision.equals(other.revision)) {
157             return false;
158         }
159         return true;
160     }
161
162     public static SourceIdentifier create(final String moduleName, final Optional<String> revision) {
163         return new SourceIdentifier(moduleName, revision);
164     }
165
166     /**
167      * Returns filename for this YANG module as specified in RFC 6020.
168      *
169      * Returns filename in format
170      * <code>name ['@' revision] '.yang'</code>
171      * <p>
172      * Where revision is  date in format YYYY-mm-dd.
173      * <p>
174      *
175      * @see <a href="http://tools.ietf.org/html/rfc6020#section-5.2">RFC6020</a>
176      *
177      * @return Filename for this source identifier.
178      */
179     public String toYangFilename() {
180         return toYangFileName(name, Optional.fromNullable(revision));
181     }
182
183     @Override
184     public String toString() {
185         return "SourceIdentifier [name=" + name + "@" + revision + "]";
186     }
187
188     /**
189      * Returns filename for this YANG module as specified in RFC 6020.
190      *
191      * Returns filename in format
192      * <code>moduleName ['@' revision] '.yang'</code>
193      *
194      * Where Where revision-date is in format YYYY-mm-dd.
195      *
196      * <p>
197      * See
198      * http://tools.ietf.org/html/rfc6020#section-5.2
199      *
200      * @return Filename for this source identifier.
201      */
202     public static final String toYangFileName(final String moduleName, final Optional<String> revision) {
203         StringBuilder filename = new StringBuilder(moduleName);
204         if (revision.isPresent()) {
205             filename.append('@');
206             filename.append(revision.get());
207         }
208         filename.append(".yang");
209         return filename.toString();
210     }
211
212 }