001: package org.kohsuke.rngom.binary;
002:
003: import org.kohsuke.rngom.binary.visitor.PatternFunction;
004: import org.kohsuke.rngom.binary.visitor.PatternVisitor;
005: import org.kohsuke.rngom.nc.NameClass;
006: import org.kohsuke.rngom.nc.SimpleNameClass;
007: import org.xml.sax.Locator;
008: import org.xml.sax.SAXException;
009:
010: public final class AttributePattern extends Pattern {
011: private NameClass nameClass;
012: private Pattern p;
013: private Locator loc;
014:
015: AttributePattern(NameClass nameClass, Pattern value, Locator loc) {
016: super (false, EMPTY_CONTENT_TYPE, combineHashCode(
017: ATTRIBUTE_HASH_CODE, nameClass.hashCode(), value
018: .hashCode()));
019: this .nameClass = nameClass;
020: this .p = value;
021: this .loc = loc;
022: }
023:
024: Pattern expand(SchemaPatternBuilder b) {
025: Pattern ep = p.expand(b);
026: if (ep != p)
027: return b.makeAttribute(nameClass, ep, loc);
028: else
029: return this ;
030: }
031:
032: void checkRestrictions(int context, DuplicateAttributeDetector dad,
033: Alphabet alpha) throws RestrictionViolationException {
034: switch (context) {
035: case START_CONTEXT:
036: throw new RestrictionViolationException(
037: "start_contains_attribute");
038: case ELEMENT_CONTEXT:
039: if (nameClass.isOpen())
040: throw new RestrictionViolationException(
041: "open_name_class_not_repeated");
042: break;
043: case ELEMENT_REPEAT_GROUP_CONTEXT:
044: throw new RestrictionViolationException(
045: "one_or_more_contains_group_contains_attribute");
046: case ELEMENT_REPEAT_INTERLEAVE_CONTEXT:
047: throw new RestrictionViolationException(
048: "one_or_more_contains_interleave_contains_attribute");
049: case LIST_CONTEXT:
050: throw new RestrictionViolationException(
051: "list_contains_attribute");
052: case ATTRIBUTE_CONTEXT:
053: throw new RestrictionViolationException(
054: "attribute_contains_attribute");
055: case DATA_EXCEPT_CONTEXT:
056: throw new RestrictionViolationException(
057: "data_except_contains_attribute");
058: }
059: if (!dad.addAttribute(nameClass)) {
060: if (nameClass instanceof SimpleNameClass)
061: throw new RestrictionViolationException(
062: "duplicate_attribute_detail",
063: ((SimpleNameClass) nameClass).name);
064: else
065: throw new RestrictionViolationException(
066: "duplicate_attribute");
067: }
068: try {
069: p.checkRestrictions(ATTRIBUTE_CONTEXT, null, null);
070: } catch (RestrictionViolationException e) {
071: e.maybeSetLocator(loc);
072: throw e;
073: }
074: }
075:
076: boolean samePattern(Pattern other) {
077: if (!(other instanceof AttributePattern))
078: return false;
079: AttributePattern ap = (AttributePattern) other;
080: return nameClass.equals(ap.nameClass) && p == ap.p;
081: }
082:
083: void checkRecursion(int depth) throws SAXException {
084: p.checkRecursion(depth);
085: }
086:
087: public void accept(PatternVisitor visitor) {
088: visitor.visitAttribute(nameClass, p);
089: }
090:
091: public Object apply(PatternFunction f) {
092: return f.caseAttribute(this );
093: }
094:
095: public Pattern getContent() {
096: return p;
097: }
098:
099: public NameClass getNameClass() {
100: return nameClass;
101: }
102:
103: public Locator getLocator() {
104: return loc;
105: }
106: }
|