/**
   * Tests correct MBean interface.
   *
   * @throws Exception Thrown if test fails.
   */
  public void testCorrectMBeanInfo() throws Exception {
    StandardMBean mbean =
        new IgniteStandardMXBean(new GridMBeanImplementation(), GridMBeanInterface.class);

    MBeanInfo info = mbean.getMBeanInfo();

    assert info.getDescription().equals("MBeanDescription.") == true;

    assert info.getOperations().length == 2;

    for (MBeanOperationInfo opInfo : info.getOperations()) {
      if (opInfo.getDescription().equals("MBeanOperation."))
        assert opInfo.getSignature().length == 2;
      else {
        assert opInfo.getDescription().equals("MBeanSuperOperation.") == true;
        assert opInfo.getSignature().length == 1;
      }
    }

    for (MBeanParameterInfo paramInfo : info.getOperations()[0].getSignature()) {
      if (paramInfo.getName().equals("ignored"))
        assert paramInfo.getDescription().equals("MBeanOperationParameter1.") == true;
      else {
        assert paramInfo.getName().equals("someData") == true;
        assert paramInfo.getDescription().equals("MBeanOperationParameter2.") == true;
      }
    }

    assert info.getAttributes().length == 4
        : "Expected 4 attributes but got " + info.getAttributes().length;

    for (MBeanAttributeInfo attrInfo : info.getAttributes()) {
      if (attrInfo.isWritable() == false) {
        assert (attrInfo.getDescription().equals("MBeanReadonlyGetter.") == true
            || attrInfo.getDescription().equals("MBeanROGetter."));
      } else {
        assert (attrInfo.getDescription().equals("MBeanWritableGetter.") == true
            || attrInfo.getDescription().equals("MBeanWritableIsGetter."));
      }
    }
  }
  public Object getPropertyValue(Object id) {
    if ("name".equals(id)) { // $NON-NLS-1$
      return attrInfo.getName();
    }
    if ("description".equals(id)) { // $NON-NLS-1$
      return attrInfo.getDescription();
    }
    if ("type".equals(id)) { // $NON-NLS-1$
      Object obj = attrInfo.getType();
      if (obj instanceof Object[]) {
        return Arrays.asList((Object[]) obj).toString();
      }
      return obj;
    }
    if ("readable".equals(id)) { // $NON-NLS-1$
      return Boolean.valueOf(attrInfo.isReadable());
    }
    if ("writable".equals(id)) { // $NON-NLS-1$
      return Boolean.valueOf(attrInfo.isWritable());
    }
    if ("value".equals(id)) { // $NON-NLS-1$
      try {
        if (mbsc != null) {
          Object obj = mbsc.getAttribute(on, attrInfo.getName());
          if (obj instanceof Object[]) {
            return Arrays.asList((Object[]) obj).toString();
          }
          return obj;
        } else {
          conn.run(
              new IJMXRunnable() {
                final Object[] ret = new Object[1];

                @Override
                public void run(MBeanServerConnection connection) throws Exception {
                  Object obj = connection.getAttribute(on, attrInfo.getName());
                  if (obj instanceof Object[]) {
                    ret[0] = Arrays.asList((Object[]) obj).toString();
                  }
                  ret[0] = obj;
                }
              });
        }
      } catch (Exception e) {
        JMXUIActivator.log(
            IStatus.WARNING, NLS.bind(Messages.MBeanAttributeValue_Warning, attrInfo.getName()), e);
        return null;
      }
    }
    return null;
  }
  private MBeanAttributeInfo[] createMBeanAttributeInfo(
      MBeanMetaData metadata, MBeanDescription description) {
    Logger logger = getLogger();

    HashMap attributes = new HashMap();
    HashMap getterNames = new HashMap();

    Method[] methods = metadata.management.getMethods();
    for (int j = 0; j < methods.length; ++j) {
      Method method = methods[j];
      if (Utils.isAttributeGetter(method)) {
        String name = method.getName();
        boolean isIs = name.startsWith("is");

        String attribute = null;
        if (isIs) attribute = name.substring(2);
        else attribute = name.substring(3);

        String descr = description == null ? null : description.getAttributeDescription(attribute);

        MBeanAttributeInfo info = (MBeanAttributeInfo) attributes.get(attribute);

        if (info != null) {
          // JMX spec does not allow overloading attributes.
          // If an attribute with the same name already exists the MBean is not compliant
          if (!info.getType().equals(method.getReturnType().getName())) {
            if (logger.isEnabledFor(Logger.DEBUG))
              logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
            return null;
          } else {
            // They return the same value,
            if (getterNames.get(name) != null) {
              // This is the case of an attribute being present in multiple interfaces
              // Ignore all but the first, since they resolve to the same method anyways
              continue;
            }

            // there is a chance that one is a get-getter and one is a is-getter
            // for a boolean attribute. In this case, the MBean is not compliant.
            if (info.isReadable()) {
              if (logger.isEnabledFor(Logger.DEBUG))
                logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
              return null;
            }

            // MBeanAttributeInfo is already present due to a setter method, just update its
            // readability
            info =
                new MBeanAttributeInfo(
                    attribute,
                    info.getType(),
                    info.getDescription(),
                    true,
                    info.isWritable(),
                    isIs);
          }
        } else {
          info =
              new MBeanAttributeInfo(
                  attribute, method.getReturnType().getName(), descr, true, false, isIs);
        }

        // Replace if exists
        attributes.put(attribute, info);
        getterNames.put(name, method);
      } else if (Utils.isAttributeSetter(method)) {
        String name = method.getName();
        String attribute = name.substring(3);

        String descr = description == null ? null : description.getAttributeDescription(attribute);

        MBeanAttributeInfo info = (MBeanAttributeInfo) attributes.get(attribute);

        if (info != null) {
          // JMX spec does not allow overloading attributes.
          // If an attribute with the same name already exists the MBean is not compliant
          if (!info.getType().equals(method.getParameterTypes()[0].getName())) {
            if (logger.isEnabledFor(Logger.DEBUG))
              logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
            return null;
          } else {
            // MBeanAttributeInfo is already present due to a getter method, just update its
            // writability
            info =
                new MBeanAttributeInfo(
                    info.getName(),
                    info.getType(),
                    info.getDescription(),
                    info.isReadable(),
                    true,
                    info.isIs());
          }
        } else {
          info =
              new MBeanAttributeInfo(
                  attribute, method.getParameterTypes()[0].getName(), descr, false, true, false);
        }

        // Replace if exists
        attributes.put(attribute, info);
      }
    }

    return (MBeanAttributeInfo[])
        attributes.values().toArray(new MBeanAttributeInfo[attributes.size()]);
  }
 /**
  * Subclasses could provide here a different description for the given counter.
  *
  * @param oname
  * @param ainfo
  * @return
  */
 protected String[] getCounterNameAndDescription(ObjectName oname, MBeanAttributeInfo ainfo) {
   return new String[] {ainfo.getName(), ainfo.getDescription()};
 }