    001/*
    002 * Copyright (c) 2007-2017 Xplenty, 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
    021package cascading.operation.assertion;
    022
    023import java.beans.ConstructorProperties;
    024import java.util.regex.Matcher;
    025
    026import cascading.flow.FlowProcess;
    027import cascading.operation.AssertionLevel;
    028import cascading.operation.PlannerLevel;
    029import cascading.operation.ValueAssertion;
    030import cascading.operation.ValueAssertionCall;
    031import cascading.operation.regex.RegexMatcher;
    032import cascading.tuple.TupleEntry;
    033
    034/**
    035 * Class AssertMatchesAll matches the given regular expression patternString against each argument
    036 * {@link cascading.tuple.Tuple} element individually. See {@link AssertMatches} if you need to match the patternString regex against
    037 * the tuple as a whole.
    038 * <p/>
    039 * This operation uses {@link java.util.regex.Matcher} internally, specifically the method {@link java.util.regex.Matcher#find()}.
    040 * <p/>
    041 * Note a {@code null} valued argument passed to the parser will be converted to an empty string ({@code ""}) before
    042 * the regex is applied.
    043 * <p/>
    044 * Any Object value will be coerced to a String type via any provided {@link cascading.tuple.type.CoercibleType} on
    045 * the argument selector or via its {@code toString()} method.
    046 *
    047 * @see java.util.regex.Matcher
    048 * @see java.util.regex.Pattern
    049 */
    050public class AssertMatchesAll extends RegexMatcher implements ValueAssertion<Matcher>
    051  {
    052  /** Field message */
    053  private final static String message = "argument '%s' value was: %s, did not match: %s, in tuple: %s";
    054
    055  /**
    056   * Constructor AssertMatchesAll creates a new AssertMatchesAll instance.
    057   *
    058   * @param patternString of type String
    059   */
    060  @ConstructorProperties({"patternString"})
    061  public AssertMatchesAll( String patternString )
    062    {
    063    super( patternString, false );
    064    }
    065
    066  /**
    067   * Constructor AssertMatchesAll creates a new AssertMatchesAll instance.
    068   *
    069   * @param patternString of type String
    070   * @param negateMatch   of type boolean
    071   */
    072  @ConstructorProperties({"patternString", "negateMatch"})
    073  public AssertMatchesAll( String patternString, boolean negateMatch )
    074    {
    075    super( patternString, negateMatch );
    076    }
    077
    078  @Override
    079  public boolean supportsPlannerLevel( PlannerLevel plannerLevel )
    080    {
    081    return plannerLevel instanceof AssertionLevel;
    082    }
    083
    084  @Override
    085  public void doAssert( FlowProcess flowProcess, ValueAssertionCall<Matcher> assertionCall )
    086    {
    087    TupleEntry input = assertionCall.getArguments();
    088
    089    int pos = matchEachElementPos( assertionCall.getContext(), input );
    090
    091    if( pos != -1 )
    092      BaseAssertion.throwFail( message, input.getFields().get( pos ), input.getObject( pos ), patternString, input.getTuple().print() );
    093    }
    094  }