Remove formattedRevision from serialization format
[yangtools.git] / yang / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / QNameModule.java
index 89a11c98eb2b56d736994e28a01e26cb0cfbb366..702a527c0c0805d5d491a4c585f20b95cedc9339 100644 (file)
@@ -7,18 +7,23 @@
  */
 package org.opendaylight.yangtools.yang.common;
 
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Interner;
+import com.google.common.collect.Interners;
 import java.io.Serializable;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Date;
-
+import java.util.Objects;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class QNameModule implements Immutable, Serializable {
-       private static final Logger LOG = LoggerFactory.getLogger(QNameModule.class);
-       private static final long serialVersionUID = 1L;
+    private static final Interner<QNameModule> INTERNER = Interners.newWeakInterner();
+    private static final Logger LOG = LoggerFactory.getLogger(QNameModule.class);
+    private static final QNameModule NULL_INSTANCE = new QNameModule(null, null);
+    private static final long serialVersionUID = 2L;
 
     //Nullable
     private final URI namespace;
@@ -27,40 +32,79 @@ public final class QNameModule implements Immutable, Serializable {
     private final Date revision;
 
     //Nullable
-    private final String formattedRevision;
+    private transient volatile String formattedRevision;
+
+    private transient int hash;
 
     private QNameModule(final URI namespace, final Date revision) {
         this.namespace = namespace;
         this.revision = revision;
-        if(revision != null) {
-            this.formattedRevision = SimpleDateFormatUtil.getRevisionFormat().format(revision);
-        } else {
-            this.formattedRevision = null;
+    }
+
+    /**
+     * Return an interned reference to a equivalent QNameModule.
+     *
+     * @return Interned reference, or this object if it was interned.
+     */
+    public QNameModule intern() {
+        return INTERNER.intern(this);
+    }
+
+    /**
+     * 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, final Date revision) {
+        if (namespace == null && revision == null) {
+            return NULL_INSTANCE;
         }
+
+        return new QNameModule(namespace, revision);
     }
 
-       public static QNameModule create(final URI namespace, final Date revision) {
-               return new QNameModule(namespace, revision);
-       }
+    public String getFormattedRevision() {
+        if (revision == null) {
+            return null;
+        }
 
-       public String getFormattedRevision() {
-               return formattedRevision;
-       }
+        String ret = formattedRevision;
+        if (ret == null) {
+            ret = SimpleDateFormatUtil.getRevisionFormat().format(revision);
+            formattedRevision = ret;
+        }
 
-       public URI getNamespace() {
-               return namespace;
-       }
+        return ret;
+    }
 
-       public Date getRevision() {
-               return revision;
-       }
+    /**
+     * Returns the namespace of the module which is specified as argument of
+     * YANG Module <b><font color="#00FF00">namespace</font></b> keyword.
+     *
+     * @return URI format of the namespace of the module
+     */
+    public URI getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * Returns the revision date for the module.
+     *
+     * @return date of the module revision which is specified as argument of
+     *         YANG Module <b><font color="#339900">revison</font></b> keyword
+     */
+    public Date getRevision() {
+        return revision;
+    }
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = (namespace == null) ? 0 : namespace.hashCode();
-        result = prime * result + ((formattedRevision == null) ? 0 : formattedRevision.hashCode());
-        return result;
+        if (hash == 0) {
+            hash = Objects.hash(namespace, revision);
+        }
+        return hash;
     }
 
     @Override
@@ -72,21 +116,7 @@ public final class QNameModule implements Immutable, Serializable {
             return false;
         }
         final QNameModule other = (QNameModule) obj;
-        if (namespace == null) {
-            if (other.namespace != null) {
-                return false;
-            }
-        } else if (!namespace.equals(other.namespace)) {
-            return false;
-        }
-        if (formattedRevision == null) {
-            if (other.formattedRevision != null) {
-                return false;
-            }
-        } else if (!revision.equals(other.revision)) {
-            return false;
-        }
-        return true;
+        return Objects.equals(revision, other.revision) && Objects.equals(namespace, other.namespace);
     }
 
     /**
@@ -101,23 +131,22 @@ public final class QNameModule implements Immutable, Serializable {
      *
      */
     URI getRevisionNamespace() {
-
         if (namespace == null) {
             return null;
         }
 
-        String query = "";
-        if (revision != null) {
-            query = "revision=" + formattedRevision;
-        }
-
-        URI compositeURI = null;
+        final String query = revision == null ? "" : "revision=" + getFormattedRevision();
         try {
-            compositeURI = new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(),
+            return new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(),
                     namespace.getPort(), namespace.getPath(), query, namespace.getFragment());
-        } catch (URISyntaxException e) {
-            LOG.error("", e);
+        } catch (final URISyntaxException e) {
+            LOG.error("Failed to construct URI for {}", this, e);
+            return null;
         }
-        return compositeURI;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(QNameModule.class).omitNullValues().add("ns", getNamespace()).add("rev", getFormattedRevision()).toString();
     }
 }