/**
* Copyright © 2013 Antonin Stefanutti (antonin.stefanutti@gmail.com)
*
* Licensed 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 io.astefanutti.metrics.cdi;
import javax.el.ArrayELResolver;
import javax.el.BeanELResolver;
import javax.el.CompositeELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.el.FunctionMapper;
import javax.el.ListELResolver;
import javax.el.MapELResolver;
import javax.el.ResourceBundleELResolver;
import javax.el.ValueExpression;
import javax.el.VariableMapper;
import javax.enterprise.inject.Vetoed;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Vetoed
/* package-private */ final class ElMetricName extends SeMetricName {
private static final Pattern PATTERN = Pattern.compile("[#|$]\\{(.*)\\}");
private final ELResolver elResolver;
private final ExpressionFactory expressionFactory;
ElMetricName(ELResolver resolver, ExpressionFactory expressionFactory, Set<MetricsParameter> parameters) {
super(parameters);
CompositeELResolver composite = new CompositeELResolver();
composite.add(resolver);
composite.add(new MapELResolver());
composite.add(new ListELResolver());
composite.add(new ArrayELResolver());
composite.add(new ResourceBundleELResolver());
composite.add(new BeanELResolver(true));
this.elResolver = composite;
this.expressionFactory = expressionFactory;
}
@Override
public String of(String attribute) {
Matcher matcher = PATTERN.matcher(attribute);
// Avoid creating objects if no expressions are found
if (!matcher.find())
return super.of(attribute);
else
return evaluateCompositeExpression(matcher);
}
private String evaluateCompositeExpression(Matcher matcher) {
StringBuffer buffer = new StringBuffer();
do {
String result = evaluateExpression(matcher.group());
matcher.appendReplacement(buffer, result != null ? result : "");
} while (matcher.find());
matcher.appendTail(buffer);
return buffer.toString();
}
private String evaluateExpression(String name) {
ELContext context = createELContext(elResolver, new FunctionMapper() {
@Override
public Method resolveFunction(String prefix, String localName) {
return null;
}
}, new VariableMapper() {
@Override
public ValueExpression resolveVariable(String variable) {
return null;
}
@Override
public ValueExpression setVariable(String variable, ValueExpression expression) {
return null;
}
});
return (String) expressionFactory.createValueExpression(context, name, String.class).getValue(context);
}
private ELContext createELContext(final ELResolver resolver, final FunctionMapper functionMapper, final VariableMapper variableMapper) {
return new ELContext() {
@Override
public ELResolver getELResolver() {
return resolver;
}
@Override
public FunctionMapper getFunctionMapper() {
return functionMapper;
}
@Override
public VariableMapper getVariableMapper() {
return variableMapper;
}
};
}
}