/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.predicates;
import java.util.List;
import xxl.core.cursors.Subquery;
/**
* This class provides a prototypical implementation of the exist-predicate.
* The <code>invoke</code> method of this class returns <code>true</code>, if
* the subquery delivers a non-empty result with the applied arguments.
*
* <p>For example consider the implementation of the query:
* <pre>
* SELECT (Integer2)
* FROM Cursor 2
* WHERE EXIST (SELECT Integer1
* FROM Cursor 1
* WHERE Integer1=Integer2)
* </pre>
* by using an <code>ExistPredicate</code> instance
* <code><pre>
* System.out.println("Cursor 1: integers 8 to 15");
* Cursor<Integer> cursor1 = Cursors.wrap(new Enumerator(8,16));
*
* System.out.println("Cursor 2: integers 9 to 19");
* Cursor<Integer> cursor2 = Cursors.wrap(new Enumerator(9,20));
*
* Predicate<Integer> pred = new Equal<Integer>();
* BindingPredicate<Integer> bindPred = new BindingPredicate<Integer>(pred, Arrays.asList(1));
*
* Filter<Integer> sel = new Filter<Integer>(cursor1, bindPred);
*
* Subquery<Integer> sub = new Subquery<Integer>(
* sel,
* Arrays.asList(bindPred),
* new int[][] {
* new int[] {1}
* }
* );
*
* Predicate<Integer> exist0 = new ExistPredicate<Integer>(sub);
*
* Filter<Integer> cursor = new Filter<Integer>(cursor2, exist0);
*
* System.out.println("Cursor: result");
*
* Cursors.println(cursor);
* </code></pre></p>
*
* @param <P> the type of the predicate's parameters.
*/
public class ExistPredicate<P> extends AbstractPredicate<P> {
/**
* The subquery used in the exist-predicate.
*/
protected Subquery<? super P> subquery;
/**
* Creates a new exist-predicate. The <code>invoke</code> method returns
* <code>true</code>, if the subquery delivers a non-empty result with the
* applied arguments.
*
* @param subquery the subquery used in the exist-predicate.
*/
public ExistPredicate(Subquery<? super P> subquery) {
this.subquery = subquery;
}
/**
* Set the subquery of the exist-predicate.
*
* @param subquery the subquery used in the exist-predicate.
*/
public void setSubquery(Subquery<? super P> subquery) {
this.subquery = subquery;
}
/**
* Test whether the subquery of the predicate delivers a non-empty result
* with the applied arguments.
*
* @param arguments the arguments to be applied to the underlying
* predicate.
* @return the result of the underlying predicate's <code>invoke</code>
* method that is called with applied arguments.
*/
@Override
public boolean invoke(List<? extends P> arguments) {
if (arguments == null)
return invoke((P)null);
subquery.bind(arguments);
subquery.reset();
if (subquery.hasNext()) {
subquery.next();
return true;
}
return false;
}
}