Package br.gov.frameworkdemoiselle.jmx.internal

Source Code of br.gov.frameworkdemoiselle.jmx.internal.DynamicMBeanProxy

/*
* Demoiselle Framework
* Copyright (C) 2010 SERPRO
* ----------------------------------------------------------------------------
* This file is part of Demoiselle Framework.
*
* Demoiselle Framework is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License version 3
* 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public License version 3
* along with this program; if not,  see <http://www.gnu.org/licenses/>
* or write to the Free Software Foundation, Inc., 51 Franklin Street,
* Fifth Floor, Boston, MA  02110-1301, USA.
* ----------------------------------------------------------------------------
* Este arquivo é parte do Framework Demoiselle.
*
* O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
* modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
* do Software Livre (FSF).
*
* Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
* GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
* APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
* para maiores detalhes.
*
* Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
* "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/>
* ou escreva para a Fundação do Software Livre (FSF) Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
*/
package br.gov.frameworkdemoiselle.jmx.internal;

import java.util.ArrayList;
import java.util.Locale;
import java.util.Map.Entry;

import javax.management.Attribute;
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.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.ReflectionException;

import br.gov.frameworkdemoiselle.DemoiselleException;
import br.gov.frameworkdemoiselle.internal.management.ManagedType;
import br.gov.frameworkdemoiselle.internal.management.ManagedType.FieldDetail;
import br.gov.frameworkdemoiselle.internal.management.ManagedType.MethodDetail;
import br.gov.frameworkdemoiselle.internal.management.ManagedType.ParameterDetail;
import br.gov.frameworkdemoiselle.internal.management.Management;
import br.gov.frameworkdemoiselle.internal.producer.ResourceBundleProducer;
import br.gov.frameworkdemoiselle.stereotype.ManagementController;
import br.gov.frameworkdemoiselle.util.Beans;
import br.gov.frameworkdemoiselle.util.ResourceBundle;

/**
* <p>
* This class is a MBean that gets registered everytime you mark a class with {@link ManagementController}. It dynamicaly reads the
* fields and operations contained in a {@link ManagementController} class and exposes them to the MBean server. Everytime a client
* tries to call an operation or read/write a property inside a ManagementController class, this class will call the appropriate
* method and pass the result to the MBean client.
* </p>
*
* @author SERPRO
*/
public class DynamicMBeanProxy implements DynamicMBean {

  private MBeanInfo delegateInfo;
 
  private ManagedType managedType;

  private ResourceBundle bundle = ResourceBundleProducer.create("demoiselle-jmx-bundle", Locale.getDefault());

  public DynamicMBeanProxy(ManagedType type) {
    if (type == null) {
      throw new NullPointerException(bundle.getString("mbean-null-type-defined"));
    }
    managedType = type;
  }

  @Override
  public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
    // Se o bean ainda não foi lido para determinar seus atributos, o faz agora.
    if (delegateInfo == null) {
      initializeMBeanInfo();
    }

