View Javadoc

1   package org.jscsi.target.settings.entry;
2   
3   
4   import org.jscsi.target.TargetServer;
5   import org.jscsi.target.settings.KeySet;
6   import org.jscsi.target.settings.NegotiationStatus;
7   import org.jscsi.target.settings.NegotiationType;
8   import org.jscsi.target.settings.NumericalResultFunction;
9   import org.jscsi.target.settings.NumericalValueRange;
10  import org.jscsi.target.settings.SingleNumericalValue;
11  
12  
13  /**
14   * An {@link Entry} sub-class for boolean parameters.
15   * <p>
16   * During text parameter negotiation, numerical parameters are negotiated by sending a single integer <i>value</i> as
17   * part of a <i>key=value</i> pair. Based on the values permitted for the specific <i>key</i> (
18   * {@link #protocolValueRange}), the {@link #resultFunction} and the {@link #negotiationValue}, the jSCSI Target will
19   * choose a single value as the negotiation outcome.
20   * <p>
21   * For declared parameters this process is less complex, any proposed value from the {@link #protocolValueRange} will be
22   * silently accepted.
23   * <p>
24   * Please note the difference between numerical values and numerical range values (see {@link NumericalRangeEntry}).
25   * <p>
26   * The default or negotiated value can be accessed via the {@link #getIntegerValue()} method.
27   * 
28   * @see Entry
29   * @author Andreas Ergenzinger
30   */
31  public final class NumericalEntry extends Entry {
32  
33      /**
34       * The integer interval describing the range of legal values.
35       */
36      private final NumericalValueRange protocolValueRange;
37  
38      /**
39       * An integer serving as a boundary to the values the jSCSI Target is willing to accept.
40       */
41      private final int negotiationValue;
42  
43      /**
44       * The {@link NumericalResultFunction} used for negotiating the parameter.
45       */
46      private final NumericalResultFunction resultFunction;
47  
48      /**
49       * <code>true</code> means that a {@link #negotiationValue} of <code>0</code> allows the jSCSI Target to choose any
50       * value from the resulting range. <code>false</code> means that {@link #negotiationValue} must always be treated as
51       * an upper or lower boundary.
52       */
53      private final boolean zeroMeansDontCare;
54  
55      /**
56       * The {@link NumericalEntry} constructor.
57       * 
58       * @param keySet contains all relevant keys
59       * @param negotiationType declared or negotiated
60       * @param use determines under which circumstances the parameter may be negotiated
61       * @param negotiationStatus indicates whether there is a default value or if the parameter must be negotiated
62       * @param negotiationValue together with the <i>resultFunction</i> and the <i>protocolValueRange</i> parameters this
63       *            value indicates the values supported by the jSCSI Target
64       * @param protocolValueRange specifying the range of legal values
65       * @param resultFunction determines the negotiation outcome
66       * @param defaultValue the default value or <code>null</code>
67       * @param zeroMeansDontCare if <code>true</code> and <i>negotiationValue</i> equals <code>0</code> then
68       *            <i>negotiationValue</i> does not serve as an upper or lower boundary to the values the jSCSI Target
69       *            will accept
70       */
71      public NumericalEntry (final KeySet keySet, final NegotiationType negotiationType, final Use use, final NegotiationStatus negotiationStatus, final int negotiationValue, final NumericalValueRange protocolValueRange, final NumericalResultFunction resultFunction, final Integer defaultValue, final boolean zeroMeansDontCare) {
72          super(keySet, negotiationType, use, negotiationStatus, defaultValue);
73          this.protocolValueRange = protocolValueRange;
74          this.negotiationValue = negotiationValue;
75          this.resultFunction = resultFunction;
76          this.zeroMeansDontCare = zeroMeansDontCare;
77      }
78  
79      @Override
80      protected boolean inProtocolValueRange (final Object values) {
81          // receives an Integer
82          final int val = (Integer) values;
83          if (zeroMeansDontCare && val == 0) // val might not lie inside reg.
84                                             // interval
85          return true;
86          return protocolValueRange.contains(val);
87      }
88  
89      @Override
90      protected Object parseOffer (final TargetServer target, final String values) {
91          // return an Integer
92          return SingleNumericalValue.parseSingleNumericValue(values).getValue();
93      }
94  
95      @Override
96      protected void processDeclaration (final Object values) {
97          // receives an Integer
98          final int val = (Integer) values;
99          if (zeroMeansDontCare && val == 0)// pick value desired by target
100             value = negotiationValue;
101         else
102             value = values;
103     }
104 
105     @Override
106     protected String processNegotiation (final Object values) {
107         // receives an Integer
108         final int val = (Integer) values;
109         if (zeroMeansDontCare && val == 0)// pick value desired by target
110             value = negotiationValue;
111         else
112             // pick value based on result function and offer
113             value = resultFunction.getResult(negotiationValue, val);
114         return value.toString();
115     }
116 
117     @Override
118     public Integer getIntegerValue () {
119         return (Integer) value;
120     }
121 
122     @Override
123     public Entry copy () {
124         final NumericalEntry e = new NumericalEntry(keySet, negotiationType, use, negotiationStatus, negotiationValue, protocolValueRange, resultFunction, (Integer) value, zeroMeansDontCare);
125         e.alreadyNegotiated = this.alreadyNegotiated;
126         return e;
127     }
128 }