/* Copyright (c) 2013 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Johnathan Garrett (LMN Solutions) - initial implementation
*/
package org.locationtech.geogig.api;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.geotools.filter.text.cql2.CQL;
import org.geotools.filter.text.cql2.CQLException;
import org.locationtech.geogig.api.RevObject.TYPE;
import org.opengis.feature.Feature;
import org.opengis.filter.Filter;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
/**
* Provides a filter for sparse repositories. A default filter can be applied to all feature types,
* and specific filters can be applied to individual feature types.
*/
public class RepositoryFilter {
private Map<String, Filter> repositoryFilters;
private List<FilterDescription> filterDescriptions;
/**
* Provides a text description of a particular filter.
*/
public class FilterDescription {
private String featurePath;
private String filterType;
private String filter;
/**
* Constructs a new {@code FilterDescription} with the provided values.
*
* @param featurePath the path of the features this filter applies to, use "default" as a
* fall back filter
* @param filterType the type of filter, for example "CQL"
* @param filter the filter text
*/
public FilterDescription(String featurePath, String filterType, String filter) {
this.featurePath = featurePath;
this.filterType = filterType;
this.filter = filter;
}
/**
* @return the path of the features this filter applies to
*/
public String getFeaturePath() {
return featurePath;
}
/**
* @return the format of the filter
*/
public String getFilterType() {
return filterType;
}
/**
* @return the filter in string form
*/
public String getFilter() {
return filter;
}
}
/**
* Constructs a new {@code RepositoryFilter}.
*/
public RepositoryFilter() {
repositoryFilters = new HashMap<String, Filter>();
filterDescriptions = new LinkedList<FilterDescription>();
}
/**
* @return an immutable copy of the filter descriptions
*/
public ImmutableList<FilterDescription> getFilterDescriptions() {
return ImmutableList.copyOf(filterDescriptions);
}
/**
* Adds a new filter to the repository.
*
* @param featurePath the path of the features to filter, "default" for a fall back filter
* @param filterType the format of the filter text, for example "CQL"
* @param filterText the filter text
*/
public void addFilter(String featurePath, String filterType, String filterText) {
Preconditions.checkState(featurePath != null && filterType != null && filterText != null,
"Missing filter parameter.");
if (filterType.equals("CQL")) {
try {
Filter newFilter = CQL.toFilter(filterText);
repositoryFilters.put(featurePath, newFilter);
filterDescriptions.add(new FilterDescription(featurePath, filterType, filterText));
} catch (CQLException e) {
Throwables.propagate(e);
}
}
}
/**
* Determines if the provided object is filtered in this repository.
*
* @param type the feature type
* @param featurePath the path of the feature (without the feature ID)
* @param object the object to filter
* @return true if the object lies within the filter, false otherwise
*/
public boolean filterObject(RevFeatureType type, String featurePath, RevObject object) {
if (object.getType() == TYPE.FEATURE) {
RevFeature revFeature = (RevFeature) object;
FeatureBuilder builder = new FeatureBuilder(type);
Feature feature = builder.build("TEMP_ID", revFeature);
Filter typeFilter = repositoryFilters.get(featurePath);
if (typeFilter == null) {
typeFilter = repositoryFilters.get("default");
}
if (typeFilter.evaluate(feature)) {
return true;
}
}
return false;
}
}