org.opennms.protocols.xml.vtdxml.AbstractVTDXmlCollectionHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.opennms.protocols.xml.vtdxml.AbstractVTDXmlCollectionHandler.java

Source

/*******************************************************************************
 * This file is part of OpenNMS(R).
 *
 * Copyright (C) 2013-2014 The OpenNMS Group, Inc.
 * OpenNMS(R) is Copyright (C) 1999-2014 The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * OpenNMS(R) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with OpenNMS(R).  If not, see:
 *      http://www.gnu.org/licenses/
 *
 * For more information contact:
 *     OpenNMS(R) Licensing <license@opennms.org>
 *     http://www.opennms.org/
 *     http://www.opennms.com/
 *******************************************************************************/

package org.opennms.protocols.xml.vtdxml;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.opennms.netmgt.collection.api.CollectionAgent;
import org.opennms.netmgt.collection.api.AttributeGroupType;
import org.opennms.netmgt.collection.api.CollectionResource;
import org.opennms.protocols.xml.collector.AbstractXmlCollectionHandler;
import org.opennms.protocols.xml.collector.UrlFactory;
import org.opennms.protocols.xml.collector.XmlCollectionAttributeType;
import org.opennms.protocols.xml.collector.XmlCollectionResource;
import org.opennms.protocols.xml.collector.XmlCollectionSet;
import org.opennms.protocols.xml.collector.XmlSingleInstanceCollectionResource;
import org.opennms.protocols.xml.config.Request;
import org.opennms.protocols.xml.config.XmlGroup;
import org.opennms.protocols.xml.config.XmlObject;
import org.opennms.protocols.xml.config.XmlSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ximpleware.AutoPilot;
import com.ximpleware.NavException;
import com.ximpleware.VTDGen;
import com.ximpleware.VTDNav;
import com.ximpleware.XPathEvalException;
import com.ximpleware.XPathParseException;

/**
 * The Abstract Class VTD-XML Collection Handler.
 * <p>All CollectionHandler based on VTD-XML should extend this class.</p>
 *
 * @author <a href="mailto:ronald.roskens@gmail.com">Ronald Roskens</a>
 */
public abstract class AbstractVTDXmlCollectionHandler extends AbstractXmlCollectionHandler {

    /** The Constant LOG. */
    private static final Logger LOG = LoggerFactory.getLogger(AbstractVTDXmlCollectionHandler.class);

    /**
     * Gets the resource name.
     *
     * @param resource the resource
     * @param group the group
     * @return the resource name
     * @throws XPathParseException the x-path parse exception
     */
    private String getResourceName(VTDNav resource, XmlGroup group) throws XPathParseException {
        // Processing multiple-key resource name.
        if (group.hasMultipleResourceKey()) {
            List<String> keys = new ArrayList<String>();
            for (String key : group.getXmlResourceKey().getKeyXpathList()) {
                LOG.debug("getResourceName: getting key for resource's name using {}", key);
                resource.push();
                AutoPilot ap = new AutoPilot();
                ap.bind(resource);
                ap.selectXPath(key);
                keys.add(ap.evalXPathToString());
                resource.pop();
            }
            return StringUtils.join(keys, "_");
        }
        // If key-xpath doesn't exist or not found, a node resource will be assumed.
        if (group.getKeyXpath() == null) {
            return "node";
        }
        // Processing single-key resource name.
        LOG.debug("getResourceName: getting key for resource's name using {}", group.getKeyXpath());

        resource.push();
        AutoPilot ap = new AutoPilot();
        ap.bind(resource);
        ap.selectXPath(group.getKeyXpath());
        String s = ap.evalXPathToString();
        resource.pop();

        return s;
    }

