package org.infinispan.objectfilter.impl;
import java.beans.IntrospectionException;
import java.util.List;
import org.infinispan.objectfilter.impl.predicateindex.ReflectionMatcherEvalContext;
import org.infinispan.objectfilter.impl.syntax.parser.EntityNameResolver;
import org.infinispan.objectfilter.impl.syntax.parser.ObjectPropertyHelper;
import org.infinispan.objectfilter.impl.syntax.parser.ReflectionEntityNamesResolver;
import org.infinispan.objectfilter.impl.syntax.parser.ReflectionPropertyHelper;
import org.infinispan.objectfilter.impl.util.ReflectionHelper;
/**
* @author anistor@redhat.com
* @since 7.0
*/
public class ReflectionMatcher extends BaseMatcher<Class<?>, ReflectionHelper.PropertyAccessor, String> {
public ReflectionMatcher(ObjectPropertyHelper<Class<?>> propertyHelper) {
super(propertyHelper);
}
public ReflectionMatcher(ClassLoader classLoader) {
this(new ReflectionEntityNamesResolver(classLoader));
}
public ReflectionMatcher(EntityNameResolver entityNameResolver) {
super(new ReflectionPropertyHelper(entityNameResolver));
}
@Override
protected ReflectionMatcherEvalContext startMultiTypeContext(boolean isDeltaFilter, Object userContext, Object eventType, Object instance) {
FilterRegistry<Class<?>, ReflectionHelper.PropertyAccessor, String> filterRegistry = getFilterRegistryForType(isDeltaFilter, instance.getClass());
if (filterRegistry != null) {
ReflectionMatcherEvalContext context = new ReflectionMatcherEvalContext(userContext, eventType, instance);
context.initMultiFilterContext(filterRegistry);
return context;
}
return null;
}
@Override
protected ReflectionMatcherEvalContext startSingleTypeContext(Object userContext, Object eventType, Object instance, MetadataAdapter<Class<?>, ReflectionHelper.PropertyAccessor, String> metadataAdapter) {
if (metadataAdapter.getTypeMetadata() == instance.getClass()) {
return new ReflectionMatcherEvalContext(userContext, eventType, instance);
} else {
return null;
}
}
@Override
protected MetadataAdapter<Class<?>, ReflectionHelper.PropertyAccessor, String> createMetadataAdapter(Class<?> clazz) {
return new MetadataAdapterImpl(clazz, propertyHelper);
}
private static class MetadataAdapterImpl implements MetadataAdapter<Class<?>, ReflectionHelper.PropertyAccessor, String> {
private final Class<?> clazz;
private final ObjectPropertyHelper<Class<?>> propertyHelper;
MetadataAdapterImpl(Class<?> clazz, ObjectPropertyHelper<Class<?>> propertyHelper) {
this.clazz = clazz;
this.propertyHelper = propertyHelper;
}
@Override
public String getTypeName() {
return clazz.getName();
}
@Override
public Class<?> getTypeMetadata() {
return clazz;
}
@Override
public List<String> mapPropertyNamePathToFieldIdPath(String[] path) {
return (List<String>) propertyHelper.mapPropertyNamePathToFieldIdPath(clazz, path);
}
@Override
public ReflectionHelper.PropertyAccessor makeChildAttributeMetadata(ReflectionHelper.PropertyAccessor parentAttributeMetadata, String attribute) {
try {
return parentAttributeMetadata == null ?
ReflectionHelper.getAccessor(clazz, attribute) : parentAttributeMetadata.getAccessor(attribute);
} catch (IntrospectionException e) {
return null;
}
}
@Override
public boolean isComparableProperty(ReflectionHelper.PropertyAccessor attributeMetadata) {
Class<?> propertyType = attributeMetadata.getPropertyType();
return propertyType != null && (propertyType.isPrimitive() || Comparable.class.isAssignableFrom(propertyType));
}
}
}