1 package net.sourceforge.jparam.paramset; 2 3 import net.sourceforge.jparam.JParamException; 4 5 /*** 6 * Represents a single parameter in a ParamSet 7 */ 8 9 public class Param { 10 private String name; 11 12 private String description; 13 14 boolean isInput; 15 16 boolean isOutput; 17 18 Object defaultValue; 19 20 Object assignedValue; 21 22 Class typeBound; 23 24 /*** 25 * Creates a Param object with given attributes. Set defaultValue to null to 26 * indicate there's no default value. 27 */ 28 protected Param(String name_description, boolean isInput, boolean isOutput, 29 Object defaultValue, Class typeBound) throws JParamException { 30 separateNameAndDescription(name_description); 31 this.isInput = isInput; 32 this.isOutput = isOutput; 33 this.assignedValue = null; 34 35 if (typeBound == null) 36 typeBound = Object.class; 37 38 this.typeBound = typeBound; 39 40 setDefaultValue(defaultValue); 41 } 42 43 protected void clearValue() { 44 assignedValue = null; 45 } 46 47 /*** 48 * Returns the parameter's name. 49 */ 50 public String getName() { 51 return name; 52 } 53 54 /*** 55 * Returns the parameter's description. 56 */ 57 public String getDescription() { 58 return description; 59 } 60 61 /*** 62 * Sets the parameter's description. 63 */ 64 public void setDescription(String description) { 65 this.description = description; 66 } 67 68 /*** 69 * Returns whether the parameter is an input parameter 70 */ 71 public boolean isInput() { 72 return isInput; 73 } 74 75 /*** 76 * Returns whether the parameter is an output parameter 77 */ 78 public boolean isOutput() { 79 return isOutput; 80 } 81 82 /*** 83 * Returns whether the parameter was assigned a value. If the parameter has 84 * a default value, this method may return false, but getValue will still 85 * return a non null object. 86 */ 87 public boolean wasAssignedTo() { 88 return (assignedValue != null); 89 } 90 91 public boolean hasDefaultValue() { 92 return (defaultValue != null); 93 } 94 95 public boolean hasGivenValue() { 96 return (wasAssignedTo() || hasDefaultValue()); 97 } 98 99 /*** 100 * Returns the parameter's type bound. If getValue() returns a valid object 101 * (non null), then it is guaranteed to be assignable to a variable of this 102 * class. 103 */ 104 public Class getTypeBound() { 105 return typeBound; 106 } 107 108 /*** 109 * Returns the parameter's current value, or null if no such value exists. 110 */ 111 public Object getValue() { 112 if (assignedValue != null) 113 return assignedValue; 114 return defaultValue; 115 } 116 117 /*** 118 * Sets the parameter's current value. If val is not null, then calls to 119 * wasAssignedTo() following this call will return true. If val is null, 120 * this removed the parameter's value, and resets wasAssignedTo(), so it 121 * will return false. 122 */ 123 public void setValue(Object value) throws JParamException { 124 if ((value != null) && !typeBound.isInstance(value)) { 125 throw new JParamException( 126 "assigned value does not conform to parameter's typeBound, parameter type: " 127 + typeBound.getName() + ", value type: " 128 + value.getClass().getName()); 129 } 130 this.assignedValue = value; 131 } 132 133 /*** 134 * Returns the parameter's default value, or null if it has none. 135 */ 136 public Object getDefaultValue() { 137 return defaultValue; 138 } 139 140 /*** 141 * Sets the parameter's default value. null removes it. If defaultValue 142 * isn't null, it must be compatible with the parameter's typeBound. 143 */ 144 public void setDefaultValue(Object defaultValue) throws JParamException { 145 if ((defaultValue != null) && !typeBound.isInstance(defaultValue)) { 146 throw new JParamException( 147 "default value does not conform to parameter's typeBound"); 148 } 149 this.defaultValue = defaultValue; 150 } 151 152 /*** 153 * Extracts name and optional description, separated by !, and assigns them 154 * to class members. Also checks that the parameter's name is a legal 155 * identifier. 156 */ 157 private void separateNameAndDescription(String s) throws JParamException { 158 int separatorPos = s.indexOf('!'); 159 160 this.description = (separatorPos == -1) ? "" : s.substring( 161 separatorPos + 1).trim(); 162 163 String name = (separatorPos == -1) ? s.trim() : s.substring(0, 164 separatorPos).trim(); 165 if (name.length() == 0) 166 throw new JParamException("empty parameter name in '" + s + "'"); 167 verifyName(name); 168 this.name = name; 169 } 170 171 /*** 172 * Verifies that name is a legal identifier. Throws an exception if it 173 * isn't. 174 */ 175 private void verifyName(String name) throws JParamException { 176 if (name.length() == 0) 177 throw new JParamException("empty parameter name in " + name); 178 179 String msg = "'" + name + "' isn't a legal parameter name"; 180 181 String firstChar = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 182 if (firstChar.indexOf(name.charAt(0)) == -1) { 183 throw new JParamException(msg + ": '" + name.charAt(0) 184 + "' is not allowed as first character"); 185 } 186 187 String idChars = firstChar + "0123456789"; 188 189 for (int i = 1; i < name.length(); ++i) { 190 char c = name.charAt(i); 191 if (idChars.indexOf(c) == -1) { 192 throw new JParamException(msg + ": character '" + c 193 + "' is not allowed"); 194 } 195 } 196 } 197 198 }