X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frepo%2FURLSchemaContextResolver.java;h=97d0c64c51128af9f2798b4af83b5bae5bcbcc9b;hb=6445362084c167640d41a1dec9127899fb54b8c0;hp=47de6b1a540b5bd1b0a14014ce9a5364447977b3;hpb=df568194d106efa63c3138f0cc699dd53735cf44;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/URLSchemaContextResolver.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/URLSchemaContextResolver.java index 47de6b1a54..97d0c64c51 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/URLSchemaContextResolver.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/URLSchemaContextResolver.java @@ -8,24 +8,21 @@ package org.opendaylight.yangtools.yang.parser.repo; import static com.google.common.base.Preconditions.checkArgument; - import com.google.common.annotations.Beta; -import com.google.common.base.Objects.ToStringHelper; +import com.google.common.base.MoreObjects.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; - import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Collection; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicReference; - import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException; @@ -37,30 +34,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 { +public class URLSchemaContextResolver implements AutoCloseable, SchemaSourceProvider { private static final Logger LOG = LoggerFactory.getLogger(URLSchemaContextResolver.class); - private final Cache sources = CacheBuilder.newBuilder().build(); private final Collection requiredSources = new ConcurrentLinkedDeque<>(); + private final Multimap texts = ArrayListMultimap.create(); private final AtomicReference> currentSchemaContext = new AtomicReference<>(Optional.absent()); + private final InMemorySchemaSourceCache 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 +104,31 @@ public class URLSchemaContextResolver implements SchemaSourceProvider 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 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 +155,7 @@ public class URLSchemaContextResolver implements SchemaSourceProvider sources; do { v = version; - sources = ImmutableList.copyOf(requiredSources); + sources = ImmutableSet.copyOf(requiredSources); } while (v != version); while (true) { @@ -148,11 +164,13 @@ public class URLSchemaContextResolver implements SchemaSourceProvider getSource(final SourceIdentifier sourceIdentifier) { - final YangTextSchemaSource ret = sources.getIfPresent(sourceIdentifier); - if (ret == null) { + public synchronized CheckedFuture getSource(final SourceIdentifier sourceIdentifier) { + final Collection ret = texts.get(sourceIdentifier); + + LOG.debug("Lookup {} result {}", sourceIdentifier, ret); + if (ret.isEmpty()) { return Futures.immediateFailedCheckedFuture( - new MissingSchemaSourceException("URL for " + sourceIdentifier + " not registered")); + new MissingSchemaSourceException("URL for " + sourceIdentifier + " not registered", sourceIdentifier)); } - return Futures.immediateCheckedFuture(ret); + return Futures.immediateCheckedFuture(ret.iterator().next()); + } + + @Override + public void close() { + transReg.close(); } }