KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > jforum > util > legacy > commons > fileupload > ParameterParser


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.jforum.util.legacy.commons.fileupload;
17
18 import java.util.HashMap JavaDoc;
19 import java.util.Map JavaDoc;
20
21 /**
22  * A simple parser intended to parse sequences of name/value pairs.
23  * Parameter values are exptected to be enclosed in quotes if they
24  * contain unsafe characters, such as '=' characters or separators.
25  * Parameter values are optional and can be omitted.
26  *
27  * <p>
28  * <code>param1 = value; param2 = "anything goes; really"; param3</code>
29  * </p>
30  *
31  * @author <a HREF="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
32  */

33
34 public class ParameterParser {
35     /**
36      * String to be parsed.
37      */

38     private char[] chars = null;
39
40     /**
41      * Current position in the string.
42      */

43     private int pos = 0;
44
45     /**
46      * Maximum position in the string.
47      */

48     private int len = 0;
49
50     /**
51      * Start of a token.
52      */

53     private int i1 = 0;
54
55     /**
56      * End of a token.
57      */

58     private int i2 = 0;
59
60     /**
61      * Whether names stored in the map should be converted to lower case.
62      */

63     private boolean lowerCaseNames = false;
64
65     /**
66      * Default ParameterParser constructor.
67      */

68     public ParameterParser() {
69         super();
70     }
71
72     /**
73      * Are there any characters left to parse?
74      *
75      * @return <tt>true</tt> if there are unparsed characters,
76      * <tt>false</tt> otherwise.
77      */

78     private boolean hasChar() {
79         return this.pos < this.len;
80     }
81
82     /**
83      * A helper method to process the parsed token. This method removes
84      * leading and trailing blanks as well as enclosing quotation marks,
85      * when necessary.
86      *
87      * @param quoted <tt>true</tt> if quotation marks are expected,
88      * <tt>false</tt> otherwise.
89      * @return the token
90      */

91     private String JavaDoc getToken(boolean quoted) {
92         // Trim leading white spaces
93
while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) {
94             i1++;
95         }
96         // Trim trailing white spaces
97
while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) {
98             i2--;
99         }
100         // Strip away quotation marks if necessary
101
if (quoted) {
102             if (((i2 - i1) >= 2)
103                 && (chars[i1] == '"')
104                 && (chars[i2 - 1] == '"')) {
105                 i1++;
106                 i2--;
107             }
108         }
109         String JavaDoc result = null;
110         if (i2 > i1) {
111             result = new String JavaDoc(chars, i1, i2 - i1);
112         }
113         return result;
114     }
115
116     /**
117      * Tests if the given character is present in the array of characters.
118      *
119      * @param ch the character to test for presense in the array of characters
120      * @param charray the array of characters to test against
121      *
122      * @return <tt>true</tt> if the character is present in the array of
123      * characters, <tt>false</tt> otherwise.
124      */

125     private boolean isOneOf(char ch, final char[] charray) {
126         boolean result = false;
127         for (int i = 0; i < charray.length; i++) {
128             if (ch == charray[i]) {
129                 result = true;
130                 break;
131             }
132         }
133         return result;
134     }
135
136     /**
137      * Parses out a token until any of the given terminators
138      * is encountered.
139      *
140      * @param terminators the array of terminating characters. Any of these
141      * characters when encountered signify the end of the token
142      *
143      * @return the token
144      */

145     private String JavaDoc parseToken(final char[] terminators) {
146         char ch;
147         i1 = pos;
148         i2 = pos;
149         while (hasChar()) {
150             ch = chars[pos];
151             if (isOneOf(ch, terminators)) {
152                 break;
153             }
154             i2++;
155             pos++;
156         }
157         return getToken(false);
158     }
159
160     /**
161      * Parses out a token until any of the given terminators
162      * is encountered outside the quotation marks.
163      *
164      * @param terminators the array of terminating characters. Any of these
165      * characters when encountered outside the quotation marks signify the end
166      * of the token
167      *
168      * @return the token
169      */

