*/
package org.opendaylight.yangtools.yang.parser.stmt.reactor;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite;
+import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace;
+
+import java.util.Map.Entry;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
.build();
private final Map<QName,StatementDefinitionContext<?,?,?>> definitions = new HashMap<>();
- private final Map<Class<?>,NamespaceBehaviourWithListeners<?, ?, ?>> namespaces = new HashMap<>();
+ private final Map<Class<?>,NamespaceBehaviourWithListeners<?, ?, ?>> supportedNamespaces = new HashMap<>();
private final Map<ModelProcessingPhase,StatementSupportBundle> supports;
private final Set<SourceSpecificContext> sources = new HashSet<>();
- private ModelProcessingPhase currentPhase;
- private ModelProcessingPhase finishedPhase;
+ private ModelProcessingPhase currentPhase = ModelProcessingPhase.INIT;
+ private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT;
public BuildGlobalContext(Map<ModelProcessingPhase, StatementSupportBundle> supports) {
super();
- this.supports = supports;
+ this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null");
+ }
+
+ public BuildGlobalContext(Map<ModelProcessingPhase, StatementSupportBundle> supports, Map<ValidationBundleType,Collection<?>> supportedValidation) {
+ super();
+ this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null");
+
+ Set<Entry<ValidationBundleType, Collection<?>>> validationBundles = supportedValidation.entrySet();
+ for (Entry<ValidationBundleType, Collection<?>> validationBundle : validationBundles) {
+ addToNs(ValidationBundlesNamespace.class, validationBundle.getKey(), validationBundle.getValue());
+ }
+ }
+
+ public StatementSupportBundle getSupportsForPhase(ModelProcessingPhase currentPhase) {
+ return supports.get(currentPhase);
}
public void addSource(@Nonnull StatementStreamSource source) {
@Override
public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> getNamespaceBehaviour(Class<N> type) {
- NamespaceBehaviourWithListeners<?, ?, ?> potential = namespaces.get(type);
+ NamespaceBehaviourWithListeners<?, ?, ?> potential = supportedNamespaces.get(type);
if (potential == null) {
NamespaceBehaviour<K, V, N> potentialRaw = supports.get(currentPhase).getNamespaceBehaviour(type);
if(potentialRaw != null) {
potential = new NamespaceBehaviourWithListeners<>(potentialRaw);
- namespaces.put(type, potential);
+ supportedNamespaces.put(type, potential);
}
}
if (potential != null) {
* Safe cast, previous checkState checks equivalence of key from
* which type argument are derived
*/
- @SuppressWarnings("unchecked")
- NamespaceBehaviourWithListeners<K, V, N> casted = (NamespaceBehaviourWithListeners<K, V, N>) potential;
- return casted;
+ return (NamespaceBehaviourWithListeners<K, V, N>) potential;
}
- throw new NamespaceNotAvailableException("Namespace " + type + "is not available in phase " + currentPhase);
+ throw new NamespaceNotAvailableException("Namespace " + type + " is not available in phase " + currentPhase);
}
public StatementDefinitionContext<?, ?, ?> getStatementDefinition(QName name) {
return new EffectiveModelContext(rootStatements);
}
+ public EffectiveSchemaContext buildEffective() throws SourceException, ReactorException {
+ for(ModelProcessingPhase phase : PHASE_EXECUTION_ORDER) {
+ startPhase(phase);
+ loadPhaseStatements();
+ completePhaseActions();
+ endPhase(phase);
+ }
+ return transformEffective();
+ }
+
+ private EffectiveSchemaContext transformEffective() {
+ Preconditions.checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
+ List<DeclaredStatement<?>> rootStatements = new ArrayList<>();
+ List<EffectiveStatement<?,?>> rootEffectiveStatements = new ArrayList<>();
+
+ for(SourceSpecificContext source : sources) {
+ DeclaredStatement<?> root = source.getRoot().buildDeclared();
+ rootStatements.add(root);
+
+ EffectiveStatement<?,?> rootEffective = source.getRoot().buildEffective();
+ rootEffectiveStatements.add(rootEffective);
+ }
+
+ return new EffectiveSchemaContext(rootStatements,rootEffectiveStatements);
+ }
+
private void startPhase(ModelProcessingPhase phase) {
Preconditions.checkState(Objects.equals(finishedPhase, phase.getPreviousPhase()));
for(SourceSpecificContext source : sources) {
private void completePhaseActions() throws ReactorException {
Preconditions.checkState(currentPhase != null);
- ArrayList<SourceSpecificContext> sourcesToProgress = Lists.newArrayList(sources);
+ List<SourceSpecificContext> sourcesToProgress = Lists.newArrayList(sources);
try {
boolean progressing = true;
while(progressing) {
progressing = false;
Iterator<SourceSpecificContext> currentSource = sourcesToProgress.iterator();
while(currentSource.hasNext()) {
- PhaseCompletionProgress sourceProgress = currentSource.next().tryToCompletePhase(currentPhase);
+ SourceSpecificContext nextSourceCtx = currentSource.next();
+ PhaseCompletionProgress sourceProgress = nextSourceCtx.tryToCompletePhase(currentPhase);
switch (sourceProgress) {
case FINISHED:
currentSource.remove();
+ // Fallback to progress, since we were able to make progress in computation
case PROGRESS:
progressing = true;
+ break;
case NO_PROGRESS:
- // Noop;
+ // Noop
+ break;
+ default:
+ throw new IllegalStateException("Unsupported phase progress " + sourceProgress);
}
}
}