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 }