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 }