001: /*
002: WikiForms - a WikiPage FORM handler for JSPWiki.
003:
004: Copyright (C) 2003 BaseN.
005:
006: JSPWiki Copyright (C) 2002 Janne Jalkanen (Janne.Jalkanen@iki.fi)
007:
008: This program is free software; you can redistribute it and/or modify
009: it under the terms of the GNU Lesser General Public License as published
010: by the Free Software Foundation; either version 2.1 of the License, or
011: (at your option) any later version.
012:
013: This program is distributed in the hope that it will be useful,
014: but WITHOUT ANY WARRANTY; without even the implied warranty of
015: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: GNU Lesser General Public License for more details.
017:
018: You should have received a copy of the GNU Lesser General Public License
019: along with this program; if not, write to the Free Software
020: */
021: package com.ecyrd.jspwiki.util;
022:
023: import java.util.*;
024:
025: import javax.servlet.http.HttpServletRequest;
026:
027: /**
028: * A collection of (static) utilities used by the WikiForms code.
029: * FormUtil is mainly concerned with mapping HTTP parameters to
030: * WikiPlugin parameters.
031: *
032: * @author ebu
033: */
034: public final class FormUtil {
035: /**
036: * Private constructor to prevent direct instantiation.
037: */
038: private FormUtil() {
039: }
040:
041: /**
042: * <p>Looks for a named value in the Map. Returns either the
043: * value named by key, or values named by key.0, key.1, ...
044: * if the direct value is not found. The values are packed
045: * in an ArrayList.</p>
046: * <p>This is a utility method, mainly used when we don't know
047: * whether there was just one value, or several, in a mapping list
048: * (e.g. an HttpRequest / FORM checkbox).</p>
049: * @param params the Map container form parameters
050: * @param key the key to look up
051: * @return the List of keys
052: */
053: public static List getValues(Map params, String key) {
054: if (params == null || key == null)
055: return new ArrayList(0);
056:
057: Object entry = params.get(key);
058: if (entry != null) {
059: ArrayList rval = new ArrayList(1);
060: rval.add(entry);
061: return rval;
062: }
063:
064: return getNumberedValues(params, key);
065: }
066:
067: /**
068: * Looks up all keys starting with a given prefix and returns
069: * the values in an ArrayList. The keys must be Strings.
070: *
071: * <p>For example, calling this method for a Map containing
072: * key-value pairs foo.1 = a, foo.2 = b, and foo.3 = c returns
073: * an ArrayList containing [a, b, c].
074: *
075: * <p>Handles both 0- and 1-indexed names. Parsing stops at the
076: * first gap in the numeric postfix.
077: *
078: * @param params a Map of string-object pairs, presumably containing
079: * key.1, key.2,...
080: * @param keyPrefix a String prefix; values will be looked up by adding
081: * ".0", ".1", and so on, until the first gap.
082: * @return ArrayList, containing the values corresponding to the
083: * keyPrefix, in order.
084: */
085: public static ArrayList getNumberedValues(Map params,
086: String keyPrefix) {
087: ArrayList rval = new ArrayList();
088: if (params == null || params.size() == 0 || keyPrefix == null
089: || keyPrefix.length() == 0)
090: return rval;
091:
092: String fullPrefix = null;
093: if (keyPrefix.charAt(keyPrefix.length() - 1) == '.')
094: fullPrefix = keyPrefix;
095: else
096: fullPrefix = keyPrefix + ".";
097:
098: int ix = 0;
099: Object value = params.get(fullPrefix + (ix++));
100: if (value == null)
101: value = params.get(fullPrefix + (ix++));
102: if (value == null)
103: return rval;
104: while (true) {
105: rval.add(value);
106: value = params.get(fullPrefix + (ix++));
107: if (value == null)
108: break;
109: }
110:
111: return rval;
112: }
113:
114: /**
115: * <p>Converts the parameter contents of an HTTP request into a map,
116: * modifying the keys to preserve multiple values per key. This
117: * is done by adding an ordered suffix to the key:</p>
118: * <p><pre>foo=bar,baz,xyzzy</pre></p>
119: * <p>becomes</p>
120: * <p><pre>foo.0=bar foo.1=baz foo.2=xyzzy</pre></p>
121: * <p>If filterPrefix is specified, only keys starting with the prefix
122: * are included in the result map. If the prefix is null, all keys are
123: * checked.</p>
124: * <p>FIX: this is not necessarily encoding-safe: see
125: * WikiContext.getHttpParameter().</p>
126: * @param req the HTTP request
127: * @param filterPrefix the prefix
128: * @return the Map containing parsed key/value pairs
129: */
130: public static Map requestToMap(HttpServletRequest req,
131: String filterPrefix) {
132: HashMap params = new HashMap();
133:
134: if (filterPrefix == null)
135: filterPrefix = "";
136:
137: Enumeration en = req.getParameterNames();
138: while (en.hasMoreElements()) {
139: String param = (String) en.nextElement();
140:
141: if (param.startsWith(filterPrefix)) {
142: String realName = param
143: .substring(filterPrefix.length());
144: String[] values = req.getParameterValues(param);
145: if (values != null) {
146: if (values.length == 1) {
147: params.put(realName, values[0]);
148: } else {
149: for (int i = 0; i < values.length; i++) {
150: if (values[i] != null
151: && values[i].length() > 0) {
152: params.put(realName + "." + i,
153: values[i]);
154: }
155: }
156: }
157: }
158: }
159: }
160:
161: return params;
162: }
163:
164: }
|