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