001/* 002 * Copyright (c) 2016-2017 Chris K Wensel <chris@wensel.net>. All Rights Reserved. 003 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved. 004 * 005 * Project and contact information: http://www.cascading.org/ 006 * 007 * This file is part of the Cascading project. 008 * 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 */ 021 022package cascading.operation.assertion; 023 024import java.beans.ConstructorProperties; 025import java.util.regex.Matcher; 026 027import cascading.flow.FlowProcess; 028import cascading.operation.AssertionLevel; 029import cascading.operation.PlannerLevel; 030import cascading.operation.ValueAssertion; 031import cascading.operation.ValueAssertionCall; 032import cascading.operation.regex.RegexMatcher; 033import cascading.tuple.TupleEntry; 034 035/** 036 * Class AssertMatches matches the given regular expression patternString against the whole argument 037 * {@link cascading.tuple.Tuple} by joining each individual element of the Tuple with a tab character (\t) unless 038 * otherwise specified. 039 * See {@link AssertMatchesAll} if you need to match the patternString regex against each individual tuple element. 040 * <p> 041 * This operation uses {@link java.util.regex.Matcher} internally, specifically the method {@link java.util.regex.Matcher#find()}. 042 * <p> 043 * Note a {@code null} valued argument passed to the parser will be converted to an empty string ({@code ""}) before 044 * the regex is applied. 045 * <p> 046 * Any Object value will be coerced to a String type via any provided {@link cascading.tuple.type.CoercibleType} on 047 * the argument selector or via its {@code toString()} method. 048 * 049 * @see java.util.regex.Matcher 050 * @see java.util.regex.Pattern 051 */ 052public class AssertMatches extends RegexMatcher implements ValueAssertion<Matcher> 053 { 054 /** Field message */ 055 private final static String message = "argument tuple: %s did not match: %s"; 056 057 /** 058 * Constructor AssertMatches creates a new AssertMatches instance. 059 * 060 * @param patternString of type String 061 */ 062 @ConstructorProperties({"patternString"}) 063 public AssertMatches( String patternString ) 064 { 065 super( patternString, false ); 066 } 067 068 /** 069 * Constructor AssertMatches creates a new AssertMatches instance. 070 * 071 * @param patternString of type String 072 * @param delimiter of type String 073 */ 074 @ConstructorProperties({"patternString", "delimiter"}) 075 public AssertMatches( String patternString, String delimiter ) 076 { 077 super( patternString, false, delimiter ); 078 } 079 080 /** 081 * Constructor AssertMatches creates a new AssertMatches instance. 082 * 083 * @param patternString of type String 084 * @param negateMatch of type boolean 085 */ 086 @ConstructorProperties({"patternString", "negateMatch"}) 087 public AssertMatches( String patternString, boolean negateMatch ) 088 { 089 super( patternString, negateMatch ); 090 } 091 092 /** 093 * Constructor AssertMatches creates a new AssertMatches instance. 094 * 095 * @param patternString of type String 096 * @param negateMatch of type boolean 097 * @param delimiter of type String 098 */ 099 @ConstructorProperties({"patternString", "negateMatch", "delimiter"}) 100 public AssertMatches( String patternString, boolean negateMatch, String delimiter ) 101 { 102 super( patternString, negateMatch, delimiter ); 103 } 104 105 @Override 106 public boolean supportsPlannerLevel( PlannerLevel plannerLevel ) 107 { 108 return plannerLevel instanceof AssertionLevel; 109 } 110 111 @Override 112 public void doAssert( FlowProcess flowProcess, ValueAssertionCall<Matcher> assertionCall ) 113 { 114 TupleEntry tupleEntry = assertionCall.getArguments(); 115 116 if( matchWholeTuple( assertionCall.getContext(), tupleEntry ) ) 117 BaseAssertion.throwFail( message, tupleEntry.getTuple().print(), patternString ); 118 } 119 }