Package org.apache.felix.mosgi.jmx.agent.mx4j.server

Source Code of org.apache.felix.mosgi.jmx.agent.mx4j.server.ReflectedMBeanInvoker

/*
* 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.mosgi.jmx.agent.mx4j.server;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.JMRuntimeException;
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 javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;

import org.apache.felix.mosgi.jmx.agent.mx4j.ImplementationException;
import org.apache.felix.mosgi.jmx.agent.mx4j.util.Utils;
import org.apache.felix.mosgi.jmx.agent.mx4j.util.MethodTernaryTree;

/**
* MBeanInvoker that uses reflection to invoke on MBean instances.
*
* @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
* @version $Revision: 1.1.1.1 $
*/
public class ReflectedMBeanInvoker implements MBeanInvoker
{
   private static final String[] EMPTY_PARAMS = new String[0];
   private static final Object[] EMPTY_ARGS = new Object[0];

   private final Map attributes = new HashMap();
   private final Map attributeNames = new HashMap();
   private final MethodTernaryTree operations = new MethodTernaryTree();
   private final MethodTernaryTree methods = new MethodTernaryTree();

   public Object invoke(MBeanMetaData metadata, String method, String[] params, Object[] args) throws MBeanException, ReflectionException
   {
      MBeanOperationInfo oper = getStandardOperationInfo(metadata, method, params);
      if (oper != null)
      {
         try
         {
            return invokeImpl(metadata, method, params, args);
         }
         catch (IllegalArgumentException x)
         {
            throw new RuntimeOperationsException(x);
         }
      }
      else
      {
         throw new ReflectionException(new NoSuchMethodException("Operation " + method + " does not belong to the management interface"));
      }
   }

   public Object getAttribute(MBeanMetaData metadata, String attribute) throws MBeanException, AttributeNotFoundException, ReflectionException
   {
      MBeanAttributeInfo attr = getStandardAttributeInfo(metadata, attribute, false);
      if (attr != null)
      {
         String attributeName = getAttributeName(attr, true);
         try
         {
            return invokeImpl(metadata, attributeName, EMPTY_PARAMS, EMPTY_ARGS);
         }
         catch (IllegalArgumentException x)
         {
            // Never thrown, since there are no arguments
            throw new ImplementationException();
         }
      }
      else
      {
         throw new AttributeNotFoundException(attribute);
      }
   }

   public void setAttribute(MBeanMetaData metadata, Attribute attribute) throws MBeanException, AttributeNotFoundException, InvalidAttributeValueException, ReflectionException
   {
      String name = attribute.getName();
      MBeanAttributeInfo attr = getStandardAttributeInfo(metadata, name, true);
      if (attr != null)
      {
         String attributeName = getAttributeName(attr, false);
         try
         {
            invokeImpl(metadata, attributeName, new String[]{attr.getType()}, new Object[]{attribute.getValue()});
         }
         catch (IllegalArgumentException x)
         {
            throw new InvalidAttributeValueException("Invalid value for attribute " + name + ": " + attribute.getValue());
         }
      }
      else
      {
         throw new AttributeNotFoundException(name);
      }
   }

   protected Object invokeImpl(MBeanMetaData metadata, String method, String[] signature, Object[] args) throws ReflectionException, MBeanException, IllegalArgumentException
   {
      Method m = getStandardManagementMethod(metadata, method, signature);

      try
      {
         return m.invoke(metadata.mbean, args);
      }
      catch (IllegalAccessException x)
      {
         throw new ReflectionException(x);
      }
      catch (InvocationTargetException x)
      {
         Throwable t = x.getTargetException();
         if (t instanceof Error) throw new RuntimeErrorException((Error)t);
         if (t instanceof JMRuntimeException) throw (JMRuntimeException)t;
         if (t instanceof RuntimeException) throw new RuntimeMBeanException((RuntimeException)t);
         throw new MBeanException((Exception)t);
      }
   }

