/***********************************************************************************
* Copyright (c) 2013. Nickolay Gerilovich. Russia.
* Some Rights Reserved.
************************************************************************************/
package com.github.nickvl.xspring.core.log.aop;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.BitSet;
import org.springframework.core.ParameterNameDiscoverer;
import com.github.nickvl.xspring.core.log.aop.annotation.Lp;
/**
* Method arguments descriptor.
*/
final class ArgumentDescriptor {
private final BitSet loggedValueIndexes;
private final String[] names;
private ArgumentDescriptor(BitSet loggedValueIndexes, String[] names) {
this.loggedValueIndexes = loggedValueIndexes;
this.names = names;
}
public int nextArgumentIndex(int i) {
return loggedValueIndexes.nextSetBit(i);
}
public boolean isArgumentIndex(int i) {
return loggedValueIndexes.get(i);
}
/**
* Gets names of method parameters.
*
* @return all parameter names or <code>null</code> if the method has no parameters or the names can not be discovered
*/
public String[] getNames() {
return names;
}
/**
* Builder.
*/
public static final class Builder {
private static final ArgumentDescriptor NO_ARGUMENTS_DESCRIPTOR = new ArgumentDescriptor(new BitSet(0), null);
private final Method method;
private final int argumentCount;
private final ParameterNameDiscoverer parameterNameDiscoverer;
public Builder(Method method, int argumentCount, ParameterNameDiscoverer parameterNameDiscoverer) {
this.method = method;
this.argumentCount = argumentCount;
this.parameterNameDiscoverer = parameterNameDiscoverer;
}
public ArgumentDescriptor build() {
if (argumentCount == 0) {
return NO_ARGUMENTS_DESCRIPTOR;
}
String[] argNames = parameterNameDiscoverer.getParameterNames(method);
BitSet lpParameters = getMethodParameters(Lp.class);
if (lpParameters.isEmpty()) {
lpParameters.set(0, argumentCount);
}
return new ArgumentDescriptor(lpParameters, argNames);
}
private <T> BitSet getMethodParameters(Class<T> annotationMarker) {
Annotation[][] annotations = method.getParameterAnnotations();
BitSet result = new BitSet(annotations.length);
for (int i = 0; i < annotations.length; i++) {
Annotation[] paramAnnotations = annotations[i];
for (Annotation currAnnotation : paramAnnotations) {
if (currAnnotation.annotationType().equals(annotationMarker)) {
result.set(i);
}
}
}
return result;
}
}
}