org.opennms.ng.dao.support.GenericIndexResourceType.java Source code

Java tutorial

Introduction

Here is the source code for org.opennms.ng.dao.support.GenericIndexResourceType.java

Source

/*******************************************************************************
 * This file is part of OpenNMS(R).
 *
 * Copyright (C) 2007-2012 The OpenNMS Group, Inc.
 * OpenNMS(R) is Copyright (C) 1999-2012 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 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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.ng.dao.support;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.opennms.core.utils.LazySet;
import org.opennms.core.utils.PropertiesUtils;
import org.opennms.core.utils.PropertiesUtils.SymbolTable;
import org.opennms.netmgt.config.StorageStrategy;
import org.opennms.netmgt.dao.api.ResourceDao;
import org.opennms.netmgt.model.ExternalValueAttribute;
import org.opennms.netmgt.model.OnmsAttribute;
import org.opennms.netmgt.model.OnmsResource;
import org.opennms.netmgt.model.OnmsResourceType;
import org.opennms.netmgt.model.StringPropertyAttribute;
import org.springframework.orm.ObjectRetrievalFailureException;

/**
 * <p>GenericIndexResourceType class.</p>
 */
public class GenericIndexResourceType implements OnmsResourceType {
    private static final Pattern SUB_INDEX_PATTERN = Pattern.compile("^subIndex\\((.*)\\)$");
    private static final Pattern SUB_INDEX_ARGUMENTS_PATTERN = Pattern.compile("^(-?\\d+|n)(?:,\\s*(\\d+|n))?$");
    private static final Pattern HEX_PATTERN = Pattern.compile("^hex\\((.*)\\)$");
    private static final Pattern STRING_PATTERN = Pattern.compile("^string\\((.*)\\)$");

    private final String m_name;
    private final String m_label;
    private final String m_resourceLabelExpression;
    private final ResourceDao m_resourceDao;
    private final StorageStrategy m_storageStrategy;

    /**
     * <p>Constructor for GenericIndexResourceType.</p>
     *
     * @param resourceDao a {@link org.opennms.netmgt.dao.api.ResourceDao} object.
     * @param name a {@link String} object.
     * @param label a {@link String} object.
     * @param resourceLabelExpression a {@link String} object.
     * @param storageStrategy a {@link org.opennms.netmgt.config.StorageStrategy} object.
     */
    public GenericIndexResourceType(ResourceDao resourceDao, String name, String label,
            String resourceLabelExpression, StorageStrategy storageStrategy) {
        m_resourceDao = resourceDao;
        m_name = name;
        m_label = label;
        m_resourceLabelExpression = resourceLabelExpression;
        m_storageStrategy = storageStrategy;
    }

    /**
     * <p>getName</p>
     *
     * @return a {@link String} object.
     */
    @Override
    public String getName() {
        return m_name;
    }

    /**
     * <p>getLabel</p>
     *
     * @return a {@link String} object.
     */
    @Override
    public String getLabel() {
        return m_label;
    }

    /**
     * <p>getStorageStrategy</p>
     *
     * @return a {@link org.opennms.netmgt.config.StorageStrategy} object.
     */
    public StorageStrategy getStorageStrategy() {
        return m_storageStrategy;
    }

    /** {@inheritDoc} */
    @Override
    public boolean isResourceTypeOnNode(int nodeId) {
        return getResourceTypeDirectory(nodeId, false).isDirectory();
    }

    private File getResourceTypeDirectory(int nodeId, boolean verify) {
        File snmp = new File(m_resourceDao.getRrdDirectory(verify), DefaultResourceDao.SNMP_DIRECTORY);

        File node = new File(snmp, Integer.toString(nodeId));
        if (verify && !node.isDirectory()) {
            throw new ObjectRetrievalFailureException(File.class,
                    "No node directory exists for node " + nodeId + ": " + node);
        }

        File generic = new File(node, getName());
        if (verify && !generic.isDirectory()) {
            throw new ObjectRetrievalFailureException(File.class,
                    "No node directory exists for generic index " + getName() + ": " + generic);
        }

        return generic;
    }

