package org.jboss.resteasy.core;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import javax.ws.rs.core.MultivaluedMap;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Abstract implementation of {@link NestedFormInjector} that can inject collections.
*
* @param <T> The type of collection that will be created.
*/
public abstract class AbstractCollectionFormInjector<T> extends PrefixedFormInjector
{
private final Class collectionType;
private final Pattern pattern;
/**
* Creates an injector to inject a collection.
*
* @param collectionType The type of collection to return.
* @param genericType The type of elements in the collection.
* @param pattern The pattern that a field name should follow to be a part of this collection. The first group in the pattern must be the index.
*/
protected AbstractCollectionFormInjector(Class collectionType, Class genericType, String prefix, Pattern pattern, ResteasyProviderFactory factory)
{
super(genericType, prefix, factory);
this.collectionType = collectionType;
this.pattern = pattern;
}
/**
* {@inheritDoc} Creates a collection instance and fills it with content by using the super implementation.
*/
@Override
public Object inject(HttpRequest request, HttpResponse response)
{
T result = createInstance(collectionType);
for (String collectionPrefix : findMatchingPrefixesWithNoneEmptyValues(request.getDecodedFormParameters()))
{
Matcher matcher = pattern.matcher(collectionPrefix);
matcher.matches();
String key = matcher.group(1);
addTo(result, key, super.doInject(collectionPrefix, request, response));
}
return result;
}
/**
* Finds all field names that follow the pattern.
*/
private Set<String> findMatchingPrefixesWithNoneEmptyValues(MultivaluedMap<String, String> parameters)
{
final HashSet<String> result = new HashSet<String>();
for (String parameterName : parameters.keySet())
{
final Matcher matcher = pattern.matcher(parameterName);
if (matcher.lookingAt() && hasValue(parameters.get(parameterName)))
{
result.add(matcher.group(0));
}
}
return result;
}
/**
* Creates an instance of the collection type.
*/
protected abstract T createInstance(Class collectionType);
/**
* Adds the item to the collection.
*/
protected abstract void addTo(T collection, String key, Object value);
}