   private MBeanAttributeInfo getStandardAttributeInfo(MBeanMetaData metadata, String attribute, boolean isWritable)
   {
      MBeanAttributeInfo attr = null;
      synchronized (attributes)
      {
         attr = (MBeanAttributeInfo)attributes.get(attribute);
      }
      if (attr != null)
      {
         if (isWritable && attr.isWritable()) return attr;
         if (!isWritable && attr.isReadable()) return attr;
      }
      else
      {
         MBeanAttributeInfo[] attrs = metadata.info.getAttributes();
         if (attrs != null)
         {
            for (int i = 0; i < attrs.length; ++i)
            {
               attr = attrs[i];
               String name = attr.getName();
               if (attribute.equals(name))
               {
                  synchronized (attributes)
                  {
                     attributes.put(attribute, attr);
                  }
                  if (isWritable && attr.isWritable()) return attr;
                  if (!isWritable && attr.isReadable()) return attr;
               }
            }
         }
      }
      return null;
   }

   private MBeanOperationInfo getStandardOperationInfo(MBeanMetaData metadata, String method, String[] signature)
   {
      MBeanOperationInfo oper = null;

      synchronized (operations)
      {
         oper = (MBeanOperationInfo)operations.get(method, signature);
      }

      if (oper != null) return oper;

      // The MBeanOperationInfo is not in the cache, look it up
      MBeanInfo info = metadata.info;
      MBeanOperationInfo[] opers = info.getOperations();
      if (opers != null)
      {
         for (int i = 0; i < opers.length; ++i)
         {
            oper = opers[i];
            String name = oper.getName();
            if (method.equals(name))
            {
               // Same method name, check number of parameters
               MBeanParameterInfo[] params = oper.getSignature();
               if (signature.length == params.length)
               {
                  boolean match = true;
                  for (int j = 0; j < params.length; ++j)
                  {
                     MBeanParameterInfo param = params[j];
                     if (!signature[j].equals(param.getType()))
                     {
                        match = false;
                        break;
                     }
                  }
                  if (match)
                  {
                     synchronized (operations)
                     {
                        operations.put(method, signature, oper);
                     }
                     return oper;
                  }
               }
            }
         }
      }
      return null;
   }

   private Method getStandardManagementMethod(MBeanMetaData metadata, String name, String[] signature) throws ReflectionException
   {
      Method method = null;
      synchronized (methods)
      {
         method = (Method)methods.get(name, signature);
      }
      if (method != null) return method;

      // Method is not in cache, look it up
      try
      {
         Class[] params = Utils.loadClasses(metadata.classloader, signature);
         method = metadata.mbean.getClass().getMethod(name, params);
         synchronized (methods)
         {
            methods.put(name, signature, method);
         }
         return method;
      }
      catch (ClassNotFoundException x)
      {
         throw new ReflectionException(x);
      }
      catch (NoSuchMethodException x)
      {
         throw new ReflectionException(x);
      }
   }

   private String getAttributeName(MBeanAttributeInfo attribute, boolean getter)
   {
      AttributeName attributeName = null;
      String name = attribute.getName();
      synchronized (attributeNames)
      {
         attributeName = (AttributeName)attributeNames.get(name);
      }
      if (attributeName == null)
      {
         String prefix = attribute.isIs() ? "is" : "get";
         attributeName = new AttributeName(prefix + name, "set" + name);
         synchronized (attributeNames)
         {
            attributeNames.put(name, attributeName);
         }
      }

      if (getter) return attributeName.getter;
      return attributeName.setter;
   }

   private static class AttributeName
   {
      private final String getter;
      private final String setter;

      public AttributeName(String getter, String setter)
      {
         this.getter = getter;
         this.setter = setter;
      }
   }
}
TOP

Related Classes of org.apache.felix.mosgi.jmx.agent.mx4j.server.ReflectedMBeanInvoker

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.