001    package com.thaiopensource.relaxng.impl;
002    
003    import org.xml.sax.Locator;
004    import org.xml.sax.SAXException;
005    import org.xml.sax.SAXParseException;
006    
007    class RefPattern extends Pattern {
008      private Pattern p;
009      private Locator refLoc;
010      private final String name;
011      private int checkRecursionDepth = -1;
012      private boolean combineImplicit = false;
013      private byte combineType = COMBINE_NONE;
014      private byte replacementStatus = REPLACEMENT_KEEP;
015      private boolean expanded = false;
016    
017      static final byte REPLACEMENT_KEEP = 0;
018      static final byte REPLACEMENT_REQUIRE = 1;
019      static final byte REPLACEMENT_IGNORE = 2;
020    
021      static final byte COMBINE_NONE = 0;
022      static final byte COMBINE_CHOICE = 1;
023      static final byte COMBINE_INTERLEAVE = 2;
024    
025      RefPattern(String name) {
026        this.name = name;
027      }
028    
029      Pattern getPattern() {
030        return p;
031      }
032      
033      void setPattern(Pattern p) {
034        this.p = p;
035      }
036    
037      Locator getRefLocator() {
038        return refLoc;
039      }
040      
041      void setRefLocator(Locator loc) {
042        this.refLoc = loc;
043      }
044      
045      void checkRecursion(int depth) throws SAXException {
046        if (checkRecursionDepth == -1) {
047          checkRecursionDepth = depth;
048          p.checkRecursion(depth);
049          checkRecursionDepth = -2;
050        }
051        else if (depth == checkRecursionDepth)
052          // XXX try to recover from this?
053          throw new SAXParseException(SchemaBuilderImpl.localizer.message("recursive_reference", name),
054                                      refLoc);
055      }
056    
057      Pattern expand(SchemaPatternBuilder b) {
058        if (!expanded) {
059          p = p.expand(b);
060          expanded = true;
061        }
062        return p;
063      }
064    
065      boolean samePattern(Pattern other) {
066        return false;
067      }
068    
069      void accept(PatternVisitor visitor) {
070        p.accept(visitor);
071      }
072    
073      Object apply(PatternFunction f) {
074        return f.caseRef(this);
075      }
076    
077      byte getReplacementStatus() {
078        return replacementStatus;
079      }
080      
081      void setReplacementStatus(byte replacementStatus) {
082        this.replacementStatus = replacementStatus;
083      }
084    
085      boolean isCombineImplicit() {
086        return combineImplicit;
087      }
088    
089      void setCombineImplicit() {
090        combineImplicit = true;
091      }
092    
093      byte getCombineType() {
094        return combineType;
095      }
096    
097      void setCombineType(byte combineType) {
098        this.combineType = combineType;
099      }
100    
101      String getName() {
102        return name;
103      }
104    }
105