blob: c176ade089767254afe8d518e9fa8a4b9ba11a98 [file] [log] [blame]
/**
* Copyright 2009-2013 Oy Vaadin Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eclipse.osbp.dsl.dto.lib.services.filters;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Path;
/**
* Helper class that implements the filtering methods defined in
* {@link LAdvancedFilterable} and can be either extended or used as a delegate.
*
* @author Petter Holmström (Vaadin Ltd)
* @since 1.0
*/
public class LAdvancedFilterableSupport implements LAdvancedFilterable,
Serializable {
private static final long serialVersionUID = 398382431841547719L;
/**
* ApplyFiltersListener interface to be implemented by classes that want to
* be notified when the filters are applied.
*
* @author Petter Holmström (Vaadin Ltd)
* @since 1.0
*/
public static interface ApplyFiltersListener extends Serializable {
/**
* Called when the filters have been applied.
*
* @param sender
* the sender of the event.
*/
public void filtersApplied(LAdvancedFilterableSupport sender);
}
/**
* Adds <code>listener</code> to the list of listeners to be notified when
* the filters are applied. The listener will be notified as many times as
* it has been added.
*
* @param listener
* the listener to add (must not be null).
*/
public void addListener(ApplyFiltersListener listener) {
assert listener != null : "listener must not be null";
listeners.add(listener);
}
/**
* Removes <code>listener</code> from the list of listeners. If the listener
* has been added more than once, it will be notified one less time. If the
* listener has not been added at all, nothing happens.
*
* @param listener
* the listener to remove (must not be null).
*/
public void removeListener(ApplyFiltersListener listener) {
assert listener != null : "listener must not be null";
listeners.remove(listener);
}
@SuppressWarnings("unchecked")
protected void fireListeners() {
LinkedList<ApplyFiltersListener> listenerList = (LinkedList<ApplyFiltersListener>) listeners
.clone();
for (ApplyFiltersListener l : listenerList) {
l.filtersApplied(this);
}
}
private Collection<Object> filterablePropertyIds;
private LinkedList<ApplyFiltersListener> listeners = new LinkedList<ApplyFiltersListener>();
private LinkedList<ILFilter> appliedFilters = new LinkedList<ILFilter>();
private LinkedList<ILFilter> filters = new LinkedList<ILFilter>();
private boolean applyFiltersImmediately = true;
private boolean unappliedFilters = false;
/**
* @see LAdvancedFilterable#getFilterablePropertyIds()
*/
public Collection<Object> getFilterablePropertyIds() {
if (filterablePropertyIds == null) {
return Collections.emptyList();
} else {
return Collections.unmodifiableCollection(filterablePropertyIds);
}
}
/**
* Sets the filterable property IDs.
*
* @param propertyIds
* the property IDs to set (must not be null).
*/
@SuppressWarnings("unchecked")
public void setFilterablePropertyIds(Collection<?> propertyIds) {
assert propertyIds != null : "propertyIds must not be null";
filterablePropertyIds = (Collection<Object>) propertyIds;
}
/**
* Sets the filterable property IDs.
*
* @param propertyIds
* the property IDs to set (must not be null).
*/
public void setFilterablePropertyIds(Object... propertyIds) {
assert propertyIds != null : "propertyIds must not be null";
setFilterablePropertyIds(Arrays.asList(propertyIds));
}
/**
* @see LAdvancedFilterable#isFilterable(java.lang.Object)
*/
public boolean isFilterable(Object propertyId) {
return getFilterablePropertyIds().contains(propertyId);
}
/**
* Checks if <code>filter</code> is a valid filter, i.e. that all the
* properties that the filter restricts are filterable.
*
* @param filter
* the filter to check (must not be null).
* @return true if the filter is valid, false if it is not.
*/
public boolean isValidFilter(ILFilter filter) {
assert filter != null : "filter must not be null";
if (filter instanceof LBetween) {
return isFilterable(((LBetween) filter).getPropertyId());
} else if (filter instanceof LCompare) {
return isFilterable(((LCompare) filter).getPropertyId());
} else if (filter instanceof LIsNull) {
return isFilterable(((LIsNull) filter).getPropertyId());
} else if (filter instanceof LLike) {
return isFilterable(((LLike) filter).getPropertyId());
} else if (filter instanceof LSimpleStringFilter) {
return isFilterable(((LSimpleStringFilter) filter).getPropertyId());
} else if (filter instanceof LAbstractJunctionFilter) {
for (ILFilter f : ((LAbstractJunctionFilter) filter).getFilters()) {
if (!isValidFilter(f)) {
return false;
}
}
}
return true;
}
/**
* @see LAdvancedFilterable#getFilters()
*/
public List<ILFilter> getFilters() {
return Collections.unmodifiableList(filters);
}
/**
* @see LAdvancedFilterable#getAppliedFilters()
*/
public List<ILFilter> getAppliedFilters() {
return isApplyFiltersImmediately() ? getFilters() : Collections
.unmodifiableList(appliedFilters);
}
/**
* @see LAdvancedFilterable#setApplyFiltersImmediately(boolean)
*/
public void setApplyFiltersImmediately(boolean applyFiltersImmediately) {
this.applyFiltersImmediately = applyFiltersImmediately;
}
/**
* @see LAdvancedFilterable#isApplyFiltersImmediately()
*/
public boolean isApplyFiltersImmediately() {
return applyFiltersImmediately;
}
/**
* @see LAdvancedFilterable#applyFilters()
*/
public void applyFilters() {
unappliedFilters = false;
appliedFilters.clear();
appliedFilters.addAll(filters);
fireListeners();
}
/**
* @see LAdvancedFilterable#hasUnappliedFilters()
*/
public boolean hasUnappliedFilters() {
return unappliedFilters;
}
@SuppressWarnings("unchecked")
public static Path<String> getPropertyPath(From<?, ?> root,
Object propertyId) {
return (Path<String>) getPropertyPathTyped(root, propertyId);
}
public static <X, Y> Path<X> getPropertyPathTyped(From<X, Y> root,
Object propertyId) {
String pid = propertyId.toString();
String[] idStrings = pid.split("\\.");
Path<X> path = root.get(idStrings[0]);
for (int i = 1; i < idStrings.length; i++) {
path = path.get(idStrings[i]);
}
return path;
}
/**
* @param filter
*/
public void addFilter(ILFilter filter) {
filters.add(filter);
unappliedFilters = true;
if (isApplyFiltersImmediately()) {
applyFilters();
}
}
/**
* @param filter
*/
public void removeFilter(ILFilter filter) {
filters.remove(filter);
unappliedFilters = true;
if (isApplyFiltersImmediately()) {
applyFilters();
}
}
public void removeAllFilters() {
filters.clear();
unappliedFilters = true;
if (isApplyFiltersImmediately()) {
applyFilters();
}
}
}