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 }