package org.solrmarc.index.mapping.impl;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.solrmarc.index.extractor.methodcall.AbstractMappingMethodCall;
import org.solrmarc.index.extractor.methodcall.MethodCallContext;
import org.solrmarc.index.extractor.methodcall.MethodCallManager;
import org.solrmarc.index.extractor.methodcall.MultiValueMappingMethodCall;
import org.solrmarc.index.extractor.methodcall.SingleValueMappingMethodCall;
import org.solrmarc.index.indexer.IndexerSpecException;
import org.solrmarc.index.mapping.AbstractMultiValueMapping;
import org.solrmarc.index.mapping.AbstractValueMappingFactory;
public class MethodCallMappingFactory extends AbstractValueMappingFactory
{
protected final MethodCallManager methodCallManager;
private final static Pattern mapShortcut1 = Pattern.compile("(map|filter)[A-Za-z0-9]+");
private final static Pattern mapShortcut2 = Pattern.compile("(([a-z]+[.])*[A-Z][A-Za-z0-9_]*)::((map|filter)[A-Za-z0-9]+)");
public MethodCallMappingFactory()
{
this(MethodCallManager.instance());
}
public MethodCallMappingFactory(final MethodCallManager methodCallManager)
{
this.methodCallManager = methodCallManager;
}
public void addMethodsFromClasses(Collection<Class<?>> classes)
{
try
{
for (final Class<?> aClass : classes)
{
methodCallManager.add(aClass.newInstance());
}
}
catch (InstantiationException | IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
@Override
public boolean canHandle(String mappingConfiguration)
{
return (mappingConfiguration.startsWith("custom_map") ||
mapShortcut1.matcher(mappingConfiguration).matches() ||
mapShortcut2.matcher(mappingConfiguration).matches());
}
private AbstractMultiValueMapping createMultiValueMapping(MethodCallContext context)
{
final AbstractMappingMethodCall<?> methodCall = methodCallManager.getMappingMethodCallForContext(context);
if (methodCall instanceof MultiValueMappingMethodCall)
{
return new MethodCallMultiValueMapping((MultiValueMappingMethodCall) methodCall, context.getParameters());
}
else if (methodCall instanceof SingleValueMappingMethodCall)
{
return new MethodCallSingleValueMapping((SingleValueMappingMethodCall) methodCall, context.getParameters());
}
else
{
throw new IndexerSpecException("Unknown custom mapping method: " + context.toString()
+ " -- Known methods are: \n" + methodCallManager.loadedMappingMixinsToString());
}
}
@Override
public AbstractMultiValueMapping createMultiValueMapping(String mappingConfiguration)
{
// method unused, but must be present
return null;
}
@Override
public AbstractMultiValueMapping createMultiValueMapping(String[] mapParts)
{
MethodCallContext context;
Matcher shortcut1 = mapShortcut1.matcher(mapParts[0]);
Matcher shortcut2 = mapShortcut2.matcher(mapParts[0]);
if (shortcut1.matches())
{
String[] extraParts = new String[mapParts.length+2];
extraParts[0] = "custom_map";
extraParts[1] = null;
System.arraycopy(mapParts, 0, extraParts, 2, mapParts.length);
context = MethodCallContext.parseContextFromMapParts(extraParts);
}
else if (shortcut2.matches())
{
String[] extraParts = new String[mapParts.length+2];
extraParts[0] = "custom_map";
extraParts[1] = shortcut2.group(1);
extraParts[2] = shortcut2.group(3);
System.arraycopy(mapParts, 1, extraParts, 3, mapParts.length-1);
context = MethodCallContext.parseContextFromMapParts(extraParts);
}
else
{
context = MethodCallContext.parseContextFromMapParts(mapParts);
}
return createMultiValueMapping(context);
}
}