~ubuntu-branches/ubuntu/utopic/jing-trang/utopic

« back to all changes in this revision

Viewing changes to mod/nvdl/src/main/com/thaiopensource/validate/nvdl/ModeUsage.java

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Thibault
  • Date: 2009-09-01 15:53:03 UTC
  • Revision ID: james.westby@ubuntu.com-20090901155303-2kweef05h5v9j3ni
Tags: upstream-20090818
ImportĀ upstreamĀ versionĀ 20090818

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package com.thaiopensource.validate.nvdl;
 
2
 
 
3
import com.thaiopensource.util.Equal;
 
4
 
 
5
import java.util.Vector;
 
6
import java.util.Enumeration;
 
7
 
 
8
/**
 
9
 * Stores mode usage information.
 
10
 */
 
11
class ModeUsage {
 
12
  /**
 
13
   * The use mode.
 
14
   */
 
15
  private final Mode mode;
 
16
  
 
17
  /**
 
18
   * The current mode used until now.
 
19
   */
 
20
  private final Mode currentMode;
 
21
  
 
22
  /**
 
23
   * Modes depending on context.
 
24
   */
 
25
  private ContextMap modeMap;
 
26
  private int attributeProcessing = -1;
 
27
 
 
28
  /**
 
29
   * Creates a use mode.
 
30
   * @param mode The mode to be used.
 
31
   * @param currentMode The mode used until the new mode.
 
32
   */
 
33
  ModeUsage(Mode mode, Mode currentMode) {
 
34
    this(mode, currentMode, null);
 
35
  }
 
36
 
 
37
  /**
 
38
   * Creates a use mode.
 
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.
 
42
   */
 
43
  private ModeUsage(Mode mode, Mode currentMode, ContextMap modeMap) {
 
44
    this.mode = mode;
 
45
    this.currentMode = currentMode;
 
46
    this.modeMap = modeMap;
 
47
  }
 
48
 
 
49
  /**
 
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.
 
54
   */
 
55
  ModeUsage changeCurrentMode(Mode currentMode) {
 
56
    return new ModeUsage(mode, currentMode, modeMap);
 
57
  }
 
58
 
 
59
  /**
 
60
   * Check to see if this mode usage is equals with another mode usage.
 
61
   */
 
62
  public boolean equals(Object obj) {
 
63
    if (!(obj instanceof ModeUsage))
 
64
      return false;
 
65
    ModeUsage other = (ModeUsage)obj;
 
66
    return this.mode == other.mode && this.currentMode == other.currentMode && Equal.equal(this.modeMap, other.modeMap);
 
67
  }
 
68
 
 
69
  /**
 
70
   * Gets a hash code for this mode usage.
 
71
   */
 
72
  public int hashCode() {
 
73
    int hc = mode.hashCode() ^ currentMode.hashCode();
 
74
    if (modeMap != null)
 
75
      hc ^= modeMap.hashCode();
 
76
    return hc;
 
77
  }
 
78
 
 
79
  /**
 
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.
 
86
   */
 
87
  private Mode resolve(Mode mode) {
 
88
    if (mode == Mode.CURRENT) { 
 
89
      return currentMode;
 
90
    }
 
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()) {
 
98
      return currentMode;
 
99
    }
 
100
    return mode;
 
101
  }
 
102
 
 
103
  /**
 
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.
 
107
   */
 
108
  int getAttributeProcessing() {
 
109
    if (attributeProcessing == -1) {
 
110
      attributeProcessing = resolve(mode).getAttributeProcessing();
 
111
      if (modeMap != null) {
 
112
        for (Enumeration e = modeMap.values();
 
113
             e.hasMoreElements()
 
114
             && attributeProcessing != Mode.ATTRIBUTE_PROCESSING_FULL;)
 
115
          attributeProcessing = Math.max(resolve((Mode)e.nextElement()).getAttributeProcessing(),
 
116
                                         attributeProcessing);
 
117
      }
 
118
    }
 
119
    return attributeProcessing;
 
120
  }
 
121
 
 
122
  /**
 
123
   * Check if we have context dependent modes.
 
124
   * @return true if the modeMap exists.
 
125
   */
 
126
  boolean isContextDependent() {
 
127
    return modeMap != null;
 
128
  }
 
129
 
 
130
  /**
 
131
   * Get the mode to be used for a specific context.
 
132
   * @param context The current context.
 
133
   * @return A mode.
 
134
   */
 
135
  Mode getMode(Vector context) {
 
136
    // first look in the modeMap if exists.
 
137
    if (modeMap != null) {
 
138
      Mode m = (Mode)modeMap.get(context);
 
139
      if (m != null)
 
140
        return resolve(m);
 
141
    }
 
142
    // if no modeMap or no context specific mode found then
 
143
    // return the default mode for this mode usage.
 
144
    return resolve(mode);
 
145
  }
 
146
 
 
147
  /**
 
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.
 
153
   */
 
154
  boolean addContext(boolean isRoot, Vector names, Mode mode) {
 
155
    if (modeMap == null)
 
156
      modeMap = new ContextMap();
 
157
    return modeMap.put(isRoot, names, mode);
 
158
  }
 
159
}