1 package net.sf.saxon.functions; 2 import net.sf.saxon.expr.Expression; 3 import net.sf.saxon.expr.StaticContext; 4 import net.sf.saxon.expr.XPathContext; 5 import net.sf.saxon.om.Item; 6 import net.sf.saxon.trans.DynamicError; 7 import net.sf.saxon.trans.StaticError; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.type.RegexTranslator; 10 import net.sf.saxon.value.AtomicValue; 11 import net.sf.saxon.value.BooleanValue; 12 import net.sf.saxon.value.StringValue; 13 import net.sf.saxon.value.Value; 14 15 import java.util.regex.Pattern ; 16 import java.util.regex.PatternSyntaxException ; 17 18 19 22 23 public class Matches extends SystemFunction { 24 25 private Pattern regexp; 26 27 33 34 public Expression simplify(StaticContext env) throws XPathException { 35 Expression e = simplifyArguments(env); 36 37 if (!(e instanceof Value)) { 39 regexp = Matches.tryToCompile(argument, 1, 2); 40 } 41 42 return e; 43 } 44 45 51 52 public static int setFlags(CharSequence inFlags) throws StaticError { 53 int flags = Pattern.UNIX_LINES; 54 for (int i=0; i<inFlags.length(); i++) { 55 char c = inFlags.charAt(i); 56 switch (c) { 57 case 'm': 58 flags |= Pattern.MULTILINE; 59 break; 60 case 'i': 61 flags |= Pattern.CASE_INSENSITIVE; 62 break; 63 case 's': 64 flags |= Pattern.DOTALL; 65 break; 66 case 'x': 67 flags |= Pattern.COMMENTS; break; 69 default: 70 StaticError err = new StaticError("Invalid character '" + c + "' in regular expression flags"); 71 err.setErrorCode("FORX0001"); 72 throw err; 73 } 74 } 75 return flags; 76 } 77 78 90 91 protected static Pattern tryToCompile(Expression[] args, int patternArg, int flagsArg) 92 throws StaticError { 93 if (patternArg > args.length - 1) { 94 return null; 96 } 97 CharSequence flagstr = null; 98 if (args.length-1 < flagsArg) { 99 flagstr = ""; 100 } else if (args[flagsArg] instanceof StringValue) { 101 flagstr = ((StringValue)args[flagsArg]).getStringValueCS(); 102 } 103 104 if (args[patternArg] instanceof StringValue && flagstr != null) { 105 int flags = Matches.setFlags(flagstr); 106 107 try { 108 String javaRegex = RegexTranslator.translate( 109 ((StringValue)args[patternArg]).getStringValueCS(), true); 110 return Pattern.compile(javaRegex, flags); 111 } catch (RegexTranslator.RegexSyntaxException err) { 112 StaticError e2 = new StaticError(err.getMessage()); 113 e2.setErrorCode("FORX0002"); 114 throw e2; 115 } catch (PatternSyntaxException err) { 116 StaticError e2 = new StaticError(err.getMessage()); 117 e2.setErrorCode("FORX0002"); 118 throw e2; 119 } 120 } else { 121 return null; 122 } 123 } 124 125 131 132 public Item evaluateItem(XPathContext c) throws XPathException { 133 AtomicValue sv0 = (AtomicValue)argument[0].evaluateItem(c); 134 if (sv0==null) { 135 sv0 = StringValue.EMPTY_STRING; 136 }; 137 138 Pattern re = regexp; 139 if (re == null) { 140 141 AtomicValue pat = (AtomicValue)argument[1].evaluateItem(c); 142 if (pat==null) return null; 143 144 CharSequence flags; 145 if (argument.length==2) { 146 flags = ""; 147 } else { 148 AtomicValue sv2 = (AtomicValue)argument[2].evaluateItem(c); 149 if (sv2==null) return null; 150 flags = sv2.getStringValueCS(); 151 } 152 153 try { 154 String javaRegex = RegexTranslator.translate(pat.getStringValueCS(), true); 155 re = Pattern.compile(javaRegex, setFlags(flags)); 156 } catch (RegexTranslator.RegexSyntaxException err) { 157 DynamicError de = new DynamicError(err); 158 de.setErrorCode("FORX0002"); 159 de.setXPathContext(c); 160 throw de; 161 } catch (PatternSyntaxException err) { 162 DynamicError de = new DynamicError(err); 163 de.setErrorCode("FORX0002"); 164 de.setXPathContext(c); 165 throw de; 166 } catch (StaticError serr) { 167 dynamicError(serr.getMessage(), serr.getErrorCodeLocalPart(), c); 168 } 169 } 170 return BooleanValue.get(re.matcher(sv0.getStringValueCS()).find()); 171 } 172 173 } 174 175 176 177 | Popular Tags |