public static RevisionAwareXPath parseXPath(final StmtContext<?, ?, ?> ctx, final String path) { final XPath xPath = XPATH_FACTORY.get().newXPath(); xPath.setNamespaceContext(StmtNamespaceContext.create(ctx, ImmutableBiMap.of(RFC6020_YANG_NAMESPACE_STRING, YANG_XPATH_FUNCTIONS_PREFIX))); final String trimmed = trimSingleLastSlashFromXPath(path); try { // XPath extension functions have to be prefixed // yang-specific XPath functions are in fact extended functions, therefore we have to add // "yang" prefix to them so that they can be properly validated with the XPath.compile() method // the "yang" prefix is bound to RFC6020 YANG namespace final String prefixedXPath = addPrefixToYangXPathFunctions(trimmed, ctx); // TODO: we could capture the result and expose its 'evaluate' method xPath.compile(prefixedXPath); } catch (final XPathExpressionException e) { LOG.warn("Argument \"{}\" is not valid XPath string at \"{}\"", path, ctx.getStatementSourceReference(), e); } return new RevisionAwareXPathImpl(path, PATH_ABS.matcher(path).matches()); }
/** * Returns base type for {@code typeDefinition} which belongs to module specified via {@code qname}. This handle * the case when leafref type isn't specified as type substatement of leaf or leaf-list but is defined in other * module as typedef which is then imported to referenced module. * * <p> * Because {@code typeDefinition} is definied via typedef statement, only absolute path is meaningful. */ public static TypeDefinition<?> getBaseTypeForLeafRef(final LeafrefTypeDefinition typeDefinition, final SchemaContext schemaContext, final QName qname) { final RevisionAwareXPath pathStatement = typeDefinition.getPathStatement(); final RevisionAwareXPath strippedPathStatement = new RevisionAwareXPathImpl( stripConditionsFromXPathString(pathStatement), pathStatement.isAbsolute()); if (!strippedPathStatement.isAbsolute()) { return null; } final Optional<Module> parentModule = schemaContext.findModule(qname.getModule()); checkArgument(parentModule.isPresent(), "Failed to find parent module for %s", qname); final DataSchemaNode dataSchemaNode = (DataSchemaNode) SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule.get(), strippedPathStatement); final TypeDefinition<?> targetTypeDefinition = typeDefinition(dataSchemaNode); if (targetTypeDefinition instanceof LeafrefTypeDefinition) { return getBaseTypeForLeafRef((LeafrefTypeDefinition) targetTypeDefinition, schemaContext, dataSchemaNode); } return targetTypeDefinition; }
/** * Returns base type for {@code typeDefinition} which belongs to module specified via {@code qname}. This handle * the case when leafref type isn't specified as type substatement of leaf or leaf-list but is defined in other * module as typedef which is then imported to referenced module. * * <p> * Because {@code typeDefinition} is definied via typedef statement, only absolute path is meaningful. */ public static TypeDefinition<?> getBaseTypeForLeafRef(final LeafrefTypeDefinition typeDefinition, final SchemaContext schemaContext, final QName qname) { final RevisionAwareXPath pathStatement = typeDefinition.getPathStatement(); final RevisionAwareXPath strippedPathStatement = new RevisionAwareXPathImpl( stripConditionsFromXPathString(pathStatement), pathStatement.isAbsolute()); if (!strippedPathStatement.isAbsolute()) { return null; } final Optional<Module> parentModule = schemaContext.findModule(qname.getModule()); checkArgument(parentModule.isPresent(), "Failed to find parent module for %s", qname); final DataSchemaNode dataSchemaNode = (DataSchemaNode) SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule.get(), strippedPathStatement); final TypeDefinition<?> targetTypeDefinition = typeDefinition(dataSchemaNode); if (targetTypeDefinition instanceof LeafrefTypeDefinition) { return getBaseTypeForLeafRef((LeafrefTypeDefinition) targetTypeDefinition, schemaContext, dataSchemaNode); } return targetTypeDefinition; }
private boolean isLeafRefSelfReference(final LeafrefTypeDefinition leafref, final SchemaNode parentNode) { final SchemaNode leafRefValueNode; final RevisionAwareXPath leafRefXPath = leafref.getPathStatement(); final RevisionAwareXPath leafRefStrippedXPath = new RevisionAwareXPathImpl( GROUPS_PATTERN.matcher(leafRefXPath.toString()).replaceAll(""), leafRefXPath.isAbsolute());
final SchemaContext schemaContext, final SchemaNode schema) { RevisionAwareXPath pathStatement = typeDefinition.getPathStatement(); pathStatement = new RevisionAwareXPathImpl(stripConditionsFromXPathString(pathStatement), pathStatement.isAbsolute());
final SchemaContext schemaContext, final SchemaNode schema) { RevisionAwareXPath pathStatement = typeDefinition.getPathStatement(); pathStatement = new RevisionAwareXPathImpl(stripConditionsFromXPathString(pathStatement), pathStatement.isAbsolute());