001 package com.thaiopensource.relaxng.impl; 002 003 import org.relaxng.datatype.ValidationContext; 004 005 import java.util.Hashtable; 006 007 import com.thaiopensource.xml.util.Name; 008 009 final class PatternMemo { 010 private final Pattern pattern; 011 private final ValidatorPatternBuilder builder; 012 private final boolean notAllowed; 013 private PatternMemo memoEndAttributes; 014 private PatternMemo memoTextOnly; 015 private PatternMemo memoEndTagDeriv; 016 private PatternMemo memoMixedTextDeriv; 017 private PatternMemo memoIgnoreMissingAttributes; 018 private Hashtable startTagOpenDerivMap; 019 private Hashtable startTagOpenRecoverDerivMap; 020 private Hashtable startAttributeDerivMap; 021 private DataDerivType memoDataDerivType; 022 023 PatternMemo(Pattern pattern, ValidatorPatternBuilder builder) { 024 this.pattern = pattern; 025 this.builder = builder; 026 this.notAllowed = pattern.isNotAllowed(); 027 } 028 029 Pattern getPattern() { 030 return pattern; 031 } 032 033 ValidatorPatternBuilder getPatternBuilder() { 034 return builder; 035 } 036 037 boolean isNotAllowed() { 038 return notAllowed; 039 } 040 041 PatternMemo endAttributes() { 042 if (memoEndAttributes == null) 043 memoEndAttributes = applyForPatternMemo(builder.getEndAttributesFunction()); 044 return memoEndAttributes; 045 } 046 047 PatternMemo endAttributes(PatternFunction f) { 048 if (memoEndAttributes == null) 049 memoEndAttributes = applyForPatternMemo(f); 050 return memoEndAttributes; 051 } 052 053 PatternMemo ignoreMissingAttributes() { 054 if (memoIgnoreMissingAttributes == null) 055 memoIgnoreMissingAttributes 056 = applyForPatternMemo(builder.getIgnoreMissingAttributesFunction()); 057 return memoIgnoreMissingAttributes; 058 } 059 060 PatternMemo ignoreMissingAttributes(PatternFunction f) { 061 if (memoIgnoreMissingAttributes == null) 062 memoIgnoreMissingAttributes = applyForPatternMemo(f); 063 return memoIgnoreMissingAttributes; 064 } 065 066 PatternMemo textOnly() { 067 if (memoTextOnly == null) 068 memoTextOnly = applyForPatternMemo(builder.getTextOnlyFunction()); 069 return memoTextOnly; 070 } 071 072 PatternMemo textOnly(PatternFunction f) { 073 if (memoTextOnly == null) 074 memoTextOnly = applyForPatternMemo(f); 075 return memoTextOnly; 076 } 077 078 PatternMemo endTagDeriv() { 079 if (memoEndTagDeriv == null) 080 memoEndTagDeriv = applyForPatternMemo(builder.getEndTagDerivFunction()); 081 return memoEndTagDeriv; 082 } 083 084 PatternMemo endTagDeriv(PatternFunction f) { 085 if (memoEndTagDeriv == null) 086 memoEndTagDeriv = applyForPatternMemo(f); 087 return memoEndTagDeriv; 088 } 089 090 091 PatternMemo mixedTextDeriv() { 092 if (memoMixedTextDeriv == null) 093 memoMixedTextDeriv = applyForPatternMemo(builder.getMixedTextDerivFunction()); 094 return memoMixedTextDeriv; 095 } 096 097 PatternMemo mixedTextDeriv(PatternFunction f) { 098 if (memoMixedTextDeriv == null) 099 memoMixedTextDeriv = applyForPatternMemo(f); 100 return memoMixedTextDeriv; 101 } 102 103 PatternMemo startTagOpenDeriv(Name name) { 104 return startTagOpenDeriv(name, null); 105 } 106 107 PatternMemo startTagOpenDeriv(StartTagOpenDerivFunction f) { 108 return startTagOpenDeriv(f.getName(), f); 109 } 110 111 private PatternMemo startTagOpenDeriv(Name name, StartTagOpenDerivFunction f) { 112 PatternMemo tem; 113 if (startTagOpenDerivMap == null) 114 startTagOpenDerivMap = new Hashtable(); 115 else { 116 tem = (PatternMemo)startTagOpenDerivMap.get(name); 117 if (tem != null) 118 return tem; 119 } 120 if (f == null) 121 f = new StartTagOpenDerivFunction(name, builder); 122 tem = applyForPatternMemo(f); 123 startTagOpenDerivMap.put(name, tem); 124 return tem; 125 } 126 127 PatternMemo startTagOpenRecoverDeriv(Name name) { 128 return startTagOpenRecoverDeriv(name, null); 129 } 130 131 PatternMemo startTagOpenRecoverDeriv(StartTagOpenRecoverDerivFunction f) { 132 return startTagOpenRecoverDeriv(f.getName(), f); 133 } 134 135 private PatternMemo startTagOpenRecoverDeriv(Name name, StartTagOpenRecoverDerivFunction f) { 136 PatternMemo tem; 137 if (startTagOpenRecoverDerivMap == null) 138 startTagOpenRecoverDerivMap = new Hashtable(); 139 else { 140 tem = (PatternMemo)startTagOpenRecoverDerivMap.get(name); 141 if (tem != null) 142 return tem; 143 } 144 if (f == null) 145 f = new StartTagOpenRecoverDerivFunction(name, builder); 146 tem = applyForPatternMemo(f); 147 startTagOpenRecoverDerivMap.put(name, tem); 148 return tem; 149 } 150 151 PatternMemo startAttributeDeriv(Name name) { 152 return startAttributeDeriv(name, null); 153 } 154 155 PatternMemo startAttributeDeriv(StartAttributeDerivFunction f) { 156 return startAttributeDeriv(f.getName(), f); 157 } 158 159 private PatternMemo startAttributeDeriv(Name name, StartAttributeDerivFunction f) { 160 PatternMemo tem; 161 if (startAttributeDerivMap == null) 162 startAttributeDerivMap = new Hashtable(); 163 else { 164 tem = (PatternMemo)startAttributeDerivMap.get(name); 165 if (tem != null) 166 return tem; 167 } 168 if (f == null) 169 f = new StartAttributeDerivFunction(name, builder); 170 tem = applyForPatternMemo(f); 171 startAttributeDerivMap.put(name, tem); 172 return tem; 173 } 174 175 DataDerivType dataDerivType() { 176 if (memoDataDerivType == null) 177 memoDataDerivType = DataDerivTypeFunction.dataDerivType(builder, pattern).copy(); 178 return memoDataDerivType; 179 } 180 181 PatternMemo dataDeriv(String str, ValidationContext vc) { 182 return dataDerivType().dataDeriv(builder, pattern, str, vc); 183 } 184 185 PatternMemo recoverAfter() { 186 // XXX memoize 187 return applyForPatternMemo(builder.getRecoverAfterFunction()); 188 } 189 190 private PatternMemo applyForPatternMemo(PatternFunction f) { 191 return builder.getPatternMemo(pattern.applyForPattern(f)); 192 } 193 }