Source Code Cross Referenced for MultipartRequest.java in  » Swing-Library » wings3 » org » wings » session » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Swing Library » wings3 » org.wings.session 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2000,2005 wingS development team.
003:         *
004:         * This file is part of wingS (http://wingsframework.org).
005:         *
006:         * wingS is free software; you can redistribute it and/or modify
007:         * it under the terms of the GNU Lesser General Public License
008:         * as published by the Free Software Foundation; either version 2.1
009:         * of the License, or (at your option) any later version.
010:         *
011:         * Please see COPYING for the complete licence.
012:         */
013:        package org.wings.session;
014:
015:        import org.apache.commons.logging.Log;
016:        import org.apache.commons.logging.LogFactory;
017:        import org.wings.UploadFilterManager;
018:        import org.wings.util.SStringBuilder;
019:        import org.wings.util.LocaleCharSet;
020:
021:        import javax.servlet.ServletInputStream;
022:        import javax.servlet.http.HttpServletRequest;
023:        import javax.servlet.http.HttpServletRequestWrapper;
024:        import java.io.*;
025:        import java.net.URLEncoder;
026:        import java.util.*;
027:
028:        /**
029:         * A utility class to handle <tt>multipart/form-data</tt> requests,
030:         * the kind of requests that support file uploads.  This class can
031:         * receive arbitrarily large files (up to an artificial limit you can set),
032:         * and fairly efficiently too. And it knows and works around several browser
033:         * bugs that don't know how to upload files correctly.
034:         * <p/>
035:         * A client can upload files using an HTML form with the following structure.
036:         * Note that not all browsers support file uploads.
037:         * <blockquote><pre>
038:         * &lt;FORM ACTION="/servlet/Handler" METHOD=POST
039:         *          ENCTYPE="multipart/form-data"&gt;
040:         * What is your name? &lt;INPUT TYPE=TEXT NAME=submitter&gt; &lt;BR&gt;
041:         * Which file to upload? &lt;INPUT TYPE=FILE NAME=file&gt; &lt;BR&gt;
042:         * &lt;INPUT TYPE=SUBMIT&GT;
043:         * &lt;/FORM&gt;
044:         * </pre></blockquote>
045:         * <p/>
046:         * The full file upload specification is contained in experimental RFC 1867,
047:         * available at <a href="http://ds.internic.net/rfc/rfc1867.txt">
048:         * http://ds.internic.net/rfc/rfc1867.txt</a>.
049:         *
050:         * @author Holger Engels
051:         */
052:        public final class MultipartRequest extends HttpServletRequestWrapper {
053:            private final transient static Log log = LogFactory
054:                    .getLog(MultipartRequest.class);
055:
056:            private static final int DEFAULT_MAX_POST_SIZE = 1024 * 1024; // 1 Meg
057:
058:            private int maxSize;
059:            private boolean urlencodedRequest;
060:
061:            private Map<String, List> parameters; // name - value
062:            private Map<String, UploadedFile> files; // name - UploadedFile
063:            private Map<String, String[]> parameterMap; // name - values
064:
065:            /**
066:             * @param request       the servlet request
067:             * @throws IOException if the uploaded content is larger than 1 Megabyte
068:             *                     or there's a problem reading or parsing the request
069:             */
070:            public MultipartRequest(HttpServletRequest request)
071:                    throws IOException {
072:                this (request, DEFAULT_MAX_POST_SIZE);
073:            }
074:
075:            /**
076:             * @param request     the servlet request
077:             * @param maxPostSize the maximum size of the POST content
078:             * @throws IOException if the uploaded content is larger than
079:             *                     <tt>maxPostSize</tt> or there's a problem reading or parsing the request
080:             */
081:            public MultipartRequest(HttpServletRequest request, int maxPostSize)
082:                    throws IOException {
083:                super (request);
084:
085:                if (request == null)
086:                    throw new IllegalArgumentException("request cannot be null");
087:                if (maxPostSize <= 0)
088:                    throw new IllegalArgumentException(
089:                            "maxPostSize must be positive");
090:
091:                maxSize = maxPostSize;
092:
093:                processRequest(request);
094:            }
095:
096:            /**
097:             * Returns the names of all the parameters as an Enumeration of
098:             * Strings.  It returns an empty Enumeration if there are no parameters.
099:             *
100:             * @return the names of all the parameters as an Enumeration of Strings
101:             */
102:            public Enumeration getParameterNames() {
103:                if (urlencodedRequest)
104:                    return super .getParameterNames();
105:
106:                final Iterator iter = parameters.keySet().iterator();
107:                return new Enumeration() {
108:                    public boolean hasMoreElements() {
109:                        return iter.hasNext();
110:                    }
111:
112:                    public Object nextElement() {
113:                        return iter.next();
114:                    }
115:                };
116:            }
117:
118:            /**
119:             * Returns the names of all the uploaded files as an Enumeration of
120:             * Strings.  It returns an empty Enumeration if there are no uploaded
121:             * files.  Each file name is the name specified by the form, not by
122:             * the user.
123:             *
124:             * @return the names of all the uploaded files as an Enumeration of Strings
125:             */
126:            public Iterator getFileNames() {
127:                if (urlencodedRequest)
128:                    return Collections.EMPTY_SET.iterator();
129:                return files.keySet().iterator();
130:            }
131:
132:            public String[] getParameterValues(String name) {
133:                if (urlencodedRequest)
134:                    return super .getParameterValues(name);
135:
136:                List v = parameters.get(name);
137:                if (v == null)
138:                    return null;
139:                String result[] = new String[v.size()];
140:                return (String[]) v.toArray(result);
141:            }
142:
143:            public Map getParameterMap() {
144:                if (urlencodedRequest)
145:                    return super .getParameterMap();
146:
147:                if (parameterMap == null) {
148:                    parameterMap = new HashMap<String, String[]>();
149:                    Iterator<Map.Entry<String, List>> it = parameters
150:                            .entrySet().iterator();
151:                    while (it.hasNext()) {
152:                        Map.Entry<String, List> entry = it.next();
153:                        List list = entry.getValue();
154:                        String[] values = (String[]) list
155:                                .toArray(new String[list.size()]);
156:                        parameterMap.put(entry.getKey(), values);
157:                    }
158:                }
159:                return parameterMap;
160:            }
161:
162:            /**
163:             * Returns the filename of the specified file, or null if the
164:             * file was not included in the upload. The filename is the name
165:             * specified by the user. It is not the name under which the file is
166:             * actually saved.
167:             *
168:             * @param name the file name
169:             * @return the filesystem name of the file
170:             */
171:            public String getFileName(String name) {
172:                try {
173:                    return files.get(name).getFileName();
174:                } catch (Exception e) {
175:                    return null;
176:                }
177:            }
178:
179:            /**
180:             * Returns the fileid of the specified file, or null if the
181:             * file was not included in the upload. The fileid is the name
182:             * under which the file is saved in the filesystem.
183:             *
184:             * @param name the file name
185:             * @return the filesystem name of the file
186:             */
187:            public String getFileId(String name) {
188:                try {
189:                    return files.get(name).getId();
190:                } catch (Exception e) {
191:                    return null;
192:                }
193:            }
194:
195:            /**
196:             * Returns the content type of the specified file (as supplied by the
197:             * client browser), or null if the file was not included in the upload.
198:             *
199:             * @param name the file name
200:             * @return the content type of the file
201:             */
202:            public String getContentType(String name) {
203:                try {
204:                    return files.get(name).getContentType();
205:                } catch (Exception e) {
206:                    return null;
207:                }
208:            }
209:
210:            /**
211:             * Returns a File object for the specified file saved on the server's
212:             * filesystem, or null if the file was not included in the upload.
213:             *
214:             * @param name the file name
215:             * @return a File object for the named file
216:             */
217:            public File getFile(String name) {
218:                try {
219:                    return files.get(name).getFile();
220:                } catch (Exception e) {
221:                    return null;
222:                }
223:            }
224:
225:            /**
226:             * Indicates if this class was successfully able to parse request as multipart request.
227:             */
228:            public final boolean isMultipart() {
229:                return !urlencodedRequest;
230:            }
231:
232:            /**
233:             * Store exception as request parameter.
234:             */
235:            protected void setException(String param, Exception ex) {
236:                if (!urlencodedRequest) {
237:                    // I'm not 100% sure if it's ok to comment out the following line!
238:                    // However, if we delete all parameters that have been set before
239:                    // the occurence of the exception, the only component that will get
240:                    // triggered during event processing is the filechooser. But since
241:                    // a filechooser provides no ability to register any listeners, the
242:                    // developer has no chance to get informed about the exception in
243:                    // the application code. There is only one reason I can imaging why
244:                    // someone set this line: if other components have been placed below
245:                    // the filechooser on the GUI, their parts won't get processed by
246:                    // the MultipartRequest, the according parameters won't be set and
247:                    // therefore no event processing of such components is done. If we
248:                    // process components above the exception raising filechooser but
249:                    // not components below it, we might end up in an inconsitent state.
250:                    // Anyway, I think it's the better solution to leave it out here!!!
251:                    //
252:                    // -- stephan
253:                    //
254:                    // parameters.clear();
255:                    files.clear();
256:                }
257:                putParameter(param, "exception");
258:                putParameter(param, ex.getMessage());
259:            }
260:
261:            /**
262:             * Parses passed request and stores contained parameters.
263:             *
264:             * @throws IOException On unrecoverable parsing bugs due to old Tomcat version.
265:             */
266:            protected void processRequest(HttpServletRequest req)
267:                    throws IOException {
268:                String type = req.getContentType();
269:                if (type == null
270:                        || !type.toLowerCase()
271:                                .startsWith("multipart/form-data")) {
272:                    urlencodedRequest = true;
273:                    return;
274:                }
275:
276:                urlencodedRequest = false;
277:                parameters = new HashMap<String, List>();
278:                files = new HashMap<String, UploadedFile>();
279:
280:                for (Iterator iterator = req.getParameterMap().entrySet()
281:                        .iterator(); iterator.hasNext(); /**/) {
282:                    Map.Entry entry = (Map.Entry) iterator.next();
283:                    parameters.put((String) entry.getKey(), new ArrayList(
284:                            Arrays.asList((String[]) entry.getValue())));
285:                }
286:
287:                String boundaryToken = extractBoundaryToken(type);
288:                if (boundaryToken == null) {
289:                    /*
290:                     * this could happen due to a bug in Tomcat 3.2.2 in combination
291:                     * with Opera.
292:                     * Opera sends the boundary on a separate line, which is perfectly
293:                     * correct regarding the way header may be constructed 
294:                     * (multiline headers). Alas, Tomcat fails to read the header in 
295:                     * the content type line and thus we cannot read it.. haven't 
296:                     * checked later versions of Tomcat, but upgrading is
297:                     * definitly needed, since we cannot do anything about it here.
298:                     * (JServ works fine, BTW.) (Henner)
299:                     */
300:                    throw new IOException(
301:                            "Separation boundary was not specified (BUG in Tomcat 3.* with Opera?)");
302:                }
303:
304:                MultipartInputStream mimeStream = null;
305:
306:                ByteArrayOutputStream headerByteArray;
307:                SStringBuilder content = new SStringBuilder();
308:                HashMap headers = null;
309:                int currentByte = 0;
310:                int currentPos = 0;
311:                int currentTransformByte = 0;
312:                String currentParam = null;
313:                File uploadFile = null;
314:                OutputStream fileStream = null;
315:                boolean done;
316:                int last = -1;
317:
318:                try {
319:                    mimeStream = new MultipartInputStream(req.getInputStream(),
320:                            req.getContentLength(), maxSize);
321:                    while (currentByte != -1) {
322:                        // Read MIME part header line
323:                        done = false;
324:                        headerByteArray = new ByteArrayOutputStream();
325:                        while ((currentByte = mimeStream.read()) != -1 && !done) {
326:                            headerByteArray.write(currentByte);
327:                            done = (last == '\n' && currentByte == '\r');
328:                            last = currentByte;
329:                        }
330:                        if (currentByte == -1)
331:                            break;
332:
333:                        headers = parseHeader(headerByteArray.toString(req
334:                                .getCharacterEncoding()));
335:                        headerByteArray.reset();
336:                        currentParam = (String) headers.get("name");
337:
338:                        if (headers.size() == 1) { // .. it's not a file
339:                            byte[] bytes = new byte[req.getContentLength()];
340:                            currentPos = 0;
341:                            while ((currentByte = mimeStream.read()) != -1) {
342:                                bytes[currentPos] = (byte) currentByte;
343:                                currentPos++;
344:                                if (currentPos >= boundaryToken.length()) {
345:                                    int i;
346:                                    for (i = 0; i < boundaryToken.length(); i++) {
347:                                        if (boundaryToken.charAt(boundaryToken
348:                                                .length()
349:                                                - i - 1) != bytes[currentPos
350:                                                - i - 1]) {
351:                                            i = 0;
352:                                            break;
353:                                        }
354:                                    }
355:                                    if (i == boundaryToken.length()) { // end of part ..
356:                                        ByteArrayInputStream bais = new ByteArrayInputStream(
357:                                                bytes, 0, currentPos
358:                                                        - boundaryToken
359:                                                                .length() - 4);
360:                                        InputStreamReader ir;
361:                                        if (req.getCharacterEncoding() != null)
362:                                            // It's common behaviour of browsers to encode their form input in the character
363:                                            // encoding of the page, though they don't declare the used characterset explicetly
364:                                            // for backward compatibility.
365:                                            ir = new InputStreamReader(bais,
366:                                                    req.getCharacterEncoding());
367:                                        else
368:                                            ir = new InputStreamReader(bais);
369:                                        content.setLength(0);
370:                                        while ((currentTransformByte = ir
371:                                                .read()) != -1) {
372:                                            content
373:                                                    .append((char) currentTransformByte);
374:                                        }
375:
376:                                        putParameter(currentParam, content
377:                                                .toString());
378:                                        break;
379:                                    }
380:                                }
381:                            }
382:                        } else { // .. it's a file
383:                            String filename = (String) headers.get("filename");
384:                            if (filename != null && filename.length() != 0) {
385:                                // The filename may contain a full path.  Cut to just the filename.
386:                                int slash = Math.max(filename.lastIndexOf('/'),
387:                                        filename.lastIndexOf('\\'));
388:                                if (slash > -1) {
389:                                    filename = filename.substring(slash + 1);
390:                                }
391:                                String name = (String) headers.get("name");
392:
393:                                String contentType = (String) headers
394:                                        .get("content-type");
395:                                try {
396:                                    uploadFile = File.createTempFile(
397:                                            "wings_uploaded", "tmp");
398:                                } catch (IOException e) {
399:                                    log
400:                                            .error(
401:                                                    "couldn't create temp file in '"
402:                                                            + System
403:                                                                    .getProperty("java.io.tmpdir")
404:                                                            + "' (CATALINA_TMPDIR set correctly?)",
405:                                                    e);
406:                                    throw e;
407:                                }
408:
409:                                UploadedFile upload = new UploadedFile(
410:                                        filename, contentType, uploadFile);
411:                                fileStream = new FileOutputStream(uploadFile);
412:
413:                                fileStream = UploadFilterManager
414:                                        .createFilterInstance(name, fileStream);
415:
416:                                AccessibleByteArrayOutputStream byteArray = new AccessibleByteArrayOutputStream();
417:                                byte[] bytes = null;
418:
419:                                int blength = boundaryToken.length();
420:                                int i;
421:                                while ((currentByte = mimeStream.read()) != -1) {
422:                                    byteArray.write(currentByte);
423:                                    for (i = 0; i < blength; i++) {
424:                                        if (boundaryToken.charAt(blength - i
425:                                                - 1) != byteArray
426:                                                .charAt(-i - 1)) {
427:                                            i = 0;
428:                                            if (byteArray.size() > 512 + blength + 2)
429:                                                byteArray.writeTo(fileStream,
430:                                                        512);
431:                                            break;
432:                                        }
433:                                    }
434:                                    if (i == blength) // end of part ..
435:                                        break;
436:                                }
437:                                bytes = byteArray.toByteArray();
438:                                fileStream.write(bytes, 0, bytes.length
439:                                        - blength - 4);
440:                                fileStream.close();
441:
442:                                files.put(name, upload);
443:                                putParameter(name, upload.toString());
444:                            } else { // workaround for some netscape bug
445:                                int i;
446:                                int blength = boundaryToken.length();
447:                                while ((currentByte = mimeStream.read()) != -1) {
448:                                    content.append((char) currentByte);
449:                                    if (content.length() >= blength) {
450:                                        for (i = 0; i < blength; i++) {
451:                                            if (boundaryToken.charAt(blength
452:                                                    - i - 1) != content
453:                                                    .charAt(content.length()
454:                                                            - i - 1)) {
455:                                                i = 0;
456:                                                break;
457:                                            }
458:                                        }
459:                                        if (i == blength)
460:                                            break;
461:                                    }
462:                                }
463:                            }
464:                        }
465:
466:                        currentByte = mimeStream.read();
467:                        if (currentByte == '\r' && mimeStream.read() != '\n')
468:                            log.error("No line return char? " + currentByte);
469:                        if (currentByte == '-' && mimeStream.read() != '-')
470:                            log.error("?? No clue " + currentByte);
471:                    }
472:                } catch (IOException ex) {
473:                    // cleanup and store the exception for notification of SFileChooser
474:                    log.warn("upload", ex);
475:                    if (uploadFile != null)
476:                        uploadFile.delete();
477:                    setException(currentParam, ex);
478:                } finally {
479:                    try {
480:                        fileStream.close();
481:                    } catch (Exception ign) {
482:                    }
483:                    try {
484:                        mimeStream.close();
485:                    } catch (Exception ign) {
486:                    }
487:                }
488:            }
489:
490:            private static class AccessibleByteArrayOutputStream extends
491:                    ByteArrayOutputStream {
492:                public byte charAt(int index) {
493:                    if (count + index < 0) {
494:                        log.warn("count: " + count + ", index: " + index
495:                                + ", buffer: " + new String(buf));
496:                        return -1;
497:                    }
498:                    if (index < 0)
499:                        return buf[count + index];
500:                    if (index < count)
501:                        return buf[index];
502:                    return -1;
503:                }
504:
505:                public byte[] getBuffer() {
506:                    return buf;
507:                }
508:
509:                public void writeTo(OutputStream out, int num)
510:                        throws IOException {
511:                    out.write(buf, 0, num);
512:                    System.arraycopy(buf, num, buf, 0, count - num);
513:                    count = count - num;
514:                }
515:            }
516:
517:            private HashMap parseHeader(String header) {
518:                int lastHeader = -1;
519:                String[] headerLines;
520:                HashMap nameValuePairs = new HashMap();
521:
522:                StringTokenizer stLines = new StringTokenizer(header, "\r\n",
523:                        false);
524:                headerLines = new String[stLines.countTokens()];
525:
526:                // Get all the header lines
527:                while (stLines.hasMoreTokens()) {
528:                    String hLine = stLines.nextToken();
529:                    if (hLine.length() == 0)
530:                        continue;
531:                    /* if the first character is a space, then
532:                     * this line is a header continuation.
533:                     * (opera sends multiline headers..)
534:                     */
535:                    if (lastHeader >= 0
536:                            && Character.isWhitespace(hLine.charAt(0)))
537:                        headerLines[lastHeader] += hLine;
538:                    else
539:                        headerLines[++lastHeader] = hLine;
540:                }
541:
542:                for (int i = 0; i <= lastHeader; ++i) {
543:                    String currentHeader = headerLines[i];
544:                    if (currentHeader.startsWith("Content-Type")) {
545:                        String contentType = currentHeader
546:                                .substring(currentHeader.indexOf(':') + 1);
547:                        int semiColonPos = contentType.indexOf(';');
548:                        if (semiColonPos != -1)
549:                            contentType = contentType
550:                                    .substring(0, semiColonPos);
551:                        nameValuePairs.put("content-type", contentType.trim());
552:                        continue;
553:                    }
554:
555:                    if (!currentHeader.startsWith("Content-Disposition"))
556:                        continue;
557:
558:                    StringTokenizer stTokens = new StringTokenizer(
559:                            currentHeader, ";", false);
560:
561:                    // Get all the tokens from each line
562:                    if (stTokens.countTokens() > 1) {
563:                        stTokens.nextToken(); // Skip fist Token Content-Disposition: form-data
564:                        StringTokenizer stnameValue = new StringTokenizer(
565:                                stTokens.nextToken(), "=", false);
566:                        nameValuePairs.put(stnameValue.nextToken().trim(),
567:                                trim(stnameValue.nextToken(), "\""));
568:
569:                        // This is a file
570:                        if (stTokens.hasMoreTokens()) {
571:                            stnameValue = new StringTokenizer(stTokens
572:                                    .nextToken(), "=", false);
573:
574:                            String formType = stnameValue.nextToken().trim(); // String Object default function
575:                            String filePath = trim(stnameValue.nextToken(),
576:                                    "\""); // Our own trim function.
577:                            // If is a DOS file get rid of drive letter and colon  "e:"
578:                            if (filePath.indexOf(":") != -1)
579:                                filePath = filePath.substring((filePath
580:                                        .indexOf(":") + 1));
581:
582:                            // get rid of PATH
583:                            filePath = filePath.substring(filePath
584:                                    .lastIndexOf(File.separator) + 1);
585:                            nameValuePairs.put(formType, filePath);
586:                        }
587:                    }
588:                }
589:                return nameValuePairs;
590:            }
591:
592:            /**
593:             * This method gets the substring enclosed in trimChar  ; "string" returns string
594:             */
595:            private String trim(String source, String trimChar) {
596:                String target = "";
597:                //Blank space from both sides
598:                source = source.trim();
599:
600:                // Make sure a substring is enclosed between specified characters
601:                if (source.indexOf(trimChar) != -1
602:                        && (source.lastIndexOf(trimChar) >= (source
603:                                .indexOf(trimChar) + 1)))
604:                    // Remove double character from both sides
605:                    target = source.substring(source.indexOf(trimChar) + 1,
606:                            source.lastIndexOf(trimChar));
607:
608:                return target;
609:            }
610:
611:            private static class MultipartInputStream extends InputStream {
612:                ServletInputStream istream = null;
613:                int len, pos, maxLength;
614:
615:                public MultipartInputStream(ServletInputStream istream,
616:                        int len, int maxLength) {
617:                    this .istream = istream;
618:                    this .len = len;
619:                    this .pos = 0;
620:                    this .maxLength = maxLength;
621:                }
622:
623:                /**
624:                 * @return bytes available in stream.
625:                 */
626:                public int available() throws IOException {
627:                    return len - pos - 1;
628:                }
629:
630:                /**
631:                 * @return Next byte in Request.
632:                 * @throws IOException
633:                 */
634:                public int read() throws IOException {
635:                    if (pos >= maxLength)
636:                        throw new IOException("Size (" + len
637:                                + ") exceeds maxlength " + maxLength);
638:
639:                    if (pos >= len)
640:                        return -1;
641:                    pos++;
642:
643:                    return istream.read();
644:                }
645:
646:                public int read(byte b[]) throws IOException {
647:                    return read(b, 0, b.length);
648:                }
649:
650:                public int read(byte b[], int off, int num) throws IOException {
651:                    if (off > 0)
652:                        istream.skip(off);
653:
654:                    if (pos >= len)
655:                        return -1;
656:
657:                    if (num > len - pos)
658:                        num = len - pos;
659:
660:                    num = istream.read(b, 0, num);
661:                    pos += num;
662:
663:                    if (pos >= maxLength)
664:                        throw new IOException("Size (" + len
665:                                + ") exceeds maxlength " + maxLength);
666:
667:                    return num;
668:                }
669:
670:                public long skip(long num) throws IOException {
671:                    if (pos >= len)
672:                        return -1;
673:
674:                    if (num > len - pos)
675:                        num = len - pos;
676:
677:                    num = istream.skip(num);
678:                    pos += num;
679:
680:                    if (pos >= maxLength)
681:                        throw new IOException("Size (" + len
682:                                + ") exceeds maxlength " + maxLength);
683:
684:                    return num;
685:                }
686:
687:                public void close() throws IOException {
688:                    //Ignore closing of the input stream ..
689:                }
690:            }
691:
692:            /**
693:             * Stores a parameter identified in this request.
694:             */
695:            protected void putParameter(String name, String value) {
696:                ArrayList v = (ArrayList) parameters.get(name);
697:                // there is no Parameter yet; create one
698:                if (v == null) {
699:                    v = new ArrayList(2);
700:                    parameters.put(name, v);
701:                }
702:                v.add(value);
703:            }
704:
705:            /**
706:             * Extracts and returns the boundary token from a line.
707:             */
708:            private String extractBoundaryToken(String line) {
709:                int index = line.indexOf("boundary=");
710:                if (index == -1) {
711:                    return null;
712:                }
713:                String boundary = line.substring(index + 9); // 9 for "boundary="
714:                // The real boundary is always preceeded by an extra "--"
715:                //boundary = "--" + boundary;
716:
717:                return boundary;
718:            }
719:
720:            /**
721:             * Extracts and returns the content type from a line, or null if the line was empty.
722:             *
723:             * @throws IOException if the line is malformatted.
724:             */
725:            private String extractContentType(String line) throws IOException {
726:                String contentType = null;
727:
728:                // Convert the line to a lowercase string
729:                String origline = line;
730:                line = origline.toLowerCase();
731:
732:                // Get the content type, if any
733:                if (line.startsWith("content-type")) {
734:                    int start = line.indexOf(" ");
735:                    if (start == -1) {
736:                        throw new IOException("Content type corrupt: "
737:                                + origline);
738:                    }
739:                    contentType = line.substring(start + 1);
740:                } else if (line.length() != 0) { // no content type, so should be empty
741:                    throw new IOException("Malformed line after disposition: "
742:                            + origline);
743:                }
744:
745:                return contentType;
746:            }
747:
748:            private static long uniqueId = 0;
749:
750:            private static final synchronized String uniqueId() {
751:                uniqueId++;
752:                return System.currentTimeMillis() + "." + uniqueId;
753:            }
754:
755:            /**
756:             * A class to hold information about an uploaded file.
757:             */
758:            class UploadedFile {
759:                private String fileName;
760:                private String type;
761:                private File uploadedFile;
762:
763:                UploadedFile(String fileName, String type, File f) {
764:                    this .uploadedFile = f;
765:                    this .fileName = fileName;
766:                    this .type = type;
767:                }
768:
769:                /**
770:                 * @return Path of uploaded file
771:                 */
772:                public String getDir() {
773:                    if (uploadedFile != null)
774:                        return uploadedFile.getParentFile().getPath();
775:                    else
776:                        return null;
777:                }
778:
779:                /**
780:                 * @return Filename passed by browser
781:                 */
782:                public String getFileName() {
783:                    return fileName;
784:                }
785:
786:                /**
787:                 * @return MIME type passed by browser
788:                 */
789:                public String getContentType() {
790:                    return type;
791:                }
792:
793:                /**
794:                 * @return Uploaded file
795:                 */
796:                public File getFile() {
797:                    return uploadedFile;
798:                }
799:
800:                /**
801:                 * @return Uploaded file name
802:                 */
803:                public String getId() {
804:                    if (uploadedFile != null)
805:                        return uploadedFile.getName();
806:                    else
807:                        return null;
808:                }
809:
810:                /**
811:                 * create a URL-encoded form of this uploaded file, that contains
812:                 * all parameters important for this file. The parameters returned
813:                 * are 'dir', 'name', 'type' and 'id'
814:                 * <ul>
815:                 * <li>'dir' contains the directory in the filesystem, the file
816:                 * has been stored into.</li>
817:                 * <li>'name' contains the filename as provided by the user</li>
818:                 * <li>'type' contains the mime-type of this file.</li>
819:                 * <li>'id' contains the internal name of the file in the
820:                 * filesystem.</li>
821:                 * </ul>
822:                 */
823:                public String toString() {
824:                    String encoding = getRequest().getCharacterEncoding() != null ? getRequest()
825:                            .getCharacterEncoding()
826:                            : LocaleCharSet.DEFAULT_ENCODING;
827:
828:                    try {
829:                        SStringBuilder buffer = new SStringBuilder();
830:                        buffer.append("dir=");
831:                        buffer.append(URLEncoder.encode(getDir(), encoding));
832:                        if (getFileName() != null) {
833:                            buffer.append("&name=");
834:                            buffer.append(URLEncoder.encode(getFileName(),
835:                                    encoding));
836:                        }
837:                        if (getContentType() != null) {
838:                            buffer.append("&type=");
839:                            buffer.append(URLEncoder.encode(getContentType(),
840:                                    encoding));
841:                        }
842:                        buffer.append("&id=");
843:                        buffer.append(URLEncoder.encode(getId(), encoding));
844:
845:                        return buffer.toString();
846:                    } catch (UnsupportedEncodingException e) {
847:                        log.error(getClass().getName(), e);
848:                        return null;
849:                    }
850:                }
851:            }
852:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.