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