001 package com.thaiopensource.validate.nrl;
002
003 import org.xml.sax.Locator;
004 import org.xml.sax.helpers.LocatorImpl;
005
006 import java.util.Hashtable;
007 import java.util.Enumeration;
008
009 import com.thaiopensource.validate.nrl.ActionSet;
010 import com.thaiopensource.validate.nrl.AttributeActionSet;
011
012 class Mode {
013 static final String ANY_NAMESPACE = "##any";
014 static final int ATTRIBUTE_PROCESSING_NONE = 0;
015 static final int ATTRIBUTE_PROCESSING_QUALIFIED = 1;
016 static final int ATTRIBUTE_PROCESSING_FULL = 2;
017 static final Mode CURRENT = new Mode("#current", null);
018
019 private final String name;
020 private Mode baseMode;
021 private boolean defined;
022 private Locator whereDefined;
023 private Locator whereUsed;
024 private final Hashtable elementMap = new Hashtable();
025 private final Hashtable attributeMap = new Hashtable();
026 private int attributeProcessing = -1;
027
028 Mode(String name, Mode baseMode) {
029 this.name = name;
030 this.baseMode = baseMode;
031 }
032
033 String getName() {
034 return name;
035 }
036
037 Mode getBaseMode() {
038 return baseMode;
039 }
040
041 void setBaseMode(Mode baseMode) {
042 this.baseMode = baseMode;
043 }
044
045 ActionSet getElementActions(String ns) {
046 ActionSet actions = getElementActionsExplicit(ns);
047 if (actions == null) {
048 actions = getElementActionsExplicit(ANY_NAMESPACE);
049 // this is not correct: it breaks a derived mode that use anyNamespace
050 // elementMap.put(ns, actions);
051 }
052 return actions;
053 }
054
055 private ActionSet getElementActionsExplicit(String ns) {
056 ActionSet actions = (ActionSet)elementMap.get(ns);
057 if (actions == null && baseMode != null) {
058 actions = baseMode.getElementActionsExplicit(ns);
059 if (actions != null) {
060 actions = actions.changeCurrentMode(this);
061 elementMap.put(ns, actions);
062 }
063 }
064 return actions;
065 }
066
067 AttributeActionSet getAttributeActions(String ns) {
068 AttributeActionSet actions = getAttributeActionsExplicit(ns);
069 if (actions == null) {
070 actions = getAttributeActionsExplicit(ANY_NAMESPACE);
071 // this is not correct: it breaks a derived mode that use anyNamespace
072 // attributeMap.put(ns, actions);
073 }
074 return actions;
075 }
076
077 private AttributeActionSet getAttributeActionsExplicit(String ns) {
078 AttributeActionSet actions = (AttributeActionSet)attributeMap.get(ns);
079 if (actions == null && baseMode != null) {
080 actions = baseMode.getAttributeActionsExplicit(ns);
081 if (actions != null)
082 attributeMap.put(ns, actions);
083 }
084 return actions;
085 }
086
087 int getAttributeProcessing() {
088 if (attributeProcessing == -1) {
089 if (baseMode != null)
090 attributeProcessing = baseMode.getAttributeProcessing();
091 else
092 attributeProcessing = ATTRIBUTE_PROCESSING_NONE;
093 for (Enumeration en = attributeMap.keys(); en.hasMoreElements() && attributeProcessing != ATTRIBUTE_PROCESSING_FULL;) {
094 String ns = (String)en.nextElement();
095 AttributeActionSet actions = (AttributeActionSet)attributeMap.get(ns);
096 if (!actions.getAttach()
097 || actions.getReject()
098 || actions.getSchemas().length > 0)
099 attributeProcessing = ((ns.equals("") || ns.equals(ANY_NAMESPACE))
100 ? ATTRIBUTE_PROCESSING_FULL
101 : ATTRIBUTE_PROCESSING_QUALIFIED);
102 }
103 }
104 return attributeProcessing;
105 }
106
107 Locator getWhereDefined() {
108 return whereDefined;
109 }
110
111 boolean isDefined() {
112 return defined;
113 }
114
115 Locator getWhereUsed() {
116 return whereUsed;
117 }
118
119 void noteUsed(Locator locator) {
120 if (whereUsed == null && locator != null)
121 whereUsed = new LocatorImpl(locator);
122 }
123
124 void noteDefined(Locator locator) {
125 defined = true;
126 if (whereDefined == null && locator != null)
127 whereDefined = new LocatorImpl(locator);
128 }
129
130 boolean bindElement(String ns, ActionSet actions) {
131 if (elementMap.get(ns) != null)
132 return false;
133 elementMap.put(ns, actions);
134 return true;
135 }
136
137 boolean bindAttribute(String ns, AttributeActionSet actions) {
138 if (attributeMap.get(ns) != null)
139 return false;
140 attributeMap.put(ns, actions);
141 return true;
142 }
143
144 }