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 }