*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.RootModificationApplyOperation.LatestOperationHolder;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
/**
* Read-only snapshot of the data tree.
private static final InstanceIdentifier PUBLIC_ROOT_PATH = InstanceIdentifier.builder().build();
private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
- private ModificationApplyOperation applyOper = new AlwaysFailOperation();
+ private final LatestOperationHolder operationHolder = new LatestOperationHolder();
private SchemaContext currentSchemaContext;
private TreeNode rootNode;
public synchronized void setSchemaContext(final SchemaContext newSchemaContext) {
Preconditions.checkNotNull(newSchemaContext);
- LOG.info("Attepting to install schema context {}", newSchemaContext);
+ LOG.info("Attempting to install schema context {}", newSchemaContext);
/*
* FIXME: we should walk the schema contexts, both current and new and see
// Ready to change the context now, make sure no operations are running
rwLock.writeLock().lock();
try {
- this.applyOper = newApplyOper;
+ this.operationHolder.setCurrent(newApplyOper);
this.currentSchemaContext = newSchemaContext;
} finally {
rwLock.writeLock().unlock();
public InMemoryDataTreeSnapshot takeSnapshot() {
rwLock.readLock().lock();
try {
- return new InMemoryDataTreeSnapshot(currentSchemaContext, rootNode, applyOper);
+ return new InMemoryDataTreeSnapshot(currentSchemaContext, rootNode, operationHolder.newSnapshot());
} finally {
rwLock.readLock().unlock();
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
import java.util.Map.Entry;
import javax.annotation.concurrent.GuardedBy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
final class InMemoryDataTreeModification implements DataTreeModification {
private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class);
- private final ModificationApplyOperation strategyTree;
+ private final RootModificationApplyOperation strategyTree;
private final InMemoryDataTreeSnapshot snapshot;
private final ModifiedNode rootNode;
@GuardedBy("this")
private boolean sealed = false;
- InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final ModificationApplyOperation resolver) {
+ InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final RootModificationApplyOperation resolver) {
this.snapshot = Preconditions.checkNotNull(snapshot);
- this.strategyTree = Preconditions.checkNotNull(resolver);
+ this.strategyTree = Preconditions.checkNotNull(resolver).snapshot();
this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode());
}
private ModificationApplyOperation resolveModificationStrategy(final InstanceIdentifier path) {
LOG.trace("Resolving modification apply strategy for {}", path);
- return TreeNodeUtils.findNodeChecked(strategyTree, path);
+ if(rootNode.getType() == ModificationType.UNMODIFIED) {
+ strategyTree.upgradeIfPossible();
+ }
+
+ return TreeNodeUtils.<ModificationApplyOperation>findNodeChecked(strategyTree, path);
}
private OperationWithModification resolveModificationFor(final InstanceIdentifier path) {
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
final class InMemoryDataTreeSnapshot implements DataTreeSnapshot {
- private final ModificationApplyOperation applyOper;
+ private final RootModificationApplyOperation applyOper;
private final SchemaContext schemaContext;
private final TreeNode rootNode;
InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final TreeNode rootNode,
- final ModificationApplyOperation applyOper) {
+ final RootModificationApplyOperation applyOper) {
this.schemaContext = Preconditions.checkNotNull(schemaContext);
this.rootNode = Preconditions.checkNotNull(rootNode);
this.applyOper = Preconditions.checkNotNull(applyOper);
--- /dev/null
+/*
+ * Copyright (c) 2014 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.data.impl.schema.tree;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
+
+import com.google.common.base.Optional;
+
+public abstract class RootModificationApplyOperation implements ModificationApplyOperation {
+
+ @Override
+ public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
+ return getDelegate().getChild(child);
+ }
+
+ @Override
+ public final void checkApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current)
+ throws DataValidationFailedException {
+ getDelegate().checkApplicable(path, modification, current);
+ }
+
+ @Override
+ public final Optional<TreeNode> apply(final ModifiedNode modification, final Optional<TreeNode> currentMeta, final Version version) {
+ return getDelegate().apply(modification, currentMeta, version);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return getDelegate().equals(obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return getDelegate().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getDelegate().toString();
+ }
+
+ @Override
+ public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException {
+ getDelegate().verifyStructure(modification);
+ }
+
+ abstract ModificationApplyOperation getDelegate();
+
+ public abstract RootModificationApplyOperation snapshot();
+
+ public abstract void upgradeIfPossible();
+
+
+
+ public static RootModificationApplyOperation from(final ModificationApplyOperation resolver) {
+ if(resolver instanceof RootModificationApplyOperation) {
+ return ((RootModificationApplyOperation) resolver).snapshot();
+ }
+ return new NotUpgradable(resolver);
+ }
+
+ private static final class Upgradable extends RootModificationApplyOperation {
+
+ private final LatestOperationHolder holder;
+ private ModificationApplyOperation delegate;
+
+
+ public Upgradable(final LatestOperationHolder holder, final ModificationApplyOperation delegate) {
+ this.holder = holder;
+ this.delegate = delegate;
+
+ }
+
+ @Override
+ public void upgradeIfPossible() {
+ ModificationApplyOperation holderCurrent = holder.getCurrent();
+ if(holderCurrent != delegate) {
+ // FIXME: Allow update only if there is addition of models, not removals.
+ delegate = holderCurrent;
+ }
+
+ }
+
+ @Override
+ ModificationApplyOperation getDelegate() {
+ return delegate;
+ }
+
+ @Override
+ public RootModificationApplyOperation snapshot() {
+ return new Upgradable(holder,getDelegate());
+ }
+
+ }
+
+ private static final class NotUpgradable extends RootModificationApplyOperation {
+
+ private final ModificationApplyOperation delegate;
+
+ public NotUpgradable(final ModificationApplyOperation delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public ModificationApplyOperation getDelegate() {
+ return delegate;
+ }
+
+ @Override
+ public void upgradeIfPossible() {
+ // Intentional noop
+ }
+
+ @Override
+ public RootModificationApplyOperation snapshot() {
+ return this;
+ }
+ }
+
+ public static class LatestOperationHolder {
+
+ private ModificationApplyOperation current = new AlwaysFailOperation();
+
+ public ModificationApplyOperation getCurrent() {
+ return current;
+ }
+
+ public void setCurrent(final ModificationApplyOperation newApplyOper) {
+ current = newApplyOper;
+ }
+
+ public RootModificationApplyOperation newSnapshot() {
+ return new Upgradable(this,current);
+ }
+
+ }
+}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-import com.google.common.base.Optional;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
+
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
-import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
-import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
+import com.google.common.base.Optional;
.build();
private SchemaContext schemaContext;
- private ModificationApplyOperation applyOper;
+ private RootModificationApplyOperation rootOper;
@Before
public void prepare() {
schemaContext = TestModel.createTestContext();
assertNotNull("Schema context must not be null.", schemaContext);
- applyOper = SchemaAwareApplyOperation.from(schemaContext);
+ rootOper = RootModificationApplyOperation.from(SchemaAwareApplyOperation.from(schemaContext));
}
/**
@Test
public void basicReadWrites() {
DataTreeModification modificationTree = new InMemoryDataTreeModification(new InMemoryDataTreeSnapshot(schemaContext,
- TreeNodeFactory.createTreeNode(createDocumentOne(), Version.initial()), applyOper),
- new SchemaAwareApplyOperationRoot(schemaContext));
+ TreeNodeFactory.createTreeNode(createDocumentOne(), Version.initial()), rootOper),
+ rootOper);
Optional<NormalizedNode<?, ?>> originalBarNode = modificationTree.readNode(OUTER_LIST_2_PATH);
assertTrue(originalBarNode.isPresent());
assertSame(BAR_NODE, originalBarNode.get());
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
-
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
return findNodeInModule(module, path);
}
- public static GroupingDefinition findGrouping(final SchemaContext context, final Module module, final List<QName> path) {
- QName first = path.get(0);
+ public static GroupingDefinition findGrouping(final SchemaContext context, final Module module, final Iterable<QName> path) {
+ Iterator<QName> iterator = path.iterator();
+ QName first = iterator.next();
Module m = context.findModuleByNamespace(first.getNamespace()).iterator().next();
DataNodeContainer currentParent = m;
for (QName qname : path) {
}
private static DataSchemaNode getResultFromUses(final UsesNode u, final String currentName, final SchemaContext ctx) {
- SchemaNode targetGrouping = findNodeInSchemaContext(ctx, u.getGroupingPath().getPathFromRoot());
-
+ SchemaNode targetGrouping = SchemaContextUtil.findNodeInSchemaContext(ctx, u.getGroupingPath()
+ .getPathFromRoot());
+ if (!(targetGrouping instanceof GroupingDefinition)) {
+ targetGrouping = findGrouping(ctx, getParentModule(targetGrouping, ctx), u.getGroupingPath()
+ .getPathFromRoot());
+ }
Preconditions.checkArgument(targetGrouping instanceof GroupingDefinition,
"Failed to generate code for augment in %s", u);
GroupingDefinition gr = (GroupingDefinition) targetGrouping;