    private File getResourceTypeDirectory(String nodeSource, boolean verify) {
        File snmp = new File(m_resourceDao.getRrdDirectory(verify), DefaultResourceDao.SNMP_DIRECTORY);

        File dir = new File(snmp, ResourceTypeUtils.getRelativeNodeSourceDirectory(nodeSource).toString());
        if (verify && !dir.isDirectory()) {
            throw new ObjectRetrievalFailureException(File.class,
                    "No directory exists for nodeSource " + nodeSource);
        }

        File generic = new File(dir, getName());
        if (verify && !generic.isDirectory()) {
            throw new ObjectRetrievalFailureException(File.class,
                    "No node directory exists for generic index " + getName() + ": " + generic);
        }

        return generic;
    }

    /** {@inheritDoc} */
    @Override
    public List<OnmsResource> getResourcesForNode(int nodeId) {
        ArrayList<OnmsResource> resources = new ArrayList<OnmsResource>();

        List<String> indexes = getQueryableIndexesForNode(nodeId);
        for (String index : indexes) {
            resources.add(getResourceByNodeAndIndex(nodeId, index));
        }
        return OnmsResource.sortIntoResourceList(resources);
    }

    /**
     * <p>getQueryableIndexesForNode</p>
     *
     * @param nodeId a int.
     * @return a {@link java.util.List} object.
     */
    public List<String> getQueryableIndexesForNode(int nodeId) {
        File nodeDir = getResourceTypeDirectory(nodeId, true);

        List<String> indexes = new LinkedList<String>();

        File[] indexDirs = nodeDir.listFiles(RrdFileConstants.INTERFACE_DIRECTORY_FILTER);

        if (indexDirs == null) {
            return indexes;
        }

        for (File indexDir : indexDirs) {
            indexes.add(indexDir.getName());
        }

        return indexes;
    }

    /**
     * <p>getQueryableIndexesForNodeSource</p>
     *
     * @param nodeSource a String.
     * @return a {@link java.util.List} object.
     */
    public List<String> getQueryableIndexesForNodeSource(String nodeSource) {
        File dir = getResourceTypeDirectory(nodeSource, true);

        List<String> indexes = new LinkedList<String>();

        File[] indexDirs = dir.listFiles(RrdFileConstants.INTERFACE_DIRECTORY_FILTER);

        if (indexDirs == null) {
            return indexes;
        }

        for (File indexDir : indexDirs) {
            indexes.add(indexDir.getName());
        }

        return indexes;
    }

    /**
     * <p>getResourceByNodeAndIndex</p>
     *
     * @param nodeId a int.
     * @param index a {@link String} object.
     * @return a {@link org.opennms.netmgt.model.OnmsResource} object.
     */
    public OnmsResource getResourceByNodeAndIndex(int nodeId, final String index) {
        final Set<OnmsAttribute> set = new LazySet<OnmsAttribute>(new AttributeLoader(nodeId, index));
        return getResourceByIndex(set, index);
    }

    /**
     * <p>getResourceByNodeSourceAndIndex</p>
     *
     * @param nodeSource a {@link String} object.
     * @param index a {@link String} object.
     * @return a {@link org.opennms.netmgt.model.OnmsResource} object.
     */
    public OnmsResource getResourceByNodeSourceAndIndex(String nodeSource, final String index) {
        final Set<OnmsAttribute> set = new LazySet<OnmsAttribute>(new NodeSourceAttributeLoader(nodeSource, index));
        return getResourceByIndex(set, index);
    }

