/**
*
*/
package br.com.caelum.iogi.collections;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import br.com.caelum.iogi.parameters.Parameter;
import br.com.caelum.iogi.parameters.Parameters;
import br.com.caelum.iogi.reflection.Target;
import com.google.common.base.Function;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;
class ParametersByIndex {
private static final Pattern firstComponentPattern = Pattern.compile("[^\\[]+\\[(\\d+)\\]");
private static final Function<Parameter, Integer> EXTRACT_INDEX_OR_RETURN_NEGATIVE = new Function<Parameter, Integer>() {
public Integer apply(Parameter parameter) {
final Matcher matcher = firstComponentPattern.matcher(parameter.getFirstNameComponentWithDecoration());
return matcher.find() ? Integer.valueOf(matcher.group(1)) : -1;
}
};
private final ListMultimap<Integer, Parameter> firstComponentToParameterMap;
public ParametersByIndex(final Parameters parameters, final Target<?> target) {
this.firstComponentToParameterMap = groupByIndex(parameters, target);
}
private ListMultimap<Integer, Parameter> groupByIndex(final Parameters parameters, final Target<?> target) {
final List<Parameter> relevant = parameters.forTarget(target);
final List<Parameter> sorted = Ordering.natural().onResultOf(EXTRACT_INDEX_OR_RETURN_NEGATIVE).sortedCopy(relevant);
final ListMultimap<Integer, Parameter> map = LinkedListMultimap.create();
for (final Parameter parameter : sorted) {
final Integer index = EXTRACT_INDEX_OR_RETURN_NEGATIVE.apply(parameter);
if (index >= 0)
map.put(index, parameter);
}
return Multimaps.unmodifiableListMultimap(map);
}
public Collection<Integer> indexes() {
return firstComponentToParameterMap.keySet();
}
public boolean isEmpty() {
return firstComponentToParameterMap.isEmpty();
}
public Parameters at(final int index) {
return new Parameters(firstComponentToParameterMap.get(index));
}
public int count() {
return firstComponentToParameterMap.values().size();
}
}