package jadex.commons;
import java.io.Serializable;
import java.util.Arrays;
/**
* A filter checks if an object matches
* the given subfilters.
*/
public class ComposedFilter implements IFilter, Serializable
{
//-------- constants --------
/** The AND operator. */
public static final int AND = 1;
/** The OR operator. */
public static final int OR = 2;
/** The NOT operator. */
public static final int NOT = 3;
//-------- attributes ---------
/** The filters */
protected IFilter[] filters;
/** The operator. */
protected int operator;
//-------- constructors --------
/**
* Create a composed filter.
* @param filters The filters.
* @param operator The operator.
*/
public ComposedFilter(IFilter[] filters)
{
}
/**
* Create a composed filter.
* @param filters The filters.
* @param operator The operator.
*/
public ComposedFilter(IFilter[] filters, int operator)
{
this.filters = filters;
this.operator = operator;
}
//-------- methods --------
/**
* Match an object against the filter.
* @param object The object.
* @return True, if the filter matches.
* @throws Exception
*/
public boolean filter(Object object)
{
boolean ret = false;
if(operator==AND)
{
ret = true;
for(int i=0; i<filters.length && ret; i++)
{
ret = ret && filters[i].filter(object);
}
}
else if(operator==OR)
{
// When exception occurs: remember.
RuntimeException exception = null;
for(int i=0; i<filters.length && !ret; i++)
{
try
{
ret = ret || filters[i].filter(object);
}
catch(RuntimeException e)
{
exception = exception!=null ? exception : e;
}
}
// Throw remembered exception (if any), when filter doesn't match.
if(!ret && exception!=null)
throw exception;
}
else if(operator==NOT)
{
ret = !filters[0].filter(object);
}
return ret;
}
/**
* Get the filters.
* @return the filters.
*/
public IFilter[] getFilters()
{
return filters;
}
/**
* Set the filters.
* @param filters The filters to set.
*/
public void setFilters(IFilter[] filters)
{
this.filters = filters;
}
/**
* Add a filter.
* @param filter The filter.
*/
public void addFilter(IFilter filter)
{
IFilter[] copy = new IFilter[filters==null? 1: filters.length+1];
if(filters!=null)
System.arraycopy(filter, 0, copy, 0, filters.length);
copy[copy.length-1] = filter;
this.filters = copy;
}
/**
* Get the operator.
* @return the operator.
*/
public int getOperator()
{
return operator;
}
/**
* Set the operator.
* @param operator The operator to set.
*/
public void setOperator(int operator)
{
this.operator = operator;
}
/**
* Get the hashcode.
*/
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(filters);
result = prime * result + operator;
return result;
}
/**
* Test if an object is equal to this.
*/
public boolean equals(Object obj)
{
boolean ret = false;
if(obj instanceof ComposedFilter)
{
ComposedFilter other = (ComposedFilter)obj;
ret = Arrays.equals(filters, other.filters) && operator == other.operator;
}
return ret;
}
/**
* Create a string representation of the operator.
* @return A string representing the operator.
*/
public static String operatorToString(int operator)
{
switch(operator)
{
case AND:
return "AND";
case OR:
return "OR";
case NOT:
return "NOT";
default:
throw new RuntimeException("Unknown operator: "+operator);
}
}
/**
* Create a string representation of this filter.
* @return A string representing this filter.
*/
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append(SReflect.getInnerClassName(this.getClass()));
sb.append("(operator=");
sb.append(operatorToString(operator));
sb.append(", filters=");
sb.append(SUtil.arrayToString(filters));
sb.append(")");
return sb.toString();
}
}