    /**
     * <p>getResourceByIndex</p>
     *
     * @param set a Set<OnmsAttribute> object.
     * @param index a {@link String} object.
     * @return a {@link org.opennms.netmgt.model.OnmsResource} object.
     */
    public OnmsResource getResourceByIndex(final Set<OnmsAttribute> set, final String index) {

        String label;
        if (m_resourceLabelExpression == null) {
            label = index;
        } else {
            SymbolTable symbolTable = new SymbolTable() {
                private int lastN;
                private boolean lastNSet = false;

                @Override
                public String getSymbolValue(String symbol) {
                    if (symbol.equals("index")) {
                        return index;
                    }

                    Matcher subIndexMatcher = SUB_INDEX_PATTERN.matcher(symbol);
                    if (subIndexMatcher.matches()) {
                        Matcher subIndexArgumentsMatcher = SUB_INDEX_ARGUMENTS_PATTERN
                                .matcher(subIndexMatcher.group(1));
                        if (!subIndexArgumentsMatcher.matches()) {
                            // Invalid arguments
                            return null;
                        }

                        List<String> indexElements = tokenizeIndex(index);

                        int start;
                        int offset;
                        if ("n".equals(subIndexArgumentsMatcher.group(1)) && lastNSet) {
                            start = lastN;
                            lastNSet = false;
                        } else if ("n".equals(subIndexArgumentsMatcher.group(1))) {
                            // Invalid use of "n" when lastN is not set
                            return null;
                        } else {
                            offset = Integer.parseInt(subIndexArgumentsMatcher.group(1));
                            if (offset < 0) {
                                start = indexElements.size() + offset;
                            } else {
                                start = offset;
                            }
                        }

                        int end;
                        if ("n".equals(subIndexArgumentsMatcher.group(2))) {
                            end = start + Integer.parseInt(indexElements.get(start)) + 1;
                            start++;
                            lastN = end;
                            lastNSet = true;
                        } else {
                            if (subIndexArgumentsMatcher.group(2) == null) {
                                end = indexElements.size();
                            } else {
                                end = start + Integer.parseInt(subIndexArgumentsMatcher.group(2));
                            }
                        }

                        if (start < 0 || start >= indexElements.size()) {
                            // Bogus index start
                            return null;
                        }

                        if (end < 0 || end > indexElements.size()) {
                            // Bogus index end
                            return null;
                        }

                        StringBuffer indexSubString = new StringBuffer();
                        for (int i = start; i < end; i++) {
                            if (indexSubString.length() != 0) {
                                indexSubString.append(".");
                            }

                            indexSubString.append(indexElements.get(i));
                        }

                        return indexSubString.toString();
                    }

                    Matcher hexMatcher = HEX_PATTERN.matcher(symbol);
                    if (hexMatcher.matches()) {
                        String subSymbol = getSymbolValue(hexMatcher.group(1));
                        List<String> indexElements = tokenizeIndex(subSymbol);

                        StringBuffer hexString = new StringBuffer();
                        for (String indexElement : indexElements) {
                            if (hexString.length() > 0) {
                                hexString.append(":");
                            }
                            try {
                                hexString.append(String.format("%02X", Integer.parseInt(indexElement)));
                            } catch (NumberFormatException e) {
                                return null;
                            }
                        }

                        return hexString.toString();
                    }

                    Matcher stringMatcher = STRING_PATTERN.matcher(symbol);
                    if (stringMatcher.matches()) {
                        String subSymbol = getSymbolValue(stringMatcher.group(1));
                        List<String> indexElements = tokenizeIndex(subSymbol);

                        StringBuffer stringString = new StringBuffer();
                        for (String indexElement : indexElements) {
                            stringString.append(String.format("%c", Integer.parseInt(indexElement)));
                        }

                        return stringString.toString();
                    }

                    for (OnmsAttribute attr : set) {
                        if (symbol.equals(attr.getName())) {
                            if (StringPropertyAttribute.class.isAssignableFrom(attr.getClass())) {
                                StringPropertyAttribute stringAttr = (StringPropertyAttribute) attr;
                                return stringAttr.getValue();
                            }
                            if (ExternalValueAttribute.class.isAssignableFrom(attr.getClass())) {
                                ExternalValueAttribute extAttr = (ExternalValueAttribute) attr;
                                return extAttr.getValue();
                            }
                        }
                    }

                    return null;
                }

                private List<String> tokenizeIndex(final String index) {
                    List<String> indexElements = new ArrayList<String>();
                    StringTokenizer t = new StringTokenizer(index, ".");
                    while (t.hasMoreTokens()) {
                        indexElements.add(t.nextToken());
                    }
                    return indexElements;
                }
            };

            label = PropertiesUtils.substitute(m_resourceLabelExpression, symbolTable);
        }

        return new OnmsResource(index, label, this, set);
    }

