From: Tony Tkacik Date: Sat, 3 Oct 2015 12:22:49 +0000 (+0000) Subject: Revert "Revert "Updated SchemaNodeIdentifier namespace handling."" X-Git-Tag: release/beryllium~216 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=ea2f209fe116f2d90e48238906a2f3b24ed455c4;hp=1bea341bd7a23b9537354821673db2c4bc19b20c;p=yangtools.git Revert "Revert "Updated SchemaNodeIdentifier namespace handling."" Bringing back updated augment lookup and validation code which turned out to be correct, but unfortunatelly original implementation of parser (from Hydrogen) accepted incorrect values and "normalized" them to probably what user really intented. New code is stricter and did not accept that input, since it really was unclear what user intented. Change-Id: I187c3479fd7bbb986f414805401e8b54f6b49ee0 Release-Note: Incompatible-Behaviour Signed-off-by: Tony Tkacik --- diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedNamespaceBehaviour.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedNamespaceBehaviour.java new file mode 100644 index 0000000000..03dbfa8565 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedNamespaceBehaviour.java @@ -0,0 +1,40 @@ +/* + * 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 com.google.common.base.Preconditions; +import java.util.Map; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; + +public abstract class DerivedNamespaceBehaviour, T extends IdentifierNamespace> + extends NamespaceBehaviour { + + private Class derivedFrom; + + protected DerivedNamespaceBehaviour(Class identifier, Class derivedFrom) { + super(identifier); + this.derivedFrom = Preconditions.checkNotNull(derivedFrom); + } + + public Class getDerivedFrom() { + return derivedFrom; + } + + @Override + public Map getAllFrom(NamespaceStorageNode storage) { + throw new UnsupportedOperationException("Virtual namespaces does not support provision of all items."); + } + + @Override + public abstract V getFrom(NamespaceBehaviour.NamespaceStorageNode storage, K key); + + @Override + public void addTo(NamespaceStorageNode storage, K key, V value) { + // Intentional noop + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java index 41d22500e4..54605dbc67 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java @@ -151,7 +151,7 @@ public interface ModelActionBuilder { @Nonnull > Prerequisite mutatesEffectiveCtx(T stmt); - @Nonnull ,N extends StatementNamespace> Prerequisite> mutatesEffectiveCtx(StmtContext context,Class namespace, K key); + @Nonnull , N extends IdentifierNamespace>> Prerequisite> mutatesEffectiveCtx(StmtContext context,Class namespace, K key); void apply(InferenceAction action) throws InferenceException; diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java index 6d156b1c83..53c12ccd57 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java @@ -33,7 +33,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; public abstract class NamespaceBehaviour> implements Identifiable> { public enum StorageNodeType { - GLOBAL, SOURCE_LOCAL_SPECIAL, STATEMENT_LOCAL, + GLOBAL, SOURCE_LOCAL_SPECIAL, STATEMENT_LOCAL, ROOT_STATEMENT_LOCAL } public interface Registry { @@ -184,10 +184,7 @@ public abstract class NamespaceBehaviour potentialRaw = supports.get(currentPhase).getNamespaceBehaviour(type); if(potentialRaw != null) { - potential = new NamespaceBehaviourWithListeners<>(potentialRaw); + potential = createNamespaceContext(potentialRaw); supportedNamespaces.put(type, potential); + } else { + throw new NamespaceNotAvailableException( + "Namespace " + type + " is not available in phase " + currentPhase); } } - if (potential != null) { - Preconditions.checkState(type.equals(potential.getIdentifier())); + Verify.verify(type.equals(potential.getIdentifier())); /* - * Safe cast, previous checkState checks equivalence of key from - * which type argument are derived - */ - return (NamespaceBehaviourWithListeners) potential; + * Safe cast, previous checkState checks equivalence of key from which type argument are + * derived + */ + return (NamespaceBehaviourWithListeners) potential; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private > NamespaceBehaviourWithListeners createNamespaceContext( + NamespaceBehaviour potentialRaw) { + if (potentialRaw instanceof DerivedNamespaceBehaviour) { + VirtualNamespaceContext derivedContext = + new VirtualNamespaceContext<>(potentialRaw); + getNamespaceBehaviour(((DerivedNamespaceBehaviour) potentialRaw).getDerivedFrom()) + .addDerivedNamespace(derivedContext); + return derivedContext; } - throw new NamespaceNotAvailableException("Namespace " + type + " is not available in phase " + currentPhase); + return new SimpleNamespaceContext<>(potentialRaw); } public StatementDefinitionContext getStatementDefinition(final QName name) { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java index 1c71972237..254b65c76b 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java @@ -9,6 +9,7 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.EFFECTIVE_MODEL; import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.FULL_DECLARATION; + import com.google.common.base.Function; import com.google.common.base.Preconditions; import java.util.HashSet; @@ -62,16 +63,6 @@ class ModifierImpl implements ModelActionBuilder { return new IllegalStateException("Source exception during registering prerequisite. This is probably bug.",e); } - private void tryToResolve() throws InferenceException { - if(action == null || isApplied()) { - // Action was not yet defined - return; - } - if(removeSatisfied()) { - applyAction(); - } - } - private boolean removeSatisfied() { Iterator> prereq = unsatisfied.iterator(); boolean allSatisfied = true; @@ -102,14 +93,8 @@ class ModifierImpl implements ModelActionBuilder { } private void applyAction() throws InferenceException { - - try { - action.apply(); - } catch (InferenceException e) { - actionApplied = false; - return; - } - //  Mark all mutations as performed, so context node could move to next. + Preconditions.checkState(!actionApplied); + action.apply(); actionApplied = true; } @@ -139,10 +124,11 @@ class ModifierImpl implements ModelActionBuilder { } @SuppressWarnings({ "rawtypes", "unchecked" }) - private , N extends StatementNamespace> AbstractPrerequisite mutatesCtxImpl( + private , N extends IdentifierNamespace>> AbstractPrerequisite mutatesCtxImpl( final StmtContext context, final Class namespace, final K key, final ModelProcessingPhase phase) { try { PhaseModificationInNamespace mod = new PhaseModificationInNamespace(phase); + addReq(mod); addMutation(mod); contextImpl(context).onNamespaceItemAddedAction((Class) namespace,key,mod); return mod; @@ -151,9 +137,19 @@ class ModifierImpl implements ModelActionBuilder { } } - private static StatementContextBase contextImpl(final StmtContext context) { - Preconditions.checkArgument(context instanceof StatementContextBase,"Supplied context was not provided by this reactor."); - return StatementContextBase.class.cast(context); + private static StatementContextBase contextImpl(final Object value) { + Preconditions.checkArgument(value instanceof StatementContextBase,"Supplied context was not provided by this reactor."); + return StatementContextBase.class.cast(value); + } + + boolean tryApply() { + Preconditions.checkState(action != null, "Action was not defined yet."); + + if (removeSatisfied()) { + applyAction(); + return true; + } + return false; } @Override @@ -230,7 +226,7 @@ class ModifierImpl implements ModelActionBuilder { @Override - public , N extends StatementNamespace> AbstractPrerequisite> mutatesEffectiveCtx( + public , N extends IdentifierNamespace>> AbstractPrerequisite> mutatesEffectiveCtx( final StmtContext context, final Class namespace, final K key) { return mutatesCtxImpl(context, namespace, key, EFFECTIVE_MODEL); } @@ -240,7 +236,6 @@ class ModifierImpl implements ModelActionBuilder { @Override public void apply(final InferenceAction action) throws InferenceException { this.action = Preconditions.checkNotNull(action); - tryToResolve(); } private abstract class AbstractPrerequisite implements Prerequisite { @@ -262,7 +257,6 @@ class ModifierImpl implements ModelActionBuilder { protected boolean resolvePrereq(final T value) throws InferenceException { this.value = value; this.done = true; - tryToResolve(); return isApplied(); } @@ -353,8 +347,9 @@ class ModifierImpl implements ModelActionBuilder { @Override public void namespaceItemAdded(final StatementContextBase context, final Class namespace, final Object key, final Object value) throws SourceException { - context.addMutation(modPhase,this); - resolvePrereq((C) context); + StatementContextBase targetCtx = contextImpl(value); + targetCtx.addMutation(modPhase,this); + resolvePrereq((C) targetCtx); } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java index c4bbb76f00..1f10c18a96 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java @@ -7,76 +7,78 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; -import com.google.common.base.Optional; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import java.util.Collection; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.Map; -import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; -import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; -import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; -final class NamespaceBehaviourWithListeners> extends NamespaceBehaviour { +abstract class NamespaceBehaviourWithListeners> + extends NamespaceBehaviour { - abstract static class ValueAddedListener { + abstract static class ValueAddedListener { private final NamespaceStorageNode ctxNode; + private K key; - public ValueAddedListener(final NamespaceStorageNode contextNode) { + public ValueAddedListener(final NamespaceStorageNode contextNode, K key) { this.ctxNode = contextNode; + this.key = key; + } + + public NamespaceStorageNode getCtxNode() { + return ctxNode; + } + + public K getKey() { + return key; } abstract void onValueAdded(Object key, Object value); } private final NamespaceBehaviour delegate; - private final Multimap listeners = HashMultimap.create(); + private final List> derivedNamespaces = new ArrayList<>(); + protected NamespaceBehaviourWithListeners(final NamespaceBehaviour delegate) { super(delegate.getIdentifier()); this.delegate = delegate; } + protected abstract void addListener(K key, ValueAddedListener listener); + + protected abstract Iterator> getMutableListeners(K key); + + protected abstract boolean isRequestedValue(ValueAddedListener listener, NamespaceStorageNode storage, V value); + @Override public void addTo(final NamespaceStorageNode storage, final K key, final V value) { delegate.addTo(storage, key, value); - Iterator keyListeners = listeners.get(key).iterator(); + Iterator> keyListeners = getMutableListeners(key); + List> toNotify = new ArrayList<>(); while (keyListeners.hasNext()) { - ValueAddedListener listener = keyListeners.next(); - if (listener.ctxNode == storage || hasIdentiticalValue(listener.ctxNode,key,value)) { + ValueAddedListener listener = keyListeners.next(); + if (isRequestedValue(listener, storage, value)) { keyListeners.remove(); - listener.onValueAdded(key, value); + toNotify.add(listener); } } - - if (key instanceof ModuleIdentifier && !listeners.isEmpty()) { - Collection defaultImportListeners = getDefaultImportListeners((ModuleIdentifier) key); - Iterator defaultImportsIterator = defaultImportListeners.iterator(); - while (defaultImportsIterator.hasNext()) { - ValueAddedListener listener = defaultImportsIterator.next(); - if(listener.ctxNode == storage || hasIdentiticalValue(listener.ctxNode,key,value)) { - defaultImportsIterator.remove(); - listener.onValueAdded(key, value); - } - } + for(ValueAddedListener listener : toNotify) { + listener.onValueAdded(key, value); + } + for (VirtualNamespaceContext derived : derivedNamespaces) { + derived.addTo(storage, null, value); } } - private Collection getDefaultImportListeners(final ModuleIdentifier key) { - ModuleIdentifier defaultImportKey = new ModuleIdentifierImpl(key.getName(), - Optional.fromNullable(key.getNamespace()), Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_IMP)); - return listeners.get((K)defaultImportKey); - } - - private boolean hasIdentiticalValue(final NamespaceStorageNode ctxNode, final K key, final V value) { - return getFrom(ctxNode, key) == value; + final void addValueListener(final ValueAddedListener listener) { + addListener(listener.key, listener); } - void addValueListener(final K key, final ValueAddedListener listener) { - listeners.put(key, listener); + final void addDerivedNamespace(VirtualNamespaceContext namespace) { + derivedNamespaces.add(namespace); } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java index 8c883dd265..b1bf364e0c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java @@ -15,6 +15,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; 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.NamespaceBehaviour.StorageNodeType; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -100,6 +101,10 @@ public class RootStatementContext, E extends E return sourceContext; } + @Override + public StorageNodeType getStorageNodeType() { + return StorageNodeType.ROOT_STATEMENT_LOCAL; + } /** * @return this as its own root */ diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SimpleNamespaceContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SimpleNamespaceContext.java new file mode 100644 index 0000000000..01e499f37c --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SimpleNamespaceContext.java @@ -0,0 +1,40 @@ +/* + * 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.stmt.reactor; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; + +final class SimpleNamespaceContext> + extends NamespaceBehaviourWithListeners { + + // FIXME: Change this to Multimap, once issue with modules + // is resolved. + private final List> listeners = new ArrayList<>(); + public SimpleNamespaceContext(NamespaceBehaviour delegate) { + super(delegate); + } + + protected boolean isRequestedValue(NamespaceBehaviourWithListeners.ValueAddedListener listener, NamespaceStorageNode storage, V value) { + NamespaceStorageNode listenerCtx = listener.getCtxNode(); + return value == getFrom(listenerCtx, listener.getKey()); + } + + @Override + protected void addListener(K key, NamespaceBehaviourWithListeners.ValueAddedListener listener) { + listeners.add(listener); + } + + @Override + protected Iterator> getMutableListeners(K key) { + return listeners.iterator(); + } +} \ No newline at end of file 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 db760d0792..b11d2a40aa 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 @@ -255,11 +255,11 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh PhaseCompletionProgress tryToCompletePhase(final ModelProcessingPhase phase) throws SourceException { Collection currentPhaseModifiers = modifiers.get(phase); - boolean hasProgressed = hasProgress(currentPhaseModifiers); + boolean hasProgressed = tryToProgress(currentPhaseModifiers); boolean phaseCompleted = root.tryToCompletePhase(phase); - hasProgressed = (hasProgress(currentPhaseModifiers) | hasProgressed); + hasProgressed = (tryToProgress(currentPhaseModifiers) | hasProgressed); if (phaseCompleted && (currentPhaseModifiers.isEmpty())) { finishedPhase = phase; @@ -273,12 +273,12 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh } - private static boolean hasProgress(final Collection currentPhaseModifiers) { + private static boolean tryToProgress(final Collection currentPhaseModifiers) { Iterator modifier = currentPhaseModifiers.iterator(); boolean hasProgressed = false; while (modifier.hasNext()) { - if (modifier.next().isApplied()) { + if (modifier.next().tryApply()) { modifier.remove(); hasProgressed = true; } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java index d28dc9a458..5e05a47580 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java @@ -7,9 +7,6 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; -import java.util.LinkedList; - -import java.util.List; import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.collect.HashMultimap; @@ -20,6 +17,8 @@ import java.util.Collections; import java.util.EventListener; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import javax.annotation.Nonnull; import org.opendaylight.yangtools.concepts.Identifiable; @@ -486,7 +485,7 @@ public abstract class StatementContextBase, E NamespaceBehaviour behaviour = getBehaviourRegistry().getNamespaceBehaviour(type); if (behaviour instanceof NamespaceBehaviourWithListeners) { NamespaceBehaviourWithListeners casted = (NamespaceBehaviourWithListeners) behaviour; - casted.addValueListener(key, new ValueAddedListener(this) { + casted.addValueListener(new ValueAddedListener(this, key) { @Override void onValueAdded(Object key, Object value) { try { 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 4c3be3e9a2..04a01d17fc 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 @@ -63,10 +63,6 @@ class SubstatementContext, E extends Effective } else { this.argument = original.argument; } - - copyDeclaredStmts(original, newQNameModule, typeOfCopy); - - copyEffectiveStmts(original, newQNameModule, typeOfCopy); } private void copyDeclaredStmts(SubstatementContext original, @@ -150,6 +146,9 @@ class SubstatementContext, E extends Effective } definition().onStatementAdded(copy); + + copy.copyDeclaredStmts(this, newQNameModule, typeOfCopy); + copy.copyEffectiveStmts(this, newQNameModule, typeOfCopy); return copy; } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/VirtualNamespaceContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/VirtualNamespaceContext.java new file mode 100644 index 0000000000..75c4b5e50f --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/VirtualNamespaceContext.java @@ -0,0 +1,38 @@ +/* + * 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.stmt.reactor; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; + +final class VirtualNamespaceContext> + extends NamespaceBehaviourWithListeners { + + private final List> listeners = new ArrayList<>(20); + + public VirtualNamespaceContext(NamespaceBehaviour delegate) { + super(delegate); + } + + protected boolean isRequestedValue(NamespaceBehaviourWithListeners.ValueAddedListener listener, NamespaceStorageNode storage, V value) { + return value == getFrom(listener.getCtxNode(), listener.getKey()); + } + + @Override + protected void addListener(K key, NamespaceBehaviourWithListeners.ValueAddedListener listener) { + listeners.add(listener); + } + + @Override + protected Iterator> getMutableListeners(K key) { + return listeners.iterator(); + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java index 12e1a06bb1..4d660e91b2 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java @@ -20,8 +20,10 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.spi.source.StmtOrderingNamespace; @@ -77,32 +79,21 @@ public class AugmentStatementImpl extends AbstractDeclaredStatement>> sourceCtxPrereq = augmentAction - .requiresCtx(augmentNode, - ModelProcessingPhase.FULL_DECLARATION); - + .requiresCtx(augmentNode, ModelProcessingPhase.EFFECTIVE_MODEL); + final Prerequisite>> target = augmentAction.mutatesEffectiveCtx(getSearchRoot(augmentNode), SchemaNodeIdentifierBuildNamespace.class, augmentNode.getStatementArgument()); augmentAction.apply(new ModelActionBuilder.InferenceAction() { @Override public void apply() throws InferenceException { - final StatementContextBase augmentTargetCtx = AugmentUtils - .getAugmentTargetCtx(augmentNode); - - if (augmentTargetCtx == null) { - throw new InferenceException( - "Augment target not found: " - + augmentNode.getStatementArgument(), - augmentNode.getStatementSourceReference()); - } + final StatementContextBase augmentTargetCtx = (StatementContextBase) target.get(); if (!AugmentUtils.isSupportedAugmentTarget(augmentTargetCtx) || StmtContextUtils.isInExtensionBody(augmentTargetCtx)) { augmentNode.setIsSupportedToBuildEffective(false); return; } - final StatementContextBase augmentSourceCtx = (StatementContextBase) augmentNode; - try { AugmentUtils.copyFromSourceToTarget(augmentSourceCtx, augmentTargetCtx); @@ -140,6 +131,15 @@ public class AugmentStatementImpl extends AbstractDeclaredStatement getSearchRoot(Mutable augmentContext) { + Mutable parent = augmentContext.getParentContext(); + // Augment is in uses - we need to augment instantiated nodes in parent. + if(Rfc6020Mapping.USES.equals(parent.getPublicDefinition())) { + return parent.getParentContext(); + } + return parent; + } } @Nonnull diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java index 3a068971d5..08acdd5a01 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java @@ -10,54 +10,37 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Set; -import javax.annotation.Nullable; +import java.util.regex.Pattern; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; -import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement; import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement; -import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; -import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace; import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +// FIXME: Move this to the AugmentStatementDefinition#ApplyAction public final class AugmentUtils { - - private static final Logger LOG = LoggerFactory.getLogger(AugmentUtils.class); - private AugmentUtils() { - throw new UnsupportedOperationException(); } public static void copyFromSourceToTarget(final StatementContextBase sourceCtx, final StatementContextBase targetCtx) throws SourceException { - copyDeclaredStmts(sourceCtx, targetCtx); copyEffectiveStmts(sourceCtx, targetCtx); } - public static void copyDeclaredStmts(final StatementContextBase sourceCtx, + // FIXME: Declared statements should not be copied. + private static void copyDeclaredStmts(final StatementContextBase sourceCtx, final StatementContextBase targetCtx) throws SourceException { final List> subStatements = new Builder>() @@ -80,7 +63,7 @@ public final class AugmentUtils { } } - public static void copyEffectiveStmts(final StatementContextBase sourceCtx, + private static void copyEffectiveStmts(final StatementContextBase sourceCtx, final StatementContextBase targetCtx) throws SourceException { final List> subStatements = new Builder>() @@ -104,54 +87,41 @@ public final class AugmentUtils { } private static void validateNodeCanBeCopiedByAugment(final StatementContextBase sourceCtx, - final Iterable> targetSubStatements, - final boolean sourceAndTargetInSameModule) { + final List> targetSubStatements, final boolean sourceAndTargetInSameModule) { - if (WhenStatement.class.equals(sourceCtx.getPublicDefinition().getDeclaredRepresentationClass())) { + if (sourceCtx.getPublicDefinition().getDeclaredRepresentationClass().equals(WhenStatement.class)) { return; } if (!sourceAndTargetInSameModule) { - for (final StatementContextBase sourceSubStatement : - Iterables.concat(sourceCtx.declaredSubstatements(), sourceCtx.effectiveSubstatements())) { - Preconditions.checkArgument(!MandatoryStatement.class.equals( - sourceSubStatement.getPublicDefinition().getDeclaredRepresentationClass()), - "An augment cannot add node '%s' because it is mandatory and in module different from target", - sourceCtx.rawStatementArgument()); + final List> sourceSubStatements = new Builder>() + .addAll(sourceCtx.declaredSubstatements()).addAll(sourceCtx.effectiveSubstatements()).build(); + + for (final StatementContextBase sourceSubStatement : sourceSubStatements) { + if (sourceSubStatement.getPublicDefinition().getDeclaredRepresentationClass() + .equals(MandatoryStatement.class)) { + throw new IllegalArgumentException( + String.format( + "An augment cannot add node '%s' because it is mandatory and in module different from target", + sourceCtx.rawStatementArgument())); + } } } for (final StatementContextBase subStatement : targetSubStatements) { - final boolean sourceIsDataNode = DataDefinitionStatement.class.isAssignableFrom( - sourceCtx.getPublicDefinition().getDeclaredRepresentationClass()); - final boolean targetIsDataNode = DataDefinitionStatement.class.isAssignableFrom( - subStatement.getPublicDefinition().getDeclaredRepresentationClass()); - Preconditions.checkState(!sourceIsDataNode || !targetIsDataNode - || !Objects.equals(sourceCtx.getStatementArgument(), subStatement.getStatementArgument()), - "An augment cannot add node named '%s' because this name is already used in target", - sourceCtx.rawStatementArgument()); - } - } - - public static QNameModule getNewQNameModule(final StatementContextBase targetCtx, - final StatementContextBase sourceCtx) { - Object targetStmtArgument = targetCtx.getStatementArgument(); - - final StatementContextBase root = sourceCtx.getRoot(); - final QNameModule sourceQNameModule = root.getFromNamespace(ModuleCtxToModuleQName.class, root); - - if (targetStmtArgument instanceof QName) { - QName targetQName = (QName) targetStmtArgument; - QNameModule targetQNameModule = targetQName.getModule(); - - if (targetQNameModule.equals(sourceQNameModule)) { - return null; - } else { - return targetQNameModule; + final boolean sourceIsDataNode = DataDefinitionStatement.class.isAssignableFrom(sourceCtx + .getPublicDefinition().getDeclaredRepresentationClass()); + final boolean targetIsDataNode = DataDefinitionStatement.class.isAssignableFrom(subStatement + .getPublicDefinition().getDeclaredRepresentationClass()); + boolean qNamesEqual = sourceIsDataNode && targetIsDataNode + && Objects.equals(sourceCtx.getStatementArgument(), subStatement.getStatementArgument()); + + if (qNamesEqual) { + throw new IllegalStateException(String.format( + "An augment cannot add node named '%s' because this name is already used in target", + sourceCtx.rawStatementArgument())); } - } else { - return null; } } @@ -167,100 +137,7 @@ public final class AugmentUtils { return REUSED_DEF_SET.contains(stmtContext.getPublicDefinition()); } - public static StatementContextBase getAugmentTargetCtx( - final Mutable> augmentNode) { - - final SchemaNodeIdentifier augmentTargetNode = augmentNode.getStatementArgument(); - Preconditions.checkArgument(augmentTargetNode != null, - "Augment argument null, something bad happened in some of previous parsing phases"); - - List> rootStatementCtxList = new ArrayList<>(); - if (augmentTargetNode.isAbsolute()) { - - QNameModule module = augmentTargetNode.getPathFromRoot().iterator().next().getModule(); - - StatementContextBase rootStatementCtx = - (StatementContextBase) augmentNode.getFromNamespace(NamespaceToModule.class, module); - rootStatementCtxList.add(rootStatementCtx); - - final Map subModules = rootStatementCtx.getAllFromNamespace(IncludedModuleContext.class); - if (subModules != null) { - rootStatementCtxList.addAll((Collection>) subModules.values()); - } - - } else { - StatementContextBase parent = (StatementContextBase) augmentNode.getParentContext(); - if (StmtContextUtils.producesDeclared(parent, UsesStatement.class)) { - rootStatementCtxList.add(parent.getParentContext()); - } else { - // error - } - } - - StatementContextBase augmentTargetCtx = null; - for (final StatementContextBase rootStatementCtx : rootStatementCtxList) { - augmentTargetCtx = findCtxOfNodeInRoot(rootStatementCtx, augmentTargetNode); - if (augmentTargetCtx != null) { - break; - } - } - - return augmentTargetCtx; - } - - @Nullable - public static StatementContextBase findCtxOfNodeInSubstatements(final StatementContextBase rootStmtCtx, - final Iterable path) { - - StatementContextBase parent = rootStmtCtx; - - Iterator pathIter = path.iterator(); - while (pathIter.hasNext()) { - QName nextPathQName = pathIter.next(); - StatementContextBase foundSubstatement = getSubstatementByQName(parent, nextPathQName); - - if (foundSubstatement == null) { - return null; - } - if (!pathIter.hasNext()) { - return foundSubstatement; - } - - parent = foundSubstatement; - } - - return null; - } - - public static StatementContextBase getSubstatementByQName(final StatementContextBase parent, - final QName nextPathQName) { - - Collection> declaredSubstatement = parent.declaredSubstatements(); - Collection> effectiveSubstatement = parent.effectiveSubstatements(); - - for (StatementContextBase substatement : Iterables.concat(declaredSubstatement, effectiveSubstatement)) { - Object substatementArgument = substatement.getStatementArgument(); - QName substatementQName; - if (substatementArgument instanceof QName) { - substatementQName = (QName) substatementArgument; - - if (nextPathQName.getLocalName().equals( - substatementQName.getLocalName())) { - if (isSupportedAugmentTarget(substatement)) { - return substatement; - } else if (Utils.isUnknownNode(substatement)) { - LOG.warn("Module '{}': augment into unknown node '{}'.", - substatement.getRoot().getStatementArgument(), substatementArgument); - return substatement; - } - } - } - } - - return null; - } - - public static boolean isSupportedAugmentTarget(final StatementContextBase substatementCtx) { + static boolean isSupportedAugmentTarget(final StatementContextBase substatementCtx) { /* * :TODO Substatement must be allowed augment target type e.g. Container, etc... and must be not for example @@ -276,10 +153,4 @@ public final class AugmentUtils { return allowedAugmentTargets == null || allowedAugmentTargets.isEmpty() || allowedAugmentTargets.contains(substatementCtx.getPublicDefinition()); } - - @Nullable - public static StatementContextBase findCtxOfNodeInRoot(final StatementContextBase rootStmtCtx, - final SchemaNodeIdentifier node) { - return findCtxOfNodeInSubstatements(rootStmtCtx, node.getPathFromRoot()); - } } 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 b9761b1a91..6482c99f51 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 @@ -7,10 +7,13 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; +import java.util.Map; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; /** * Statement local namespace, which holds direct schema node descendants. @@ -18,6 +21,42 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace; * @param * @param */ -public interface ChildSchemaNodes,E extends EffectiveStatement> extends StatementNamespace{ +public class ChildSchemaNodes,E extends EffectiveStatement> + extends NamespaceBehaviour, ChildSchemaNodes> + implements StatementNamespace{ + protected ChildSchemaNodes() { + super((Class>) (Class) ChildSchemaNodes.class); + } + + @Override + public StmtContext get(QName key) { + // TODO Auto-generated method stub + return null; + } + + @Override + public StmtContext getFrom(NamespaceStorageNode storage, QName key) { + return globalOrStatementSpecific(storage).getFromLocalStorage(getIdentifier(), key); + } + + @Override + public Map> getAllFrom(NamespaceStorageNode storage) { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + @Override + public void addTo(NamespaceBehaviour.NamespaceStorageNode storage, QName key, StmtContext value) { + globalOrStatementSpecific(storage).addToLocalStorage(ChildSchemaNodes.class, key, value); + } + + private NamespaceStorageNode globalOrStatementSpecific(NamespaceBehaviour.NamespaceStorageNode storage) { + NamespaceStorageNode current = storage; + while(current.getStorageNodeType() != StorageNodeType.STATEMENT_LOCAL && current.getStorageNodeType() != StorageNodeType.GLOBAL) { + current = current.getParentNamespaceStorage(); + } + return current; + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SchemaNodeIdentifierBuildNamespace.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SchemaNodeIdentifierBuildNamespace.java new file mode 100644 index 0000000000..bee80c9ba0 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SchemaNodeIdentifierBuildNamespace.java @@ -0,0 +1,59 @@ +/* + * 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.stmt.rfc6020; + +import java.util.Iterator; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedNamespaceBehaviour; +import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; + +class SchemaNodeIdentifierBuildNamespace extends + DerivedNamespaceBehaviour>, SchemaNodeIdentifierBuildNamespace, ChildSchemaNodes> + implements IdentifierNamespace>> { + + @SuppressWarnings({"unchecked", "rawtypes"}) + protected SchemaNodeIdentifierBuildNamespace() { + super(SchemaNodeIdentifierBuildNamespace.class, (Class) ChildSchemaNodes.class); + } + + @Override + public StmtContext.Mutable> get( + SchemaNodeIdentifier key) { + throw new UnsupportedOperationException("Direct access to namespace is not supported"); + } + + @Override + public StmtContext.Mutable> getFrom(NamespaceStorageNode storage, SchemaNodeIdentifier key) { + + final NamespaceStorageNode lookupStartStorage; + if(key.isAbsolute() || storage.getStorageNodeType() == StorageNodeType.ROOT_STATEMENT_LOCAL) { + lookupStartStorage = NamespaceBehaviour.findClosestTowardsRoot(storage, StorageNodeType.GLOBAL); + } else { + lookupStartStorage = storage; + } + Iterator iterator = key.getPathFromRoot().iterator(); + if(!iterator.hasNext()) { + if(lookupStartStorage instanceof StmtContext) { + return (StmtContext.Mutable>) lookupStartStorage; + } else { + return null; + } + } + StmtContext.Mutable> current = (StmtContext.Mutable>) lookupStartStorage.getFromLocalStorage(ChildSchemaNodes.class, iterator.next()); + while(current != null && iterator.hasNext()) { + current = (StmtContext.Mutable>) current.getFromNamespace(ChildSchemaNodes.class, iterator.next()); + } + return current; + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java index 514b9f0408..57e5bb0368 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java @@ -30,6 +30,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; @@ -67,13 +68,13 @@ public class UsesStatementImpl extends AbstractDeclaredStatement implemen return; } - ModelActionBuilder usesAction = usesNode.newInferenceAction(FULL_DECLARATION); + ModelActionBuilder usesAction = usesNode.newInferenceAction(ModelProcessingPhase.EFFECTIVE_MODEL); final QName groupingName = usesNode.getStatementArgument(); final Prerequisite> sourceGroupingPre = usesAction.requiresCtx(usesNode, - GroupingNamespace.class, groupingName, FULL_DECLARATION); - final Prerequisite> targetNodePre = usesAction.mutatesCtx( - usesNode.getParentContext(), FULL_DECLARATION); + GroupingNamespace.class, groupingName, ModelProcessingPhase.EFFECTIVE_MODEL); + final Prerequisite> targetNodePre = usesAction.mutatesEffectiveCtx( + usesNode.getParentContext()); usesAction.apply(new InferenceAction() { 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 e3b9152d2b..32ab655db7 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 @@ -294,14 +294,9 @@ public final class Utils { } @Nullable - public static StatementContextBase findNode(final StatementContextBase rootStmtCtx, + public static StatementContextBase findNode(final StmtContext rootStmtCtx, final SchemaNodeIdentifier node) { - StatementContextBase current = rootStmtCtx; - Iterator arguments = node.getPathFromRoot().iterator(); - while(current != null && arguments.hasNext()) { - current = (StatementContextBase) current.getFromNamespace(ChildSchemaNodes.class, arguments.next()); - } - return current; + return (StatementContextBase) rootStmtCtx.getFromNamespace(SchemaNodeIdentifierBuildNamespace.class, node); } public static SchemaPath getSchemaPath(final StmtContext ctx) { 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 9f316ec949..6dd2595d3e 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 @@ -83,7 +83,8 @@ public final class YangInferencePipeline { .addSupport(new YinElementStatementImpl.Definition()) .addSupport(new ArgumentStatementImpl.Definition()) .addSupport(new ExtensionStatementImpl.Definition()) - .addSupport(global(ChildSchemaNodes.class)) + .addSupport(new ChildSchemaNodes()) + .addSupport(new SchemaNodeIdentifierBuildNamespace()) .addSupport(global(ExtensionNamespace.class)) .addSupport(new TypedefStatementImpl.Definition()) .addSupport(treeScoped(TypeNamespace.class)) diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java index fdc1802e68..890c47b0fc 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java @@ -33,6 +33,7 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.meta.ModelStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; @@ -108,11 +109,7 @@ public class AugmentProcessTest { MULTIPLE_AUGMENT_SUBMODULE); EffectiveSchemaContext result = null; - try { - result = reactor.buildEffective(); - } catch (Exception e) { - log(e, ""); - } + result = reactor.buildEffective(); assertNotNull(result); } @@ -123,15 +120,11 @@ public class AugmentProcessTest { addSources(reactor, MULTIPLE_AUGMENT); EffectiveSchemaContext result = null; - try { - result = reactor.buildEffective(); - } catch (Exception e) { - log(e, ""); - } + result = reactor.buildEffective(); assertNotNull(result); } - @Test + @Test(expected=SomeModifiersUnresolvedException.class) public void multipleAugmentIncorrectPathTest() throws SourceException, ReactorException { CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR @@ -139,40 +132,22 @@ public class AugmentProcessTest { addSources(reactor, MULTIPLE_AUGMENT_INCORRECT); EffectiveSchemaContext result = null; - try { - result = reactor.buildEffective(); - } catch (Exception e) { - log(e, ""); - } - + result = reactor.buildEffective(); assertNull(result); } - @Test + @Test(expected=SomeModifiersUnresolvedException.class) public void multipleAugmentIncorrectPathAndGrpTest() throws SourceException, ReactorException { CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR .newBuild(); addSources(reactor, MULTIPLE_AUGMENT_INCORRECT2); - EffectiveSchemaContext result = null; - try { - result = reactor.buildEffective(); - } catch (Exception e) { - log(e, ""); - } - + result = reactor.buildEffective(); assertNull(result); } - private void log(final Throwable e, final String indent) { - System.out.println(indent + e.getMessage()); - Throwable[] suppressed = e.getSuppressed(); - for (Throwable throwable : suppressed) { - log(throwable, indent + " "); - } - } @Test public void readAndParseYangFileTest() throws SourceException, diff --git a/yang/yang-parser-impl/src/test/resources/model-new/foo.yang b/yang/yang-parser-impl/src/test/resources/model-new/foo.yang index ba12bd6ee7..1c361e4b5c 100644 --- a/yang/yang-parser-impl/src/test/resources/model-new/foo.yang +++ b/yang/yang-parser-impl/src/test/resources/model-new/foo.yang @@ -130,7 +130,7 @@ module foo { status obsolete; } - augment "/br:interfaces/br:ifEntry/br:augment-holder" { + augment "/br:interfaces/br:ifEntry/bz:augment-holder" { when "if:ifType='ds0'"; leaf ds0ChannelNumber { type string; diff --git a/yang/yang-parser-impl/src/test/resources/model-new/subfoo.yang b/yang/yang-parser-impl/src/test/resources/model-new/subfoo.yang index 190053010c..412f9c15a9 100644 --- a/yang/yang-parser-impl/src/test/resources/model-new/subfoo.yang +++ b/yang/yang-parser-impl/src/test/resources/model-new/subfoo.yang @@ -54,7 +54,7 @@ submodule subfoo { status obsolete; } - augment "/br:interfaces/br:ifEntry/br:augment-holder" { + augment "/br:interfaces/br:ifEntry/bz:augment-holder" { when "if:ifType='ds0'"; leaf subleaf { type string; diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-imported.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-imported.yang index 0d030b23fa..26ec3c8978 100644 --- a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-imported.yang +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-imported.yang @@ -3,10 +3,6 @@ module multiple-augment-imported { namespace "multiple-augment-imported"; prefix imp; - augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment/sub-container-from-augment2/sub-container-from-augment3 { - container sub-container-from-augment4 { - } - } container root-container { uses grp1 { @@ -29,11 +25,6 @@ module multiple-augment-imported { } } - augment /root-container/added-container-1 { - container added-container-2 { - } - } - grouping grp2 { container container-from-grp2 { container sub-container-from-grp2 { @@ -51,10 +42,10 @@ module multiple-augment-imported { container sub-container-from-augment2 { } } - + grouping grp-from-import { container container-from-grp-from-import { - + } } } diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-root.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-root.yang index 88123f7736..5ec75d342b 100644 --- a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-root.yang +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-root.yang @@ -4,7 +4,7 @@ module multiple-augment-root { prefix root; import multiple-augment-imported { prefix imp; revision-date 1970-01-01; } - + include multiple-augment-submodule { revision-date 1970-01-01; } augment /imp:root-container/imp:container-from-grp1/imp:sub-container-from-grp1/imp:container-in-uses-augment/imp:sub-container-from-augment2 { @@ -22,7 +22,7 @@ module multiple-augment-root { } } - augment /imp:root-container/imp:container-from-grp1/imp:sub-container-from-grp1/imp:container-from-grp2/imp:sub-container-from-grp2/imp:sub-container-from-augment5 { + augment /imp:root-container/imp:container-from-grp1/imp:sub-container-from-grp1/imp:container-from-grp2/imp:sub-container-from-grp2/sub-container-from-augment5 { container sub-container-from-augment7 { } } @@ -36,7 +36,7 @@ module multiple-augment-root { container added-container-1 { } } - + container container-with-multiple-uses { uses imp:grp-from-import{ augment container-from-grp-from-import {