001    package com.thaiopensource.relaxng.impl;
002    
003    import org.xml.sax.SAXException;
004    import com.thaiopensource.relaxng.parse.ParsedPattern;
005    
006    public abstract class Pattern implements ParsedPattern {
007      private final boolean nullable;
008      private final int hc;
009      private final int contentType;
010    
011      static final int TEXT_HASH_CODE = 1;
012      static final int ERROR_HASH_CODE = 3;
013      static final int EMPTY_HASH_CODE = 5;
014      static final int NOT_ALLOWED_HASH_CODE = 7;
015      static final int CHOICE_HASH_CODE = 11;
016      static final int GROUP_HASH_CODE = 13;
017      static final int INTERLEAVE_HASH_CODE = 17;
018      static final int ONE_OR_MORE_HASH_CODE = 19;
019      static final int ELEMENT_HASH_CODE = 23;
020      static final int VALUE_HASH_CODE = 27;
021      static final int ATTRIBUTE_HASH_CODE = 29;
022      static final int DATA_HASH_CODE = 31;
023      static final int LIST_HASH_CODE = 37;
024      static final int AFTER_HASH_CODE = 41;
025    
026      static int combineHashCode(int hc1, int hc2, int hc3) {
027        return hc1 * hc2 * hc3;
028      }
029    
030      static int combineHashCode(int hc1, int hc2) {
031        return hc1 * hc2;
032      }
033    
034      static final int EMPTY_CONTENT_TYPE = 0;
035      static final int ELEMENT_CONTENT_TYPE = 1;
036      static final int MIXED_CONTENT_TYPE = 2;
037      static final int DATA_CONTENT_TYPE = 3;
038    
039      Pattern(boolean nullable, int contentType, int hc) {
040        this.nullable = nullable;
041        this.contentType = contentType;
042        this.hc = hc;
043      }
044    
045      Pattern() {
046        this.nullable = false;
047        this.hc = hashCode();
048        this.contentType = EMPTY_CONTENT_TYPE;
049      }
050    
051      void checkRecursion(int depth) throws SAXException { }
052    
053      Pattern expand(SchemaPatternBuilder b) {
054        return this;
055      }
056    
057      final boolean isNullable() {
058        return nullable;
059      }
060    
061      boolean isNotAllowed() {
062        return false;
063      }
064    
065      static final int START_CONTEXT = 0;
066      static final int ELEMENT_CONTEXT = 1;
067      static final int ELEMENT_REPEAT_CONTEXT = 2;
068      static final int ELEMENT_REPEAT_GROUP_CONTEXT = 3;
069      static final int ELEMENT_REPEAT_INTERLEAVE_CONTEXT = 4;
070      static final int ATTRIBUTE_CONTEXT = 5;
071      static final int LIST_CONTEXT = 6;
072      static final int DATA_EXCEPT_CONTEXT = 7;
073    
074      void checkRestrictions(int context, DuplicateAttributeDetector dad, Alphabet alpha)
075        throws RestrictionViolationException {
076      }
077    
078      // Know that other is not null
079      abstract boolean samePattern(Pattern other);
080    
081      final int patternHashCode() {
082        return hc;
083      }
084    
085      final int getContentType() {
086        return contentType;
087      }
088    
089      boolean containsChoice(Pattern p) {
090        return this == p;
091      }
092    
093      abstract void accept(PatternVisitor visitor);
094      abstract Object apply(PatternFunction f);
095    
096      Pattern applyForPattern(PatternFunction f) {
097        return (Pattern)apply(f);
098      }
099    
100      static boolean contentTypeGroupable(int ct1, int ct2) {
101        if (ct1 == EMPTY_CONTENT_TYPE || ct2 == EMPTY_CONTENT_TYPE)
102          return true;
103        if (ct1 == DATA_CONTENT_TYPE || ct2 == DATA_CONTENT_TYPE)
104          return false;
105        return true;
106      }
107    
108    }