MetricsHelper.java
// Copyright (c) ZeroC, Inc.
package com.zeroc.IceMX;
import com.zeroc.Ice.ConnectionInfo;
import com.zeroc.Ice.EndpointInfo;
import java.util.HashMap;
import java.util.Map;
/**
* Helper class for metrics operations.
*
* @param <T> the metrics type
*/
public class MetricsHelper<T> {
/**
* Resolves attribute values from metrics objects.
*/
public static class AttributeResolver {
private abstract class Resolver {
abstract Object resolve(Object obj) throws Exception;
String resolveImpl(Object obj) {
try {
Object result = resolve(obj);
if (result != null) {
return result.toString();
}
return "";
} catch (IllegalArgumentException ex) {
throw ex;
} catch (Exception ex) {
ex.printStackTrace();
assert false;
return null;
}
}
}
/**
* Constructs an AttributeResolver.
*/
protected AttributeResolver() {}
/**
* Resolves an attribute value using the specified helper.
*
* @param helper the metrics helper
* @param attribute the attribute name to resolve
* @return the resolved attribute value
* @throws IllegalArgumentException if the attribute is unknown
*/
public String resolve(MetricsHelper<?> helper, String attribute) {
Resolver resolver = _attributes.get(attribute);
if (resolver == null) {
if ("none".equals(attribute)) {
return "";
}
String v = helper.defaultResolve(attribute);
if (v != null) {
return v;
}
throw new IllegalArgumentException(attribute);
}
return resolver.resolveImpl(helper);
}
/**
* Adds an attribute resolver using a method.
*
* @param name the attribute name
* @param method the method to invoke for resolution
*/
public void add(final String name, final java.lang.reflect.Method method) {
_attributes.put(
name,
new Resolver() {
@Override
public Object resolve(Object obj) throws Exception {
return method.invoke(obj);
}
});
}
/**
* Adds an attribute resolver using a field.
*
* @param name the attribute name
* @param field the field to access for resolution
*/
public void add(final String name, final java.lang.reflect.Field field) {
_attributes.put(
name,
new Resolver() {
@Override
public Object resolve(Object obj) throws Exception {
return getField(name, field, obj);
}
});
}
/**
* Adds an attribute resolver using a method and field combination.
*
* @param name the attribute name
* @param method the method to invoke first
* @param field the field to access on the method result
*/
public void add(
final String name,
final java.lang.reflect.Method method,
final java.lang.reflect.Field field) {
_attributes.put(
name,
new Resolver() {
@Override
public Object resolve(Object obj) throws Exception {
return getField(name, field, method.invoke(obj));
}
});
}
/**
* Adds an attribute resolver using two chained methods.
*
* @param name the attribute name
* @param method the first method to invoke
* @param subMethod the second method to invoke on the first method's result
*/
public void add(
final String name,
final java.lang.reflect.Method method,
final java.lang.reflect.Method subMethod) {
_attributes.put(
name,
new Resolver() {
@Override
public Object resolve(Object obj) throws Exception {
Object o = method.invoke(obj);
if (o != null) {
return subMethod.invoke(o);
}
throw new IllegalArgumentException(name);
}
});
}
private Object getField(String name, java.lang.reflect.Field field, Object o)
throws IllegalArgumentException, IllegalAccessException {
while (o != null) {
try {
return field.get(o);
} catch (IllegalArgumentException ex) {
// If we're dealing with an endpoint/connection information class,
// check if the field is from the underlying info objects.
if (o instanceof EndpointInfo) {
o = ((EndpointInfo) o).underlying;
} else if (o instanceof ConnectionInfo) {
o = ((ConnectionInfo) o).underlying;
} else {
throw ex;
}
}
}
throw new IllegalArgumentException(name);
}
private Map<String, Resolver> _attributes = new HashMap<>();
}
/**
* Constructs a MetricsHelper with the specified attribute resolver.
*
* @param attributes the attribute resolver to use
*/
protected MetricsHelper(AttributeResolver attributes) {
_attributes = attributes;
}
/**
* Resolves an attribute value.
*
* @param attribute the attribute name to resolve
* @return the resolved attribute value
* @throws IllegalArgumentException if the attribute is unknown
*/
public String resolve(String attribute) {
return _attributes.resolve(this, attribute);
}
/**
* Initializes the metrics object.
*
* @param metrics the metrics object to initialize
*/
public void initMetrics(T metrics) {
// Override in specialized helpers.
}
/**
* Provides default resolution for unknown attributes.
*
* @param attribute the attribute name
* @return the default value, or null if no default is available
*/
protected String defaultResolve(String attribute) {
return null;
}
private final AttributeResolver _attributes;
}