1
package com.thaiopensource.validate.nvdl;
3
import com.thaiopensource.util.Equal;
5
import java.util.Vector;
6
import java.util.Enumeration;
9
* Stores mode usage information.
15
private final Mode mode;
18
* The current mode used until now.
20
private final Mode currentMode;
23
* Modes depending on context.
25
private ContextMap modeMap;
26
private int attributeProcessing = -1;
30
* @param mode The mode to be used.
31
* @param currentMode The mode used until the new mode.
33
ModeUsage(Mode mode, Mode currentMode) {
34
this(mode, currentMode, null);
39
* @param mode The mode to be used.
40
* @param currentMode The mode used until now.
41
* @param modeMap Modes to be used depending on context.
43
private ModeUsage(Mode mode, Mode currentMode, ContextMap modeMap) {
45
this.currentMode = currentMode;
46
this.modeMap = modeMap;
50
* Gets a new mode usage with a different current mode
51
* but with the same mode and modeMap as this one.
52
* @param currentMode The new current mode.
53
* @return A new mode usage with the changed current mode.
55
ModeUsage changeCurrentMode(Mode currentMode) {
56
return new ModeUsage(mode, currentMode, modeMap);
60
* Check to see if this mode usage is equals with another mode usage.
62
public boolean equals(Object obj) {
63
if (!(obj instanceof ModeUsage))
65
ModeUsage other = (ModeUsage)obj;
66
return this.mode == other.mode && this.currentMode == other.currentMode && Equal.equal(this.modeMap, other.modeMap);
70
* Gets a hash code for this mode usage.
72
public int hashCode() {
73
int hc = mode.hashCode() ^ currentMode.hashCode();
75
hc ^= modeMap.hashCode();
80
* Resolves the Mode.CURRENT to the currentMode for this mode usage.
81
* If Mode.CURRENT is not passed as argument then the same mode is returned
82
* with the exception of an anonymous mode that is not defined, when we
83
* get also the current mode.
84
* @param mode The mode to be resolved.
85
* @return Either the current mode mode usage or the same mode passed as argument.
87
private Mode resolve(Mode mode) {
88
if (mode == Mode.CURRENT) {
91
// For an action that does not specify the useMode attribute
92
// we create an anonymous next mode that becomes defined if we
93
// have a nested mode element inside the action.
94
// If we do not have a nested mode then the anonymous mode
95
// is not defined and basically that means we should use the
96
// current mode to perform that action.
97
if (mode.isAnonymous() && !mode.isDefined()) {
104
* Get the maximum attribute processing value from the default mode and
105
* from all the modes specified in the contexts.
106
* @return The attribute processing value.
108
int getAttributeProcessing() {
109
if (attributeProcessing == -1) {
110
attributeProcessing = resolve(mode).getAttributeProcessing();
111
if (modeMap != null) {
112
for (Enumeration e = modeMap.values();
114
&& attributeProcessing != Mode.ATTRIBUTE_PROCESSING_FULL;)
115
attributeProcessing = Math.max(resolve((Mode)e.nextElement()).getAttributeProcessing(),
116
attributeProcessing);
119
return attributeProcessing;
123
* Check if we have context dependent modes.
124
* @return true if the modeMap exists.
126
boolean isContextDependent() {
127
return modeMap != null;
131
* Get the mode to be used for a specific context.
132
* @param context The current context.
135
Mode getMode(Vector context) {
136
// first look in the modeMap if exists.
137
if (modeMap != null) {
138
Mode m = (Mode)modeMap.get(context);
142
// if no modeMap or no context specific mode found then
143
// return the default mode for this mode usage.
144
return resolve(mode);
148
* Adds a new context (isRoot, path --> mode).
149
* @param isRoot Flag indicating that the path starts or not with /
150
* @param names The local names that form the path.
151
* @param mode The mode for this path.
152
* @return true if we do not have a duplicate path.
154
boolean addContext(boolean isRoot, Vector names, Mode mode) {
156
modeMap = new ContextMap();
157
return modeMap.put(isRoot, names, mode);