Merge "BUG-576: fixed javadoc warnings."
authorTony Tkacik <ttkacik@cisco.com>
Mon, 25 Aug 2014 10:19:22 +0000 (10:19 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 25 Aug 2014 10:19:22 +0000 (10:19 +0000)
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNormalizedNodeStreamWriter.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTree.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeModification.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/URLSchemaContextResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/URLSchemaContextResolver.java

index c39c2ecd78b452d0e5102ce8df6bc04b58f09d94..fe3d1841a2bd8b67041aa66b7cddaa40120cb4e9 100644 (file)
@@ -176,17 +176,15 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
     @Override
     public void startMapEntryNode(final NodeIdentifierWithPredicates identifier,final int childSizeHint) throws IllegalArgumentException {
         if(!(getCurrent() instanceof NormalizedNodeResultBuilder)) {
-            Preconditions.checkArgument(getCurrent() instanceof ImmutableMapNodeBuilder);
+            Preconditions.checkArgument(getCurrent() instanceof ImmutableMapNodeBuilder || getCurrent() instanceof ImmutableOrderedMapNodeBuilder);
         }
         enter(Builders.mapEntryBuilder().withNodeIdentifier(identifier));
     }
 
     @Override
     public void startOrderedMapNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
-        if(!(getCurrent() instanceof NormalizedNodeResultBuilder)) {
-            Preconditions.checkArgument(getCurrent() instanceof ImmutableOrderedMapNodeBuilder);
-        }
-        enter(Builders.mapBuilder().withNodeIdentifier(name));
+        checkDataNodeContainer();
+        enter(Builders.orderedMapBuilder().withNodeIdentifier(name));
     }
 
     @Override
index 02e85a46a0bca643c3f2315d71730417ea3ac875..0f0b4a12da7e96f594a5d7a8f78c1a0dc79bf8c4 100644 (file)
@@ -103,7 +103,7 @@ final class InMemoryDataTree implements DataTree {
         rwLock.writeLock().lock();
         try {
             final Optional<TreeNode> newRoot = m.getStrategy().apply(m.getRootModification(),
-                    Optional.<TreeNode>of(rootNode), rootNode.getSubtreeVersion().next());
+                    Optional.<TreeNode>of(rootNode), m.getVersion());
             Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node");
             return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, rootNode, newRoot.get());
         } finally {
index 73d3ac36c03980d86d3235764755ea924ad38a10..e26c32ee5b03bfc01edd2ec64698a66911797bd0 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
 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.api.schema.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,6 +31,7 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     private final RootModificationApplyOperation strategyTree;
     private final InMemoryDataTreeSnapshot snapshot;
     private final ModifiedNode rootNode;
+    private final Version version;
 
     @GuardedBy("this")
     private boolean sealed = false;
@@ -38,6 +40,17 @@ final class InMemoryDataTreeModification implements DataTreeModification {
         this.snapshot = Preconditions.checkNotNull(snapshot);
         this.strategyTree = Preconditions.checkNotNull(resolver).snapshot();
         this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode());
+        /*
+         * We could allocate version beforehand, since Version contract
+         * states two allocated version must be allways different.
+         * 
+         * Preallocating version simplifies scenarios such as
+         * chaining of modifications, since version for particular
+         * node in modification and in data tree (if successfully
+         * commited) will be same and will not change.
+         * 
+         */
+        this.version = snapshot.getRootNode().getSubtreeVersion().next();
     }
 
     ModifiedNode getRootModification() {
@@ -108,7 +121,7 @@ final class InMemoryDataTreeModification implements DataTreeModification {
 
         try {
             return resolveModificationStrategy(path).apply(modification, modification.getOriginal(),
-                    snapshot.getRootNode().getSubtreeVersion().next());
+                    version);
         } catch (Exception e) {
             LOG.error("Could not create snapshot for {}:{}", path,modification,e);
             throw e;
@@ -160,22 +173,17 @@ final class InMemoryDataTreeModification implements DataTreeModification {
         }
 
         /*
-         *  FIXME: Add advanced transaction chaining for modification of not rebased
-         *  modification.
-         *
-         *  Current computation of tempRoot may yeld incorrect subtree versions
-         *  if there are multiple concurrent transactions, which may break
-         *  versioning preconditions for modification of previously occured write,
-         *  directly nested under parent node, since node version is derived from
-         *  subtree version.
-         *
-         *  For deeper nodes subtree version is derived from their respective metadata
-         *  nodes, so this incorrect root subtree version is not affecting us.
+         *  We will use preallocated version, this means returned snapshot will 
+         *  have same version each time this method is called.
          */
         TreeNode originalSnapshotRoot = snapshot.getRootNode();
-        Optional<TreeNode> tempRoot = strategyTree.apply(rootNode, Optional.of(originalSnapshotRoot), originalSnapshotRoot.getSubtreeVersion().next());
+        Optional<TreeNode> tempRoot = strategyTree.apply(rootNode, Optional.of(originalSnapshotRoot), version);
 
         InMemoryDataTreeSnapshot tempTree = new InMemoryDataTreeSnapshot(snapshot.getSchemaContext(), tempRoot.get(), strategyTree);
         return tempTree.newModification();
     }
+
+    Version getVersion() {
+        return version;
+    }
 }
