    001    /*
    002     * Copyright (c) 2007-2014 Concurrent, Inc. All Rights Reserved.
    003     *
    004     * Project and contact information: http://www.cascading.org/
    005     *
    006     * This file is part of the Cascading project.
    007     *
    008     * Licensed under the Apache License, Version 2.0 (the "License");
    009     * you may not use this file except in compliance with the License.
    010     * You may obtain a copy of the License at
    011     *
    012     *     http://www.apache.org/licenses/LICENSE-2.0
    013     *
    014     * Unless required by applicable law or agreed to in writing, software
    015     * distributed under the License is distributed on an "AS IS" BASIS,
    016     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    017     * See the License for the specific language governing permissions and
    018     * limitations under the License.
    019     */
    020
    021    package cascading.operation.filter;
    022
    023    import java.beans.ConstructorProperties;
    024
    025    import cascading.flow.FlowProcess;
    026    import cascading.operation.Filter;
    027    import cascading.operation.FilterCall;
    028    import cascading.tuple.Fields;
    029    import cascading.tuple.Tuple;
    030    import cascading.tuple.TupleEntry;
    031
    032    /**
    033     * Class And is a {@link Filter} class that will logically 'and' the results of the constructor provided Filter
    034     * instances.
    035     * <p/>
    036     * Logically, if {@link Filter#isRemove(cascading.flow.FlowProcess, cascading.operation.FilterCall)} returns {@code true} for all given instances,
    037     * this filter will return {@code true}.
    038     *
    039     * @see Or
    040     * @see Xor
    041     * @see Not
    042     */
    043    public class And extends Logic
    044      {
    045      /**
    046       * Constructor And creates a new And instance where all Filter instances receive all arguments.
    047       *
    048       * @param filters of type Filter...
    049       */
    050      @ConstructorProperties({"filters"})
    051      public And( Filter... filters )
    052        {
    053        super( filters );
    054        }
    055
    056      /**
    057       * Constructor And creates a new And instance.
    058       *
    059       * @param lhsArgumentSelector of type Fields
    060       * @param lhsFilter           of type Filter
    061       * @param rhsArgumentSelector of type Fields
    062       * @param rhsFilter           of type Filter
    063       */
    064      @ConstructorProperties({"lhsArgumentsSelector", "lhsFilter", "rhsArgumentSelector", "rhsFilter"})
    065      public And( Fields lhsArgumentSelector, Filter lhsFilter, Fields rhsArgumentSelector, Filter rhsFilter )
    066        {
    067        super( lhsArgumentSelector, lhsFilter, rhsArgumentSelector, rhsFilter );
    068        }
    069
    070      /**
    071       * Constructor And creates a new And instance.
    072       *
    073       * @param argumentSelectors of type Fields[]
    074       * @param filters           of type Filter[]
    075       */
    076      @ConstructorProperties({"argumentFilters", "filters"})
    077      public And( Fields[] argumentSelectors, Filter[] filters )
    078        {
    079        super( argumentSelectors, filters );
    080        }
    081
    082      @Override
    083      public boolean isRemove( FlowProcess flowProcess, FilterCall filterCall )
    084        {
    085        TupleEntry arguments = filterCall.getArguments();
    086        Context context = (Context) filterCall.getContext();
    087
    088        TupleEntry[] argumentEntries = context.argumentEntries;
    089
    090        for( int i = 0; i < argumentSelectors.length; i++ )
    091          {
    092          Tuple selected = arguments.selectTuple( argumentSelectors[ i ] );
    093
    094          argumentEntries[ i ].setTuple( selected );
    095
    096          if( !filters[ i ].isRemove( flowProcess, context.calls[ i ] ) )
    097            return false;
    098          }
    099
    100        return true;
    101        }
    102      }