package org.infinispan.objectfilter.impl;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.infinispan.objectfilter.FilterCallback;
import org.infinispan.objectfilter.FilterSubscription;
import org.infinispan.objectfilter.SortField;
import org.infinispan.objectfilter.impl.predicateindex.PredicateIndex;
import org.infinispan.objectfilter.impl.predicateindex.Predicates;
import org.infinispan.objectfilter.impl.predicateindex.be.BENode;
import org.infinispan.objectfilter.impl.predicateindex.be.BETree;
import org.infinispan.objectfilter.impl.predicateindex.be.PredicateNode;
import org.infinispan.objectfilter.impl.util.ComparableArrayComparator;
/**
* @author anistor@redhat.com
* @since 7.0
*/
public final class FilterSubscriptionImpl<TypeMetadata, AttributeMetadata, AttributeId extends Comparable<AttributeId>> implements FilterSubscription {
private final String queryString;
private final Map<String, Object> namedParameters;
private final boolean useIntervals;
public int index = -1; // todo [anistor] hide this
private final MetadataAdapter<TypeMetadata, AttributeMetadata, AttributeId> metadataAdapter;
private final BETree beTree;
private final List<Predicates.Subscription<AttributeId>> predicateSubscriptions = new ArrayList<>();
private final FilterCallback callback;
private final boolean isDeltaFilter;
private final String[] projection;
private final Class<?>[] projectionTypes;
private final List<List<AttributeId>> translatedProjection;
private final SortField[] sortFields;
private final List<List<AttributeId>> translatedSortProjection;
private final Object[] eventTypes;
private Comparator<Comparable[]> comparator;
protected FilterSubscriptionImpl(String queryString, Map<String, Object> namedParameters,
boolean useIntervals, MetadataAdapter<TypeMetadata, AttributeMetadata, AttributeId> metadataAdapter,
BETree beTree, FilterCallback callback, boolean isDeltaFilter,
String[] projection, Class<?>[] projectionTypes, List<List<AttributeId>> translatedProjection,
SortField[] sortFields, List<List<AttributeId>> translatedSortProjection,
Object[] eventTypes) {
this.queryString = queryString;
this.namedParameters = namedParameters;
this.useIntervals = useIntervals;
this.metadataAdapter = metadataAdapter;
this.beTree = beTree;
this.callback = callback;
this.isDeltaFilter = isDeltaFilter;
this.projection = projection;
this.projectionTypes = projectionTypes;
this.sortFields = sortFields;
this.translatedProjection = translatedProjection;
this.translatedSortProjection = translatedSortProjection;
this.eventTypes = eventTypes;
}
public String getQueryString() {
return queryString;
}
public Map<String, Object> getNamedParameters() {
return namedParameters;
}
public boolean useIntervals() {
return useIntervals;
}
public BETree getBETree() {
return beTree;
}
@Override
public String getEntityTypeName() {
return metadataAdapter.getTypeName();
}
public MetadataAdapter<TypeMetadata, AttributeMetadata, AttributeId> getMetadataAdapter() {
return metadataAdapter;
}
@Override
public FilterCallback getCallback() {
return callback;
}
@Override
public boolean isDeltaFilter() {
return isDeltaFilter;
}
@Override
public String[] getProjection() {
return projection;
}
public Class<?>[] getProjectionTypes() {
return projectionTypes;
}
@Override
public SortField[] getSortFields() {
return sortFields;
}
@Override
public Comparator<Comparable[]> getComparator() {
if (sortFields != null && comparator == null) {
boolean[] direction = new boolean[sortFields.length];
for (int i = 0; i < sortFields.length; i++) {
direction[i] = sortFields[i].isAscending();
}
comparator = new ComparableArrayComparator(direction);
}
return comparator;
}
@Override
public Object[] getEventTypes() {
return eventTypes;
}
public void registerProjection(PredicateIndex<AttributeMetadata, AttributeId> predicateIndex) {
int i = 0;
if (translatedProjection != null) {
i = predicateIndex.addProjections(this, translatedProjection, i);
}
if (translatedSortProjection != null) {
predicateIndex.addProjections(this, translatedSortProjection, i);
}
}
public void unregisterProjection(PredicateIndex<AttributeMetadata, AttributeId> predicateIndex) {
if (translatedProjection != null) {
predicateIndex.removeProjections(this, translatedProjection);
}
if (translatedSortProjection != null) {
predicateIndex.removeProjections(this, translatedSortProjection);
}
}
public void subscribe(PredicateIndex<AttributeMetadata, AttributeId> predicateIndex) {
for (BENode node : beTree.getNodes()) {
if (node instanceof PredicateNode) {
PredicateNode<AttributeId> predicateNode = (PredicateNode<AttributeId>) node;
predicateSubscriptions.add(predicateIndex.addSubscriptionForPredicate(predicateNode, this));
}
}
}
public void unsubscribe(PredicateIndex<AttributeMetadata, AttributeId> predicateIndex) {
for (Predicates.Subscription<AttributeId> subscription : predicateSubscriptions) {
predicateIndex.removeSubscriptionForPredicate(subscription);
}
}
}