blob: f1d9c6b747e7d88dba1aaa6474e7623c54a40a79 [file] [log] [blame]
/*
*
* 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.qpid.server.model;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.qpid.server.util.ServerScopedRuntimeException;
final public class ConfiguredObjectInjectedStatistic<C extends ConfiguredObject, T extends Number>
extends ConfiguredObjectInjectedAttributeOrStatistic<C, T> implements ConfiguredObjectStatistic<C, T>
{
private static final Logger LOGGER = LoggerFactory.getLogger(ConfiguredObjectInjectedStatistic.class);
private final String _description;
private final Method _method;
private final StatisticUnit _units;
private final StatisticType _type;
private final String _label;
private final Object[] _staticParams;
private final String _metricName;
private final boolean _metricDisabled;
public ConfiguredObjectInjectedStatistic(final String name,
final Method method,
final Object[] staticParams,
final String description,
final TypeValidator typeValidator,
final StatisticUnit units,
final StatisticType type,
final String label,
final String metricName,
final boolean metricDisabled)
{
super(name,
(Class<T>) AttributeValueConverter.getTypeFromMethod(method), method.getGenericReturnType(), typeValidator);
_units = units;
_type = type;
_label = label;
_staticParams = staticParams == null ? new Object[0] : staticParams;
_metricName = metricName;
_metricDisabled = metricDisabled;
if(!(method.getParameterTypes().length == 1 + _staticParams.length
&& ConfiguredObject.class.isAssignableFrom(method.getParameterTypes()[0])
&& Modifier.isStatic(method.getModifiers())
&& Number.class.isAssignableFrom(AttributeValueConverter.getTypeFromMethod(method))))
{
throw new IllegalArgumentException("Injected statistic method must be static, have first argument which inherits from ConfiguredObject, and return a Number");
}
final Class<?>[] methodParamTypes = method.getParameterTypes();
for(int i = 0; i < _staticParams.length; i++)
{
if(methodParamTypes[i+1].isPrimitive() && _staticParams[i] == null)
{
throw new IllegalArgumentException("Static parameter has null value, but the " + methodParamTypes[i+1].getSimpleName() + " type is a primitive");
}
if(!AttributeValueConverter.convertPrimitiveToBoxed(methodParamTypes[i+1]).isAssignableFrom(_staticParams[i].getClass()))
{
throw new IllegalArgumentException("Static parameter cannot be assigned value as it is of incompatible type");
}
}
_method = method;
method.setAccessible(true);
_description = description;
}
@Override
public String getDescription()
{
return _description;
}
@Override
public StatisticUnit getUnits()
{
return _units;
}
@Override
public StatisticType getStatisticType()
{
return _type;
}
@Override
public String getLabel()
{
return _label;
}
@Override
public T getValue(final C configuredObject)
{
try
{
Object[] params = new Object[1+_staticParams.length];
params[0] = configuredObject;
for(int i = 0; i < _staticParams.length; i++)
{
params[i+1] = _staticParams[i];
}
return (T) _method.invoke(null, params);
}
catch (IllegalAccessException e)
{
throw new ServerScopedRuntimeException("Unable to get value for '"+getName()
+"' from configured object of category "
+ configuredObject.getCategoryClass().getSimpleName(), e);
}
catch (InvocationTargetException e)
{
Throwable targetException = e.getTargetException();
if(targetException instanceof RuntimeException)
{
throw (RuntimeException)targetException;
}
else if(targetException instanceof Error)
{
throw (Error)targetException;
}
else
{
// This should never happen as it would imply a getter which is declaring a checked exception
throw new ServerScopedRuntimeException("Unable to get value for '"+getName()
+"' from configured object of category "
+ configuredObject.getCategoryClass().getSimpleName(), e);
}
}
}
@Override
public String getMetricName()
{
return _metricName;
}
@Override
public boolean isMetricDisabled()
{
return _metricDisabled;
}
}