+/*
+ * 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.parser.impl.util;
+import static com.google.common.base.Preconditions.checkArgument;
+
+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;
-import java.util.List;
+import java.util.Collection;
import java.util.Map.Entry;
-import java.util.Set;
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.Registration;
-import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.util.repo.AdvancedSchemaSourceProvider;
import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.collect.ImmutableSet;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
+/**
+ * @deprecated Use {@link org.opendaylight.yangtools.yang.parser.repo.URLSchemaContextResolver}
+ * instead.
+ */
+@Deprecated
+@ThreadSafe
public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<InputStream> {
private static final Logger LOG = LoggerFactory.getLogger(URLSchemaContextResolver.class);
- private final ConcurrentMap<SourceIdentifier, SourceContext> availableSources = new ConcurrentHashMap<>();
+ @GuardedBy("this")
+ private final ConcurrentMap<SourceIdentifier, SourceContext> availableSources = new ConcurrentHashMap<>();
+ @GuardedBy("this")
private YangSourceContext currentSourceContext;
- private Optional<SchemaContext> currentSchemaContext;
-
- public Registration<URL> registerSource(URL source) {
+ @GuardedBy("this")
+ private Optional<SchemaContext> currentSchemaContext = Optional.absent();
+
+ /**
+ * Register new yang schema when it appears.
+ */
+ 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);
return sourceContext;
}
- public Optional<SchemaContext> getSchemaContext() {
+ public synchronized Optional<SchemaContext> getSchemaContext() {
return currentSchemaContext;
}
@Override
- public 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());
}
@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 InputStream getInputStream(URL source) {
+ private static InputStream getInputStream(final URL source) {
InputStream stream;
try {
stream = source.openStream();
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;
}
+ @Override
public SourceIdentifier getIdentifier() {
return identifier;
}
}
}
- private void removeSource(SourceContext sourceContext) {
+ private synchronized void removeSource(final SourceContext sourceContext) {
boolean removed = availableSources.remove(sourceContext.getIdentifier(), sourceContext);
- if(removed) {
+ if (removed) {
tryToUpdateSchemaContext();
}
}
+ /**
+ * Try to parse all currently available yang files and build new schema context.
+ * @return new schema context iif there is at least 1 yang file registered and new schema context was successfully built.
+ */
public synchronized Optional<SchemaContext> tryToUpdateSchemaContext() {
- if(availableSources.isEmpty()) {
+ if (availableSources.isEmpty()) {
return Optional.absent();
}
ImmutableMap<SourceIdentifier, SourceContext> actualSources = ImmutableMap.copyOf(availableSources);
- Builder<SourceIdentifier, YangModelDependencyInfo> builder = ImmutableMap.<SourceIdentifier, YangModelDependencyInfo> builder();
- for(Entry<SourceIdentifier, SourceContext> entry : actualSources.entrySet()) {
+ Builder<SourceIdentifier, YangModelDependencyInfo> builder = ImmutableMap.<SourceIdentifier, YangModelDependencyInfo>builder();
+ for (Entry<SourceIdentifier, SourceContext> entry : actualSources.entrySet()) {
builder.put(entry.getKey(), entry.getValue().getDependencyInfo());
}
ImmutableMap<SourceIdentifier, YangModelDependencyInfo> sourcesMap = builder.build();
- YangSourceContext context = YangSourceContext.createFrom(sourcesMap);
- LOG.debug("Trying to create schema context from {}",sourcesMap.keySet());
- LOG.debug("Ommiting {} because of unresolved dependencies",context.getMissingDependencies().keySet());
-
- try {
- if(currentSourceContext == null || !context.getValidSources().equals(currentSourceContext.getValidSources())) {
- List<InputStream> streams = YangSourceContext.getValidInputStreams(context, this);
- YangParserImpl parser = new YangParserImpl();
- Set<Module> modules = parser.parseYangModelsFromStreams(streams);
- SchemaContext schemaContext = parser.resolveSchemaContext(modules);
+ YangSourceContext yangSourceContext = YangSourceContext.createFrom(sourcesMap, this);
+ LOG.debug("Trying to create schema context from {}", sourcesMap.keySet());
+
+ if (yangSourceContext.getMissingDependencies().size() != 0) {
+ LOG.debug("Omitting {} because of unresolved dependencies", yangSourceContext.getMissingDependencies().keySet());
+ LOG.debug("Missing model sources for {}", yangSourceContext.getMissingSources());
+ }
+ if (currentSourceContext == null || !yangSourceContext.getValidSources().equals(currentSourceContext.getValidSources())) {
+ try {
+ Collection<ByteSource> byteSources = yangSourceContext.getValidByteSources();
+ YangParserImpl parser = YangParserImpl.getInstance();
+ SchemaContext schemaContext = parser.parseSources(byteSources);
currentSchemaContext = Optional.of(schemaContext);
- currentSourceContext = context;
- return currentSchemaContext;
- }
- currentSourceContext = context;
- } catch (Exception e) {
- LOG.error("Could not create schema context for {} ",context.getValidSources());
+ currentSourceContext = yangSourceContext;
+ return Optional.of(schemaContext);
+ } catch (Exception e) {
+ LOG.error("Could not create schema context for {} ", yangSourceContext.getValidSources(), e);
+ return Optional.absent();
+ }
+ } else {
+ currentSourceContext = yangSourceContext;
+ return Optional.absent();
}
- return Optional.absent();
}
-
}