1 package com.thaiopensource.relaxng.impl; 2 3 import java.util.Hashtable ; 4 5 public class ValidatorPatternBuilder extends PatternBuilder { 6 private final Hashtable patternMemoMap = new Hashtable (); 7 private final PatternFunction endAttributesFunction; 8 private final PatternFunction ignoreMissingAttributesFunction; 9 private final PatternFunction endTagDerivFunction; 10 private final PatternFunction mixedTextDerivFunction; 11 private final PatternFunction textOnlyFunction; 12 private final PatternFunction recoverAfterFunction; 13 private final PatternFunction dataDerivTypeFunction; 14 15 private final Hashtable choiceMap = new Hashtable (); 16 private final PatternFunction removeChoicesFunction = new RemoveChoicesFunction(); 17 private final PatternFunction noteChoicesFunction = new NoteChoicesFunction(); 18 19 private class NoteChoicesFunction extends AbstractPatternFunction { 20 public Object caseOther(Pattern p) { 21 choiceMap.put(p, p); 22 return null; 23 } 24 25 public Object caseChoice(ChoicePattern p) { 26 p.getOperand1().apply(this); 27 p.getOperand2().apply(this); 28 return null; 29 } 30 } 31 32 private class RemoveChoicesFunction extends AbstractPatternFunction { 33 public Object caseOther(Pattern p) { 34 if (choiceMap.get(p) != null) 35 return notAllowed; 36 return p; 37 } 38 39 public Object caseChoice(ChoicePattern p) { 40 Pattern p1 = p.getOperand1().applyForPattern(this); 41 Pattern p2 = p.getOperand2().applyForPattern(this); 42 if (p1 == p.getOperand1() && p2 == p.getOperand2()) 43 return p; 44 if (p1 == notAllowed) 45 return p2; 46 if (p2 == notAllowed) 47 return p1; 48 Pattern p3 = new ChoicePattern(p1, p2); 49 return interner.intern(p3); 50 } 51 } 52 53 public ValidatorPatternBuilder(PatternBuilder builder) { 54 super(builder); 55 endAttributesFunction = new EndAttributesFunction(this); 56 ignoreMissingAttributesFunction = new IgnoreMissingAttributesFunction(this); 57 endTagDerivFunction = new EndTagDerivFunction(this); 58 mixedTextDerivFunction = new MixedTextDerivFunction(this); 59 textOnlyFunction = new TextOnlyFunction(this); 60 recoverAfterFunction = new RecoverAfterFunction(this); 61 dataDerivTypeFunction = new DataDerivTypeFunction(this); 62 } 63 64 PatternMemo getPatternMemo(Pattern p) { 65 PatternMemo memo = (PatternMemo)patternMemoMap.get(p); 66 if (memo == null) { 67 memo = new PatternMemo(p, this); 68 patternMemoMap.put(p, memo); 69 } 70 return memo; 71 } 72 73 PatternFunction getEndAttributesFunction() { 74 return endAttributesFunction; 75 } 76 77 PatternFunction getIgnoreMissingAttributesFunction() { 78 return ignoreMissingAttributesFunction; 79 } 80 81 PatternFunction getEndTagDerivFunction() { 82 return endTagDerivFunction; 83 } 84 85 PatternFunction getMixedTextDerivFunction() { 86 return mixedTextDerivFunction; 87 } 88 89 PatternFunction getTextOnlyFunction() { 90 return textOnlyFunction; 91 } 92 93 PatternFunction getRecoverAfterFunction() { 94 return recoverAfterFunction; 95 } 96 97 PatternFunction getDataDerivTypeFunction() { 98 return dataDerivTypeFunction; 99 } 100 101 Pattern makeAfter(Pattern p1, Pattern p2) { 102 Pattern p = new AfterPattern(p1, p2); 103 return interner.intern(p); 104 } 105 106 Pattern makeChoice(Pattern p1, Pattern p2) { 107 if (p1 == p2) 108 return p1; 109 if (p1 == notAllowed) 110 return p2; 111 if (p2 == notAllowed) 112 return p1; 113 if (!(p1 instanceof ChoicePattern)) { 114 if (p2.containsChoice(p1)) 115 return p2; 116 } 117 else if (!(p2 instanceof ChoicePattern)) { 118 if (p1.containsChoice(p2)) 119 return p1; 120 } 121 else { 122 p1.apply(noteChoicesFunction); 123 p2 = p2.applyForPattern(removeChoicesFunction); 124 if (choiceMap.size() > 0) 125 choiceMap.clear(); 126 } 127 if (p1 instanceof AfterPattern && p2 instanceof AfterPattern) { 128 AfterPattern ap1 = (AfterPattern)p1; 129 AfterPattern ap2 = (AfterPattern)p2; 130 if (ap1.getOperand1() == ap2.getOperand1()) 131 return makeAfter(ap1.getOperand1(), makeChoice(ap1.getOperand2(), ap2.getOperand2())); 132 if (ap1.getOperand1() == notAllowed) 133 return ap2; 134 if (ap2.getOperand1() == notAllowed) 135 return ap1; 136 if (ap1.getOperand2() == ap2.getOperand2()) 137 return makeAfter(makeChoice(ap1.getOperand1(), ap2.getOperand1()), ap1.getOperand2()); 138 } 139 return super.makeChoice(p1, p2); 140 } 141 } 142 | Popular Tags |