001: // Copyright (C) 1998-2001 by Jason Hunter <jhunter_AT_acm_DOT_org>.
002: // All rights reserved. Use of this class is limited.
003: // Please see the LICENSE for more information.
004:
005: package com.oreilly.servlet;
006:
007: import java.io.*;
008: import java.util.*;
009: import javax.servlet.*;
010:
011: /**
012: * A class to simplify parameter handling. It can return parameters of
013: * any primitive type (no casting or parsing required), can throw an
014: * exception when a parameter is not found (simplifying error handling),
015: * and can accept default values (eliminating error handling).
016: * <p>
017: * It is used like this:
018: * <blockquote><pre>
019: * ParameterParser parser = new ParameterParser(req);
020: *
021: * float ratio = parser.getFloatParameter("ratio", 1.0);
022: *
023: * int count = 0;
024: * try {
025: * count = parser.getIntParameter("count");
026: * }
027: * catch (NumberFormatException e) {
028: * handleMalformedCount();
029: * }
030: * catch (ParameterNotFoundException e) {
031: * handleNoCount();
032: * }
033: * </pre></blockquote>
034: *
035: * There's also a capability to find out if any required parameters are
036: * missing from a request:
037: * <blockquote><pre>
038: * ParameterParser parser = new ParameterParser(req);
039: * String[] required = { "fname", "lname", "account" };
040: * String[] missing = parser.getMissingParameters(required);
041: * </pre></blockquote>
042: *
043: * The default charset for input parameters is ISO-8859-1 (Latin-1).
044: * If the parameter values are encoded in another format, specify that using
045: * setCharacterEncoding() before parsing. The parameter names currently
046: * have to be in the Latin-1 character set:
047: * <blockquote><pre>
048: * ParameterParser parser = new ParameterParser(req);
049: * parser.setCharacterEncoding("Shift_JIS");
050: * String japaneseValue = parser.getStringParameter("latinName");
051: * </pre></blockquote>
052: *
053: * @see com.oreilly.servlet.ParameterNotFoundException
054: *
055: * @author <b>Jason Hunter</b>, Copyright © 1998, 1999
056: * @version 1.4, 2000/12/14, better checking the selected encoding is valid in
057: * setCharacterEncoding() thanks to Dewayne McNair
058: * @version 1.3, 2000/05/17, added setCharacterEncoding()
059: * @version 1.2, 2000/05/17, getBooleanParameter() now recognizes "on" and "yes"
060: * @version 1.1, 1999/12/20, added getMissingParameters() method
061: * @version 1.0, 1998/09/18
062: */
063: public class ParameterParser {
064:
065: private ServletRequest req;
066: private String encoding;
067:
068: /**
069: * Constructs a new ParameterParser to handle the parameters of the
070: * given request.
071: *
072: * @param req the servlet request
073: */
074: public ParameterParser(ServletRequest req) {
075: this .req = req;
076: }
077:
078: /**
079: * Sets the character encoding (charset) of the request to help the parser
080: * properly decode parameter values. The default is to return undecoded values,
081: * the same as would be returned by getParameter().
082: *
083: * @param encoding the charset of the request
084: * @exception UnsupportedEncodingException if the charset is not supported
085: * on this sytem
086: */
087: public void setCharacterEncoding(String encoding)
088: throws UnsupportedEncodingException {
089: // Test the encoding is valid
090: new String("".getBytes("8859_1"), encoding);
091: // Getting here means we're valid, so set the encoding
092: this .encoding = encoding;
093: }
094:
095: /**
096: * Gets the named parameter value as a String
097: *
098: * @param name the parameter name
099: * @return the parameter value as a String
100: * @exception ParameterNotFoundException if the parameter was not found
101: * or was the empty string
102: */
103: public String getStringParameter(String name)
104: throws ParameterNotFoundException {
105: String[] values = req.getParameterValues(name);
106: if (values == null) {
107: throw new ParameterNotFoundException(name + " not found");
108: } else if (values[0].length() == 0) {
109: throw new ParameterNotFoundException(name + " was empty");
110: } else {
111: if (encoding == null) {
112: return values[0];
113: } else {
114: try {
115: return new String(values[0].getBytes("8859_1"),
116: encoding);
117: } catch (UnsupportedEncodingException e) {
118: return values[0]; // should never happen
119: }
120: }
121: }
122: }
123:
124: /**
125: * Gets the named parameter value as a String, with a default.
126: * Returns the default value if the parameter is not found or
127: * is the empty string.
128: *
129: * @param name the parameter name
130: * @param def the default parameter value
131: * @return the parameter value as a String, or the default
132: */
133: public String getStringParameter(String name, String def) {
134: try {
135: return getStringParameter(name);
136: } catch (Exception e) {
137: return def;
138: }
139: }
140:
141: /**
142: * Gets the named parameter value as a boolean, with true indicated by
143: * "true", "on", or "yes" in any letter case, false indicated by "false",
144: * "off", or "no" in any letter case.
145: *
146: * @param name the parameter name
147: * @return the parameter value as a boolean
148: * @exception ParameterNotFoundException if the parameter was not found
149: * @exception NumberFormatException if the parameter could not be converted
150: * to a boolean
151: */
152: public boolean getBooleanParameter(String name)
153: throws ParameterNotFoundException, NumberFormatException {
154: String value = getStringParameter(name).toLowerCase();
155: if ((value.equalsIgnoreCase("true"))
156: || (value.equalsIgnoreCase("on"))
157: || (value.equalsIgnoreCase("yes"))) {
158: return true;
159: } else if ((value.equalsIgnoreCase("false"))
160: || (value.equalsIgnoreCase("off"))
161: || (value.equalsIgnoreCase("no"))) {
162: return false;
163: } else {
164: throw new NumberFormatException("Parameter " + name
165: + " value " + value + " is not a boolean");
166: }
167: }
168:
169: /**
170: * Gets the named parameter value as a boolean, with a default.
171: * Returns the default value if the parameter is not found.
172: *
173: * @param name the parameter name
174: * @param def the default parameter value
175: * @return the parameter value as a boolean, or the default
176: */
177: public boolean getBooleanParameter(String name, boolean def) {
178: try {
179: return getBooleanParameter(name);
180: } catch (Exception e) {
181: return def;
182: }
183: }
184:
185: /**
186: * Gets the named parameter value as a byte
187: *
188: * @param name the parameter name
189: * @return the parameter value as a byte
190: * @exception ParameterNotFoundException if the parameter was not found
191: * @exception NumberFormatException if the parameter value could not
192: * be converted to a byte
193: */
194: public byte getByteParameter(String name)
195: throws ParameterNotFoundException, NumberFormatException {
196: return Byte.parseByte(getStringParameter(name));
197: }
198:
199: /**
200: * Gets the named parameter value as a byte, with a default.
201: * Returns the default value if the parameter is not found or cannot
202: * be converted to a byte.
203: *
204: * @param name the parameter name
205: * @param def the default parameter value
206: * @return the parameter value as a byte, or the default
207: */
208: public byte getByteParameter(String name, byte def) {
209: try {
210: return getByteParameter(name);
211: } catch (Exception e) {
212: return def;
213: }
214: }
215:
216: /**
217: * Gets the named parameter value as a char
218: *
219: * @param name the parameter name
220: * @return the parameter value as a char
221: * @exception ParameterNotFoundException if the parameter was not found
222: * or was the empty string
223: */
224: public char getCharParameter(String name)
225: throws ParameterNotFoundException {
226: String param = getStringParameter(name);
227: if (param.length() == 0)
228: throw new ParameterNotFoundException(name
229: + " is empty string");
230: else
231: return (param.charAt(0));
232: }
233:
234: /**
235: * Gets the named parameter value as a char, with a default.
236: * Returns the default value if the parameter is not found.
237: *
238: * @param name the parameter name
239: * @param def the default parameter value
240: * @return the parameter value as a char, or the default
241: */
242: public char getCharParameter(String name, char def) {
243: try {
244: return getCharParameter(name);
245: } catch (Exception e) {
246: return def;
247: }
248: }
249:
250: /**
251: * Gets the named parameter value as a double
252: *
253: * @param name the parameter name
254: * @return the parameter value as a double
255: * @exception ParameterNotFoundException if the parameter was not found
256: * @exception NumberFormatException if the parameter could not be converted
257: * to a double
258: */
259: public double getDoubleParameter(String name)
260: throws ParameterNotFoundException, NumberFormatException {
261: return new Double(getStringParameter(name)).doubleValue();
262: }
263:
264: /**
265: * Gets the named parameter value as a double, with a default.
266: * Returns the default value if the parameter is not found.
267: *
268: * @param name the parameter name
269: * @param def the default parameter value
270: * @return the parameter value as a double, or the default
271: */
272: public double getDoubleParameter(String name, double def) {
273: try {
274: return getDoubleParameter(name);
275: } catch (Exception e) {
276: return def;
277: }
278: }
279:
280: /**
281: * Gets the named parameter value as a float
282: *
283: * @param name the parameter name
284: * @return the parameter value as a float
285: * @exception ParameterNotFoundException if the parameter was not found
286: * @exception NumberFormatException if the parameter could not be converted
287: * to a float
288: */
289: public float getFloatParameter(String name)
290: throws ParameterNotFoundException, NumberFormatException {
291: return new Float(getStringParameter(name)).floatValue();
292: }
293:
294: /**
295: * Gets the named parameter value as a float, with a default.
296: * Returns the default value if the parameter is not found.
297: *
298: * @param name the parameter name
299: * @param def the default parameter value
300: * @return the parameter value as a float, or the default
301: */
302: public float getFloatParameter(String name, float def) {
303: try {
304: return getFloatParameter(name);
305: } catch (Exception e) {
306: return def;
307: }
308: }
309:
310: /**
311: * Gets the named parameter value as a int
312: *
313: * @param name the parameter name
314: * @return the parameter value as a int
315: * @exception ParameterNotFoundException if the parameter was not found
316: * @exception NumberFormatException if the parameter could not be converted
317: * to a int
318: */
319: public int getIntParameter(String name)
320: throws ParameterNotFoundException, NumberFormatException {
321: return Integer.parseInt(getStringParameter(name));
322: }
323:
324: /**
325: * Gets the named parameter value as a int, with a default.
326: * Returns the default value if the parameter is not found.
327: *
328: * @param name the parameter name
329: * @param def the default parameter value
330: * @return the parameter value as a int, or the default
331: */
332: public int getIntParameter(String name, int def) {
333: try {
334: return getIntParameter(name);
335: } catch (Exception e) {
336: return def;
337: }
338: }
339:
340: /**
341: * Gets the named parameter value as a long
342: *
343: * @param name the parameter name
344: * @return the parameter value as a long
345: * @exception ParameterNotFoundException if the parameter was not found
346: * @exception NumberFormatException if the parameter could not be converted
347: * to a long
348: */
349: public long getLongParameter(String name)
350: throws ParameterNotFoundException, NumberFormatException {
351: return Long.parseLong(getStringParameter(name));
352: }
353:
354: /**
355: * Gets the named parameter value as a long, with a default.
356: * Returns the default value if the parameter is not found.
357: *
358: * @param name the parameter name
359: * @param def the default parameter value
360: * @return the parameter value as a long, or the default
361: */
362: public long getLongParameter(String name, long def) {
363: try {
364: return getLongParameter(name);
365: } catch (Exception e) {
366: return def;
367: }
368: }
369:
370: /**
371: * Gets the named parameter value as a short
372: *
373: * @param name the parameter name
374: * @return the parameter value as a short
375: * @exception ParameterNotFoundException if the parameter was not found
376: * @exception NumberFormatException if the parameter could not be converted
377: * to a short
378: */
379: public short getShortParameter(String name)
380: throws ParameterNotFoundException, NumberFormatException {
381: return Short.parseShort(getStringParameter(name));
382: }
383:
384: /**
385: * Gets the named parameter value as a short, with a default.
386: * Returns the default value if the parameter is not found.
387: *
388: * @param name the parameter name
389: * @param def the default parameter value
390: * @return the parameter value as a short, or the default
391: */
392: public short getShortParameter(String name, short def) {
393: try {
394: return getShortParameter(name);
395: } catch (Exception e) {
396: return def;
397: }
398: }
399:
400: /**
401: * Determines which of the required parameters were missing from the
402: * request. Returns null if all the parameters are present.
403: *
404: * @param an array of required parameters
405: * @return an array of missing parameters, or null if none are missing
406: */
407: public String[] getMissingParameters(String[] required) {
408: Vector missing = new Vector();
409: for (int i = 0; i < required.length; i++) {
410: String val = getStringParameter(required[i], null);
411: if (val == null) {
412: missing.addElement(required[i]);
413: }
414: }
415: if (missing.size() == 0) {
416: return null;
417: } else {
418: String[] ret = new String[missing.size()];
419: missing.copyInto(ret);
420: return ret;
421: }
422: }
423: }
|