2 * Copyright (c) 2016 Cisco Systems, Inc. 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.netconf.sal.streams.listeners;
10 import java.io.StringReader;
11 import java.util.Date;
12 import javax.xml.XMLConstants;
13 import javax.xml.parsers.DocumentBuilderFactory;
14 import javax.xml.parsers.ParserConfigurationException;
15 import javax.xml.xpath.XPath;
16 import javax.xml.xpath.XPathConstants;
17 import javax.xml.xpath.XPathFactory;
18 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
19 import org.w3c.dom.Document;
20 import org.xml.sax.InputSource;
23 * Features of query parameters part of both notifications
26 abstract class AbstractQueryParams extends AbstractNotificationsData {
27 // FIXME: BUG-7956: switch to using UntrustedXML
28 private static final DocumentBuilderFactory DBF;
30 final DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
31 f.setCoalescing(true);
32 f.setExpandEntityReferences(false);
33 f.setIgnoringElementContentWhitespace(true);
34 f.setIgnoringComments(true);
35 f.setXIncludeAware(false);
37 f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
38 f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
39 f.setFeature("http://xml.org/sax/features/external-general-entities", false);
40 f.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
41 } catch (final ParserConfigurationException e) {
42 throw new ExceptionInInitializerError(e);
47 // FIXME: these should be final
48 private Date start = null;
49 private Date stop = null;
50 private String filter = null;
53 * Set query parameters for listener
56 * - start-time of getting notification
58 * - stop-time of getting notification
60 * - indicate which subset of all possible events are of interest
62 public void setQueryParams(final Date start, final Date stop, final String filter) {
69 * Checking query parameters on specific notification
72 * - data of notification
74 * - listener of notification
75 * @return true if notification meets the requirements of query parameters,
78 protected <T extends BaseListenerInterface> boolean checkQueryParams(final String xml, final T listener) {
79 final Date now = new Date();
80 if (this.stop != null) {
81 if ((this.start.compareTo(now) < 0) && (this.stop.compareTo(now) > 0)) {
82 return checkFilter(xml);
84 if (this.stop.compareTo(now) < 0) {
87 } catch (final Exception e) {
88 throw new RestconfDocumentedException("Problem with unregister listener." + e);
91 } else if (this.start != null) {
92 if (this.start.compareTo(now) < 0) {
94 return checkFilter(xml);
97 return checkFilter(xml);
103 * Check if is filter used and then prepare and post data do client
106 * - data of notification
108 private boolean checkFilter(final String xml) {
109 if (this.filter == null) {
114 return parseFilterParam(xml);
115 } catch (final Exception e) {
116 throw new RestconfDocumentedException("Problem while parsing filter.", e);
121 * Parse and evaluate filter value by xml
123 * @return true or false - depends on filter expression and data of
127 private boolean parseFilterParam(final String xml) throws Exception {
128 final Document docOfXml = DBF.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
129 final XPath xPath = XPathFactory.newInstance().newXPath();
130 // FIXME: BUG-7956: xPath.setNamespaceContext(nsContext);
131 return (boolean) xPath.compile(this.filter).evaluate(docOfXml, XPathConstants.BOOLEAN);