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    }