1 package org.apache.fulcrum.parser;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.UnsupportedEncodingException;
23 import java.net.URLDecoder;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.Enumeration;
27 import java.util.List;
28 import java.util.StringTokenizer;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31 import java.util.stream.Collectors;
32
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.Part;
35
36 import org.apache.avalon.framework.service.ServiceException;
37 import org.apache.commons.lang3.ArrayUtils;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class DefaultParameterParser
65 extends BaseValueParser
66 implements ParameterParser
67 {
68
69
70
71 private HttpServletRequest request = null;
72
73
74
75
76 private byte[] uploadData = null;
77
78
79
80
81
82
83
84
85
86 public DefaultParameterParser()
87 {
88 super();
89 }
90
91
92
93
94
95
96
97
98
99
100
101 public DefaultParameterParser(String characterEncoding)
102 {
103 super (characterEncoding);
104 }
105
106
107
108
109 @Override
110 public void dispose()
111 {
112 this.request = null;
113 this.uploadData = null;
114 super.dispose();
115 }
116
117
118
119
120
121
122 @Override
123 public HttpServletRequest getRequest()
124 {
125 return request;
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 @Override
150 public void setRequest(HttpServletRequest request)
151 {
152 clear();
153
154 uploadData = null;
155
156 handleEncoding( request );
157
158 String contentType = request.getContentType();
159
160 if (parserService.getAutomaticUpload()
161 && contentType != null
162 && contentType.startsWith("multipart/form-data"))
163 {
164 try
165 {
166 List<Part> parts = parserService.parseUpload(request);
167
168 if (parts != null)
169 {
170 for (Part p : parts)
171 {
172 getLogger().debug("Found an uploaded file: " + p.getName());
173 getLogger().debug("It has " + p.getSize() + " Bytes");
174 getLogger().debug("Adding Part as " + p.getName() + " to the params");
175 add(p.getName(), p);
176 }
177 }
178 }
179 catch (ServiceException e)
180 {
181 getLogger().error("File upload failed", e);
182 }
183 }
184
185 for (Enumeration<?> names = request.getParameterNames();
186 names.hasMoreElements();)
187 {
188 String paramName = (String) names.nextElement();
189 add(paramName,
190 request.getParameterValues(paramName));
191 }
192
193 handlePathInfo( request );
194
195 this.request = request;
196
197 if (getLogger().isDebugEnabled())
198 {
199 getLogger().debug("Parameters found in the Request:");
200 for (String key : keySet())
201 {
202 getLogger().debug("Key: " + key + " -> " + getString(key));
203 }
204 }
205 }
206
207 private void handlePathInfo( HttpServletRequest request )
208 {
209
210
211 try
212 {
213 boolean isNameTok = true;
214 String paramName = null;
215 String paramValue = null;
216
217 for ( StringTokenizer st =
218 new StringTokenizer(request.getPathInfo(), "/");
219 st.hasMoreTokens();)
220 {
221 if (isNameTok)
222 {
223 paramName = URLDecoder.decode(st.nextToken(), getCharacterEncoding());
224 isNameTok = false;
225 }
226 else
227 {
228 paramValue = URLDecoder.decode(st.nextToken(), getCharacterEncoding());
229 if (paramName != null && paramName.length() > 0)
230 {
231 add(paramName, paramValue);
232 }
233 isNameTok = true;
234 }
235 }
236 }
237 catch (Exception e)
238 {
239
240
241
242
243 }
244 }
245
246 protected void handleEncoding( HttpServletRequest request )
247 {
248 String enc = request.getCharacterEncoding();
249
250 if (enc == null && !parserService.getParameterEncoding().equals(ParserService.PARAMETER_ENCODING_DEFAULT ))
251 {
252 try
253 {
254
255 request.setCharacterEncoding( parserService.getParameterEncoding() );
256
257 enc = request.getCharacterEncoding();
258 if (enc != null)
259 {
260 getLogger().debug("Set the request encoding successfully to parameterEncoding of parser: "+enc );
261 }
262 else
263 {
264 getLogger().warn("Unsuccessfully (data read happened) tried to set the request encoding to "+ parserService.getParameterEncoding() );
265 }
266 }
267 catch ( UnsupportedEncodingException e )
268 {
269 getLogger().error("Found only unsupported encoding "+ e.getMessage());
270 }
271 }
272
273 setCharacterEncoding(enc != null
274 ? enc
275 : parserService.getParameterEncoding());
276 }
277
278
279
280
281
282
283 @Override
284 public void setUploadData ( byte[] uploadData )
285 {
286
287 this.uploadData = Arrays.copyOf(uploadData, uploadData.length);
288 }
289
290
291
292
293
294
295 @Override
296 public byte[] getUploadData ()
297 {
298
299 return this.uploadData.clone();
300 }
301
302
303
304
305
306
307
308
309
310
311 @Override
312 public void add( String name, Part value )
313 {
314 Part[] items = this.getParts(name);
315 items = ArrayUtils.add(items, value);
316 parameters.put(convert(name), items);
317 }
318
319
320
321
322
323
324
325
326
327
328 @Override
329 public Part getPart(String name)
330 {
331 try
332 {
333 Part value = null;
334 Object object = parameters.get(convert(name));
335 if (object != null)
336 {
337 value = ((Part[])object)[0];
338 }
339 return value;
340 }
341 catch ( ClassCastException e )
342 {
343 return null;
344 }
345 }
346
347
348
349
350
351
352
353
354
355
356
357 @Override
358 public Part[] getParts(String name)
359 {
360 try
361 {
362 return (Part[])parameters.get(convert(name));
363 }
364 catch ( ClassCastException e )
365 {
366 return new Part[0];
367 }
368 }
369
370
371
372
373 @Override
374 public Collection<Part> getParts()
375 {
376 return parameters.values().stream().
377 filter( p-> p instanceof Part[]).
378 flatMap(c -> Arrays.stream( (Part[]) c )).
379 collect( Collectors.toList() );
380
381 }
382
383
384
385
386 @Override
387 public String getFileName(Part part)
388 {
389 final String partHeader = part.getHeader("content-disposition");
390
391
392 Pattern regex = Pattern.compile("filename\\*?=\"?(.[^\"]+)\"?");
393
394 for (String content : partHeader.split(";"))
395 {
396
397 if (content.trim().contains( "filename" ))
398 {
399 String fnTmp = "";
400 String srcStr = content.trim();
401 Matcher regexMatcher = regex.matcher(srcStr);
402 if (regexMatcher.find())
403 {
404 fnTmp = regexMatcher.group(1);
405 if (getLogger().isDebugEnabled())
406 {
407 getLogger().debug( "matched fileName:" + fnTmp );
408 }
409 } else {
410
411 fnTmp = srcStr.substring(srcStr.indexOf('=')+1).replace( "\"", "" );
412 getLogger().debug( "second fileName match:" + fnTmp );
413 }
414 return fnTmp.trim();
415 }
416 }
417 return null;
418 }
419 }