/*
* Condition.java
*
* Created on March 21, 2002, 2:02 PM
*
* Copyright (c) Jrg Wamer
* This library is free software. You can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 2 or above
* as published by the Free Software Foundation.
* For more information please visit <http://jaxlib.sourceforge.net>.
*/
package jaxlib.closure;
/**
* An abstract <tt>Filter</tt> class which supports building logical structures.
* <p>
* This is the recommended superclass for <tt>Filter</tt> implementations.
* </p>
*
* @see If#is(Filter)
*
* @author <a href="mailto:joerg.wassmer@web.de">Jrg Wamer</a>
* @since JaXLib 1.0
* @version $Id: Condition.java,v 1.2 2004/11/04 21:23:59 joerg_wassmer Exp $
*/
public abstract class Condition<E> extends Object implements Filter<E>
{
protected Condition<E> not;
protected Condition()
{
super();
}
public abstract boolean accept(E e);
/**
* Overwritten by If.Accepts.
*/
Filter<E> getFilter()
{
return this;
}
/**
* Creates a logical <tt>and</tt> operation.
* <p>
* Returns a condition which returns <tt>left.accept(e) && right.accept(e)</tt>, where <tt>left</tt> is <tt>this</tt> condition.
* The <tt>right</tt> condition gets called if and only if the <tt>left</tt> returned <tt>true</tt>.
* </p>
*
* @throws NullPointerException if <tt>right == null</tt>.
*
* @since JaXLib 1.0
*/
public Condition<E> and(Filter<? super E> right)
{
return new If.LogicChain<E>(If.LogicChain.AND, getFilter(), right);
}
/**
* Creates a logical <tt>and not</tt> operation.
* <p>
* Returns a condition which returns <tt>left.accept(e) && !right.accept(e)</tt>, where <tt>left</tt> is <tt>this</tt> condition.
* The <tt>right</tt> condition gets called if and only if the <tt>left</tt> returned <tt>true</tt>.
* <p>
* This method is a shortcut for <tt>this.and(right.not())</tt>.
* </p>
*
* @throws NullPointerException if <tt>right == null</tt>.
*
* @since JaXLib 1.0
*/
public Condition<E> andNot(Filter<? super E> right)
{
return new If.LogicChain<E>(If.LogicChain.AND_NOT, getFilter(), right);
}
/**
* Returns a condition which returns <tt>accept(function.apply(e))</tt>.
*
* @throws NullPointerException if <tt>function == null</tt>.
*
* @since JaXLib 1.0
*/
public Condition<E> chain(Function<? super E,? extends E> function)
{
return new If.FunctionChain<E>(getFilter(), true, function);
}
/**
* Returns a condition which returns the same results as this one, and sends matches to the specified procedure.
* The result of the procedure does not affect the result of the condition.
*
* @param iF <tt>true</tt> for sending matches to the specified procedure, <tt>false</tt> for sending dismatches.
* @param dest the procedure to send matches to.
*
* @throws NullPointerException if <tt>dest == null</tt>.
*
* @see #forkAll(Closure)
*
* @since JaXLib 1.0
*/
public Condition<E> fork(boolean iF, Closure<? super E> dest)
{
return new If.Fork<E>(iF ? If.Fork.TRUES : If.Fork.FALSES, getFilter(), dest);
}
/**
* Returns a condition which returns the same results as this one, and sends all received arguments to the specified procedure.
* The result of the procedure does not affect the result of the condition.
*
* @param dest the procedure to send arguments to.
*
* @throws NullPointerException if <tt>dest == null</tt>.
*
* @see #fork(boolean,Closure)
*
* @since JaXLib 1.0
*/
public Condition<E> forkAll(Closure<? super E> dest)
{
return new If.Fork<E>(If.Fork.ALL, getFilter(), dest);
}
/**
* Returns a condition which accepts those objects rejected by this condition.
*
* @since JaXLib 1.0
*/
public Condition<E> not()
{
Condition<E> not = this.not;
if (not == null)
this.not = not = new If.Accepts<E>(false, getFilter());
return not;
}
/**
* Creates a logical <tt>not and</tt> operation.
* <p>
* Returns a condition which returns <tt>!(left.accept(e) && right.accept(e))</tt>, where <tt>left</tt> is <tt>this</tt> condition.
* The <tt>right</tt> condition gets called if and only if the <tt>left</tt> returned <tt>false</tt>.
* <p>
* This method is a shortcut for <tt>this.and(right).not()</tt>.
* </p>
*
* @throws NullPointerException if <tt>right == null</tt>.
*
* @alias this.{@link #not() not}(.{@link #and(Filter) and}(right))
*
* @since JaXLib 1.0
*/
public Condition<E> notAnd(Filter<? super E> right)
{
return new If.LogicChain<E>(If.LogicChain.NAND, getFilter(), right);
}
/**
* Creates a logical <tt>or</tt> operation.
* <p>
* Returns a condition which returns <tt>left.accept(e) || right.accept(e)</tt>, where <tt>left</tt> is <tt>this</tt> condition.
* The <tt>right</tt> condition gets called if and only if the <tt>left</tt> returned <tt>false</tt>.
* </p>
*
* @throws NullPointerException if <tt>right == null</tt>.
*
* @since JaXLib 1.0
*/
public Condition<E> or(Filter<? super E> right)
{
return new If.LogicChain<E>(If.LogicChain.OR, getFilter(), right);
}
/**
* Creates a logical <tt>or not</tt> operation.
* <p>
* Returns a condition which returns <tt>left.accept(e) || !right.accept(e)</tt>, where <tt>left</tt> is <tt>this</tt> condition.
* The <tt>right</tt> condition gets called if and only if the <tt>left</tt> returned <tt>false</tt>.
* <p><p>
* This method is a shortcur for <tt>this.or(right.not())</tt>.
* </p>
*
* @throws NullPointerException if <tt>right == null</tt>.
*
* @since JaXLib 1.0
*/
public Condition<E> orNot(Filter<? super E> right)
{
return new If.LogicChain<E>(If.LogicChain.OR_NOT, getFilter(), right);
}
/**
* Creates a logical <tt>nor</tt> operation.
* <p>
* Returns a condition which returns <tt>!(left.accept(e) || right.accept(e))</tt>, where <tt>left</tt> is <tt>this</tt> condition.
* The <tt>right</tt> condition gets called if and only if the <tt>left</tt> returned <tt>false</tt>.
* </p><p>
* This method is method is a shortcut for <tt>this.or(right).not()</tt>.
* </p>
*
* @throws NullPointerException if <tt>right == null</tt>.
*
* @since JaXLib 1.0
*/
public Condition<E> nor(Filter<? super E> right)
{
return new If.LogicChain<E>(If.LogicChain.NOR, getFilter(), right);
}
/**
* Creates a logical <tt>xor</tt> operation.
* <p>
* Returns a condition which returns <tt>left.accept(e) != right.accept(e)</tt>, where <tt>left</tt> is <tt>this</tt> condition.
* The returned condition always calls both conditions.
* </p><p><i>
* Warning (for developers using generic types): this method is not typesafe!
* </i></p>
*
* @throws NullPointerException if <tt>right == null</tt>.
*
* @since JaXLib 1.0
*/
public Condition<E> xor(Filter<? super E> right)
{
return new If.LogicChain<E>(If.LogicChain.XOR, getFilter(), right);
}
/**
* Creates an <tt>if-then</tt> operation.
* <p>
* Returns a procedure which returns <tt>left.accept(e) ? right.proceed(e) : true</tt>, where <tt>left</tt> is <tt>this</tt> condition.
* The <tt>right</tt> procedure gets called if and only if the <tt>left</tt> condition returned <tt>true</tt>.
* </p>
*
* @throws NullPointerException if <tt>right == null</tt>.
*
* @since JaXLib 1.0
*/
public Closure<E> then(Closure<? super E> right)
{
return new If.Then<E>(getFilter(), true, right);
}
}
|