Package org.apache.felix.ipojo.handlers.jmx

Source Code of org.apache.felix.ipojo.handlers.jmx.DynamicMBeanImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.ipojo.handlers.jmx;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.management.Attribute;
import javax.management.AttributeChangeNotification;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ReflectionException;
import javax.management.RuntimeOperationsException;

import org.apache.felix.ipojo.InstanceManager;
import org.apache.felix.ipojo.parser.MethodMetadata;
import org.apache.felix.ipojo.util.Callback;
import org.apache.felix.ipojo.util.Logger;

/**
* This class implements iPOJO DynamicMBean. it builds the dynamic MBean
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class DynamicMBeanImpl extends NotificationBroadcasterSupport implements
        DynamicMBean {

    /**
     * The instance manager. Used to store the InstanceManager instance.
     */
    protected final InstanceManager m_instanceManager;

    /**
     * The JmxConfigDFieldMap. Stors the data extracted from metadata.xml.
     */
    private JmxConfigFieldMap m_configMap;

    /**
     * The MBeanInfo. The class storing the MBean Informations.
     */
    private MBeanInfo m_mBeanInfo;

    /**
     * The class name. Constant storing the name of the class.
     */
    private String m_className = this.getClass().getName();

    /**
     * The sequence number. Used to calculate unique id to notification.
     */
    private int m_sequenceNumber;

    /**
     * Constructor.
     *
     * @param properties the data extracted from metadat.xml file
     * @param instanceManager the InstanceManager instance
     */
    public DynamicMBeanImpl(JmxConfigFieldMap properties,
            InstanceManager instanceManager) {
        m_configMap = properties;
        m_instanceManager = instanceManager;
        this.buildMBeanInfo();
    }

    /**
     * Gets the value of the required attribute.
     *
     * @param arg0 the name of required attribute
     * @throws AttributeNotFoundException if the attribute doesn't exist
     * @throws MBeanException if something bad occures
     * @throws ReflectionException if something bad occures
     * @return the object attribute
     */
    public Object getAttribute(String arg0) throws AttributeNotFoundException,
        MBeanException, ReflectionException {
        PropertyField attribute = m_configMap.getPropertyFromName(arg0);

        if (attribute == null) {
            throw new AttributeNotFoundException(arg0 + " not found");
        } else {
            return attribute.getValue();
        }
    }

    /**
     * Gets values of required attributes.
     *
     * @param attributeNames the names of the required attributes
     * @return return the list of the attribute
     */
    public AttributeList getAttributes(String[] attributeNames) {

        if (attributeNames == null) {
            throw new IllegalArgumentException(
                "attributeNames[] cannot be null");
        }

        AttributeList resultList = new AttributeList();
        for (int i = 0; i < attributeNames.length; i++) {
            PropertyField propertyField = (PropertyField) m_configMap
                .getPropertyFromField((String) attributeNames[i]);

            if (propertyField != null) {
                resultList.add(new Attribute(attributeNames[i], propertyField
                    .getValue()));
            }
        }
        return resultList;
    }

    /**
     * Returns the MBean Class builded.
     *
     * @return return MBeanInfo class constructed by buildMBeanInfo
     */
    public MBeanInfo getMBeanInfo() {
        return m_mBeanInfo;
    }

    /**
     * Invokes the required method on the targeted POJO.
     *
     * @param operationName the name of the method called
     * @param params the parameters given to the method
     * @param signature the determine which method called
     * @return the object return by the method
     * @throws MBeanException if something bad occures
     * @throws ReflectionException if something bad occures
     */
    public Object invoke(String operationName, Object[] params,
            String[] signature) throws MBeanException, ReflectionException {

        MethodField method = m_configMap.getMethodFromName(operationName,
            signature);
        if (method != null) {
            MethodMetadata methodCall = method.getMethod();
            Callback mc = new Callback(methodCall, m_instanceManager);
            try {
                return mc.call(params);
            } catch (NoSuchMethodException e) {
                throw new ReflectionException(e);
            } catch (IllegalAccessException e) {
                throw new ReflectionException(e);
            } catch (InvocationTargetException e) {
                throw new MBeanException(e);
            }
        } else {
            throw new ReflectionException(new NoSuchMethodException(
                operationName), "Cannot find the operation " + operationName
                    + " in " + m_className);
        }
    }

    /**
     * Changes specified attribute value.
     *
     * @param attribute the attribute with new value to be changed
     * @throws AttributeNotFoundException if the required attribute was not found
     * @throws InvalidAttributeValueException if the value is inccorrect type
     * @throws MBeanException if something bad occures
     * @throws ReflectionException if something bad occures
     */
    public void setAttribute(Attribute attribute)
        throws AttributeNotFoundException, InvalidAttributeValueException,
        MBeanException, ReflectionException {

        // Check attribute is not null to avoid NullPointerException later on
        if (attribute == null) {
            throw new RuntimeOperationsException(new IllegalArgumentException(
                "Attribute cannot be null"), "Cannot invoke a setter of "
                    + m_className + " with null attribute");
        }
        String name = attribute.getName();
        Object value = attribute.getValue();

        if (name == null) {
            throw new RuntimeOperationsException(new IllegalArgumentException(
                "Attribute name cannot be null"),
                "Cannot invoke the setter of " + m_className
                        + " with null attribute name");
        }
        // Check for a recognized attribute name and call the corresponding
        // setter
        //

        PropertyField propertyField = (PropertyField) m_configMap
            .getPropertyFromName(name);
        if (propertyField == null) {
            // unrecognized attribute name:
            throw new AttributeNotFoundException("Attribute " + name
                    + " not found in " + m_className);
        }
        if (!propertyField.isWritable()) {
            throw new InvalidAttributeValueException("Attribute " + name
                    + " can not be set");
        }

        if (value == null) {
            try {
                m_instanceManager.onSet(null, propertyField.getField(), null);
            } catch (Exception e) {
                throw new InvalidAttributeValueException(
                    "Cannot set attribute " + name + " to null");
            }
        } else { // if non null value, make sure it is assignable to the
            // attribute
//            if (true /* TODO type.class.isAssignableFrom(value.getClass()) */) {
                // propertyField.setValue(value);
                // setValue(attributeField.getField(),null);
            m_instanceManager.onSet(null, propertyField.getField(), value);
//            } else {
//                throw new InvalidAttributeValueException(
//                    "Cannot set attribute " + name + " to a "
//                            + value.getClass().getName()
//                            + " object, String expected");
//            }
        }

    }

    /**
     * Changes all the attributes value.
     *
     * @param attributes the list of attribute value to be changed
     * @return the list of new attribute
     */
    public AttributeList setAttributes(AttributeList attributes) {

        // Check attributes is not null to avoid NullPointerException later on
        if (attributes == null) {
            throw new RuntimeOperationsException(new IllegalArgumentException(
                "AttributeList attributes cannot be null"),
                "Cannot invoke a setter of " + m_className);
        }
        AttributeList resultList = new AttributeList();

        // if attributeNames is empty, nothing more to do
        if (attributes.isEmpty()) {
            return resultList;
        }

        // for each attribute, try to set it and add to the result list if
        // successful
        for (Iterator i = attributes.iterator(); i.hasNext();) {
            Attribute attr = (Attribute) i.next();
            try {
                setAttribute(attr);
                String name = attr.getName();
                Object value = getAttribute(name);
                resultList.add(new Attribute(name, value));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resultList;
    }

    /**
     * Builds the MBean information on initialization. This
     * value doesn't change further.
     */
    private void buildMBeanInfo() {

        // generate infos for attributes
        MBeanAttributeInfo[] dAttributes = null;

        if (m_configMap == null) {
            return;
        }

        String dDescription = m_configMap.getDecription();

        if (m_configMap.getProperties() != null) {
            List < MBeanAttributeInfo > lAttributes = null;
            lAttributes = new ArrayList < MBeanAttributeInfo >();

            Iterator < PropertyField > iterator = m_configMap.getProperties()
                .iterator();
            while (iterator.hasNext()) {
                PropertyField propertyField = iterator.next();
                lAttributes.add(new MBeanAttributeInfo(propertyField.getName(),
                    propertyField.getType(), propertyField.getDescription(),
                    propertyField.isReadable(), propertyField.isWritable(),
                    false));
            }
            dAttributes = lAttributes
                .toArray(new MBeanAttributeInfo[lAttributes.size()]);
        }

        MBeanOperationInfo[] dOperations = null;
        if (m_configMap.getMethods() != null) {

            List < MBeanOperationInfo > lOperations = new ArrayList < MBeanOperationInfo >();

            Iterator < MethodField[] > iterator = m_configMap.getMethods()
                .iterator();
            while (iterator.hasNext()) {
                MethodField[] method = iterator.next();
                for (int i = 0; i < method.length; i++) {
                    lOperations.add(new MBeanOperationInfo(method[i].getName(),
                        method[i].getDescription(), method[i].getParams(),
                        method[i].getReturnType(), MBeanOperationInfo.UNKNOWN));
                }
                dOperations = lOperations
                    .toArray(new MBeanOperationInfo[lOperations.size()]);
            }
        }

        MBeanNotificationInfo[] dNotification = new MBeanNotificationInfo[0];
        if (m_configMap.getMethods() != null) {

            List < MBeanNotificationInfo > lNotifications = new ArrayList < MBeanNotificationInfo >();

            Iterator < NotificationField > iterator = m_configMap
                .getNotifications().iterator();
            while (iterator.hasNext()) {
                NotificationField notification = iterator
                    .next();
                lNotifications.add(notification.getNotificationInfo());
            }
            dNotification = lNotifications
                .toArray(new MBeanNotificationInfo[lNotifications.size()]);
        }

        m_mBeanInfo = new MBeanInfo(this.m_className, dDescription,
            dAttributes, null, // No constructor
            dOperations, dNotification);
    }

    /**
     * Gets the notification informations (use by JMX).
     *
     * @return the structure which describe the notifications
     */
    public MBeanNotificationInfo[] getNotificationInfo() {
        MBeanNotificationInfo[] dNotification = new MBeanNotificationInfo[0];
        if (m_configMap.getMethods() != null) {

            List < MBeanNotificationInfo > lNotifications = new ArrayList < MBeanNotificationInfo >();

            Iterator < NotificationField > iterator = m_configMap
                .getNotifications().iterator();
            while (iterator.hasNext()) {
                NotificationField notification = iterator
                    .next();
                lNotifications.add(notification.getNotificationInfo());
            }
            dNotification = lNotifications
                .toArray(new MBeanNotificationInfo[lNotifications.size()]);
        }
        return dNotification;
    }

    /**
     * Sends a notification to a subscriber.
     *
     * @param msg the msg to send
     * @param attributeName the name of the attribute
     * @param attributeType the type of the attribute
     * @param oldValue the old value of the attribute
     * @param newValue the new value of the attribute
     */
    public void sendNotification(String msg, String attributeName,
            String attributeType, Object oldValue, Object newValue) {

        long timeStamp = System.currentTimeMillis();

        if ((newValue == null  && oldValue == null)
            || (newValue != null  && newValue.equals(oldValue))) {
            return;
        }
        m_sequenceNumber++;
        Notification notification = new AttributeChangeNotification(this,
            m_sequenceNumber, timeStamp, msg, attributeName, attributeType,
            oldValue, newValue);
        sendNotification(notification);
        m_instanceManager.getFactory().getLogger().log(Logger.INFO,
            "Notification sent");
    }
}
TOP

Related Classes of org.apache.felix.ipojo.handlers.jmx.DynamicMBeanImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.