X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-common%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fcommon%2FQNameModule.java;h=8b3db1cf824eaac4d3249768b47cd6d18f05f1c4;hb=f28f8d44ac8d55fa50539186cbcad2ba7b610bae;hp=bec56bf76fe77f54467ab5fc00e46d9f03eb1a59;hpb=0eb60011b52e4e56c62b47a36eb334f2c3b3ad6a;p=yangtools.git diff --git a/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QNameModule.java b/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QNameModule.java index bec56bf76f..8b3db1cf82 100644 --- a/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QNameModule.java +++ b/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QNameModule.java @@ -7,45 +7,48 @@ */ package org.opendaylight.yangtools.yang.common; +import static java.util.Objects.requireNonNull; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; -import java.util.Date; - +import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.concepts.Identifier; import org.opendaylight.yangtools.concepts.Immutable; -import org.opendaylight.yangtools.objcache.ObjectCache; -import org.opendaylight.yangtools.objcache.ObjectCacheFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.opendaylight.yangtools.concepts.WritableObject; -public final class QNameModule implements Immutable, Serializable { - private static final ObjectCache CACHE = ObjectCacheFactory.getObjectCache(QNameModule.class); - private static final Logger LOG = LoggerFactory.getLogger(QNameModule.class); - private static final QNameModule NULL_INSTANCE = new QNameModule(null, null); - private static final long serialVersionUID = 1L; +public final class QNameModule implements Comparable, Immutable, Serializable, Identifier, WritableObject { + private static final Interner INTERNER = Interners.newWeakInterner(); + private static final long serialVersionUID = 3L; - //Nullable - private final URI namespace; + private final @NonNull URI namespace; //Nullable - private final Date revision; + private final Revision revision; - //Nullable - private String formattedRevision; + private transient int hash = 0; - private QNameModule(final URI namespace, final Date revision) { - this.namespace = namespace; + private QNameModule(final @NonNull URI namespace, final Revision revision) { + this.namespace = requireNonNull(namespace); this.revision = revision; } /** - * Look up specified module in the global cache and return a shared reference. + * Return an interned reference to a equivalent QNameModule. * - * @param module Module instance - * @return Cached instance, according to {@link ObjectCache} policy. + * @return Interned reference, or this object if it was interned. */ - public static QNameModule cachedReference(final QNameModule module) { - return CACHE.getReference(module); + public QNameModule intern() { + return INTERNER.intern(this); } /** @@ -55,34 +58,48 @@ public final class QNameModule implements Immutable, Serializable { * @param revision Module revision * @return A new, potentially shared, QNameModule instance */ - public static QNameModule create(final URI namespace, final Date revision) { - if (namespace == null && revision == null) { - return NULL_INSTANCE; - } - - return new QNameModule(namespace, revision); + public static QNameModule create(final URI namespace, final Optional revision) { + return new QNameModule(namespace, revision.orElse(null)); } - public String getFormattedRevision() { - if (revision == null) { - return null; - } + /** + * Create a new QName module instance with specified namespace and norevision. + * + * @param namespace Module namespace + * @return A new, potentially shared, QNameModule instance + */ + public static QNameModule create(final URI namespace) { + return new QNameModule(namespace, null); + } - if (formattedRevision == null) { - synchronized (this) { - if (formattedRevision == null) { - formattedRevision = SimpleDateFormatUtil.getRevisionFormat().format(revision); - } - } - } + /** + * Create a new QName module instance with specified namespace/revision. + * + * @param namespace Module namespace + * @param revision Module revision + * @return A new, potentially shared, QNameModule instance + */ + public static QNameModule create(final URI namespace, @Nullable final Revision revision) { + return new QNameModule(namespace, revision); + } - return formattedRevision; + /** + * Read a QNameModule from a DataInput. The format is expected to match the output format + * of {@link #writeTo(DataOutput)}. + * + * @param in DataInput to read + * @return A QNameModule instance + * @throws IOException if I/O error occurs + */ + public static QNameModule readFrom(final DataInput in) throws IOException { + final String namespace = in.readUTF(); + final String revision = in.readUTF(); + return new QNameModule(URI.create(namespace), revision.isEmpty() ? null : Revision.of(revision)); } /** * Returns the namespace of the module which is specified as argument of - * YANG {@link Module namespace} - * keyword. + * YANG Module namespace keyword. * * @return URI format of the namespace of the module */ @@ -94,19 +111,44 @@ public final class QNameModule implements Immutable, Serializable { * Returns the revision date for the module. * * @return date of the module revision which is specified as argument of - * YANG {@link Module revison} - * keyword + * YANG Module revison keyword */ - public Date getRevision() { - return revision; + public Optional getRevision() { + return Optional.ofNullable(revision); + } + + @Override + @SuppressWarnings("checkstyle:parameterName") + public int compareTo(final QNameModule o) { + int cmp = namespace.compareTo(o.namespace); + if (cmp != 0) { + return cmp; + } + return Revision.compare(revision, o.revision); + } + + /** + * Returns a QNameModule with the same namespace, but with no revision. If this QNameModule does not have + * a revision, this object is returned. + * + * @return a QNameModule with the same namespace, but with no revision. + */ + public QNameModule withoutRevision() { + return revision == null ? this : new QNameModule(namespace, null); + } + + @Override + public void writeTo(final DataOutput out) throws IOException { + out.writeUTF(namespace.toString()); + out.writeUTF(revision == null ? "" : revision.toString()); } @Override public int hashCode() { - final int prime = 31; - int result = (namespace == null) ? 0 : namespace.hashCode(); - result = prime * result + ((revision == null) ? 0 : revision.hashCode()); - return result; + if (hash == 0) { + hash = Objects.hash(namespace, revision); + } + return hash; } @Override @@ -118,52 +160,27 @@ public final class QNameModule implements Immutable, Serializable { return false; } final QNameModule other = (QNameModule) obj; - if (revision == null) { - if (other.revision != null) { - return false; - } - } else if (!revision.equals(other.revision)) { - return false; - } - if (namespace == null) { - if (other.namespace != null) { - return false; - } - } else if (!namespace.equals(other.namespace)) { - return false; - } - return true; + return Objects.equals(revision, other.revision) && namespace.equals(other.namespace); } /** - * Returns a namespace in form defined by section 5.6.4. of {@link https - * ://tools.ietf.org/html/rfc6020}, if namespace is not correctly defined, - * the method will return null
- * example "http://example.acme.com/system?revision=2008-04-01" + * Returns a namespace in form defined by section 5.6.4. of + * RFC6020, for example + * {@code http://example.acme.com/system?revision=2008-04-01}. * - * @return namespace in form defined by section 5.6.4. of {@link https - * ://tools.ietf.org/html/rfc6020}, if namespace is not correctly - * defined, the method will return null + * @return Namespace in form defined by section 5.6.4. of RFC6020. + * @throws URISyntaxException on incorrect namespace definition * */ - URI getRevisionNamespace() { - - if (namespace == null) { - return null; - } - - String query = ""; - if (revision != null) { - query = "revision=" + getFormattedRevision(); - } + URI getRevisionNamespace() throws URISyntaxException { + final String query = revision == null ? "" : "revision=" + revision.toString(); + return new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(), namespace.getPort(), + namespace.getPath(), query, namespace.getFragment()); + } - URI compositeURI = null; - try { - compositeURI = new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(), - namespace.getPort(), namespace.getPath(), query, namespace.getFragment()); - } catch (URISyntaxException e) { - LOG.error("", e); - } - return compositeURI; + @Override + public String toString() { + return MoreObjects.toStringHelper(QNameModule.class).omitNullValues().add("ns", namespace) + .add("rev", revision).toString(); } }