2 * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
10 import java.util.Iterator;
11 import java.util.ServiceLoader;
12 import javax.xml.xpath.XPathExpressionException;
13 import org.eclipse.jdt.annotation.NonNullByDefault;
14 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
15 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
16 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
17 import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBound;
18 import org.opendaylight.yangtools.yang.xpath.api.YangXPathParser;
19 import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory;
20 import org.slf4j.Logger;
23 abstract class XPathSupport {
24 private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(XPathSupport.class);
26 private static final XPathSupport INSTANCE;
29 final Iterator<YangXPathParserFactory> it = ServiceLoader.load(YangXPathParserFactory.class).iterator();
31 LOG.warn("Failed to find XPath parser factory, no XPath validation will be performed");
32 INSTANCE = new Noop();
34 INSTANCE = new XPathImpl(it.next());
38 static RevisionAwareXPath parseXPath(final StmtContext<?, ?, ?> ctx, final String xpath) {
39 return INSTANCE.parseXPath(xpath, ctx);
42 abstract RevisionAwareXPath parseXPath(String xpath, StmtContext<?, ?, ?> ctx);
44 private static final class Noop extends XPathSupport {
46 RevisionAwareXPath parseXPath(final String xpath, final StmtContext<?, ?, ?> ctx) {
47 return new RevisionAwareXPathImpl(xpath, ArgumentUtils.isAbsoluteXPath(xpath));
51 private static final class XPathImpl extends XPathSupport {
52 private final YangXPathParserFactory factory;
54 XPathImpl(final YangXPathParserFactory factory) {
55 this.factory = factory;
59 RevisionAwareXPath parseXPath(final String xpath, final StmtContext<?, ?, ?> ctx) {
60 final boolean isAbsolute = ArgumentUtils.isAbsoluteXPath(xpath);
61 final YangXPathParser.QualifiedBound parser = factory.newParser(new StmtNamespaceContext(ctx));
62 final QualifiedBound parsed;
64 parsed = parser.parseExpression(xpath);
65 } catch (XPathExpressionException e) {
66 LOG.warn("Argument \"{}\" is not valid XPath string at \"{}\"", xpath,
67 ctx.getStatementSourceReference(), e);
68 return new RevisionAwareXPathImpl(xpath, isAbsolute);
71 if (ctx.getRootVersion().compareTo(parsed.getYangVersion()) < 0) {
72 LOG.warn("{} features required in {} context to parse expression '{}' [at {}]",
73 parsed.getYangVersion().getReference(), ctx.getRootVersion().getReference(), xpath,
74 ctx.getStatementSourceReference());
76 return new WithExpressionImpl(xpath, isAbsolute, parsed);