index 34c81911321ac42a698252cfdeb02f6b45fbccae..252a782e1567eea80aad6ed7365df494decb9bd4 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.io.ByteSource;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
@@ -20,8 +21,10 @@ import java.util.Collection;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+
 import javax.annotation.concurrent.GuardedBy;
 import javax.annotation.concurrent.ThreadSafe;
+
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
@@ -32,6 +35,11 @@ import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * @deprecated Use {@link org.opendaylight.yangtools.yang.parser.repo.URLSchemaContextResolver}
+ * instead.
+ */
+@Deprecated
 @ThreadSafe
 public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<InputStream> {
 
@@ -47,7 +55,7 @@ public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<In
     /**
      * Register new yang schema when it appears.
      */
-    public synchronized ObjectRegistration<URL> registerSource(URL source) {
+    public synchronized ObjectRegistration<URL> registerSource(final URL source) {
         checkArgument(source != null, "Supplied source must not be null");
         InputStream yangStream = getInputStream(source);
         YangModelDependencyInfo modelInfo = YangModelDependencyInfo.fromInputStream(yangStream);
@@ -63,7 +71,7 @@ public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<In
     }
 
     @Override
-    public synchronized Optional<InputStream> getSchemaSource(SourceIdentifier key) {
+    public synchronized Optional<InputStream> getSchemaSource(final SourceIdentifier key) {
         SourceContext ctx = availableSources.get(key);
         if (ctx != null) {
             InputStream stream = getInputStream(ctx.getInstance());
@@ -73,11 +81,11 @@ public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<In
     }
 
     @Override
-    public Optional<InputStream> getSchemaSource(String name, Optional<String> version) {
+    public Optional<InputStream> getSchemaSource(final String name, final Optional<String> version) {
         return getSchemaSource(SourceIdentifier.create(name, version));
     }
 
-    private static InputStream getInputStream(URL source) {
+    private static InputStream getInputStream(final URL source) {
         InputStream stream;
         try {
             stream = source.openStream();
@@ -93,7 +101,7 @@ public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<In
         final SourceIdentifier identifier;
         final YangModelDependencyInfo dependencyInfo;
 
-        public SourceContext(URL instance, SourceIdentifier identifier, YangModelDependencyInfo modelInfo) {
+        public SourceContext(final URL instance, final SourceIdentifier identifier, final YangModelDependencyInfo modelInfo) {
             super(instance);
             this.identifier = identifier;
             this.dependencyInfo = modelInfo;
@@ -114,7 +122,7 @@ public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<In
         }
     }
 
-    private synchronized void removeSource(SourceContext sourceContext) {
+    private synchronized void removeSource(final SourceContext sourceContext) {
         boolean removed = availableSources.remove(sourceContext.getIdentifier(), sourceContext);
         if (removed) {
             tryToUpdateSchemaContext();
index bbcd95e220eb34737f50374cadd359c7af17e749..02497a880921dc19edf213ea25e36d09d58fcead 100644 (file)
@@ -13,9 +13,9 @@ import com.google.common.annotations.Beta;
 import com.google.common.base.Objects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 
@@ -37,30 +37,41 @@ import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource.Costs;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaListenerRegistration;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
+import org.opendaylight.yangtools.yang.model.repo.util.InMemorySchemaSourceCache;
 import org.opendaylight.yangtools.yang.parser.util.ASTSchemaSource;
 import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Beta
-public class URLSchemaContextResolver implements SchemaSourceProvider<YangTextSchemaSource> {
+public class URLSchemaContextResolver implements AutoCloseable, SchemaSourceProvider<YangTextSchemaSource> {
     private static final Logger LOG = LoggerFactory.getLogger(URLSchemaContextResolver.class);
 
-    private final Cache<SourceIdentifier, YangTextSchemaSource> sources = CacheBuilder.newBuilder().build();
     private final Collection<SourceIdentifier> requiredSources = new ConcurrentLinkedDeque<>();
+    private final Multimap<SourceIdentifier, YangTextSchemaSource> texts = ArrayListMultimap.create();
     private final AtomicReference<Optional<SchemaContext>> currentSchemaContext =
             new AtomicReference<>(Optional.<SchemaContext>absent());
+    private final InMemorySchemaSourceCache<ASTSchemaSource> cache;
+    private final SchemaListenerRegistration transReg;
     private final SchemaSourceRegistry registry;
     private final SchemaRepository repository;
     private volatile Object version = new Object();
     private volatile Object contextVersion = version;
 
+
     private URLSchemaContextResolver(final SchemaRepository repository, final SchemaSourceRegistry registry) {
         this.repository = Preconditions.checkNotNull(repository);
         this.registry = Preconditions.checkNotNull(registry);
+
+        final TextToASTTransformer t = TextToASTTransformer.create(repository, registry);
+        transReg = registry.registerSchemaSourceListener(t);
+
+        cache = InMemorySchemaSourceCache.createSoftCache(registry, ASTSchemaSource.class);
     }
 
     public static URLSchemaContextResolver create(final String name) {
@@ -96,23 +107,31 @@ public class URLSchemaContextResolver implements SchemaSourceProvider<YangTextSc
         LOG.trace("Resolved URL {} to source {}", url, ast);
 
         final SourceIdentifier resolvedId = ast.getIdentifier();
-        final SchemaSourceRegistration<YangTextSchemaSource> reg = registry.registerSchemaSource(this,
-                PotentialSchemaSource.create(resolvedId, YangTextSchemaSource.class, 0));
-
-        requiredSources.add(resolvedId);
-        LOG.trace("Added source {} to schema context requirements", resolvedId);
-        version = new Object();
 
-        return new AbstractURLRegistration(text) {
-            @Override
-            protected void removeRegistration() {
-                requiredSources.remove(resolvedId);
-                LOG.trace("Removed source {} from schema context requirements", resolvedId);
-                version = new Object();
-                reg.close();
-                sources.invalidate(resolvedId);
-            }
-        };
+        synchronized (this) {
+            texts.put(resolvedId, text);
+            LOG.debug("Populated {} with text", resolvedId);
+
+            final SchemaSourceRegistration<YangTextSchemaSource> reg = registry.registerSchemaSource(this,
+                PotentialSchemaSource.create(resolvedId, YangTextSchemaSource.class, Costs.IMMEDIATE.getValue()));
+            requiredSources.add(resolvedId);
+            cache.schemaSourceEncountered(ast);
+            LOG.debug("Added source {} to schema context requirements", resolvedId);
+            version = new Object();
+
+            return new AbstractURLRegistration(text) {
+                @Override
+                protected void removeRegistration() {
+                    synchronized (URLSchemaContextResolver.this) {
+                        requiredSources.remove(resolvedId);
+                        LOG.trace("Removed source {} from schema context requirements", resolvedId);
+                        version = new Object();
+                        reg.close();
+                        texts.remove(resolvedId, text);
+                    }
+                }
+            };
+        }
     }
 
     /**
@@ -139,7 +158,7 @@ public class URLSchemaContextResolver implements SchemaSourceProvider<YangTextSc
             Collection<SourceIdentifier> sources;
             do {
                 v = version;
-                sources = ImmutableList.copyOf(requiredSources);
+                sources = ImmutableSet.copyOf(requiredSources);
             } while (v != version);
 
             while (true) {
@@ -148,11 +167,13 @@ public class URLSchemaContextResolver implements SchemaSourceProvider<YangTextSc
                     sc = Optional.of(f.checkedGet());
                     break;
                 } catch (SchemaResolutionException e) {
-                    LOG.info("Failed to fully assemble schema context for {}", sources, e);
+                    LOG.debug("Failed to fully assemble schema context for {}", sources, e);
                     sources = e.getResolvedSources();
                 }
             }
 
+            LOG.debug("Resolved schema context for {}", sources);
+
             synchronized (this) {
                 if (contextVersion == cv) {
                     currentSchemaContext.set(sc);
@@ -165,13 +186,20 @@ public class URLSchemaContextResolver implements SchemaSourceProvider<YangTextSc
     }
 
     @Override
-    public CheckedFuture<YangTextSchemaSource, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
-        final YangTextSchemaSource ret = sources.getIfPresent(sourceIdentifier);
-        if (ret == null) {
+    public synchronized CheckedFuture<YangTextSchemaSource, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
+        final Collection<YangTextSchemaSource> ret = texts.get(sourceIdentifier);
+
+        LOG.debug("Lookup {} result {}", sourceIdentifier, ret);
+        if (ret.isEmpty()) {
             return Futures.<YangTextSchemaSource, SchemaSourceException>immediateFailedCheckedFuture(
                     new MissingSchemaSourceException("URL for " + sourceIdentifier + " not registered", sourceIdentifier));
         }
 
-        return Futures.immediateCheckedFuture(ret);
+        return Futures.immediateCheckedFuture(ret.iterator().next());
+    }
+
+    @Override
+    public void close() {
+        transReg.close();
     }
 }