    Management manager = Beans.getReference(Management.class);
    return manager.getProperty(managedType, attribute);
  }

  @Override
  public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException,
      MBeanException, ReflectionException {

    // Se o bean ainda não foi lido para determinar seus atributos, o faz agora.
    if (delegateInfo == null) {
      initializeMBeanInfo();
    }

    Management manager = Beans.getReference(Management.class);
    manager.setProperty(managedType, attribute.getName(), attribute.getValue());
  }

  @Override
  public AttributeList getAttributes(String[] attributes) {
    if (attributes != null) {
      AttributeList list = new AttributeList();
      for (String attribute : attributes) {
        try {
          Object value = getAttribute(attribute);
          list.add(new Attribute(attribute, value));
        } catch (Throwable t) {
        }
      }

      return list;
    }

    return null;
  }

  @Override
  public AttributeList setAttributes(AttributeList attributes) {
    AttributeList settedAttributes = new AttributeList();
    if (attributes != null) {
      for (Attribute attribute : attributes.asList()) {
        try {
          setAttribute(attribute);

          // A razão para separarmos a criação do atributo de sua adição na lista é que
          // caso a obtenção do novo valor do atributo dispare uma exceção então o atributo não será
          // adicionado na lista de atributos que foram afetados.
          Attribute attributeWithNewValue = new Attribute(attribute.getName(),
              getAttribute(attribute.getName()));
          settedAttributes.add(attributeWithNewValue);
        } catch (Throwable t) {
        }
      }
    }

    return settedAttributes;
  }

  @Override
  public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException,
      ReflectionException {

    // Se o bean ainda não foi lido para determinar seus atributos, o faz agora.
    if (this.delegateInfo == null) {
      initializeMBeanInfo();
    }

    Management manager = Beans.getReference(Management.class);
    return manager.invoke(managedType, actionName, params);
  }

  /**
   * Initialize the Managed information for this instance of Managed
   */
  private void initializeMBeanInfo() {
    // Aqui vamos armazenar nossos atributos
    ArrayList<MBeanAttributeInfo> attributes = new ArrayList<MBeanAttributeInfo>();

    // Aqui vamos armazenar nossas operações
    ArrayList<MBeanOperationInfo> operations = new ArrayList<MBeanOperationInfo>();

    // Para cada propriedade descoberta no ManagementController, cria um attributeInfo correspondente
    for (Entry<String, FieldDetail> fieldEntry : managedType.getFields().entrySet()) {

      try {

        MBeanAttributeInfo attributeInfo = new MBeanAttributeInfo(fieldEntry.getKey(), fieldEntry.getValue()
            .getDescription(), fieldEntry.getValue().getGetterMethod(), fieldEntry.getValue()
            .getSetterMethod());
        attributes.add(attributeInfo);

      } catch (javax.management.IntrospectionException e) {
        throw new DemoiselleException(bundle.getString("mbean-introspection-error", managedType.getType()
            .getSimpleName()));
      }
    }

    // Para cada operação descoberta no ManagementController, cria um operationInfo correspondente
    for (Entry<String, MethodDetail> methodEntry : managedType.getOperationMethods().entrySet()) {

      MethodDetail methodDetail = methodEntry.getValue();

      ParameterDetail[] parameterTypes = methodDetail.getParameterTypers();

      MBeanParameterInfo[] parameters = parameterTypes.length > 0 ? new MBeanParameterInfo[parameterTypes.length]
          : null;

      if (parameters != null) {

        for (int i = 0; i < parameterTypes.length; i++) {

          parameters[i] = new MBeanParameterInfo(parameterTypes[i].getParameterName(), parameterTypes[i]
              .getParameterType().getCanonicalName(), parameterTypes[i].getParameterDescription());
        }
      }

      // Com todas as informações, criamos nossa instância de MBeanOperationInfo e
      // acrescentamos na lista de todas as operações.
      int operationType = 0;
      switch(methodDetail.getType()){
        case ACTION:
          operationType = MBeanOperationInfo.ACTION;
          break;
         
        case INFO:
          operationType = MBeanOperationInfo.INFO;
          break;
         
        case ACTION_INFO:
          operationType = MBeanOperationInfo.ACTION_INFO;
          break;
         
        default:
          operationType = MBeanOperationInfo.UNKNOWN;
      }
     
      MBeanOperationInfo operation = new MBeanOperationInfo(methodDetail.getMethod().getName(),
          methodDetail.getDescription(), parameters, methodDetail.getMethod().getReturnType().getName(),
          operationType);

      operations.add(operation);

    }

    // Por fim criamos nosso bean info.
    delegateInfo = new MBeanInfo(managedType.getType().getCanonicalName(), managedType.getDescription(),
        attributes.toArray(new MBeanAttributeInfo[0]), null, operations.toArray(new MBeanOperationInfo[0]),
        null);

  }

  @Override
  public MBeanInfo getMBeanInfo() {
    if (delegateInfo == null) {
      initializeMBeanInfo();
    }

    return delegateInfo;
  }

}
TOP

Related Classes of br.gov.frameworkdemoiselle.jmx.internal.DynamicMBeanProxy

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.