View Javadoc

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 }