/* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ 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 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; //Nullable private final Date revision; //Nullable private transient volatile String formattedRevision; private transient int hash; private QNameModule(final URI namespace, final Date revision) { // FIXME: 2.0.0: Preconditions.checkNotNull(namespace) this.namespace = namespace; this.revision = revision; } /** * 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 String getFormattedRevision() { if (revision == null) { return null; } String ret = formattedRevision; if (ret == null) { ret = SimpleDateFormatUtil.getRevisionFormat().format(revision); formattedRevision = ret; } return ret; } /** * 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 */ // FIXME: BUG-4688: should return Optional<Revision> public Date getRevision() { return revision; } @Override public int hashCode() { if (hash == 0) { hash = Objects.hash(namespace, revision); } return hash; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (!(obj instanceof QNameModule)) { return false; } final QNameModule other = (QNameModule) obj; return Objects.equals(revision, other.revision) && Objects.equals(namespace, 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 <code>null</code> <br> * example "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 <code>null</code> * */ URI getRevisionNamespace() { if (namespace == null) { return null; } final String query = revision == null ? "" : "revision=" + getFormattedRevision(); try { return new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(), namespace.getPort(), namespace.getPath(), query, namespace.getFragment()); } catch (final URISyntaxException e) { LOG.error("Failed to construct URI for {}", this, e); return null; } } @Override public String toString() { return MoreObjects.toStringHelper(QNameModule.class).omitNullValues().add("ns", getNamespace()).add("rev", getFormattedRevision()).toString(); } }