1 package com.thaiopensource.relaxng.impl; 2 3 import org.relaxng.datatype.Datatype; 4 import org.relaxng.datatype.ValidationContext; 5 6 class DataDerivFunction extends AbstractPatternFunction { 7 private final ValidatorPatternBuilder builder; 8 private final ValidationContext vc; 9 private final String str; 10 11 DataDerivFunction(String str, ValidationContext vc, ValidatorPatternBuilder builder) { 12 this.str = str; 13 this.vc = vc; 14 this.builder = builder; 15 } 16 17 static boolean isBlank(String str) { 18 int len = str.length(); 19 for (int i = 0; i < len; i++) { 20 switch (str.charAt(i)) { 21 case '\r': 22 case '\n': 23 case ' ': 24 case '\t': 25 break; 26 default: 27 return false; 28 } 29 } 30 return true; 31 } 32 33 public Object caseText(TextPattern p) { 34 return p; 35 } 36 37 public Object caseList(ListPattern p) { 38 int len = str.length(); 39 int tokenStart = -1; 40 PatternMemo memo = builder.getPatternMemo(p.getOperand()); 41 for (int i = 0; i < len; i++) { 42 switch (str.charAt(i)) { 43 case '\r': 44 case '\n': 45 case ' ': 46 case '\t': 47 if (tokenStart >= 0) { 48 memo = tokenDeriv(memo, tokenStart, i); 49 tokenStart = -1; 50 } 51 break; 52 default: 53 if (tokenStart < 0) 54 tokenStart = i; 55 break; 56 } 57 } 58 if (tokenStart >= 0) 59 memo = tokenDeriv(memo, tokenStart, len); 60 if (memo.getPattern().isNullable()) 61 return builder.makeEmpty(); 62 else 63 return builder.makeNotAllowed(); 64 } 65 66 private PatternMemo tokenDeriv(PatternMemo p, int i, int j) { 67 return p.dataDeriv(str.substring(i, j), vc); 68 } 69 70 public Object caseValue(ValuePattern p) { 71 Datatype dt = p.getDatatype(); 72 Object value = dt.createValue(str, vc); 73 if (value != null && dt.sameValue(p.getValue(), value)) 74 return builder.makeEmpty(); 75 else 76 return builder.makeNotAllowed(); 77 } 78 79 public Object caseData(DataPattern p) { 80 if (p.allowsAnyString()) 81 return builder.makeEmpty(); 82 if (p.getDatatype().isValid(str, vc)) 83 return builder.makeEmpty(); 84 else 85 return builder.makeNotAllowed(); 86 } 87 88 public Object caseDataExcept(DataExceptPattern p) { 89 Pattern tem = (Pattern)caseData(p); 90 if (tem.isNullable() && memoApply(p.getExcept()).isNullable()) 91 return builder.makeNotAllowed(); 92 return tem; 93 } 94 95 public Object caseAfter(AfterPattern p) { 96 Pattern p1 = p.getOperand1(); 97 if (memoApply(p1).isNullable() || (p1.isNullable() && isBlank(str))) 98 return p.getOperand2(); 99 return builder.makeNotAllowed(); 100 } 101 102 public Object caseChoice(ChoicePattern p) { 103 return builder.makeChoice(memoApply(p.getOperand1()), 104 memoApply(p.getOperand2())); 105 } 106 107 public Object caseGroup(GroupPattern p) { 108 final Pattern p1 = p.getOperand1(); 109 final Pattern p2 = p.getOperand2(); 110 Pattern tem = builder.makeGroup(memoApply(p1), p2); 111 if (!p1.isNullable()) 112 return tem; 113 return builder.makeChoice(tem, memoApply(p2)); 114 } 115 116 public Object caseInterleave(InterleavePattern p) { 117 final Pattern p1 = p.getOperand1(); 118 final Pattern p2 = p.getOperand2(); 119 return builder.makeChoice(builder.makeInterleave(memoApply(p1), p2), 120 builder.makeInterleave(p1, memoApply(p2))); 121 } 122 123 public Object caseOneOrMore(OneOrMorePattern p) { 124 return builder.makeGroup(memoApply(p.getOperand()), 125 builder.makeOptional(p)); 126 } 127 128 public Object caseOther(Pattern p) { 129 return builder.makeNotAllowed(); 130 } 131 132 private Pattern memoApply(Pattern p) { 133 return builder.getPatternMemo(p).dataDeriv(str, vc).getPattern(); 134 } 135 } 136 | Popular Tags |