package expressions; /** * Presents a projection, which can be used to select * an element from a {@link expressions.Tuple} expression. * * The syntax is <code>#[arity]_[index]</code>. * * @author Benedikt Meurer * @version $Id$ */ public class Projection extends UnaryOperator { // // Attributes // /** * The arity of the projection. * * @see #getArity() */ private int arity; /** * The index of the projection. * * @see #getIndex() */ private int index; // // Constructors // /** * Allocates a new {@link Projection} with the given * <code>arity</code> and the <code>index</code> of * the item that should be selected. * * @param arity the arity of the tuple to which * this projection can be applied. * @param index the index of the item to select * from the tuple, starting with * <code>1</code>. * * @throws IllegalArgumentException if the <code>arity</code> or the * <code>index</code> is invalid. */ public Projection(int arity, int index) { this(arity, index, "#" + arity + "_" + index); } /** * Allocates a new {@link Projection} with the given * <code>arity</code> and the <code>index</code> of * the item that should be selected, and the string * representation <code>op</code>. * * @param arity the arity of the tuple to which * this projection can be applied. * @param index the index of the item to select * from the tuple, starting with * <code>1</code>. * @param op the string representation of the projectin. * * @throws IllegalArgumentException if the <code>arity</code> or the * <code>index</code> is invalid. */ protected Projection(int arity, int index, String op) { super(op); // validate the settings if (arity <= 0) throw new IllegalArgumentException("The arity of a projection must be greater than 0"); else if (index <= 0 || index > arity) throw new IllegalArgumentException("The index of a projection must be greater than 0 and less than the arity"); this.arity = arity; this.index = index; } // // Primitives // /** * {@inheritDoc} * * @see expressions.UnaryOperator#applyTo(expressions.Expression) */ @Override public Expression applyTo(Expression e) throws UnaryOperatorException { try { // determine the sub expressions of the tuple Expression[] expressions = ((Tuple)e).getExpressions(); // verify that the arities match if (this.arity != expressions.length) throw new UnaryOperatorException(this, e); // return the sub expression at the index return expressions[this.index - 1]; } catch (ClassCastException exception) { // cast of expression to tuple failed throw new UnaryOperatorException(this, e); } } /** * Returns the arity. * * @return the arity. */ public int getArity() { return this.arity; } /** * Returns the index. * * @return the index. */ public int getIndex() { return this.index; } }