package org.opendaylight.yangtools.yang.common;
import static org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil.getRevisionFormat;
-
import com.google.common.base.Preconditions;
+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.regex.Matcher;
import java.util.regex.Pattern;
import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.objcache.ObjectCache;
-import org.opendaylight.yangtools.objcache.ObjectCacheFactory;
/**
* The QName from XML consists of local name of element and XML namespace, but
*
*/
public final class QName implements Immutable, Serializable, Comparable<QName> {
- private static final ObjectCache CACHE = ObjectCacheFactory.getObjectCache(QName.class);
+ private static final Interner<QName> INTERNER = Interners.newWeakInterner();
private static final long serialVersionUID = 5398411242927766414L;
static final String QNAME_REVISION_DELIMITER = "?revision=";
* Look up specified QName in the global cache and return a shared reference.
*
* @param qname QName instance
- * @return Cached instance, according to {@link ObjectCache} policy.
+ * @return Cached instance, according to {@link org.opendaylight.yangtools.objcache.ObjectCache} policy.
+ *
+ * @deprecated Use {@link #intern()} instead.
*/
+ @Deprecated
public static QName cachedReference(final QName qname) {
- // We also want to make sure we keep the QNameModule cached
- final QNameModule myMod = qname.getModule();
- final QNameModule cacheMod = QNameModule.cachedReference(myMod);
-
- final QName what;
- if (cacheMod.equals(myMod)) {
- what = qname;
- } else {
- what = QName.create(cacheMod, qname.localName);
- }
-
- return CACHE.getReference(what);
+ return qname.intern();
}
/**
return module.getRevision();
}
+ /**
+ * Return an interned reference to a equivalent QName.
+ *
+ * @return Interned reference, or this object if it was interned.
+ */
+ public QName intern() {
+ // We also want to make sure we keep the QNameModule cached
+ final QNameModule cacheMod = module.intern();
+
+ // Identity comparison is here on purpose, as we are deciding whether to potentially store 'qname' into the
+ // interner. It is important that it does not hold user-supplied reference (such a String instance from
+ // parsing of an XML document).
+ final QName template = cacheMod == module ? this : QName.create(cacheMod, localName);
+
+ return INTERNER.intern(template);
+ }
+
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((localName == null) ? 0 : localName.hashCode());
+ result = prime * result + Objects.hashCode(localName);
result = prime * result + module.hashCode();
return result;
}
return false;
}
final QName other = (QName) obj;
- if (localName == null) {
- if (other.localName != null) {
- return false;
- }
- } else if (!localName.equals(other.localName)) {
- return false;
- }
- return module.equals(other.module);
+ return Objects.equals(localName, other.localName) && module.equals(other.module);
}
public static QName create(final QName base, final String localName) {
public String toString() {
final StringBuilder sb = new StringBuilder();
if (getNamespace() != null) {
- sb.append(QNAME_LEFT_PARENTHESIS + getNamespace());
+ sb.append(QNAME_LEFT_PARENTHESIS).append(getNamespace());
if (getFormattedRevision() != null) {
- sb.append(QNAME_REVISION_DELIMITER + getFormattedRevision());
+ sb.append(QNAME_REVISION_DELIMITER).append(getFormattedRevision());
}
sb.append(QNAME_RIGHT_PARENTHESIS);
}