package org.sigmah.shared.util;
/*
* #%L
* Sigmah
* %%
* Copyright (C) 2010 - 2016 URD
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.sigmah.client.util.ClientUtils;
import org.sigmah.client.util.ToStringBuilder;
import org.sigmah.shared.dto.referential.DimensionType;
/**
* <p>
* Defines a filter of activity data as a date range and a set of restrictions on {@code Dimensions}.
* </p>
* <p>
* A server-side version of this class exists for XML manipulations, see {@link org.sigmah.server.report.model.Filter}.
* </p>
*
* @author Alexander Bertram (akbertram@gmail.com)
* @author Denis Colliot (dcolliot@ideia.fr) v2.0
*/
public class Filter implements Serializable {
// TODO: should be restrictions on DIMENSIONS and not DimensionTypes!!
/**
* Serial version UID.
*/
private static final long serialVersionUID = 1723797257472204799L;
/**
* The filter restrictions.
*/
// Should not be 'final' due to GWT RPC serialization policy.
private Map<DimensionType, Set<Integer>> restrictions = new HashMap<DimensionType, Set<Integer>>();
/**
* The filter dates range.
*/
private DateRange dateRange = new DateRange();
/**
* Constructs a <code>Filter</code> with no restrictions. All data visible to the user will be included.
*/
public Filter() {
// Serialization.
}
/**
* Constructs a copy of the given <code>filter</code>
*
* @param filter
* The filter which to copy.
*/
public Filter(final Filter filter) {
for (final Map.Entry<DimensionType, Set<Integer>> entry : filter.restrictions.entrySet()) {
this.restrictions.put(entry.getKey(), new HashSet<Integer>(entry.getValue()));
}
this.dateRange = new DateRange(filter.dateRange);
}
/**
* Constructs a <code>Filter</code> as the intersection between two <code>Filter</code>s.
*
* @param a
* The first filter
* @param b
* The second filter
*/
public Filter(final Filter a, final Filter b) {
final Set<DimensionType> types = new HashSet<DimensionType>();
types.addAll(a.restrictions.keySet());
types.addAll(b.restrictions.keySet());
for (final DimensionType type : types) {
this.restrictions.put(type, ClientUtils.intersect(a.getRestrictionSet(type, false), b.getRestrictionSet(type, false)));
}
this.dateRange = DateRange.intersection(a.getDateRange(), b.getDateRange());
}
public DateRange getDateRange() {
if (dateRange == null) {
dateRange = new DateRange();
}
return dateRange;
}
public void setDateRange(DateRange range) {
this.dateRange = range;
}
public Map<DimensionType, Set<Integer>> getRestrictions() {
return restrictions;
}
public void setRestrictions(Map<DimensionType, Set<Integer>> restrictions) {
this.restrictions = restrictions;
}
public Set<Integer> getRestrictions(DimensionType type) {
return getRestrictionSet(type, false);
}
private Set<Integer> getRestrictionSet(DimensionType type, boolean create) {
Set<Integer> set = restrictions.get(type);
if (set == null) {
if (!create) {
return Collections.emptySet();
}
set = new HashSet<Integer>();
restrictions.put(type, set);
}
return set;
}
public void addRestriction(DimensionType type, int categoryId) {
Set<Integer> set = getRestrictionSet(type, true);
set.add(categoryId);
}
public void addRestriction(DimensionType type, Collection<Integer> categoryIds) {
Set<Integer> set = getRestrictionSet(type, true);
set.addAll(categoryIds);
}
public void clearRestrictions(DimensionType type) {
restrictions.remove(type);
}
public boolean isRestricted(DimensionType type) {
return restrictions.containsKey(type);
}
public boolean isDateRestricted() {
return dateRange.getMinDate() != null || dateRange.getMaxDate() != null;
}
public Set<DimensionType> getRestrictedDimensions() {
return new HashSet<DimensionType>(restrictions.keySet());
}
public Date getMinDate() {
return getDateRange().getMinDate();
}
public void setMinDate(Date minDate) {
getDateRange().setMinDate(minDate);
}
public Date getMaxDate() {
return getDateRange().getMaxDate();
}
public void setMaxDate(Date maxDate) {
getDateRange().setMaxDate(maxDate);
}
public Filter onActivity(int activityId) {
addRestriction(DimensionType.Activity, activityId);
return this;
}
public Filter onSite(int siteId) {
addRestriction(DimensionType.Site, siteId);
return this;
}
public static Filter filter() {
return new Filter();
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
final ToStringBuilder builder = new ToStringBuilder(this);
builder.append("types", getRestrictedDimensions());
builder.append("dateRange", dateRange);
return builder.toString();
}
}