From: Robert Varga Date: Mon, 9 Nov 2015 15:24:57 +0000 (+0100) Subject: Instantiate a QName cache X-Git-Tag: release/beryllium~155 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;a=commitdiff_plain;h=3903d34ece7e98167a071e1c2bb9a89ef35790c6 Instantiate a QName cache YANG parser needs to suppress duplicate QNames when a grouping is instantiated to multiple places, for example. This the caching infrastructure which can be reused. Change-Id: Ic26298f768cba0a7f76610b93769ae1073c042a2 Signed-off-by: Robert Varga --- diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/QNameCacheNamespace.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/QNameCacheNamespace.java new file mode 100644 index 0000000000..d6f0192747 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/QNameCacheNamespace.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015 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.parser.spi.meta; + +import java.util.Map; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; + +/** + * An {@link IdentifierNamespace} implementing a {@link QName} internment interface. Lookups in this namespace always + * return a non-null object. They capture the first object instance and return that on subsequent lookups. + */ +public final class QNameCacheNamespace extends NamespaceBehaviour + implements IdentifierNamespace { + + private static final QNameCacheNamespace INSTANCE = new QNameCacheNamespace(); + + private QNameCacheNamespace() { + super(QNameCacheNamespace.class); + } + + public static QNameCacheNamespace getInstance() { + return INSTANCE; + } + + @Override + public QName get(final QName identifier) { + throw new UnsupportedOperationException("Identifier/implementation API borkage"); + } + + private static NamespaceStorageNode getRoot(final NamespaceStorageNode storage) { + NamespaceStorageNode wlk = storage; + + while (wlk.getParentNamespaceStorage() != null) { + wlk = wlk.getParentNamespaceStorage(); + } + + return wlk; + } + + @Override + public QName getFrom(final NamespaceStorageNode storage, final QName key) { + final NamespaceStorageNode root = getRoot(storage); + final QName stored = root.getFromLocalStorage(QNameCacheNamespace.class, key); + if (stored == null) { + root.addToLocalStorage(QNameCacheNamespace.class, key, key); + return key; + } else { + return stored; + } + } + + @Override + public Map getAllFrom(final NamespaceStorageNode storage) { + return getRoot(storage).getAllFromLocalStorage(QNameCacheNamespace.class); + } + + @Override + public void addTo(final NamespaceStorageNode storage, final QName key, final QName value) { + throw new UnsupportedOperationException("Automagically populated"); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java index 186ef6bca7..d7e15ddc70 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java @@ -170,7 +170,8 @@ public final class StmtContextUtils { for (SchemaNodeIdentifier arg : keyStmtCtx.getStatementArgument()) { final QName qname = arg.getLastComponent(); if (!newQNameModule.equals(qname)) { - final QName newQname = QName.create(newQNameModule, qname.getLocalName()); + final QName newQname = keyStmtCtx.getFromNamespace(QNameCacheNamespace.class, + QName.create(newQNameModule, qname.getLocalName())); builder.add(SchemaNodeIdentifier.create(false, newQname)); replaced = true; } else { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java index 9ddfae0419..836ef7b39d 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java @@ -35,6 +35,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; +import org.opendaylight.yangtools.yang.parser.spi.meta.QNameCacheNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule; @@ -101,7 +102,8 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh .getAllFromNamespace(ExtensionNamespace.class).get(key); if (extension != null) { final QName arg = (QName) ((SubstatementContext) extension).getStatementArgument(); - final QName qName = QName.create(arg, extension.getIdentifier().getArgument()); + final QName qName = current.getFromNamespace(QNameCacheNamespace.class, + QName.create(arg, extension.getIdentifier().getArgument())); def = new StatementDefinitionContext<>(new UnknownStatementImpl.Definition (getNewStatementDefinition(qName))); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java index 6e2f652a06..4b1773c6a3 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java @@ -24,6 +24,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry; +import org.opendaylight.yangtools.yang.parser.spi.meta.QNameCacheNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -56,7 +57,9 @@ final class SubstatementContext, E extends Eff if (newQNameModule != null) { if (original.argument instanceof QName) { QName originalQName = (QName) original.argument; - this.argument = (A) QName.create(newQNameModule, originalQName.getLocalName()); + this.argument = (A) + getFromNamespace(QNameCacheNamespace.class, + QName.create(newQNameModule, originalQName.getLocalName())); } else if (StmtContextUtils.producesDeclared(original, KeyStatement.class)) { this.argument = (A) StmtContextUtils.replaceModuleQNameForKey( (StmtContext, KeyStatement, ?>) original, diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ChildSchemaNodes.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ChildSchemaNodes.java index 6482c99f51..940e7c74eb 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ChildSchemaNodes.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ChildSchemaNodes.java @@ -26,33 +26,33 @@ public class ChildSchemaNodes,E extends Effec implements StatementNamespace{ protected ChildSchemaNodes() { - super((Class>) (Class) ChildSchemaNodes.class); + super((Class) ChildSchemaNodes.class); } @Override - public StmtContext get(QName key) { + public StmtContext get(final QName key) { // TODO Auto-generated method stub return null; } @Override - public StmtContext getFrom(NamespaceStorageNode storage, QName key) { + public StmtContext getFrom(final NamespaceStorageNode storage, final QName key) { return globalOrStatementSpecific(storage).getFromLocalStorage(getIdentifier(), key); } @Override - public Map> getAllFrom(NamespaceStorageNode storage) { + public Map> getAllFrom(final NamespaceStorageNode storage) { // TODO Auto-generated method stub return null; } @SuppressWarnings("unchecked") @Override - public void addTo(NamespaceBehaviour.NamespaceStorageNode storage, QName key, StmtContext value) { + public void addTo(final NamespaceBehaviour.NamespaceStorageNode storage, final QName key, final StmtContext value) { globalOrStatementSpecific(storage).addToLocalStorage(ChildSchemaNodes.class, key, value); } - private NamespaceStorageNode globalOrStatementSpecific(NamespaceBehaviour.NamespaceStorageNode storage) { + private static NamespaceStorageNode globalOrStatementSpecific(final NamespaceBehaviour.NamespaceStorageNode storage) { NamespaceStorageNode current = storage; while(current.getStorageNodeType() != StorageNodeType.STATEMENT_LOCAL && current.getStorageNodeType() != StorageNodeType.GLOBAL) { current = current.getParentNamespaceStorage(); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java index c1aa7affee..2b63dafb9c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java @@ -43,6 +43,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Relative; import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement; import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl; +import org.opendaylight.yangtools.yang.parser.spi.meta.QNameCacheNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName; @@ -252,7 +253,7 @@ public final class Utils { resultQNameModule = qNameModule; } - return QName.create(resultQNameModule, localName); + return ctx.getFromNamespace(QNameCacheNamespace.class, QName.create(resultQNameModule, localName)); } public static QNameModule getModuleQNameByPrefix(final StmtContext ctx, final String prefix) { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java index 2651618ea9..fd12028f20 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java @@ -21,6 +21,7 @@ import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace; import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedIdentitiesNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; +import org.opendaylight.yangtools.yang.parser.spi.meta.QNameCacheNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle; import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToModuleContext; import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName; @@ -69,6 +70,7 @@ public final class YangInferencePipeline { .addSupport(global(ModuleQNameToModuleName.class)) .addSupport(global(PrefixToModule.class)) .addSupport(global(ModuleIdentifierToModuleQName.class)) + .addSupport(QNameCacheNamespace.getInstance()) .addSupport(sourceLocal(ImportedModuleContext.class)) .addSupport(sourceLocal(IncludedModuleContext.class)) .addSupport(sourceLocal(IncludedSubmoduleNameToIdentifier.class))