01: package org.kohsuke.rngom.binary;
02:
03: import org.kohsuke.rngom.binary.visitor.PatternFunction;
04: import org.kohsuke.rngom.binary.visitor.PatternVisitor;
05: import org.kohsuke.rngom.nc.NameClass;
06: import org.xml.sax.Locator;
07: import org.xml.sax.SAXException;
08:
09: public final class ElementPattern extends Pattern {
10: private Pattern p;
11: private NameClass origNameClass;
12: private NameClass nameClass;
13: private boolean expanded = false;
14: private boolean checkedRestrictions = false;
15: private Locator loc;
16:
17: ElementPattern(NameClass nameClass, Pattern p, Locator loc) {
18: super (false, ELEMENT_CONTENT_TYPE, combineHashCode(
19: ELEMENT_HASH_CODE, nameClass.hashCode(), p.hashCode()));
20: this .nameClass = nameClass;
21: this .origNameClass = nameClass;
22: this .p = p;
23: this .loc = loc;
24: }
25:
26: void checkRestrictions(int context, DuplicateAttributeDetector dad,
27: Alphabet alpha) throws RestrictionViolationException {
28: if (alpha != null)
29: alpha.addElement(origNameClass);
30: if (checkedRestrictions)
31: return;
32: switch (context) {
33: case DATA_EXCEPT_CONTEXT:
34: throw new RestrictionViolationException(
35: "data_except_contains_element");
36: case LIST_CONTEXT:
37: throw new RestrictionViolationException(
38: "list_contains_element");
39: case ATTRIBUTE_CONTEXT:
40: throw new RestrictionViolationException(
41: "attribute_contains_element");
42: }
43: checkedRestrictions = true;
44: try {
45: p.checkRestrictions(ELEMENT_CONTEXT,
46: new DuplicateAttributeDetector(), null);
47: } catch (RestrictionViolationException e) {
48: checkedRestrictions = false;
49: e.maybeSetLocator(loc);
50: throw e;
51: }
52: }
53:
54: Pattern expand(SchemaPatternBuilder b) {
55: if (!expanded) {
56: expanded = true;
57: p = p.expand(b);
58: if (p.isNotAllowed())
59: nameClass = NameClass.NULL;
60: }
61: return this ;
62: }
63:
64: boolean samePattern(Pattern other) {
65: if (!(other instanceof ElementPattern))
66: return false;
67: ElementPattern ep = (ElementPattern) other;
68: return nameClass.equals(ep.nameClass) && p == ep.p;
69: }
70:
71: void checkRecursion(int depth) throws SAXException {
72: p.checkRecursion(depth + 1);
73: }
74:
75: public void accept(PatternVisitor visitor) {
76: visitor.visitElement(nameClass, p);
77: }
78:
79: public Object apply(PatternFunction f) {
80: return f.caseElement(this );
81: }
82:
83: void setContent(Pattern p) {
84: this .p = p;
85: }
86:
87: public Pattern getContent() {
88: return p;
89: }
90:
91: public NameClass getNameClass() {
92: return nameClass;
93: }
94:
95: public Locator getLocator() {
96: return loc;
97: }
98: }
|