1 package net.sf.saxon.instruct; 2 3 import net.sf.saxon.expr.*; 4 import net.sf.saxon.functions.Matches; 5 import net.sf.saxon.om.Item; 6 import net.sf.saxon.om.NamePool; 7 import net.sf.saxon.pattern.NoNodeTest; 8 import net.sf.saxon.style.StandardNames; 9 import net.sf.saxon.trans.DynamicError; 10 import net.sf.saxon.trans.XPathException; 11 import net.sf.saxon.type.ItemType; 12 import net.sf.saxon.type.RegexTranslator; 13 import net.sf.saxon.type.Type; 14 import net.sf.saxon.type.SchemaType; 15 import net.sf.saxon.value.SequenceType; 16 17 import java.io.PrintStream ; 18 import java.util.ArrayList ; 19 import java.util.Iterator ; 20 import java.util.regex.Pattern ; 21 import java.util.regex.PatternSyntaxException ; 22 23 26 27 public class AnalyzeString extends Instruction { 28 29 private Expression select; 30 private Expression regex; 31 private Expression flags; 32 private Expression matching; 33 private Expression nonMatching; 34 private Pattern pattern; 36 46 public AnalyzeString(Expression select, 47 Expression regex, 48 Expression flags, 49 Expression matching, 50 Expression nonMatching, 51 Pattern pattern) { 52 this.select = select; 53 this.regex = regex; 54 this.flags = flags; 55 this.matching = matching; 56 this.nonMatching = nonMatching; 57 this.pattern = pattern; 58 59 Iterator kids = iterateSubExpressions(); 60 while (kids.hasNext()) { 61 Expression child = (Expression)kids.next(); 62 adoptChildExpression(child); 63 } 64 65 } 66 67 public int getInstructionNameCode() { 68 return StandardNames.XSL_ANALYZE_STRING; 69 } 70 71 74 75 public Expression getMatchingExpression() { 76 return matching; 77 } 78 79 82 83 public Expression getNonMatchingExpression() { 84 return nonMatching; 85 } 86 87 88 96 97 public Expression simplify(StaticContext env) throws XPathException { 98 select = select.simplify(env); 99 regex = regex.simplify(env); 100 flags = flags.simplify(env); 101 if (matching != null) { 102 matching = matching.simplify(env); 103 } 104 if (nonMatching != null) { 105 nonMatching = nonMatching.simplify(env); 106 } 107 return this; 108 } 109 110 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 111 select = select.typeCheck(env, contextItemType); 112 adoptChildExpression(select); 113 regex = regex.typeCheck(env, contextItemType); 114 adoptChildExpression(regex); 115 flags = flags.typeCheck(env, contextItemType); 116 adoptChildExpression(flags); 117 if (matching != null) { 118 matching = matching.typeCheck(env, Type.STRING_TYPE); 119 adoptChildExpression(matching); 120 } 121 if (nonMatching != null) { 122 nonMatching = nonMatching.typeCheck(env, Type.STRING_TYPE); 123 adoptChildExpression(nonMatching); 124 } 125 RoleLocator role = 128 new RoleLocator(RoleLocator.INSTRUCTION, "analyze-string/select", 0, null); 129 role.setSourceLocator(this); 130 select = TypeChecker.staticTypeCheck(select, SequenceType.SINGLE_STRING, false, role, env); 131 132 role = new RoleLocator(RoleLocator.INSTRUCTION, "analyze-string/regex", 0, null); 133 role.setSourceLocator(this); 134 regex = TypeChecker.staticTypeCheck(regex, SequenceType.SINGLE_STRING, false, role, env); 135 136 role = new RoleLocator(RoleLocator.INSTRUCTION, "analyze-string/flags", 0, null); 137 role.setSourceLocator(this); 138 flags = TypeChecker.staticTypeCheck(flags, SequenceType.SINGLE_STRING, false, role, env); 139 140 return this; 141 } 142 143 144 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 145 select = select.optimize(opt, env, contextItemType); 146 adoptChildExpression(select); 147 regex = regex.optimize(opt, env, contextItemType); 148 adoptChildExpression(regex); 149 flags = flags.optimize(opt, env, contextItemType); 150 adoptChildExpression(flags); 151 if (matching != null) { 152 matching = matching.optimize(opt, env, Type.STRING_TYPE); 153 adoptChildExpression(matching); 154 } 155 if (nonMatching != null) { 156 nonMatching = nonMatching.optimize(opt, env, Type.STRING_TYPE); 157 adoptChildExpression(nonMatching); 158 } 159 return this; 160 } 161 162 169 170 public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException { 171 if (matching != null) { 172 matching.checkPermittedContents(parentType, env, false); 173 } 174 if (nonMatching != null) { 175 nonMatching.checkPermittedContents(parentType, env, false); 176 } 177 } 178 179 184 185 public ItemType getItemType() { 186 if (matching != null) { 187 if (nonMatching != null) { 188 return Type.getCommonSuperType(matching.getItemType(), nonMatching.getItemType()); 189 } else { 190 return matching.getItemType(); 191 } 192 } else { 193 if (nonMatching != null) { 194 return nonMatching.getItemType(); 195 } else { 196 return NoNodeTest.getInstance(); 197 } 198 } 199 } 200 201 210 211 public int computeDependencies() { 212 int dependencies = 0; 215 dependencies |= select.getDependencies(); 216 dependencies |= regex.getDependencies(); 217 dependencies |= flags.getDependencies(); 218 if (matching != null) { 219 dependencies |= (matching.getDependencies() &~ 220 (StaticProperty.DEPENDS_ON_FOCUS | StaticProperty.DEPENDS_ON_REGEX_GROUP)); 221 } 222 if (nonMatching != null) { 223 dependencies |= (nonMatching.getDependencies() &~ 224 (StaticProperty.DEPENDS_ON_FOCUS | StaticProperty.DEPENDS_ON_REGEX_GROUP)); 225 } 226 return dependencies; 227 } 228 229 235 236 protected void promoteInst(PromotionOffer offer) throws XPathException { 237 select = doPromotion(select, offer); 238 regex = doPromotion(regex, offer); 239 flags = doPromotion(flags, offer); 240 if (matching != null) { 241 matching = doPromotion(matching, offer); 242 } 243 if (nonMatching != null) { 244 nonMatching = doPromotion(nonMatching, offer); 245 } 246 } 247 248 253 254 public Iterator iterateSubExpressions() { 255 ArrayList list = new ArrayList (5); 256 list.add(select); 257 list.add(regex); 258 list.add(flags); 259 if (matching != null) { 260 list.add(matching); 261 } 262 if (nonMatching != null) { 263 list.add(nonMatching); 264 } 265 return list.iterator(); 266 } 267 268 public TailCall processLeavingTail(XPathContext context) throws XPathException { 269 RegexIterator iter = getRegexIterator(context); 270 XPathContextMajor c2 = context.newContext(); 271 c2.setOrigin(this); 272 c2.setCurrentIterator(iter); 273 c2.setCurrentRegexIterator(iter); 274 275 while (true) { 276 Item it = iter.next(); 277 if (it == null) { 278 break; 279 } 280 if (iter.isMatching()) { 281 if (matching != null) { 282 matching.process(c2); 283 } 284 } else { 285 if (nonMatching != null) { 286 nonMatching.process(c2); 287 } 288 } 289 } 290 291 return null; 292 293 } 294 295 302 303 private RegexIterator getRegexIterator(XPathContext context) throws XPathException { 304 String input = select.evaluateAsString(context); 305 306 Pattern re = pattern; 307 if (re == null) { 308 int jflags = Matches.setFlags(flags.evaluateAsString(context)); 309 try { 310 String javaRegex = RegexTranslator.translate(regex.evaluateAsString(context), true); 311 re = Pattern.compile(javaRegex, jflags); 312 } catch (RegexTranslator.RegexSyntaxException err) { 313 throw new DynamicError(err); 314 } catch (PatternSyntaxException err) { 315 throw new DynamicError(err); 316 } 317 } 318 319 RegexIterator iter = new RegexIterator(input, re); 320 return iter; 321 } 322 323 325 332 333 public void display(int level, NamePool pool, PrintStream out) { 334 out.println(ExpressionTool.indent(level) + "analyze-string"); 335 out.println(ExpressionTool.indent(level) + "select = "); 336 select.display(level + 1, pool, out); 337 out.println(ExpressionTool.indent(level) + "regex = "); 338 regex.display(level + 1, pool, out); 339 out.println(ExpressionTool.indent(level) + "flags = "); 340 flags.display(level + 1, pool, out); 341 if (matching != null) { 342 out.println(ExpressionTool.indent(level) + "matching = "); 343 matching.display(level + 1, pool, out); 344 } 345 if (nonMatching != null) { 346 out.println(ExpressionTool.indent(level) + "non-matching = "); 347 nonMatching.display(level + 1, pool, out); 348 } 349 } 350 } 351 352 | Popular Tags |