X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=parser%2Fyang-parser-rfc7950%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frfc7950%2Fstmt%2Fmeta%2FUniqueStatementSupport.java;h=36dc64c0408cdd8ceacf4d5ab7a584758cc14db3;hb=7e849648fed0d0a195f83d43d1a7d015478ad1eb;hp=18e03ee207454811d3de89360a491a4273a1535e;hpb=27a92200c91caa63b51a67972da33c63a677209f;p=yangtools.git diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/UniqueStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/UniqueStatementSupport.java index 18e03ee207..36dc64c040 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/UniqueStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/meta/UniqueStatementSupport.java @@ -14,6 +14,7 @@ import com.google.common.base.Splitter; import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import java.util.Collection; import java.util.HashSet; @@ -21,13 +22,15 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Stream; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.LeafEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ListEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant; import org.opendaylight.yangtools.yang.model.api.stmt.UniqueEffectiveStatement; @@ -66,14 +69,36 @@ public final class UniqueStatementSupport SubstatementValidator.builder(YangStmtMapping.UNIQUE).build(); public UniqueStatementSupport(final YangParserConfiguration config) { - // FIXME: This reflects what the current implementation does. We really want to define an adaptArgumentValue(), - // but how that plays with the argument and expectations needs to be investigated. - super(YangStmtMapping.UNIQUE, StatementPolicy.contextIndependent(), config, SUBSTATEMENT_VALIDATOR); + super(YangStmtMapping.UNIQUE, + StatementPolicy.copyDeclared( + (copy, current, substatements) -> copy.getArgument().equals(current.getArgument())), + config, SUBSTATEMENT_VALIDATOR); + } + + @Override + public Set adaptArgumentValue( + final StmtContext, UniqueStatement, UniqueEffectiveStatement> ctx, + final QNameModule targetModule) { + // Copy operation to a targetNamespace -- this implies rehosting node-identifiers to target namespace. Check + // if that is needed first, though, so as not to copy things unnecessarily. + final var origArg = ctx.getArgument(); + if (allMatch(origArg.stream().flatMap(desc -> desc.getNodeIdentifiers().stream()), targetModule)) { + return origArg; + } + + return origArg.stream() + .map(descendant -> { + final var nodeIds = descendant.getNodeIdentifiers(); + // Only update descendants that need updating + return allMatch(nodeIds.stream(), targetModule) ? descendant + : Descendant.of(Lists.transform(nodeIds, nodeId -> nodeId.bindTo(targetModule).intern())); + }) + .collect(ImmutableSet.toImmutableSet()); } @Override public ImmutableSet parseArgumentValue(final StmtContext ctx, final String value) { - final ImmutableSet uniqueConstraints = parseUniqueConstraintArgument(ctx, value); + final var uniqueConstraints = parseUniqueConstraintArgument(ctx, value); SourceException.throwIf(uniqueConstraints.isEmpty(), ctx, "Invalid argument value '%s' of unique statement. The value must contains at least one descendant schema " + "node identifier.", value); @@ -113,14 +138,18 @@ public final class UniqueStatementSupport return EffectiveStatements.createUnique(stmt.declared(), substatements); } + private static boolean allMatch(final Stream qnames, final QNameModule module) { + return qnames.allMatch(qname -> module.equals(qname.getModule())); + } + private static ImmutableSet parseUniqueConstraintArgument(final StmtContext ctx, final String argumentValue) { // deal with 'line-break' rule, which is either "\n" or "\r\n", but not "\r" final String nocrlf = CRLF_PATTERN.matcher(argumentValue).replaceAll("\n"); - final Set uniqueConstraintNodes = new HashSet<>(); - for (final String uniqueArgToken : SEP_SPLITTER.split(nocrlf)) { - final SchemaNodeIdentifier nodeIdentifier = ArgumentUtils.nodeIdentifierFromPath(ctx, uniqueArgToken); + final var uniqueConstraintNodes = new HashSet(); + for (var uniqueArgToken : SEP_SPLITTER.split(nocrlf)) { + final var nodeIdentifier = ArgumentUtils.nodeIdentifierFromPath(ctx, uniqueArgToken); SourceException.throwIf(nodeIdentifier instanceof Absolute, ctx, "Unique statement argument '%s' contains schema node identifier '%s' which is not in the descendant " + "node identifier form.", argumentValue, uniqueArgToken);