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 }