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%2Frfc6020%2FGroupingUtils.java;h=e6f496b0a46febf11d5c7e5fbc1dbec577f9321c;hb=30c67c4d780e897d972d60bb79d546b512516f90;hp=9802db52b3b520c2d745005b46c46a1679d46f27;hpb=1f53275ab208027b01a60c697f576ce9fca7db22;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java index 9802db52b3..e6f496b0a4 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java @@ -7,8 +7,13 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName; +import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; +import org.opendaylight.yangtools.yang.parser.stmt.reactor.RootStatementContext; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace; +import java.util.Iterator; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; import java.util.Collection; import java.util.HashSet; @@ -18,10 +23,8 @@ import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; -import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement; import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; @@ -38,52 +41,82 @@ public final class GroupingUtils { * @param targetCtx * @throws SourceException */ - public static void copyFromSourceToTarget(StatementContextBase sourceGrpStmtCtx, - StatementContextBase targetCtx) throws SourceException { + public static void copyFromSourceToTarget( + StatementContextBase sourceGrpStmtCtx, + StatementContextBase targetCtx, + StmtContext.Mutable> usesNode) + throws SourceException { - QNameModule newQNameModule = getNewQNameModule(targetCtx, sourceGrpStmtCtx); - copyDeclaredStmts(sourceGrpStmtCtx, targetCtx, newQNameModule); - copyEffectiveStmts(sourceGrpStmtCtx, targetCtx, newQNameModule); + QNameModule newQNameModule = getNewQNameModule(targetCtx, + sourceGrpStmtCtx); + copyDeclaredStmts(sourceGrpStmtCtx, targetCtx, usesNode, newQNameModule); + copyEffectiveStmts(sourceGrpStmtCtx, targetCtx, usesNode, + newQNameModule); } - public static void copyDeclaredStmts(StatementContextBase sourceGrpStmtCtx, - StatementContextBase targetCtx, QNameModule newQNameModule) throws SourceException { + public static void copyDeclaredStmts( + StatementContextBase sourceGrpStmtCtx, + StatementContextBase targetCtx, + StmtContext.Mutable> usesNode, + QNameModule newQNameModule) throws SourceException { Collection> declaredSubstatements = sourceGrpStmtCtx .declaredSubstatements(); for (StatementContextBase originalStmtCtx : declaredSubstatements) { if (needToCopyByUses(originalStmtCtx)) { - StatementContextBase copy = originalStmtCtx.createCopy(newQNameModule, targetCtx, TypeOfCopy.ADDED_BY_USES); + StatementContextBase copy = originalStmtCtx + .createCopy(newQNameModule, targetCtx, + TypeOfCopy.ADDED_BY_USES); targetCtx.addEffectiveSubstatement(copy); + usesNode.addAsEffectOfStatement(copy); } else if (isReusedByUses(originalStmtCtx)) { targetCtx.addEffectiveSubstatement(originalStmtCtx); + usesNode.addAsEffectOfStatement(originalStmtCtx); } } } - public static void copyEffectiveStmts(StatementContextBase sourceGrpStmtCtx, - StatementContextBase targetCtx, QNameModule newQNameModule) throws SourceException { + public static void copyEffectiveStmts( + StatementContextBase sourceGrpStmtCtx, + StatementContextBase targetCtx, + StmtContext.Mutable> usesNode, + QNameModule newQNameModule) throws SourceException { Collection> effectiveSubstatements = sourceGrpStmtCtx .effectiveSubstatements(); for (StatementContextBase originalStmtCtx : effectiveSubstatements) { if (needToCopyByUses(originalStmtCtx)) { - StatementContextBase copy = originalStmtCtx.createCopy(newQNameModule, targetCtx, TypeOfCopy.ADDED_BY_USES); + StatementContextBase copy = originalStmtCtx + .createCopy(newQNameModule, targetCtx, + TypeOfCopy.ADDED_BY_USES); targetCtx.addEffectiveSubstatement(copy); + usesNode.addAsEffectOfStatement(copy); } else if (isReusedByUses(originalStmtCtx)) { targetCtx.addEffectiveSubstatement(originalStmtCtx); + usesNode.addAsEffectOfStatement(originalStmtCtx); } } } - public static QNameModule getNewQNameModule(StatementContextBase targetCtx, + public static QNameModule getNewQNameModule( + StatementContextBase targetCtx, StmtContext stmtContext) { if (needToCreateNewQName(stmtContext.getPublicDefinition())) { - if(targetCtx.isRootContext()) { - return targetCtx.getFromNamespace(ModuleNameToModuleQName.class, targetCtx.rawStatementArgument()); + if (targetCtx.isRootContext()) { + return targetCtx.getFromNamespace( + ModuleCtxToModuleQName.class, + targetCtx); } + if(targetCtx.getPublicDefinition() == Rfc6020Mapping.AUGMENT) { + RootStatementContext root = targetCtx.getRoot(); + return targetCtx.getFromNamespace( + ModuleCtxToModuleQName.class, + root); + } + Object targetStmtArgument = targetCtx.getStatementArgument(); Object sourceStmtArgument = stmtContext.getStatementArgument(); - if (targetStmtArgument instanceof QName && sourceStmtArgument instanceof QName) { + if (targetStmtArgument instanceof QName + && sourceStmtArgument instanceof QName) { QName targetQName = (QName) targetStmtArgument; QNameModule targetQNameModule = targetQName.getModule(); @@ -103,14 +136,17 @@ public final class GroupingUtils { } } - public static boolean needToCreateNewQName(StatementDefinition publicDefinition) { + public static boolean needToCreateNewQName( + StatementDefinition publicDefinition) { return true; } public static boolean needToCopyByUses(StmtContext stmtContext) { - Set noCopyDefSet = new HashSet(); + Set noCopyDefSet = new HashSet<>(); noCopyDefSet.add(Rfc6020Mapping.USES); + noCopyDefSet.add(Rfc6020Mapping.TYPEDEF); + noCopyDefSet.add(Rfc6020Mapping.TYPE); StatementDefinition def = stmtContext.getPublicDefinition(); return !noCopyDefSet.contains(def); @@ -118,8 +154,9 @@ public final class GroupingUtils { public static boolean isReusedByUses(StmtContext stmtContext) { - Set reusedDefSet = new HashSet(); + Set reusedDefSet = new HashSet<>(); reusedDefSet.add(Rfc6020Mapping.TYPEDEF); + reusedDefSet.add(Rfc6020Mapping.TYPE); StatementDefinition def = stmtContext.getPublicDefinition(); return reusedDefSet.contains(def); @@ -127,22 +164,122 @@ public final class GroupingUtils { public static void resolveUsesNode( Mutable> usesNode, - StatementContextBase targetNodeStmtCtx) throws SourceException { + StatementContextBase targetNodeStmtCtx) + throws SourceException { - Collection> declaredSubstatements = usesNode.declaredSubstatements(); + Collection> declaredSubstatements = usesNode + .declaredSubstatements(); for (StatementContextBase subStmtCtx : declaredSubstatements) { - if (StmtContextUtils.producesDeclared(subStmtCtx, WhenStatement.class)) { - StatementContextBase copy = subStmtCtx.createCopy(null, targetNodeStmtCtx, TypeOfCopy.ADDED_BY_USES); - targetNodeStmtCtx.addEffectiveSubstatement(copy); + if (StmtContextUtils.producesDeclared(subStmtCtx, + RefineStatement.class)) { + performRefine(subStmtCtx, targetNodeStmtCtx); } - if (StmtContextUtils.producesDeclared(subStmtCtx, RefineStatement.class)) { - // :TODO resolve and perform refine statement - } - if (StmtContextUtils.producesDeclared(subStmtCtx, AugmentStatement.class)) { - // :TODO find target node and perform augmentation + } + } + + private static void performRefine(StatementContextBase refineCtx, + StatementContextBase usesParentCtx) { + + Object refineArgument = refineCtx.getStatementArgument(); + + SchemaNodeIdentifier refineTargetNodeIdentifier; + if (refineArgument instanceof SchemaNodeIdentifier) { + refineTargetNodeIdentifier = (SchemaNodeIdentifier) refineArgument; + } else { + throw new IllegalArgumentException( + "Invalid refine argument. It must be instance of SchemaNodeIdentifier"); + } + + StatementContextBase refineTargetNodeCtx = Utils.findNode( + usesParentCtx, refineTargetNodeIdentifier); + + if (refineTargetNodeCtx == null) { + throw new IllegalArgumentException( + "Refine target node not found. Path: " + + refineTargetNodeIdentifier); + } + + addOrReplaceNodes(refineCtx, refineTargetNodeCtx); + refineCtx.addAsEffectOfStatement(refineTargetNodeCtx); + + } + + private static void addOrReplaceNodes( + StatementContextBase refineCtx, + StatementContextBase refineTargetNodeCtx) { + + Collection> declaredSubstatements = refineCtx + .declaredSubstatements(); + for (StatementContextBase refineSubstatementCtx : declaredSubstatements) { + if (isSupportedRefineSubstatement(refineSubstatementCtx)) { + addOrReplaceNode(refineSubstatementCtx, refineTargetNodeCtx); } - // :TODO resolve other uses substatements } } + private static void addOrReplaceNode( + StatementContextBase refineSubstatementCtx, + StatementContextBase refineTargetNodeCtx) { + + StatementDefinition refineSubstatementDef = refineSubstatementCtx + .getPublicDefinition(); + StatementDefinition refineTargetNodeDef = refineTargetNodeCtx + .getPublicDefinition(); + + if (!isSupportedRefineTarget(refineSubstatementCtx, refineTargetNodeCtx)) { + throw new SourceException("Error in module '" + + refineSubstatementCtx.getRoot().getStatementArgument() + + "' in the refine of uses '" + + refineSubstatementCtx.getParentContext() + .getStatementArgument() + + "': can not perform refine of '" + + refineSubstatementCtx.getPublicDefinition() + + "' for the target '" + + refineTargetNodeCtx.getPublicDefinition() + "'.", + refineSubstatementCtx.getStatementSourceReference()); + } + + if (isAllowedToAddByRefine(refineSubstatementDef)) { + refineTargetNodeCtx.addEffectiveSubstatement(refineSubstatementCtx); + } else { + refineTargetNodeCtx.removeStatementFromEffectiveSubstatements(refineSubstatementDef); + refineTargetNodeCtx.addEffectiveSubstatement(refineSubstatementCtx); + } + } + + private static boolean isAllowedToAddByRefine( + StatementDefinition publicDefinition) { + Set allowedToAddByRefineDefSet = new HashSet<>(); + allowedToAddByRefineDefSet.add(Rfc6020Mapping.MUST); + + return allowedToAddByRefineDefSet.contains(publicDefinition); + } + + private static boolean isSupportedRefineSubstatement( + StatementContextBase refineSubstatementCtx) { + + Collection supportedRefineSubstatements = refineSubstatementCtx + .getFromNamespace(ValidationBundlesNamespace.class, + ValidationBundleType.SUPPORTED_REFINE_SUBSTATEMENTS); + + return supportedRefineSubstatements == null + || supportedRefineSubstatements.isEmpty() + || supportedRefineSubstatements.contains(refineSubstatementCtx + .getPublicDefinition()) + || StmtContextUtils.isUnknownStatement(refineSubstatementCtx); + } + + private static boolean isSupportedRefineTarget( + StatementContextBase refineSubstatementCtx, + StatementContextBase refineTargetNodeCtx) { + + Collection supportedRefineTargets = YangValidationBundles.SUPPORTED_REFINE_TARGETS + .get(refineSubstatementCtx.getPublicDefinition()); + + return supportedRefineTargets == null + || supportedRefineTargets.isEmpty() + || supportedRefineTargets.contains(refineTargetNodeCtx + .getPublicDefinition()); + } + }