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%2Fstmt%2Freactor%2FBuildGlobalContext.java;h=ed7850df7aa34e3b08affe7a9453e97081134194;hb=b212baa59f859732bd3a799425bb420035fe6154;hp=c16dc4d924a163802c93d3a77c6347b3931e846d;hpb=4fe39dd37465c2bb87f920317849ca5eb044fc3d;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java index c16dc4d924..ed7850df7a 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java @@ -13,12 +13,10 @@ import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; import com.google.common.collect.Table; import com.google.common.collect.TreeBasedTable; import java.util.ArrayList; import java.util.Collection; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -30,9 +28,10 @@ import java.util.Optional; import java.util.Set; import java.util.SortedMap; import javax.annotation.Nonnull; +import org.opendaylight.yangtools.util.RecursiveObjectLeaker; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; @@ -45,12 +44,14 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; 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.NamespaceNotAvailableException; 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.meta.StatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules; import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules.SupportedModules; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -60,17 +61,14 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamesp 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.SourceSpecificContext.PhaseCompletionProgress; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.RecursiveObjectLeaker; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBehaviour.Registry { +class BuildGlobalContext extends NamespaceStorageSupport implements Registry { private static final Logger LOG = LoggerFactory.getLogger(BuildGlobalContext.class); - private static final List PHASE_EXECUTION_ORDER = ImmutableList - . builder().add(ModelProcessingPhase.SOURCE_PRE_LINKAGE) + private static final List PHASE_EXECUTION_ORDER = + ImmutableList.builder().add(ModelProcessingPhase.SOURCE_PRE_LINKAGE) .add(ModelProcessingPhase.SOURCE_LINKAGE).add(ModelProcessingPhase.STATEMENT_DEFINITION) .add(ModelProcessingPhase.FULL_DECLARATION).add(ModelProcessingPhase.EFFECTIVE_MODEL).build(); @@ -242,7 +240,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh private SomeModifiersUnresolvedException propagateException(final SourceSpecificContext source, final RuntimeException cause) throws SomeModifiersUnresolvedException { - final SourceIdentifier sourceId = Utils.createSourceIdentifier(source.getRoot()); + final SourceIdentifier sourceId = StmtContextUtils.createSourceIdentifier(source.getRoot()); if (!(cause instanceof SourceException)) { /* * This should not be happening as all our processing should provide SourceExceptions. @@ -256,6 +254,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh throw new SomeModifiersUnresolvedException(currentPhase, sourceId, cause); } + @SuppressWarnings("checkstyle:illegalCatch") private EffectiveSchemaContext transformEffective() throws ReactorException { Preconditions.checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL); final List> rootStatements = new ArrayList<>(sources.size()); @@ -276,7 +275,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh } sealMutableStatements(); - return new EffectiveSchemaContext(rootStatements, rootEffectiveStatements); + return EffectiveSchemaContext.create(rootStatements, rootEffectiveStatements); } private void startPhase(final ModelProcessingPhase phase) { @@ -300,6 +299,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh loadPhaseStatementsFor(libSources); } + @SuppressWarnings("checkstyle:illegalCatch") private void loadPhaseStatementsFor(final Set sources) throws ReactorException { for (final SourceSpecificContext source : sources) { try { @@ -333,22 +333,22 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh if (suppressed.length > 0) { LOG.error("{} additional errors reported:", suppressed.length); - int i = 1; + int count = 1; for (final Throwable t : suppressed) { // FIXME: this should be configured in the appender, really if (LOG.isDebugEnabled()) { - LOG.error("Error {}: {}", i, t.getMessage(), t); + LOG.error("Error {}: {}", count, t.getMessage(), t); } else { - LOG.error("Error {}: {}", i, t.getMessage()); + LOG.error("Error {}: {}", count, t.getMessage()); } - i++; + count++; } } if (!addedCause) { addedCause = true; - final SourceIdentifier sourceId = Utils.createSourceIdentifier(failedSource.getRoot()); + final SourceIdentifier sourceId = StmtContextUtils.createSourceIdentifier(failedSource.getRoot()); buildFailure = new SomeModifiersUnresolvedException(currentPhase, sourceId, sourceEx); } else { buildFailure.addSuppressed(sourceEx); @@ -357,9 +357,10 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh return buildFailure; } + @SuppressWarnings("checkstyle:illegalCatch") private void completePhaseActions() throws ReactorException { Preconditions.checkState(currentPhase != null); - final List sourcesToProgress = Lists.newArrayList(sources); + final List sourcesToProgress = new ArrayList<>(sources); if (!libSources.isEmpty()) { Preconditions.checkState(currentPhase == ModelProcessingPhase.SOURCE_PRE_LINKAGE, "Yang library sources should be empty after ModelProcessingPhase.SOURCE_PRE_LINKAGE, " @@ -379,8 +380,9 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh switch (sourceProgress) { case FINISHED: currentSource.remove(); - // Fallback to progress, since we were able to make - // progress in computation + // we were able to make progress in computation + progressing = true; + break; case PROGRESS: progressing = true; break; @@ -419,7 +421,8 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh Preconditions.checkState(currentPhase == ModelProcessingPhase.SOURCE_PRE_LINKAGE, "Required library sources can be collected only in ModelProcessingPhase.SOURCE_PRE_LINKAGE phase," + " but current phase was %s", currentPhase); - final TreeBasedTable libSourcesTable = TreeBasedTable.create(); + final TreeBasedTable, SourceSpecificContext> libSourcesTable = TreeBasedTable.create( + String::compareTo, Revision::compare); for (final SourceSpecificContext libSource : libSources) { final ModuleIdentifier libSourceIdentifier = Preconditions.checkNotNull(libSource.getRootIdentifier()); libSourcesTable.put(libSourceIdentifier.getName(), libSourceIdentifier.getRevision(), libSource); @@ -428,33 +431,50 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh final Set requiredLibs = new HashSet<>(); for (final SourceSpecificContext source : sources) { collectRequiredSourcesFromLib(libSourcesTable, requiredLibs, source); + removeConflictingLibSources(source, requiredLibs); } return requiredLibs; } private void collectRequiredSourcesFromLib( - final TreeBasedTable libSourcesTable, + final TreeBasedTable, SourceSpecificContext> libSourcesTable, final Set requiredLibs, final SourceSpecificContext source) { - final Collection requiredModules = source.getRequiredModules(); - for (final ModuleIdentifier requiredModule : requiredModules) { - final SourceSpecificContext libSource = getRequiredLibSource(requiredModule, libSourcesTable); + for (final SourceIdentifier requiredSource : source.getRequiredSources()) { + final SourceSpecificContext libSource = getRequiredLibSource(requiredSource, libSourcesTable); if (libSource != null && requiredLibs.add(libSource)) { collectRequiredSourcesFromLib(libSourcesTable, requiredLibs, libSource); } } } - private static SourceSpecificContext getRequiredLibSource(final ModuleIdentifier requiredModule, - final TreeBasedTable libSourcesTable) { - return requiredModule.getRevision() == SimpleDateFormatUtil.DEFAULT_DATE_IMP ? getLatestRevision(libSourcesTable - .row(requiredModule.getName())) : libSourcesTable.get(requiredModule.getName(), - requiredModule.getRevision()); + private static SourceSpecificContext getRequiredLibSource(final SourceIdentifier requiredSource, + final TreeBasedTable, SourceSpecificContext> libSourcesTable) { + return requiredSource.getRevision() == null ? getLatestRevision(libSourcesTable.row(requiredSource.getName())) + : libSourcesTable.get(requiredSource.getName(), + Optional.of(Revision.valueOf(requiredSource.getRevision()))); } - private static SourceSpecificContext getLatestRevision(final SortedMap sourceMap) { + private static SourceSpecificContext getLatestRevision(final SortedMap, + SourceSpecificContext> sourceMap) { return sourceMap != null && !sourceMap.isEmpty() ? sourceMap.get(sourceMap.lastKey()) : null; } + // removes required library sources which would cause namespace/name conflict with one of the main sources + // later in the parsing process. this can happen if we add a parent module or a submodule as a main source + // and the same parent module or submodule is added as one of the library sources. + // such situation may occur when using the yang-system-test artifact - if a parent module/submodule is specified + // as its argument and the same dir is specified as one of the library dirs through -p option). + private static void removeConflictingLibSources(final SourceSpecificContext source, + final Set requiredLibs) { + final Iterator requiredLibsIter = requiredLibs.iterator(); + while (requiredLibsIter.hasNext()) { + final SourceSpecificContext currentReqSource = requiredLibsIter.next(); + if (source.getRootIdentifier().equals(currentReqSource.getRootIdentifier())) { + requiredLibsIter.remove(); + } + } + } + private void endPhase(final ModelProcessingPhase phase) { Preconditions.checkState(currentPhase == phase); finishedPhase = currentPhase;