001    package com.thaiopensource.validate.nrl;
002    
003    import com.thaiopensource.util.Equal;
004    import com.thaiopensource.validate.nrl.ContextMap;
005    import com.thaiopensource.validate.nrl.Mode;
006    
007    import java.util.Vector;
008    import java.util.Enumeration;
009    
010    class ModeUsage {
011      private final Mode mode;
012      private final Mode currentMode;
013      private ContextMap modeMap;
014      private int attributeProcessing = -1;
015    
016      ModeUsage(Mode mode, Mode currentMode) {
017        this(mode, currentMode, null);
018      }
019    
020      private ModeUsage(Mode mode, Mode currentMode, ContextMap modeMap) {
021        this.mode = mode;
022        this.currentMode = currentMode;
023        this.modeMap = modeMap;
024      }
025    
026      ModeUsage changeCurrentMode(Mode currentMode) {
027        return new ModeUsage(mode, currentMode, modeMap);
028      }
029    
030      public boolean equals(Object obj) {
031        if (!(obj instanceof ModeUsage))
032          return false;
033        ModeUsage other = (ModeUsage)obj;
034        return this.mode == other.mode && this.currentMode == other.currentMode && Equal.equal(this.modeMap, other.modeMap);
035      }
036    
037      public int hashCode() {
038        int hc = mode.hashCode() ^ currentMode.hashCode();
039        if (modeMap != null)
040          hc ^= modeMap.hashCode();
041        return hc;
042      }
043    
044      private Mode resolve(Mode mode) {
045        return mode == Mode.CURRENT ? currentMode : mode;
046      }
047    
048      int getAttributeProcessing() {
049        if (attributeProcessing == -1) {
050          attributeProcessing = resolve(mode).getAttributeProcessing();
051          if (modeMap != null) {
052            for (Enumeration en = modeMap.values();
053                 en.hasMoreElements()
054                 && attributeProcessing != Mode.ATTRIBUTE_PROCESSING_FULL;)
055              attributeProcessing = Math.max(resolve((Mode)en.nextElement()).getAttributeProcessing(),
056                                             attributeProcessing);
057          }
058        }
059        return attributeProcessing;
060      }
061    
062      boolean isContextDependent() {
063        return modeMap != null;
064      }
065    
066      Mode getMode(Vector context) {
067        if (modeMap != null) {
068          Mode m = (Mode)modeMap.get(context);
069          if (m != null)
070            return resolve(m);
071        }
072        return resolve(mode);
073      }
074    
075      boolean addContext(boolean isRoot, Vector names, Mode mode) {
076        if (modeMap == null)
077          modeMap = new ContextMap();
078        return modeMap.put(isRoot, names, mode);
079      }
080    }