// Copyright � 2002-2007 Canoo Engineering AG, Switzerland. package com.canoo.webtest.engine.xpath; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.transform.TransformerException; import org.apache.log4j.Logger; import org.apache.xpath.XPathContext; import org.apache.xpath.functions.Function3Args; import org.apache.xpath.functions.WrongNumberArgsException; import org.apache.xpath.objects.XBoolean; import org.apache.xpath.objects.XObject; /** * This function should work as the matches function defined by * <a href="http://www.w3.org/TR/xquery-operators/#func-matches">XPath 2</a>. * This implementation is provided as long as this is not natively available in Xalan.<br/> * This function is available under the name "wt:matches". * * @author Marc Guillemot */ public class MatchesFunction extends Function3Args { private static final Logger LOG = Logger.getLogger(MatchesFunction.class); public XObject execute(final XPathContext xctxt) throws TransformerException { final String input = getArg0().execute(xctxt).xstr().toString(); final String regex = getArg1().execute(xctxt).xstr().toString(); LOG.debug("input: " + input); final String flags; if (getArg2() != null) { flags = getArg2().execute(xctxt).xstr().toString(); } else flags = null; return new XBoolean(doExecute(input, regex, flags)); } boolean doExecute(final String input, final String regex, final String flagsString) throws TransformerException { int flags = (flagsString == null) ? 0 : computeFlags(flagsString); final Pattern pattern = Pattern.compile(regex, flags); final Matcher matcher = pattern.matcher(input); return matcher.find(); } static int computeFlags(final String flags) throws TransformerException { int flag = 0; for (int i = 0; i < flags.length(); i++) { final char c = flags.charAt(i); if (flags.indexOf(c) != i) { break; // repeated flag, ignore } switch (c) { case's': flag += Pattern.DOTALL; break; case'm': flag += Pattern.MULTILINE; break; case'i': flag += Pattern.CASE_INSENSITIVE; break; case'x': flag += Pattern.COMMENTS; break; default: throw new TransformerException("Illegal flag used for call to matches: " + c); } } return flag; } @Override public void checkNumberArgs(int _argNum) throws WrongNumberArgsException { if (_argNum < 2 || _argNum > 3) throw new WrongNumberArgsException("function matches accept 2 or 3 arguments, not " + _argNum); } }