    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 AssertMatches matches the given regular expression patternString against the whole argument
    036 * {@link cascading.tuple.Tuple} by joining each individual element of the Tuple with a tab character (\t) unless
    037 * otherwise specified.
    038 * See {@link AssertMatchesAll} if you need to match the patternString regex against each individual tuple element.
    039 * <p/>
    040 * This operation uses {@link java.util.regex.Matcher} internally, specifically the method {@link java.util.regex.Matcher#find()}.
    041 * <p/>
    042 * Note a {@code null} valued argument passed to the parser will be converted to an empty string ({@code ""}) before
    043 * the regex is applied.
    044 * <p/>
    045 * Any Object value will be coerced to a String type via any provided {@link cascading.tuple.type.CoercibleType} on
    046 * the argument selector or via its {@code toString()} method.
    047 *
    048 * @see java.util.regex.Matcher
    049 * @see java.util.regex.Pattern
    050 */
    051public class AssertMatches extends RegexMatcher implements ValueAssertion<Matcher>
    052  {
    053  /** Field message */
    054  private final static String message = "argument tuple: %s did not match: %s";
    055
    056  /**
    057   * Constructor AssertMatches creates a new AssertMatches instance.
    058   *
    059   * @param patternString of type String
    060   */
    061  @ConstructorProperties({"patternString"})
    062  public AssertMatches( String patternString )
    063    {
    064    super( patternString, false );
    065    }
    066
    067  /**
    068   * Constructor AssertMatches creates a new AssertMatches instance.
    069   *
    070   * @param patternString of type String
    071   * @param delimiter     of type String
    072   */
    073  @ConstructorProperties({"patternString", "delimiter"})
    074  public AssertMatches( String patternString, String delimiter )
    075    {
    076    super( patternString, false, delimiter );
    077    }
    078
    079  /**
    080   * Constructor AssertMatches creates a new AssertMatches instance.
    081   *
    082   * @param patternString of type String
    083   * @param negateMatch   of type boolean
    084   */
    085  @ConstructorProperties({"patternString", "negateMatch"})
    086  public AssertMatches( String patternString, boolean negateMatch )
    087    {
    088    super( patternString, negateMatch );
    089    }
    090
    091  /**
    092   * Constructor AssertMatches creates a new AssertMatches instance.
    093   *
    094   * @param patternString of type String
    095   * @param negateMatch   of type boolean
    096   * @param delimiter     of type String
    097   */
    098  @ConstructorProperties({"patternString", "negateMatch", "delimiter"})
    099  public AssertMatches( String patternString, boolean negateMatch, String delimiter )
    100    {
    101    super( patternString, negateMatch, delimiter );
    102    }
    103
    104  @Override
    105  public boolean supportsPlannerLevel( PlannerLevel plannerLevel )
    106    {
    107    return plannerLevel instanceof AssertionLevel;
    108    }
    109
    110  @Override
    111  public void doAssert( FlowProcess flowProcess, ValueAssertionCall<Matcher> assertionCall )
    112    {
    113    TupleEntry tupleEntry = assertionCall.getArguments();
    114
    115    if( matchWholeTuple( assertionCall.getContext(), tupleEntry ) )
    116      BaseAssertion.throwFail( message, tupleEntry.getTuple().print(), patternString );
    117    }
    118  }