*/
package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
+import java.util.Iterator;
+import javax.annotation.Nullable;
+
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
public final class AugmentUtils {
- private AugmentUtils() {
- }
-
private static final String REGEX_PATH_REL1 = "\\.\\.?\\s*/(.+)";
private static final String REGEX_PATH_REL2 = "//.*";
- public static Iterable<QName> parseAugmentPath(StmtContext<?, ?, ?> ctx, String path) {
+ private AugmentUtils() {
+ }
+
+ public static Iterable<QName> parseAugmentPath(StmtContext<?, ?, ?> ctx,
+ String path) {
if (path.matches(REGEX_PATH_REL1) || path.matches(REGEX_PATH_REL2)) {
throw new IllegalArgumentException(
return Utils.parseXPath(ctx, path);
}
- public static void copyFromSourceToTarget(StatementContextBase<?, ?, ?> sourceCtx,
- StatementContextBase<?, ?, ?> targetCtx) throws SourceException {
+ public static void copyFromSourceToTarget(
+ StatementContextBase<?, ?, ?> sourceCtx,
+ StatementContextBase<?, ?, ?> targetCtx) throws SourceException {
QNameModule newQNameModule = getNewQNameModule(targetCtx, sourceCtx);
copyDeclaredStmts(sourceCtx, targetCtx, newQNameModule);
}
- public static void copyDeclaredStmts(StatementContextBase<?, ?, ?> sourceCtx,
- StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule) throws SourceException {
- Collection<? extends StatementContextBase<?, ?, ?>> declaredSubstatements = sourceCtx.declaredSubstatements();
+ public static void copyDeclaredStmts(
+ StatementContextBase<?, ?, ?> sourceCtx,
+ StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule)
+ throws SourceException {
+ Collection<? extends StatementContextBase<?, ?, ?>> declaredSubstatements = sourceCtx
+ .declaredSubstatements();
for (StatementContextBase<?, ?, ?> originalStmtCtx : declaredSubstatements) {
if (needToCopyByAugment(originalStmtCtx)) {
- StatementContextBase<?, ?, ?> copy = originalStmtCtx.createCopy(newQNameModule, targetCtx);
+ StatementContextBase<?, ?, ?> copy = originalStmtCtx
+ .createCopy(newQNameModule, targetCtx,
+ TypeOfCopy.ADDED_BY_AUGMENTATION);
targetCtx.addEffectiveSubstatement(copy);
} else if (isReusedByAugment(originalStmtCtx)) {
targetCtx.addEffectiveSubstatement(originalStmtCtx);
}
}
- public static void copyEffectiveStmts(StatementContextBase<?, ?, ?> sourceCtx,
- StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule) throws SourceException {
- Collection<? extends StatementContextBase<?, ?, ?>> effectiveSubstatements = sourceCtx.effectiveSubstatements();
+ public static void copyEffectiveStmts(
+ StatementContextBase<?, ?, ?> sourceCtx,
+ StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule)
+ throws SourceException {
+ Collection<? extends StatementContextBase<?, ?, ?>> effectiveSubstatements = sourceCtx
+ .effectiveSubstatements();
for (StatementContextBase<?, ?, ?> originalStmtCtx : effectiveSubstatements) {
if (needToCopyByAugment(originalStmtCtx)) {
- StatementContextBase<?, ?, ?> copy = originalStmtCtx.createCopy(newQNameModule, targetCtx);
+ StatementContextBase<?, ?, ?> copy = originalStmtCtx
+ .createCopy(newQNameModule, targetCtx,
+ TypeOfCopy.ADDED_BY_AUGMENTATION);
targetCtx.addEffectiveSubstatement(copy);
} else if (isReusedByAugment(originalStmtCtx)) {
targetCtx.addEffectiveSubstatement(originalStmtCtx);
}
}
- public static QNameModule getNewQNameModule(StatementContextBase<?, ?, ?> targetCtx,
- StatementContextBase<?, ?, ?> sourceCtx) {
+ public static QNameModule getNewQNameModule(
+ StatementContextBase<?, ?, ?> targetCtx,
+ StatementContextBase<?, ?, ?> sourceCtx) {
Object targetStmtArgument = targetCtx.getStatementArgument();
final StatementContextBase<?, ?, ?> root = sourceCtx.getRoot();
final String moduleName = (String) root.getStatementArgument();
- final QNameModule sourceQNameModule = root.getFromNamespace(ModuleNameToModuleQName.class, moduleName);
+ final QNameModule sourceQNameModule = root.getFromNamespace(
+ ModuleNameToModuleQName.class, moduleName);
if (targetStmtArgument instanceof QName) {
QName targetQName = (QName) targetStmtArgument;
noCopyDefSet.add(Rfc6020Mapping.USES);
StatementDefinition def = stmtContext.getPublicDefinition();
- return (!noCopyDefSet.contains(def));
+ return !noCopyDefSet.contains(def);
}
public static boolean isReusedByAugment(StmtContext<?, ?, ?> stmtContext) {
- HashSet<StatementDefinition> reusedDefSet = new HashSet<>();
+ Set<StatementDefinition> reusedDefSet = new HashSet<>();
reusedDefSet.add(Rfc6020Mapping.TYPEDEF);
StatementDefinition def = stmtContext.getPublicDefinition();
- if (reusedDefSet.contains(def))
- return true;
- else
- return false;
+
+ return reusedDefSet.contains(def);
}
public static StatementContextBase<?, ?, ?> getAugmentTargetCtx(
final Mutable<SchemaNodeIdentifier, AugmentStatement, EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>> augmentNode) {
- final SchemaNodeIdentifier augmentTargetNode = augmentNode.getStatementArgument();
+ final SchemaNodeIdentifier augmentTargetNode = augmentNode
+ .getStatementArgument();
+ if (augmentTargetNode == null) {
+ throw new IllegalArgumentException(
+ "Augment argument null, something bad happened in some of previous parsing phases");
+ }
List<StatementContextBase<?, ?, ?>> rootStatementCtxList = new LinkedList<>();
if (augmentTargetNode.isAbsolute()) {
- QNameModule module;
- if (augmentTargetNode != null) {
- module = augmentTargetNode.getPathFromRoot().iterator().next().getModule();
- } else {
- throw new IllegalArgumentException(
- "Augment argument null, something bad happened in some of previous parsing phases");
- }
+ QNameModule module = augmentTargetNode.getPathFromRoot().iterator()
+ .next().getModule();
- StatementContextBase<?, ?, ?> rootStatementCtx = (StatementContextBase<?, ?, ?>) augmentNode.getFromNamespace(
- NamespaceToModule.class, module);
+ StatementContextBase<?, ?, ?> rootStatementCtx = (StatementContextBase<?, ?, ?>) augmentNode
+ .getFromNamespace(NamespaceToModule.class, module);
rootStatementCtxList.add(rootStatementCtx);
- final Map<?, ?> subModules = rootStatementCtx.getAllFromNamespace(IncludedModuleContext.class);
+ final Map<?, ?> subModules = rootStatementCtx
+ .getAllFromNamespace(IncludedModuleContext.class);
if (subModules != null) {
- rootStatementCtxList.addAll((Collection<? extends StatementContextBase<?, ?, ?>>) subModules.values());
+ rootStatementCtxList
+ .addAll((Collection<? extends StatementContextBase<?, ?, ?>>) subModules
+ .values());
}
} else {
- StatementContextBase<?, ?, ?> parent = (StatementContextBase<?, ?, ?>) augmentNode.getParentContext();
+ StatementContextBase<?, ?, ?> parent = (StatementContextBase<?, ?, ?>) augmentNode
+ .getParentContext();
if (StmtContextUtils.producesDeclared(parent, UsesStatement.class)) {
rootStatementCtxList.add(parent.getParentContext());
} else {
- //error
+ // error
}
}
- List<QName> augmentTargetPath = new LinkedList<>();
-
- augmentTargetPath.addAll((Collection<? extends QName>) augmentTargetNode.getPathFromRoot());
-
StatementContextBase<?, ?, ?> augmentTargetCtx = null;
for (final StatementContextBase<?, ?, ?> rootStatementCtx : rootStatementCtxList) {
- augmentTargetCtx = Utils.findCtxOfNodeInRoot(rootStatementCtx,
- augmentTargetPath);
- if (augmentTargetCtx != null) break;
+ augmentTargetCtx = findCtxOfNodeInRoot(rootStatementCtx,
+ augmentTargetNode);
+ if (augmentTargetCtx != null)
+ break;
}
+ return augmentTargetCtx;
+ }
- if (augmentTargetCtx == null) {
+ @Nullable
+ public static StatementContextBase<?, ?, ?> findCtxOfNodeInSubstatements(
+ StatementContextBase<?, ?, ?> rootStmtCtx,
+ final Iterable<QName> path) {
- throw new NullPointerException(String.format(
- "Augment path %s not found in target model so its resulting context is null",
- augmentNode.rawStatementArgument()));
+ StatementContextBase<?, ?, ?> parent = rootStmtCtx;
+ Iterator<QName> pathIter = path.iterator();
+ while (pathIter.hasNext()) {
+ QName nextPathQName = pathIter.next();
+ StatementContextBase<?, ?, ?> foundSubstatement = getSubstatementByQName(
+ parent, nextPathQName);
+
+ if (foundSubstatement == null) {
+ return null;
+ }
+ if (!pathIter.hasNext()) {
+ return foundSubstatement;
+ }
+
+ parent = foundSubstatement;
}
- return augmentTargetCtx;
+ return null;
+ }
+
+ public static StatementContextBase<?, ?, ?> getSubstatementByQName(
+ StatementContextBase<?, ?, ?> parent, QName nextPathQName) {
+
+ Collection<StatementContextBase<?, ?, ?>> declaredSubstatement = parent
+ .declaredSubstatements();
+ Collection<StatementContextBase<?, ?, ?>> effectiveSubstatement = parent
+ .effectiveSubstatements();
+
+ Collection<StatementContextBase<?, ?, ?>> allSubstatements = new LinkedList<>();
+ allSubstatements.addAll(declaredSubstatement);
+ allSubstatements.addAll(effectiveSubstatement);
+
+ for (StatementContextBase<?, ?, ?> substatement : allSubstatements) {
+ if (isAllowedAugmentTarget(substatement)
+ && nextPathQName
+ .equals(substatement.getStatementArgument())) {
+ return substatement;
+ }
+ }
+
+ return null;
+ }
+
+ public static boolean isAllowedAugmentTarget(
+ StatementContextBase<?, ?, ?> substatement) {
+
+ /*
+ * :TODO Substatement must be allowed augment target type e.g.
+ * Container, etc... and must be not for example grouping, identity etc.
+ * It is problem in case when more than one substatements have the same
+ * QName, for example Grouping and Container are siblings and they have the
+ * same QName. We must find the Container and the Grouping must be ignored
+ * as disallowed augment target.
+ */
+
+ return true;
+ }
+
+ @Nullable
+ public static StatementContextBase<?, ?, ?> findCtxOfNodeInRoot(
+ StatementContextBase<?, ?, ?> rootStmtCtx,
+ final SchemaNodeIdentifier node) {
+ return findCtxOfNodeInSubstatements(rootStmtCtx, node.getPathFromRoot());
}
}