org.rhq.core.pluginapi.util.ObjectUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.rhq.core.pluginapi.util.ObjectUtil.java

Source

/*
 * RHQ Management Platform
 * Copyright (C) 2005-2008 Red Hat, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation, and/or the GNU Lesser
 * General Public License, version 2.1, also as published by the Free
 * Software Foundation.
 *
 * This program 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 and the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License
 * and the GNU Lesser General Public License along with this program;
 * if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package org.rhq.core.pluginapi.util;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.HashSet;
import java.util.Set;
import java.lang.reflect.Method;

import javax.management.openmbean.CompositeData;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.Nullable;

import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.util.exception.ThrowableUtil;

/**
* @author Greg Hinkle
*/
public class ObjectUtil {
    private static final Log LOG = LogFactory.getLog(ObjectUtil.class);

    /**
    * Returns the value of the property with the specified name for the given Object, or null if the Object has no such
    * property.
    *
    * @param obj an Object
    * @param propertyName the name of the property whose value should be returned
    *
    * @return the value of the property with the specified name for the given Object, or null if the Object has no such
    *         property
    */
    @Nullable
    public static Object lookupAttributeProperty(Object obj, String propertyName) {
        Object value = null;
        if (obj instanceof CompositeData) {
            CompositeData compositeData = ((CompositeData) obj);
            if (compositeData.containsKey(propertyName)) {
                value = compositeData.get(propertyName);
            } else {
                LOG.debug("Unable to read attribute/property [" + propertyName + "] from object [" + obj
                        + "] using OpenMBean API - no such property.");
            }
        } else {
            // Try to use reflection.
            try {
                PropertyDescriptor[] pds = Introspector.getBeanInfo(obj.getClass()).getPropertyDescriptors();
                boolean propertyFound = false;
                for (PropertyDescriptor pd : pds) {
                    if (pd.getName().equals(propertyName)) {
                        propertyFound = true;
                        Method readMethod = pd.getReadMethod();
                        if (readMethod == null) {
                            LOG.debug("Unable to read attribute/property [" + propertyName + "] from object [" + obj
                                    + "] using Reflection - property is not readable (i.e. it has no getter).");
                        } else {
                            value = readMethod.invoke(obj);
                        }
                    }
                }
                if (!propertyFound) {
                    LOG.debug("Unable to read attribute/property [" + propertyName + "] from object [" + obj
                            + "] using Reflection - no such property.");
                }
            } catch (Exception e) {
                LOG.debug("Unable to read attribute/property [" + propertyName + "] from object [" + obj
                        + "] using Reflection - cause: " + ThrowableUtil.getAllMessages(e));
            }
        }

        return value;
    }

    private static Set<String> getAttributeNames(Set<MeasurementScheduleRequest> requests) {
        Set<String> names = new HashSet<String>();
        for (MeasurementScheduleRequest request : requests) {
            names.add(getAttributeName(request.getName()));
        }

        return names;
    }

    private static String getAttributeName(String property) {
        if (property.startsWith("{")) {
            return property.substring(1, property.indexOf('.'));
        } else {
            return property;
        }
    }

    private static String getAttributeProperty(String property) {
        if (property.startsWith("{")) {
            return property.substring(property.indexOf('.') + 1, property.length() - 1);
        } else {
            return null;
        }
    }

    /**
     * Reads a numeric value from a deep object graph as per {@see ObjectUtil.lookupDeepAttributeProperty()}
     *
     * @param  value        The object to look into
     * @param  propertyPath the property path to search
     *
     * @return the double value read from the object's property path or Double.NaN if it can't be read
     */
    public static Double lookupDeepNumericAttributeProperty(Object value, String propertyPath) {
        Object val = lookupDeepAttributeProperty(value, propertyPath);
        if (val instanceof Number) {
            return ((Number) val).doubleValue();
        } else {
            return Double.NaN;
        }
    }

    /**
     * Looks up deep object graph attributes using a dot delimited java bean spec style path. So if I have an object A
     * with a Member object B with a String value C I can refer to it as "b.c" and pass in the object A and I'll get
     * back the value of a.getB().getC()
     *
     * @param  value        The object to look into
     * @param  propertyPath the property path to search
     *
     * @return the value read from the object's property path
     */
    public static Object lookupDeepAttributeProperty(Object value, String propertyPath) {

        if (value == null)
            return null;

        String[] ps = propertyPath.split("\\.", 2);

        String searchProperty = ps[0];

        if (value instanceof CompositeData) {
            CompositeData compositeData = ((CompositeData) value);
            if (compositeData.containsKey(searchProperty)) {
                value = compositeData.get(searchProperty);
            } else {
                LOG.debug("Unable to read attribute property [" + propertyPath + "] from composite data value");
            }
        } else {
            // Try to use reflection
            try {
                PropertyDescriptor[] pds = Introspector.getBeanInfo(value.getClass()).getPropertyDescriptors();
                for (PropertyDescriptor pd : pds) {
                    if (pd.getName().equals(searchProperty)) {
                        value = pd.getReadMethod().invoke(value);
                    }
                }
            } catch (Exception e) {
                LOG.debug("Unable to read property from measurement attribute [" + searchProperty
                        + "] not found on [" + ((value != null) ? value.getClass().getSimpleName() : "null") + "]");
            }
        }

        if (ps.length > 1) {
            value = lookupDeepAttributeProperty(value, ps[1]);
        }

        return value;
    }

    // Prevent instantiation of this class.
    private ObjectUtil() {
    }
}