001    package com.thaiopensource.relaxng.impl;
002    
003    import org.xml.sax.Locator;
004    import org.xml.sax.SAXException;
005    
006    class ElementPattern extends Pattern {
007      private Pattern p;
008      private final NameClass origNameClass;
009      private NameClass nameClass;
010      private boolean expanded = false;
011      private boolean checkedRestrictions = false;
012      private final Locator loc;
013    
014      ElementPattern(NameClass nameClass, Pattern p, Locator loc) {
015        super(false,
016              ELEMENT_CONTENT_TYPE,
017              combineHashCode(ELEMENT_HASH_CODE,
018                              nameClass.hashCode(),
019                              p.hashCode()));
020        this.nameClass = nameClass;
021        this.origNameClass = nameClass;
022        this.p = p;
023        this.loc = loc;
024      }
025    
026      void checkRestrictions(int context, DuplicateAttributeDetector dad, Alphabet alpha)
027        throws RestrictionViolationException {
028        if (alpha != null)
029          alpha.addElement(origNameClass);
030        if (checkedRestrictions)
031          return;
032        switch (context) {
033        case DATA_EXCEPT_CONTEXT:
034          throw new RestrictionViolationException("data_except_contains_element");
035        case LIST_CONTEXT:
036          throw new RestrictionViolationException("list_contains_element");
037        case ATTRIBUTE_CONTEXT:
038          throw new RestrictionViolationException("attribute_contains_element");
039        }
040        checkedRestrictions = true;
041        try {
042          p.checkRestrictions(ELEMENT_CONTEXT, new DuplicateAttributeDetector(), null);
043        }
044        catch (RestrictionViolationException e) {
045          checkedRestrictions = false;
046          e.maybeSetLocator(loc);
047          throw e;
048        }
049      }
050    
051      Pattern expand(SchemaPatternBuilder b) {
052        if (!expanded) {
053          expanded = true;
054          p = p.expand(b);
055          if (p.isNotAllowed())
056            nameClass = new NullNameClass();
057        }
058        return this;
059      }
060    
061      boolean samePattern(Pattern other) {
062        if (!(other instanceof ElementPattern))
063          return false;
064        ElementPattern ep = (ElementPattern)other;
065        return nameClass.equals(ep.nameClass) && p == ep.p;
066      }
067    
068      void checkRecursion(int depth) throws SAXException {
069        p.checkRecursion(depth + 1);
070      }
071    
072      void accept(PatternVisitor visitor) {
073        visitor.visitElement(nameClass, p);
074      }
075    
076      Object apply(PatternFunction f) {
077        return f.caseElement(this);
078      }
079    
080      void setContent(Pattern p) {
081        this.p = p;
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    }