    public class AttributeLoader implements LazySet.Loader<OnmsAttribute> {

        private int m_nodeId;
        private String m_index;

        public AttributeLoader(int nodeId, String index) {
            m_nodeId = nodeId;
            m_index = index;
        }

        @Override
        public Set<OnmsAttribute> load() {
            return ResourceTypeUtils.getAttributesAtRelativePath(m_resourceDao.getRrdDirectory(),
                    getRelativePathForResource(m_nodeId, m_index));
        }
    }

    public class NodeSourceAttributeLoader implements LazySet.Loader<OnmsAttribute> {

        private String m_nodeSource;
        private String m_index;

        public NodeSourceAttributeLoader(String nodeSource, String index) {
            m_nodeSource = nodeSource;
            m_index = index;
        }

        @Override
        public Set<OnmsAttribute> load() {
            return ResourceTypeUtils.getAttributesAtRelativePath(m_resourceDao.getRrdDirectory(),
                    getRelativePathForNodeSourceResource(m_nodeSource, m_index));
        }
    }

    /**
     * <p>getRelativePathForResource</p>
     *
     * @param nodeId a int.
     * @param index a {@link String} object.
     * @return a {@link String} object.
     */
    public String getRelativePathForResource(int nodeId, String index) {
        return DefaultResourceDao.SNMP_DIRECTORY + File.separator + Integer.toString(nodeId) + File.separator
                + getName() + File.separator + index;
    }

    /**
     * <p>getRelativePathForNodeSourceResource</p>
     *
     * @param nodeSource a {@link String} object.
     * @param index a {@link String} object.
     * @return a {@link String} object.
     */
    public String getRelativePathForNodeSourceResource(String nodeSource, String index) {
        String[] ident = nodeSource.split(":");
        return DefaultResourceDao.SNMP_DIRECTORY + File.separator + DefaultResourceDao.FOREIGN_SOURCE_DIRECTORY
                + File.separator + ident[0] + File.separator + ident[1] + File.separator + getName()
                + File.separator + index;
    }

    /**
     * {@inheritDoc}
     *
     * This resource type is never available for domains.
     * Only the interface resource type is available for domains.
     */
    @Override
    public boolean isResourceTypeOnDomain(String domain) {
        return false;
    }

    /** {@inheritDoc} */
    @Override
    public List<OnmsResource> getResourcesForDomain(String domain) {
        List<OnmsResource> empty = Collections.emptyList();
        return empty;
    }

    /** {@inheritDoc} */
    @Override
    public String getLinkForResource(OnmsResource resource) {
        return null;
    }

    /** {@inheritDoc} */
    @Override
    public boolean isResourceTypeOnNodeSource(String nodeSource, int nodeId) {
        File forSrc = new File(m_resourceDao.getRrdDirectory(), DefaultResourceDao.SNMP_DIRECTORY);

        File node = new File(forSrc, ResourceTypeUtils.getRelativeNodeSourceDirectory(nodeSource).toString());
        File generic = new File(node, getName());
        return generic.isDirectory();
    }

    /** {@inheritDoc} */
    @Override
    public List<OnmsResource> getResourcesForNodeSource(String nodeSource, int nodeId) {
        ArrayList<OnmsResource> resources = new ArrayList<OnmsResource>();

        List<String> indexes = getQueryableIndexesForNodeSource(nodeSource);

        for (String index : indexes) {
            resources.add(getResourceByNodeSourceAndIndex(nodeSource, index));
        }
        return OnmsResource.sortIntoResourceList(resources);
    }

}