170     private String JavaDoc parseQuotedToken(final char[] terminators) {
171         char ch;
172         i1 = pos;
173         i2 = pos;
174         boolean quoted = false;
175         boolean charEscaped = false;
176         while (hasChar()) {
177             ch = chars[pos];
178             if (!quoted && isOneOf(ch, terminators)) {
179                 break;
180             }
181             if (!charEscaped && ch == '"') {
182                 quoted = !quoted;
183             }
184             charEscaped = (!charEscaped && ch == '\\');
185             i2++;
186             pos++;
187
188         }
189         return getToken(true);
190     }
191
192     /**
193      * Returns <tt>true</tt> if parameter names are to be converted to lower
194      * case when name/value pairs are parsed.
195      *
196      * @return <tt>true</tt> if parameter names are to be
197      * converted to lower case when name/value pairs are parsed.
198      * Otherwise returns <tt>false</tt>
199      */

200     public boolean isLowerCaseNames() {
201         return this.lowerCaseNames;
202     }
203
204     /**
205      * Sets the flag if parameter names are to be converted to lower case when
206      * name/value pairs are parsed.
207      *
208      * @param b <tt>true</tt> if parameter names are to be
209      * converted to lower case when name/value pairs are parsed.
210      * <tt>false</tt> otherwise.
211      */

212     public void setLowerCaseNames(boolean b) {
213         this.lowerCaseNames = b;
214     }
215
216     /**
217      * Extracts a map of name/value pairs from the given string. Names are
218      * expected to be unique.
219      *
220      * @param str the string that contains a sequence of name/value pairs
221      * @param separator the name/value pairs separator
222      *
223      * @return a map of name/value pairs
224      */

225     public Map JavaDoc parse(final String JavaDoc str, char separator) {
226         if (str == null) {
227             return new HashMap JavaDoc();
228         }
229         return parse(str.toCharArray(), separator);
230     }
231
232     /**
233      * Extracts a map of name/value pairs from the given array of
234      * characters. Names are expected to be unique.
235      *
236      * @param chars the array of characters that contains a sequence of
237      * name/value pairs
238      * @param separator the name/value pairs separator
239      *
240      * @return a map of name/value pairs
241      */

242     public Map JavaDoc parse(final char[] chars, char separator) {
243         if (chars == null) {
244             return new HashMap JavaDoc();
245         }
246         return parse(chars, 0, chars.length, separator);
247     }
248
249     /**
250      * Extracts a map of name/value pairs from the given array of
251      * characters. Names are expected to be unique.
252      *
253      * @param chars the array of characters that contains a sequence of
254      * name/value pairs
255      * @param offset - the initial offset.
256      * @param length - the length.
257      * @param separator the name/value pairs separator
258      *
259      * @return a map of name/value pairs
260      */

261     public Map JavaDoc parse(
262         final char[] chars,
263         int offset,
264         int length,
265         char separator) {
266
267         if (chars == null) {
268             return new HashMap JavaDoc();
269         }
270         HashMap JavaDoc params = new HashMap JavaDoc();
271         this.chars = chars;
272         this.pos = offset;
273         this.len = length;
274
275         String JavaDoc paramName = null;
276         String JavaDoc paramValue = null;
277         while (hasChar()) {
278             paramName = parseToken(new char[] {
279                     '=', separator });
280             paramValue = null;
281             if (hasChar() && (chars[pos] == '=')) {
282                 pos++; // skip '='
283
paramValue = parseQuotedToken(new char[] {
284                         separator });
285             }
286             if (hasChar() && (chars[pos] == separator)) {
287                 pos++; // skip separator
288
}
289             if ((paramName != null) && (paramName.length() > 0)) {
290                 if (this.lowerCaseNames) {
291                     paramName = paramName.toLowerCase();
292                 }
293                 params.put(paramName, paramValue);
294             }
295         }
296         return params;
297     }
298 }
299
Popular Tags