001package com.randomnoun.common.jexl.eval.function; 002 003/* (c) 2013-2018 randomnoun. All Rights Reserved. This work is licensed under a 004 * BSD Simplified License. (http://www.randomnoun.com/bsd-simplified.html) 005 */ 006 007import java.util.List; 008 009import com.randomnoun.common.jexl.eval.EvalContext; 010import com.randomnoun.common.jexl.eval.EvalException; 011import com.randomnoun.common.jexl.eval.EvalFunction; 012 013/** Defines a like() function. 014 * 015 * <p>like() takes a two parameters, the string being matched and the SQL LIKE pattern we 016 * are matching on. The LIKE pattern uses the "%" character to represent any sequence of 017 * characters, and "_" to indicate a single character. This class automatically deals 018 * with conflicts with the Java regex parser, so the pattern may contain any other 019 * Unicode or regular expression characters, which will be treated like any other 020 * character. 021 * 022 * <p>The result of the function is of type Boolean. 023 */ 024public class LikeFunction 025 implements EvalFunction 026{ 027 /** Implements the function as per the class description. */ 028 public Object evaluate(String functionName, EvalContext context, List<Object> arguments) 029 throws EvalException 030 { 031 if (arguments.size() != 2) { throw new EvalException(functionName + "() must contain two parameters"); } 032 if (!(arguments.get(0) instanceof String)) { 033 throw new EvalException(functionName + "() parameter 1 must be a string type"); 034 } 035 if (!(arguments.get(1) instanceof String)) { 036 throw new EvalException(functionName + "() parameter 2 must be a string type"); 037 } 038 039 String arg0 = (String)arguments.get(0); 040 String arg1 = (String)arguments.get(1); 041 if (arg0 == null) { 042 throw new EvalException(functionName + "() first parameter cannot be null"); 043 } 044 if (arg1 == null) { 045 throw new EvalException(functionName + "() second parameter cannot be null"); 046 } 047 048 // convert arg1 into a regex; first escape any chars that may confuse the 049 // regex engine (see java.util.regex.Pattern class to see how this list was derived) 050 String specialChars = "\\[]^$?*+{}|()."; 051 for (int i = 0; i < specialChars.length(); i++) { 052 arg1 = arg1.replaceAll("\\" + specialChars.charAt(i), 053 "\\\\" + "\\" + specialChars.charAt(i)); 054 } 055 arg1 = arg1.replaceAll("%", ".*"); 056 arg1 = arg1.replaceAll("_", "."); 057 return Boolean.valueOf(arg0.matches(arg1)); 058 } 059}