001: /*
002: Copyright (c) 2003, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JargP nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jargp;
030:
031: /**
032: * Command line integer parameter definition. This defines a command line flag
033: * with an associated integer value. The optionally signed value must
034: * immediately follow the flag character within the same argument string.
035: *
036: * @author Dennis M. Sosnoski
037: * @version 1.0
038: */
039:
040: public class IntDef extends ParameterDef {
041: /** Minimum allowed argument value. */
042: private final int m_min;
043:
044: /** Maximum allowed argument value. */
045: private final int m_max;
046:
047: /**
048: * Constructor with range and description.
049: *
050: * @param chr parameter flag character
051: * @param name field name for parameter
052: * @param desc discription text for parameter
053: * @param min minimum allowed value
054: * @param max maximum allowed value
055: */
056:
057: public IntDef(char chr, String name, String desc, int min, int max) {
058: super (chr, name, desc);
059: m_min = min;
060: m_max = max;
061: }
062:
063: /**
064: * Constructor with range but no description.
065: *
066: * @param chr parameter flag character
067: * @param name field name for parameter
068: * @param min minimum allowed value
069: * @param max maximum allowed value
070: */
071:
072: public IntDef(char chr, String name, int min, int max) {
073: this (chr, name, null, min, max);
074: }
075:
076: /**
077: * Constructor with no range defined.
078: *
079: * @param chr parameter flag character
080: * @param name field name for parameter
081: * @param desc discription text for parameter
082: */
083:
084: public IntDef(char chr, String name, String desc) {
085: this (chr, name, desc, Integer.MIN_VALUE, Integer.MAX_VALUE);
086: }
087:
088: /**
089: * Constructor with no range or description.
090: *
091: * @param chr parameter flag character
092: * @param name field name for parameter
093: */
094:
095: public IntDef(char chr, String name) {
096: this (chr, name, null);
097: }
098:
099: /**
100: * Get text abbreviation for parameter. This override of the base class
101: * method returns "-cNN", where 'c' is the flag character for the parameter.
102: *
103: * @return text abbreviation for showing parameter
104: */
105:
106: public String getAbbreviation() {
107: return "-" + m_char + "NN";
108: }
109:
110: /**
111: * Bind parameter to target class field.
112: *
113: * @param clas target class for saving parameter values
114: * @throws IllegalArgumentException if the field is not an int
115: */
116:
117: protected void bindToClass(Class clas) {
118: super .bindToClass(clas);
119: Class type = m_field.getType();
120: if (type != Integer.class && type != Integer.TYPE) {
121: throw new IllegalArgumentException("Field '" + m_name
122: + "'in " + clas.getName() + " is not of type int");
123: }
124: }
125:
126: /**
127: * Handle argument. This implementation of the abstract base class method
128: * interprets the characters following the flag character as an optionally
129: * signed decimal value. If the value is within the allowed range the
130: * parameter is set to that value. Other flag characters may follow the
131: * numeric value within the argument.
132: *
133: * @param proc argument processor making call to handler
134: * @throws ArgumentErrorException if decimal value missing or out of range
135: * @throws IllegalArgumentException on error in processing
136: */
137:
138: public void handle(ArgumentProcessor proc) {
139:
140: // set up for validating
141: boolean minus = false;
142: boolean digits = false;
143: long value = 0;
144: CharTracker track = proc.getChars();
145: if (track.hasNext()) {
146:
147: // check for leading sign flag
148: char chr = track.peek();
149: if (chr == '-' || chr == '+') {
150: minus = chr == '-';
151: track.next();
152: }
153:
154: // accumulate all digits in value
155: while (track.hasNext()) {
156: chr = track.peek();
157: if (chr >= '0' && chr <= '9') {
158: track.next();
159: digits = true;
160: value = value * 10 + (chr - '0');
161: } else {
162: break;
163: }
164: }
165: }
166:
167: // make sure we have a valid value
168: value = minus ? -value : value;
169: if (!digits) {
170: proc.reportArgumentError(m_char, "Missing value");
171: } else if (value < m_min || value > m_max) {
172: proc.reportArgumentError(m_char, "Value out of range");
173: } else {
174: proc.setValue(new Integer((int) value), m_field);
175: }
176: }
177: }
|