    /**
     * Fill collection set.
     *
     * @param agent the agent
     * @param collectionSet the collection set
     * @param source the source
     * @param document the document
     * @throws ParseException the parse exception
     * @throws XPathParseException the x-path parse exception
     * @throws XPathEvalException the x-path evaluation exception
     * @throws NavException the navigation exception
     */
    protected void fillCollectionSet(CollectionAgent agent, XmlCollectionSet collectionSet, XmlSource source,
            VTDNav document) throws ParseException, XPathParseException, XPathEvalException, NavException {
        XmlCollectionResource nodeResource = new XmlSingleInstanceCollectionResource(agent);
        AutoPilot resAP = new AutoPilot(document);
        for (XmlGroup group : source.getXmlGroups()) {
            LOG.debug("fillCollectionSet: getting resources for XML group {} using XPATH {}", group.getName(),
                    group.getResourceXpath());
            Date timestamp = getTimeStamp(document, group);
            resAP.selectXPath(group.getResourceXpath());
            while (resAP.evalXPath() != -1) {
                String resourceName = getResourceName(document, group);
                LOG.debug("fillCollectionSet: processing XML resource {}", resourceName);
                XmlCollectionResource collectionResource;
                if (group.getResourceType().equalsIgnoreCase(CollectionResource.RESOURCE_TYPE_NODE)) {
                    collectionResource = nodeResource;
                } else {
                    collectionResource = getCollectionResource(agent, resourceName, group.getResourceType(),
                            timestamp);
                }
                LOG.debug("fillCollectionSet: processing resource {}", collectionResource);
                AttributeGroupType attribGroupType = new AttributeGroupType(group.getName(), group.getIfType());
                for (XmlObject object : group.getXmlObjects()) {
                    XmlCollectionAttributeType attribType = new XmlCollectionAttributeType(object, attribGroupType);
                    document.push();
                    AutoPilot ap = new AutoPilot();
                    ap.bind(document);
                    ap.selectXPath(object.getXpath());
                    String value = ap.evalXPathToString();
                    document.pop();
                    collectionResource.setAttributeValue(attribType, value);
                }
                processXmlResource(collectionResource, attribGroupType);
                collectionSet.getCollectionResources().add(collectionResource);
            }
        }
    }

    /**
     * Gets the time stamp.
     *
     * @param document the document
     * @param group the group
     * @return the time stamp
     * @throws XPathParseException the x-path parse exception
     */
    protected Date getTimeStamp(VTDNav document, XmlGroup group) throws XPathParseException {
        if (group.getTimestampXpath() == null) {
            return null;
        }
        String pattern = group.getTimestampFormat() == null ? "yyyy-MM-dd HH:mm:ss" : group.getTimestampFormat();
        LOG.debug(
                "getTimeStamp: retrieving custom timestamp to be used when updating RRDs using XPATH {} and pattern {}",
                group.getTimestampXpath(), pattern);

        document.push();
        AutoPilot ap = new AutoPilot();
        ap.bind(document);
        ap.selectXPath(group.getTimestampXpath());
        String value = ap.evalXPathToString();
        document.pop();

        if (value == null || value.isEmpty()) {
            LOG.warn("getTimeStamp: can't find the custom timestamp using XPATH {}", group.getTimestampXpath());
            return null;
        }
        Date date = null;
        try {
            DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern);
            DateTime dateTime = dtf.parseDateTime(value);
            date = dateTime.toDate();
        } catch (Exception e) {
            LOG.warn("getTimeStamp: can't convert custom timetime {} using pattern {}", value, pattern);
            date = DateTime.now().toDate();
        }
        return date;
    }

    /**
     * Gets the XML document.
     *
     * @param urlString the URL string
     * @param request the request
     * @return the XML document
     * @throws Exception the exception
     */
    protected VTDNav getVTDXmlDocument(String urlString, Request request) throws Exception {
        InputStream is = null;
        URLConnection c = null;
        try {
            URL url = UrlFactory.getUrl(urlString, request);
            LOG.debug("getXmlDocument: got url");
            c = url.openConnection();
            LOG.debug("getXmlDocument: got connection");
            is = c.getInputStream();
            LOG.debug("getXmlDocument: got input stream");
            VTDNav nav = getVTDXmlDocument(is, request);
            LOG.debug("getXmlDocument: returning VTDNav");
            return nav;
        } finally {
            IOUtils.closeQuietly(is);
            UrlFactory.disconnect(c);
        }
    }

    /**
     * Gets the XML document.
     *
     * @param is the input stream
     * @param request the request
     * @return the XML document
     * @throws Exception the exception
     */
    protected VTDNav getVTDXmlDocument(InputStream is, Request request) throws Exception {
        is = preProcessHtml(request, is);
        is = applyXsltTransformation(request, is);
        VTDGen vg = new VTDGen();
        vg.setDoc(IOUtils.toByteArray(is));
        vg.parse(true);
        final VTDNav nav = vg.getNav();
        return nav;
    }

}