Source Code Cross Referenced for MultipartRequest.java in  » ERP-CRM-Financial » SourceTap-CRM » http » utils » multipartrequest » 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 » ERP CRM Financial » SourceTap CRM » http.utils.multipartrequest 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * 
0003:         * Copyright (c) 2004 SourceTap - www.sourcetap.com
0004:         *
0005:         *  The contents of this file are subject to the SourceTap Public License 
0006:         * ("License"); You may not use this file except in compliance with the 
0007:         * License. You may obtain a copy of the License at http://www.sourcetap.com/license.htm
0008:         * Software distributed under the License is distributed on an  "AS IS"  basis,
0009:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
0010:         * the specific language governing rights and limitations under the License.
0011:         *
0012:         * The above copyright notice and this permission notice shall be included
0013:         * in all copies or substantial portions of the Software.
0014:         *
0015:         */
0016:
0017:        package http.utils.multipartrequest;
0018:
0019:        import java.io.BufferedInputStream;
0020:        import java.io.BufferedOutputStream;
0021:        import java.io.ByteArrayInputStream;
0022:        import java.io.ByteArrayOutputStream;
0023:        import java.io.File;
0024:        import java.io.FileOutputStream;
0025:        import java.io.IOException;
0026:        import java.io.InputStream;
0027:        import java.io.OutputStream;
0028:        import java.io.PrintWriter;
0029:        import java.io.UnsupportedEncodingException;
0030:        import java.util.Enumeration;
0031:        import java.util.Hashtable;
0032:        import java.util.Vector;
0033:
0034:        /**
0035:         A Multipart form data parser.  Parses an input stream and writes out any files found,
0036:         making available a hashtable of other url parameters.  As of version 1.17 the files can
0037:         be saved to memory, and optionally written to a database, etc.
0038:
0039:         <BR>
0040:         <BR>
0041:         Copyright (C)2001 Jason Pell.
0042:         <BR>
0043:
0044:         <PRE>
0045:         This library is free software; you can redistribute it and/or
0046:         modify it under the terms of the GNU Lesser General Public
0047:         License as published by the Free Software Foundation; either
0048:         version 2.1 of the License, or (at your option) any later version.
0049:         <BR>
0050:         This library is distributed in the hope that it will be useful,
0051:         but WITHOUT ANY WARRANTY; without even the implied warranty of
0052:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0053:         Lesser General Public License for more details.
0054:         <BR>
0055:         You should have received a copy of the GNU Lesser General Public
0056:         License along with this library; if not, write to the Free Software
0057:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0058:         <BR>
0059:         Email:         jasonpell@hotmail.com
0060:         Url:        http://www.geocities.com/jasonpell
0061:         </PRE>
0062:
0063:         @author Jason Pell
0064:
0065:         @version 1.20        A very minor fix, but one apparently that was causing some serious issues for some users.  The intTotalRead
0066:         integer was being set to -1, which meant that it was always off by one when comparing to Content-Length.
0067:         Thanks to David Tuma for this fix.  19/10/2001
0068:         @version 1.19        Moved the MultipartRequest into a package, and thus into a java archive for easier dissemination.
0069:         Fixed a bug, where in netscape if a file was uploaded with an unrecognised extension, no Content-Type
0070:         was specified, so the first line of the file was chopped off.  Also modified the structure of the parse
0071:         method to make it easier to manage.  I was checking strFileName length and nullness in two if blocks,
0072:         so I moved them together.  This should make the parse(...) method easier to understand as well. 26/07/2001
0073:         @version 1.18        Fixed some serious bugs.  A new method readAndWrite(InputStream in, OutputStream out) which now does
0074:         the generic processing in common for readAndWriteFile and readFile.  The differences are that now
0075:         the two extra bytes at the end of a file upload are processed once, instead of after each line.  Also
0076:         if an empty file is encountered, an outputstream is opened, but then deleted if no data written to it.
0077:         The getCharArray() method has been removed.  Replaced by the new String(bytes, encoding) method using
0078:         ISO8859_1 encoding to ensure that extended characters are supported.  All creation of strings is done
0079:         using this encoding.  The addition of static methods setEncoding(String) and getEncoding() to allow the
0080:         use of MultipartRequest with a specific encoding type.  All instances of MultipartRequest will utilise
0081:         the static charEncoding variable value, that the setEncoding() method can be used to set.
0082:         Hopefully this will not introduce any latent problems. Started to introduce support for multiple file
0083:         uploads with the same form field name, but not completed for v1.18.  26/06/2001
0084:         @version 1.17        A few _very_ minor fixes.  Plus a cool new feature added.  The ability to save files into memory.
0085:         <b>Thanks to Mark Latham for the idea and some of the code.</b> 11/04/2001
0086:         @version 1.16        Added support for multiple parameter values.  Also fixed getCharArray(...) method to support
0087:         parameters with non-english ascii values (ascii above 127).  Thanks to Stefan Schmidt &
0088:         Michael Elvers for this.  (No fix yet for reported problems with Tomcat 3.2 or a single extra
0089:         byte appended to uploads of certain files).  By 1.17 hopefully will have a resolution for the
0090:         second problem.  14/03/2001
0091:         @version 1.15        A new parameter added, intMaxReadBytes, to allow arbitrary length files.  Released under
0092:         the LGPL (Lesser General Public License).          03/02/2001
0093:         @version 1.14        Fix for IE problem with filename being empty.  This is because IE includes a default Content-Type
0094:         even when no file is uploaded.  16/02/2001
0095:         @version 1.13        If an upload directory is not specified, then all file contents are sent into oblivion, but the
0096:         rest of the parsing works as normal.
0097:         @version 1.12        Fix, was allowing zero length files.  Will not even create the output file until there is
0098:         something to write.  getFile(String) now returns null, if a zero length file was specified.  06/11/2000
0099:         @version 1.11        Fix, in case Content-type is not specified.
0100:         @version 1.1        Removed dependence on Servlets.  Now passes in a generic InputStream instead.
0101:         "Borrowed" readLine from Tomcat 3.1 ServletInputStream class,
0102:         so we can remove some of the dependencies on ServletInputStream.
0103:         Fixed bug where a empty INPUT TYPE="FILE" value, would cause an exception.
0104:         @version 1.0        Initial Release.
0105:         */
0106:        public class MultipartRequest {
0107:            /**
0108:                    Define Character Encoding method here.
0109:             */
0110:            private static String charEncoding = "ISO-8859-1";
0111:
0112:            /**
0113:                    Prevent a denial of service by defining this, will never read more data.
0114:                    If Content-Length is specified to be more than this, will throw an exception.
0115:
0116:                    This limits the maximum number of bytes to the value of an int, which is 2 Gigabytes.
0117:             */
0118:            public static final int MAX_READ_BYTES = 100 * (1024 * 1024); // 100MB!
0119:
0120:            /**
0121:                    Defines the number of bytes to read per readLine call. 128K
0122:             */
0123:            public static final int READ_LINE_BLOCK = 1024 * 128;
0124:
0125:            /**
0126:                    Define the array indexes for the htFiles Object array.
0127:             */
0128:            public static final int FILENAME = 0;
0129:            public static final int CONTENT_TYPE = 1;
0130:            public static final int SIZE = 2;
0131:
0132:            // Only used for file upload to memory.
0133:            public static final int CONTENTS = 3;
0134:
0135:            // If not null, send debugging out here.
0136:            private PrintWriter debug = null;
0137:            private Hashtable htParameters = null;
0138:            private Hashtable htFiles = null;
0139:            private String strBoundary = null;
0140:
0141:            // If this Directory spec remains null, writing of files will be disabled...
0142:            private File fileOutPutDirectory = null;
0143:
0144:            //  prefix to put on front of file name, to insure files are unique
0145:            private String filePrefix = null;
0146:            private boolean loadIntoMemory = false;
0147:            private long intContentLength;
0148:            private long intTotalRead;
0149:
0150:            /**
0151:                    Store a read from the input stream here.  Global so we do not keep creating new arrays each read.
0152:             */
0153:            private byte[] blockOfBytes = null;
0154:
0155:            /**
0156:             * Constructor.
0157:             *
0158:             * @param strContentTypeText         The &quot;Content-Type&quot; HTTP header value.
0159:             * @param intContentLength                 The &quot;Content-Length&quot; HTTP header value.
0160:             * @param in                                        The InputStream to read and parse.
0161:             * @param strSaveDirectory                The temporary directory to save the file from where they can then be moved to wherever by the
0162:             *                                                                 calling process.  <b>If you specify <u>null</u> for this parameter, then any files uploaded
0163:             *                                                                will be silently ignored.</b>
0164:             *
0165:             * @exception IllegalArgumentException         If the strContentTypeText does not contain a Content-Type of "multipart/form-data" or the boundary is not found.
0166:             * @exception IOException                                If the intContentLength is higher than MAX_READ_BYTES or strSaveDirectory is invalid or cannot be written to.
0167:             *
0168:             * @see #MAX_READ_BYTES
0169:             */
0170:            public MultipartRequest(String strContentTypeText,
0171:                    int intContentLength, InputStream in,
0172:                    String strSaveDirectory) throws IllegalArgumentException,
0173:                    IOException {
0174:                this (null, strContentTypeText, intContentLength, in,
0175:                        strSaveDirectory, null, MAX_READ_BYTES);
0176:            }
0177:
0178:            /**
0179:             * Constructor.
0180:             *
0181:             * @param strContentTypeText         The &quot;Content-Type&quot; HTTP header value.
0182:             * @param intContentLength                 The &quot;Content-Length&quot; HTTP header value.
0183:             * @param in                                        The InputStream to read and parse.
0184:             * @param strSaveDirectory                The temporary directory to save the file from where they can then be moved to wherever by the
0185:             *                                                                 calling process.  <b>If you specify <u>null</u> for this parameter, then any files uploaded
0186:             *                                                                will be silently ignored.</b>
0187:             * @param strFilePrefix                        Prepend this prefix onto the filename. can be used to insure unique file names
0188:             *
0189:             * @exception IllegalArgumentException         If the strContentTypeText does not contain a Content-Type of "multipart/form-data" or the boundary is not found.
0190:             * @exception IOException                                If the intContentLength is higher than MAX_READ_BYTES or strSaveDirectory is invalid or cannot be written to.
0191:             *
0192:             * @see #MAX_READ_BYTES
0193:             */
0194:            public MultipartRequest(String strContentTypeText,
0195:                    int intContentLength, InputStream in,
0196:                    String strSaveDirectory, String strFilePrefix)
0197:                    throws IllegalArgumentException, IOException {
0198:                this (null, strContentTypeText, intContentLength, in,
0199:                        strSaveDirectory, strFilePrefix, MAX_READ_BYTES);
0200:            }
0201:
0202:            /**
0203:             * Constructor.
0204:             *
0205:             * @param strContentTypeText         The &quot;Content-Type&quot; HTTP header value.
0206:             * @param intContentLength                 The &quot;Content-Length&quot; HTTP header value.
0207:             * @param in                                        The InputStream to read and parse.
0208:             * @param strSaveDirectory                The temporary directory to save the file from where they can then be moved to wherever by the
0209:             *                                                                 calling process.  <b>If you specify <u>null</u> for this parameter, then any files uploaded
0210:             *                                                                will be silently ignored.</B>
0211:             * @param intMaxReadBytes                Overrides the MAX_BYTES_READ value, to allow arbitrarily long files.
0212:             *
0213:             * @exception IllegalArgumentException         If the strContentTypeText does not contain a Content-Type of "multipart/form-data" or the boundary is not found.
0214:             * @exception IOException                                If the intContentLength is higher than MAX_READ_BYTES or strSaveDirectory is invalid or cannot be written to.
0215:             *
0216:             * @see #MAX_READ_BYTES
0217:             */
0218:            public MultipartRequest(String strContentTypeText,
0219:                    int intContentLength, InputStream in,
0220:                    String strSaveDirectory, int intMaxReadBytes)
0221:                    throws IllegalArgumentException, IOException {
0222:                this (null, strContentTypeText, intContentLength, in,
0223:                        strSaveDirectory, null, intMaxReadBytes);
0224:            }
0225:
0226:            /**
0227:             * Constructor.
0228:             *
0229:             * @param strContentTypeText         The &quot;Content-Type&quot; HTTP header value.
0230:             * @param intContentLength                 The &quot;Content-Length&quot; HTTP header value.
0231:             * @param in                                        The InputStream to read and parse.
0232:             * @param strSaveDirectory                The temporary directory to save the file from where they can then be moved to wherever by the
0233:             *                                                                 calling process.  <b>If you specify <u>null</u> for this parameter, then any files uploaded
0234:             *                                                                will be silently ignored.</B>
0235:             * @param strFilePrefix                        Prepend this prefix onto the filename. can be used to insure unique file names
0236:             * @param intMaxReadBytes                Overrides the MAX_BYTES_READ value, to allow arbitrarily long files.
0237:             *
0238:             * @exception IllegalArgumentException         If the strContentTypeText does not contain a Content-Type of "multipart/form-data" or the boundary is not found.
0239:             * @exception IOException                                If the intContentLength is higher than MAX_READ_BYTES or strSaveDirectory is invalid or cannot be written to.
0240:             *
0241:             * @see #MAX_READ_BYTES
0242:             */
0243:            public MultipartRequest(String strContentTypeText,
0244:                    int intContentLength, InputStream in,
0245:                    String strSaveDirectory, String strFilePrefix,
0246:                    int intMaxReadBytes) throws IllegalArgumentException,
0247:                    IOException {
0248:                this (null, strContentTypeText, intContentLength, in,
0249:                        strSaveDirectory, strFilePrefix, intMaxReadBytes);
0250:            }
0251:
0252:            /**
0253:             * Constructor.
0254:             *
0255:             * @param debug                                        A PrintWriter that can be used for debugging.
0256:             * @param strContentTypeText         The &quot;Content-Type&quot; HTTP header value.
0257:             * @param intContentLength                 The &quot;Content-Length&quot; HTTP header value.
0258:             * @param in                                        The InputStream to read and parse.
0259:             * @param strSaveDirectory                The temporary directory to save the file from where they can then be moved to wherever by the
0260:             *                                                                 calling process.  <b>If you specify <u>null</u> for this parameter, then any files uploaded
0261:             *                                                                will be silently ignored.</B>
0262:             *
0263:             * @exception IllegalArgumentException         If the strContentTypeText does not contain a Content-Type of "multipart/form-data" or the boundary is not found.
0264:             * @exception IOException                                If the intContentLength is higher than MAX_READ_BYTES or strSaveDirectory is invalid or cannot be written to.
0265:             *
0266:             * @see #MAX_READ_BYTES
0267:             * @deprecated Replaced by MultipartRequest(PrintWriter, String, int, InputStream, int)
0268:             *                                                        You can specify MultipartRequest.MAX_READ_BYTES for        the intMaxReadBytes parameter
0269:             */
0270:            public MultipartRequest(PrintWriter debug,
0271:                    String strContentTypeText, int intContentLength,
0272:                    InputStream in, String strSaveDirectory)
0273:                    throws IllegalArgumentException, IOException {
0274:                this (debug, strContentTypeText, intContentLength, in,
0275:                        strSaveDirectory, null, MAX_READ_BYTES);
0276:            }
0277:
0278:            /**
0279:             * Constructor - load into memory constructor
0280:             *
0281:             * @param debug                                        A PrintWriter that can be used for debugging.
0282:             * @param strContentTypeText         The &quot;Content-Type&quot; HTTP header value.
0283:             * @param intContentLength                 The &quot;Content-Length&quot; HTTP header value.
0284:             * @param in                                        The InputStream to read and parse.
0285:             * @param intMaxReadBytes                Overrides the MAX_BYTES_READ value, to allow arbitrarily long files.
0286:             *
0287:             * @exception IllegalArgumentException         If the strContentTypeText does not contain a Content-Type of "multipart/form-data" or the boundary is not found.
0288:             * @exception IOException                                If the intContentLength is higher than MAX_READ_BYTES or strSaveDirectory is invalid or cannot be written to.
0289:             *
0290:             * @see #MAX_READ_BYTES
0291:             */
0292:            public MultipartRequest(PrintWriter debug,
0293:                    String strContentTypeText, int intContentLength,
0294:                    InputStream in, int intMaxReadBytes)
0295:                    throws IllegalArgumentException, IOException {
0296:                this .loadIntoMemory = true;
0297:
0298:                // Now initialise the object, which will actually call the parse method to parse multipart stream.
0299:                init(debug, strContentTypeText, intContentLength, in,
0300:                        intMaxReadBytes);
0301:            }
0302:
0303:            /**
0304:             * Constructor.
0305:             *
0306:             * @param debug                                        A PrintWriter that can be used for debugging.
0307:             * @param strContentTypeText         The &quot;Content-Type&quot; HTTP header value.
0308:             * @param intContentLength                 The &quot;Content-Length&quot; HTTP header value.
0309:             * @param in                                        The InputStream to read and parse.
0310:             * @param strSaveDirectory                The temporary directory to save the file from where they can then be moved to wherever by the
0311:             *                                                                 calling process.  <b>If you specify <u>null</u> for this parameter, then any files uploaded
0312:             *                                                                will be silently ignored.</B>
0313:             * @param intMaxReadBytes                Overrides the MAX_BYTES_READ value, to allow arbitrarily long files.
0314:             *
0315:             * @exception IllegalArgumentException         If the strContentTypeText does not contain a Content-Type of "multipart/form-data" or the boundary is not found.
0316:             * @exception IOException                                If the intContentLength is higher than MAX_READ_BYTES or strSaveDirectory is invalid or cannot be written to.
0317:             *
0318:             * @see #MAX_READ_BYTES
0319:             */
0320:            public MultipartRequest(PrintWriter debug,
0321:                    String strContentTypeText, int intContentLength,
0322:                    InputStream in, String strSaveDirectory,
0323:                    String strFilePrefix, int intMaxReadBytes)
0324:                    throws IllegalArgumentException, IOException {
0325:                // IF strSaveDirectory == NULL, then we should ignore any files uploaded.
0326:                if (strSaveDirectory != null) {
0327:                    fileOutPutDirectory = new File(strSaveDirectory);
0328:
0329:                    if (!fileOutPutDirectory.exists()) {
0330:                        throw new IOException("Directory [" + strSaveDirectory
0331:                                + "] is invalid.");
0332:                    } else if (!fileOutPutDirectory.canWrite()) {
0333:                        throw new IOException("Directory [" + strSaveDirectory
0334:                                + "] is readonly.");
0335:                    }
0336:                }
0337:
0338:                //set the prefix to be prepended to the file
0339:                filePrefix = strFilePrefix;
0340:
0341:                // Now initialise the object, which will actually call the parse method to parse multipart stream.
0342:                init(debug, strContentTypeText, intContentLength, in,
0343:                        intMaxReadBytes);
0344:            }
0345:
0346:            /**
0347:                    This method should be called on the MultipartRequest itself, not on any
0348:                    instances of MultipartRequest, because this sets up the encoding for all
0349:                    instances of multipartrequest.  You can set the encoding to null, in which
0350:                    case the default encoding will be applied.  The default encoding if this method
0351:                    is not called has been set to ISO-8859-1, which seems to offer the best hope
0352:                    of support for international characters, such as german "Umlaut" characters.
0353:
0354:                    <b>Warning:</b> In multithreaded environments it is the responsibility of the
0355:                    implementer to make sure that this method is not called while another instance
0356:                    is be constructed.  When an instance of MultipartRequest is constructed, it parses
0357:                    the input data, and uses the result of getEncoding() to convert between bytes and
0358:                    strings.  If setEncoding() is called by another thread, then subsequent string conversions
0359:                    in the private parse() method will utilise this new encoding, which will cause serious
0360:                    problems.
0361:             */
0362:            public static synchronized void setEncoding(String enc)
0363:                    throws UnsupportedEncodingException {
0364:                if ((enc == null) || (enc.trim() == "")) {
0365:                    charEncoding = System.getProperty("file.encoding");
0366:                } else {
0367:                    // This will test the encoding for validity.
0368:                    new String(new byte[] { (byte) '\n' }, enc);
0369:
0370:                    charEncoding = enc;
0371:                }
0372:            }
0373:
0374:            /**
0375:                    Returns the current encoding method.
0376:             */
0377:            public static String getEncoding() {
0378:                return charEncoding;
0379:            }
0380:
0381:            /**
0382:             * Initialise the parser.
0383:             *
0384:             * @param debug                                        A PrintWriter that can be used for debugging.
0385:             * @param strContentTypeText         The &quot;Content-Type&quot; HTTP header value.
0386:             * @param intContentLength                 The &quot;Content-Length&quot; HTTP header value.
0387:             * @param in                                        The InputStream to read and parse.
0388:             * @param strSaveDirectory                The temporary directory to save the file from where they can then be moved to wherever by the
0389:             *                                                                 calling process.  <b>If you specify <u>null</u> for this parameter, then any files uploaded
0390:             *                                                                will be silently ignored.</B>
0391:             * @param intMaxReadBytes                Overrides the MAX_BYTES_READ value, to allow arbitrarily long files.
0392:             *
0393:             * @exception IllegalArgumentException         If the strContentTypeText does not contain a Content-Type of "multipart/form-data" or the boundary is not found.
0394:             * @exception IOException                                If the intContentLength is higher than MAX_READ_BYTES or strSaveDirectory is invalid or cannot be written to.
0395:             *
0396:             * @see #MAX_READ_BYTES
0397:             */
0398:            private void init(PrintWriter debug, String strContentTypeText,
0399:                    int intContentLength, InputStream in, int intMaxReadBytes)
0400:                    throws IllegalArgumentException, IOException {
0401:                // save reference to debug stream for later.
0402:                this .debug = debug;
0403:
0404:                if ((strContentTypeText != null)
0405:                        && strContentTypeText.startsWith("multipart/form-data")
0406:                        && (strContentTypeText.indexOf("boundary=") != -1)) {
0407:                    strBoundary = strContentTypeText.substring(
0408:                            strContentTypeText.indexOf("boundary=")
0409:                                    + "boundary=".length()).trim();
0410:                } else {
0411:                    // <mtl,jpell>
0412:                    debug("ContentType = " + strContentTypeText);
0413:                    throw new IllegalArgumentException("Invalid Content Type.");
0414:                }
0415:
0416:                this .intContentLength = intContentLength;
0417:
0418:                // FIX: 1.15
0419:                if (intContentLength > intMaxReadBytes) {
0420:                    debug("ContentLength = " + intContentLength);
0421:                    debug("MaxReadBytes = " + intMaxReadBytes);
0422:
0423:                    throw new IOException("Content Length Error ("
0424:                            + intContentLength + " > " + intMaxReadBytes + ")");
0425:                }
0426:
0427:                // Instantiate the hashtable...
0428:                htParameters = new Hashtable();
0429:                htFiles = new Hashtable();
0430:                blockOfBytes = new byte[READ_LINE_BLOCK];
0431:
0432:                // Even though this method would never normally be called more than once
0433:                // in the objects lifetime, we will initialise it here anyway.
0434:                intTotalRead = 0; // <David Tuma> - fix: 1.20
0435:
0436:                // Now parse the data.
0437:                parse(new BufferedInputStream(in));
0438:
0439:                // No need for this once parse is complete.
0440:                this .blockOfBytes = null;
0441:                this .debug = null;
0442:                this .strBoundary = null;
0443:            }
0444:
0445:            /**
0446:                    Return the value of the strName URLParameter.
0447:                  If more than one value for a particular Parameter, will return the first.
0448:                    If an error occurs will return null.
0449:             */
0450:            public String getURLParameter(String strName) {
0451:                Object value = htParameters.get(strName);
0452:
0453:                if (value instanceof  Vector) {
0454:                    return (String) ((Vector) value).firstElement();
0455:                } else {
0456:                    return (String) htParameters.get(strName);
0457:                }
0458:            }
0459:
0460:            /**
0461:                    Return an enumeration of all values for the strName parameter.
0462:                    Even if a single value for, will always return an enumeration, although
0463:                    it may actually be empty if not value was encountered for strName or
0464:                    it is an invalid parameter name.
0465:             */
0466:            public Enumeration getURLParameters(String strName) {
0467:                Object value = htParameters.get(strName);
0468:
0469:                if (value instanceof  Vector) {
0470:                    return ((Vector) value).elements();
0471:                } else {
0472:                    Vector vector = new Vector();
0473:
0474:                    if (value != null) {
0475:                        vector.addElement(value);
0476:                    }
0477:
0478:                    return vector.elements();
0479:                }
0480:            }
0481:
0482:            /**
0483:                    An enumeration of all URL Parameters for the current HTTP Request.
0484:             */
0485:            public Enumeration getParameterNames() {
0486:                return htParameters.keys();
0487:            }
0488:
0489:            /**
0490:                    This enumeration will return all INPUT TYPE=FILE parameter NAMES as encountered
0491:                    during the upload.
0492:             */
0493:            public Enumeration getFileParameterNames() {
0494:                return htFiles.keys();
0495:            }
0496:
0497:            /**
0498:                    Returns the Content-Type of a file.
0499:
0500:                    @see #getFileParameter(java.lang.String, int)
0501:             */
0502:            public String getContentType(String strName) {
0503:                // Can cast null, it will be ignored.
0504:                return (String) getFileParameter(strName, CONTENT_TYPE);
0505:            }
0506:
0507:            /**
0508:                    If files were uploaded into memory, this method will retrieve the contents
0509:                    of the file as a InputStream.
0510:
0511:                    @return the contents of the file as a InputStream, or null if not file uploaded,
0512:                    or file uploaded to file system directory.
0513:
0514:                    @see #getFileParameter(java.lang.String, int)
0515:             */
0516:            public InputStream getFileContents(String strName) {
0517:                Object obj = getFileParameter(strName, CONTENTS);
0518:
0519:                if (obj != null) {
0520:                    return new ByteArrayInputStream((byte[]) obj);
0521:                } else {
0522:                    return null;
0523:                }
0524:            }
0525:
0526:            /**
0527:                    Returns a File reference to the uploaded file.  This reference is to the files uploaded location,
0528:                    and allows you to read/move/delete the file.
0529:
0530:                    This method is only of use, if files were uploaded to the file system.  Will return null if
0531:                    uploaded to memory, in which case you should use getFileContents(strName) instead.
0532:
0533:                    @return Returns a null file reference if a call to getFileSize(strName) returns zero or files were
0534:                    uploaded to memory.
0535:
0536:                    @see #getFileSize(java.lang.String)
0537:                    @see #getFileContents(java.lang.String)
0538:                    @see #getFileSystemName(java.lang.String)
0539:             */
0540:            public File getFile(String strName) {
0541:                String filename = getFileSystemName(strName);
0542:
0543:                // Fix: If fileOutPutDirectory is null, then we are ignoring any file contents, so we must return null.
0544:                if ((filename != null) && (getFileSize(strName) > 0)
0545:                        && (fileOutPutDirectory != null)) {
0546:                    return new File(fileOutPutDirectory, filename);
0547:                } else {
0548:                    return null;
0549:                }
0550:            }
0551:
0552:            /**
0553:                    Get the file system basename of an uploaded file.
0554:
0555:                    @return null if strName not found.
0556:
0557:                    @see #getFileParameter(java.lang.String, int)
0558:             */
0559:            public String getFileSystemName(String strName) {
0560:                // Can cast null, it will be ignored.
0561:                return (String) getFileParameter(strName, FILENAME);
0562:            }
0563:
0564:            /**
0565:                    Returns the File Size of a uploaded file.
0566:
0567:                    @return -1 if file size not defined.
0568:
0569:                    @see #getFileParameter(java.lang.String, int)
0570:             */
0571:            public long getFileSize(String strName) {
0572:                Object obj = getFileParameter(strName, SIZE);
0573:
0574:                if (obj != null) {
0575:                    return ((Long) obj).longValue();
0576:                } else {
0577:                    return (long) -1;
0578:                }
0579:            }
0580:
0581:            /**
0582:                    Access an attribute of a file upload parameter record.
0583:
0584:                    @param strName is the form field name, used to upload the file.  This identifies
0585:                                    the formfield location in the storage facility.
0586:
0587:                    @param strFilename        This is the FileSystemName of the file
0588:                    @param type        What attribute you want from the File Parameter.
0589:                            The following types are supported:
0590:                                    MultipartRequest.FILENAME,
0591:                                    MultipartRequest.CONTENT_TYPE,
0592:                                    MultipartRequest.SIZE,
0593:                                    MultipartRequest.CONTENTS
0594:
0595:                    The getFileSystemName(),getFileSize(),getContentType(),getContents() methods
0596:                    all use this method passing in a different type argument.
0597:
0598:                    <p><b>Note: </b>This class has been changed to provide for future functionality where you
0599:                    will be able to access all files uploaded, even if they are uploaded using the same
0600:                    form field name.  At this point however, only the first file uploaded via a form
0601:                    field name is accessible.</p>
0602:
0603:                    @see #getContentType(java.lang.String)
0604:                    @see #getFileSize(java.lang.String)
0605:                    @see #getFileContents(java.lang.String)
0606:                    @see #getFileSystemName(java.lang.String)
0607:             */
0608:            public Object getFileParameter(String strName, int type) {
0609:                Object[] objArray = null;
0610:                Object value = htFiles.get(strName);
0611:
0612:                if (value instanceof  Vector) {
0613:                    objArray = (Object[]) ((Vector) value).firstElement();
0614:                } else {
0615:                    objArray = (Object[]) htFiles.get(strName);
0616:                }
0617:
0618:                // Now ensure valid value.
0619:                if ((objArray != null) && (type >= FILENAME)
0620:                        && (type <= CONTENTS)) {
0621:                    return objArray[type];
0622:                } else {
0623:                    return null;
0624:                }
0625:            }
0626:
0627:            /**
0628:                    This is the main parse method.
0629:             */
0630:            private void parse(InputStream in) throws IOException {
0631:                String strContentType = null;
0632:                String strName = null;
0633:                String strFilename = null;
0634:                String strLine = null;
0635:                int read = -1;
0636:
0637:                // First run through, check that the first line is a boundary, otherwise throw a exception as format incorrect.
0638:                read = readLine(in, blockOfBytes);
0639:                strLine = (read > 0) ? new String(blockOfBytes, 0, read,
0640:                        charEncoding) : null;
0641:
0642:                // Must be boundary at top of loop, otherwise we have finished.
0643:                if ((strLine == null)
0644:                        || (strLine.indexOf(this .strBoundary) == -1)) {
0645:                    throw new IOException(
0646:                            "Invalid Form Data, no boundary encountered.");
0647:                }
0648:
0649:                // At the top of loop, we assume that the Content-Disposition line is next, otherwise we are at the end.
0650:                while (true) {
0651:                    // Get Content-Disposition line.
0652:                    read = readLine(in, blockOfBytes);
0653:
0654:                    if (read <= 0) {
0655:                        break; // Nothing to do.
0656:                    } else {
0657:                        strLine = new String(blockOfBytes, 0, read,
0658:                                charEncoding);
0659:
0660:                        // TODO: Improve performance by getting both the name and filename from strLine in one go...
0661:                        strName = trimQuotes(getValue("name", strLine));
0662:
0663:                        // If this is not null, it indicates that we are processing a filename.
0664:                        // Now if not null, strip it of any directory information.
0665:                        strFilename = trimQuotes(getValue("filename", strLine));
0666:
0667:                        // No filename specified at all - parameter
0668:                        if (strFilename == null) {
0669:                            // Skip blank line.
0670:                            readLine(in, blockOfBytes);
0671:
0672:                            String param = readParameter(in);
0673:                            addParameter(strName, param);
0674:                        } else // (strFilename!=null)
0675:                        {
0676:                            // Fix: did not check whether filename was empty string indicating a FILE was not passed.
0677:                            if (strFilename.length() == 0) {
0678:                                // FIX 1.14: IE problem with empty filename.
0679:                                read = readLine(in, blockOfBytes);
0680:                                strLine = (read > 0) ? new String(blockOfBytes,
0681:                                        0, read, charEncoding) : null;
0682:
0683:                                // FIX 1.14 IE Problem still: Check for content-type and extra line, even though no file specified.
0684:                                if ((strLine != null)
0685:                                        && strLine.startsWith("Content-Type:")) {
0686:                                    readLine(in, blockOfBytes);
0687:                                }
0688:
0689:                                // Skip blank line.
0690:                                readLine(in, blockOfBytes);
0691:
0692:                                // Fix: FILE INPUT TYPE, but no file passed as input...
0693:                                addFileParameter(strName, new Object[] { null,
0694:                                        null, null, null });
0695:
0696:                                readLine(in, blockOfBytes);
0697:                            } else // File uploaded, or at least a filename was specified, it could still be spurious.
0698:                            {
0699:                                // Need to get the content type.
0700:                                read = readLine(in, blockOfBytes);
0701:                                strLine = (read > 0) ? new String(blockOfBytes,
0702:                                        0, read, charEncoding) : null;
0703:
0704:                                strContentType = "application/octet-stream";
0705:
0706:                                // Fix 1.11: If not null AND strLine.length() is long enough.
0707:                                // Modified in 1.19, as we should be checking if it is actually a Content-Type.
0708:                                //if (strLine!=null&&strLine.length()>"Content-Type: ".length())
0709:                                if ((strLine != null)
0710:                                        && strLine.startsWith("Content-Type:")) //Changed 1.19
0711:                                {
0712:                                    strContentType = strLine.substring(
0713:                                            "Content-Type:".length()).trim(); // Changed 1.13
0714:
0715:                                    // Skip blank line, but only if a Content-Type was specified.
0716:                                    readLine(in, blockOfBytes);
0717:                                }
0718:
0719:                                long filesize = -1;
0720:
0721:                                // Will remain null for read onto file system uploads.
0722:                                byte[] contentsOfFile = null;
0723:
0724:                                // Get the BASENAME version of strFilename.
0725:                                strFilename = getBasename(strFilename);
0726:
0727:                                if (filePrefix != null) {
0728:                                    strFilename = filePrefix + strFilename;
0729:                                }
0730:
0731:                                // Are we loading files into memory instead of the filesystem?
0732:                                if (loadIntoMemory) {
0733:                                    contentsOfFile = readFile(in);
0734:
0735:                                    if (contentsOfFile != null) {
0736:                                        filesize = contentsOfFile.length;
0737:                                    }
0738:                                } else { // Read the file onto file system.
0739:                                    filesize = readAndWriteFile(in, strFilename);
0740:                                }
0741:
0742:                                // Fix 1.18 for multiple FILE parameter values.
0743:                                if (filesize > 0) {
0744:                                    addFileParameter(strName,
0745:                                            new Object[] { strFilename,
0746:                                                    strContentType,
0747:                                                    new Long(filesize),
0748:                                                    contentsOfFile });
0749:                                } else { // Zero length file.
0750:                                    addFileParameter(strName, new Object[] {
0751:                                            strFilename, null, new Long(0),
0752:                                            null });
0753:                                }
0754:                            }
0755:                        }
0756:                    }
0757:                }
0758:                // while 
0759:            }
0760:
0761:            /**
0762:                    So we can put the logic for supporting multiple parameters with the same
0763:                    form field name in the one location.
0764:             */
0765:            private void addParameter(String strName, String value) {
0766:                // Fix 1.16: for multiple parameter values.
0767:                Object objParms = htParameters.get(strName);
0768:
0769:                // Add an new entry to the param vector.
0770:                if (objParms instanceof  Vector) {
0771:                    ((Vector) objParms).addElement(value);
0772:                } else if (objParms instanceof  String) // There is only one entry, so we create a vector!
0773:                {
0774:                    Vector vecParms = new Vector();
0775:                    vecParms.addElement(objParms);
0776:                    vecParms.addElement(value);
0777:
0778:                    htParameters.put(strName, vecParms);
0779:                } else { // first entry for strName.
0780:                    htParameters.put(strName, value);
0781:                }
0782:            }
0783:
0784:            /**
0785:                    So we can put the logic for supporting multiple files with the same
0786:                    form field name in the one location.
0787:
0788:                    Assumes that this method will never be called with a null fileObj or strFilename.
0789:             */
0790:            private void addFileParameter(String strName, Object[] fileObj) {
0791:                Object objParms = htFiles.get(strName);
0792:
0793:                // Add an new entry to the param vector.
0794:                if (objParms instanceof  Vector) {
0795:                    ((Vector) objParms).addElement(fileObj);
0796:                } else if (objParms instanceof  Object[]) // There is only one entry, so we create a vector!
0797:                {
0798:                    Vector vecParms = new Vector();
0799:                    vecParms.addElement(objParms);
0800:                    vecParms.addElement(fileObj);
0801:
0802:                    htFiles.put(strName, vecParms);
0803:                } else { // first entry for strName.
0804:                    htFiles.put(strName, fileObj);
0805:                }
0806:            }
0807:
0808:            /**
0809:                    Read parameters, assume already passed Content-Disposition and blank line.
0810:
0811:                    @return the value read in.
0812:             */
0813:            private String readParameter(InputStream in) throws IOException {
0814:                StringBuffer buf = new StringBuffer();
0815:                int read = -1;
0816:
0817:                String line = null;
0818:
0819:                while (true) {
0820:                    read = readLine(in, blockOfBytes);
0821:
0822:                    if (read < 0) {
0823:                        throw new IOException("Stream ended prematurely.");
0824:                    }
0825:
0826:                    // Change v1.18: Only instantiate string once for performance reasons.
0827:                    line = new String(blockOfBytes, 0, read, charEncoding);
0828:
0829:                    if ((read < blockOfBytes.length)
0830:                            && (line.indexOf(this .strBoundary) != -1)) {
0831:                        break; // Boundary found, we need to finish up.
0832:                    } else {
0833:                        buf.append(line);
0834:                    }
0835:                }
0836:
0837:                if (buf.length() > 0) {
0838:                    buf.setLength(getLengthMinusEnding(buf));
0839:                }
0840:
0841:                return buf.toString();
0842:            }
0843:
0844:            /**
0845:                    Read from in, write to out, minus last two line ending bytes.
0846:             */
0847:            private long readAndWrite(InputStream in, OutputStream out)
0848:                    throws IOException {
0849:                long fileSize = 0;
0850:                int read = -1;
0851:
0852:                // This variable will be assigned the bytes actually read.
0853:                byte[] secondLineOfBytes = new byte[blockOfBytes.length];
0854:
0855:                // So we do not have to keep creating the second array.
0856:                int sizeOfSecondArray = 0;
0857:
0858:                while (true) {
0859:                    read = readLine(in, blockOfBytes);
0860:
0861:                    if (read < 0) {
0862:                        throw new IOException("Stream ended prematurely.");
0863:                    }
0864:
0865:                    // Found boundary.
0866:                    if ((read < blockOfBytes.length)
0867:                            && (new String(blockOfBytes, 0, read, charEncoding)
0868:                                    .indexOf(this .strBoundary) != -1)) {
0869:                        // Write the line, minus any line ending bytes.
0870:                        //The secondLineOfBytes will NEVER BE NON-NULL if out==null, so there is no need to included this in the test
0871:                        if (sizeOfSecondArray != 0) {
0872:                            // Only used once, so declare here.
0873:                            int actualLength = getLengthMinusEnding(
0874:                                    secondLineOfBytes, sizeOfSecondArray);
0875:
0876:                            if ((actualLength > 0) && (out != null)) {
0877:                                out.write(secondLineOfBytes, 0, actualLength);
0878:
0879:                                // Update file size.
0880:                                fileSize += actualLength;
0881:                            }
0882:                        }
0883:
0884:                        break;
0885:                    } else {
0886:                        // Write out previous line.
0887:                        //The sizeOfSecondArray will NEVER BE ZERO if out==null, so there is no need to included this in the test
0888:                        if (sizeOfSecondArray != 0) {
0889:                            out.write(secondLineOfBytes, 0, sizeOfSecondArray);
0890:
0891:                            // Update file size.
0892:                            fileSize += sizeOfSecondArray;
0893:                        }
0894:
0895:                        // out will always be null, so there is no need to reset sizeOfSecondArray to zero each time.
0896:                        if (out != null) {
0897:                            //Copy the read bytes into the array.
0898:                            System.arraycopy(blockOfBytes, 0,
0899:                                    secondLineOfBytes, 0, read);
0900:
0901:                            // That is how many bytes to read from the secondLineOfBytes
0902:                            sizeOfSecondArray = read;
0903:                        }
0904:                    }
0905:                }
0906:
0907:                //Return the number of bytes written to outstream.
0908:                return fileSize;
0909:            }
0910:
0911:            /**
0912:                    Read a Multipart section that is a file type.  Assumes that the Content-Disposition/Content-Type and blank line
0913:                     have already been processed.  So we read until we hit a boundary, then close file and return.
0914:
0915:                    @exception IOException if an error occurs writing the file.
0916:
0917:                    @return the number of bytes read.
0918:             */
0919:            private long readAndWriteFile(InputStream in, String strFilename)
0920:                    throws IOException {
0921:                // Store a reference to this, as we may need to delete it later.
0922:                File outFile = new File(fileOutPutDirectory, strFilename);
0923:
0924:                BufferedOutputStream out = null;
0925:
0926:                // Do not bother opening a OutputStream, if we cannot even write the file.
0927:                if (fileOutPutDirectory != null) {
0928:                    out = new BufferedOutputStream(
0929:                            new FileOutputStream(outFile));
0930:                }
0931:
0932:                long count = readAndWrite(in, out);
0933:
0934:                // Count would NOT be larger than zero if out was null.
0935:                if (count > 0) {
0936:                    out.flush();
0937:                    out.close();
0938:                } else {
0939:                    out.close();
0940:
0941:                    // Delete file as empty.  We should be able to delete it, if we can open it!
0942:                    outFile.delete();
0943:                }
0944:
0945:                return count;
0946:            }
0947:
0948:            /**
0949:             *  If the fileOutPutDirectory wasn't specified, just read the file to memory.
0950:             *
0951:             *  @param strName - Url parameter this file was loaded under.
0952:             *  @return contents of file, from which you can garner the size as well.
0953:             */
0954:            private byte[] readFile(InputStream in) throws IOException {
0955:                // In this case, we do not need to worry about a outputdirectory.
0956:                ByteArrayOutputStream out = new ByteArrayOutputStream();
0957:
0958:                long count = readAndWrite(in, out);
0959:
0960:                // Count would NOT be larger than zero if out was null.
0961:                if (count > 0) {
0962:                    // Return contents of file to parse method for inclusion in htFiles object.
0963:                    return out.toByteArray();
0964:                } else {
0965:                    return null;
0966:                }
0967:            }
0968:
0969:            /**
0970:                    Returns the length of the line minus line ending.
0971:
0972:                    @param endOfArray         This is because in many cases the byteLine will have garbage data at the end, so we
0973:                                                            act as though the actual end of the array is this parameter.  If you want to process
0974:                                                            the complete byteLine, specify byteLine.length as the endOfArray parameter.
0975:             */
0976:            private static final int getLengthMinusEnding(byte[] byteLine,
0977:                    int endOfArray) {
0978:                if (byteLine == null) {
0979:                    return 0;
0980:                }
0981:
0982:                if ((endOfArray >= 2) && (byteLine[endOfArray - 2] == '\r')
0983:                        && (byteLine[endOfArray - 1] == '\n')) {
0984:                    return endOfArray - 2;
0985:                } else if (((endOfArray >= 1) && (byteLine[endOfArray - 1] == '\n'))
0986:                        || (byteLine[endOfArray - 1] == '\r')) {
0987:                    return endOfArray - 1;
0988:                } else {
0989:                    return endOfArray;
0990:                }
0991:            }
0992:
0993:            /**
0994:             * DOCUMENT ME!
0995:             *
0996:             * @param buf 
0997:             *
0998:             * @return 
0999:             */
1000:            private static final int getLengthMinusEnding(StringBuffer buf) {
1001:                if ((buf.length() >= 2)
1002:                        && (buf.charAt(buf.length() - 2) == '\r')
1003:                        && (buf.charAt(buf.length() - 1) == '\n')) {
1004:                    return buf.length() - 2;
1005:                } else if (((buf.length() >= 1) && (buf
1006:                        .charAt(buf.length() - 1) == '\n'))
1007:                        || (buf.charAt(buf.length() - 1) == '\r')) {
1008:                    return buf.length() - 1;
1009:                } else {
1010:                    return buf.length();
1011:                }
1012:            }
1013:
1014:            /**
1015:                    Reads at most READ_BLOCK blocks of data, or a single line whichever is smaller.
1016:                    Returns -1, if nothing to read, or we have reached the specified content-length.
1017:
1018:                    Assumes that bytToBeRead.length indicates the block size to read.
1019:
1020:                    @return -1 if stream has ended, before a newline encountered (should never happen) OR
1021:                    we have read past the Content-Length specified.  (Should also not happen).  Otherwise
1022:                    return the number of characters read.  You can test whether the number returned is less
1023:                    than bytesToBeRead.length, which indicates that we have read the last line of a file or parameter or
1024:                    a border line, or some other formatting stuff.
1025:             */
1026:            private int readLine(InputStream in, byte[] bytesToBeRead)
1027:                    throws IOException {
1028:                // Ensure that there is still stuff to read...
1029:                if (intTotalRead >= intContentLength) {
1030:                    return -1;
1031:                }
1032:
1033:                // Get the length of what we are wanting to read.
1034:                int length = bytesToBeRead.length;
1035:
1036:                // End of content, but some servers (apparently) may not realise this and end the InputStream, so
1037:                // we cover ourselves this way.
1038:                if (length > (intContentLength - intTotalRead)) {
1039:                    length = (int) (intContentLength - intTotalRead); // So we only read the data that is left.
1040:                }
1041:
1042:                int result = readLine(in, bytesToBeRead, 0, length);
1043:
1044:                // Only if we get actually read something, otherwise something weird has happened, such as the end of stream.
1045:                if (result > 0) {
1046:                    intTotalRead += result;
1047:                }
1048:
1049:                return result;
1050:            }
1051:
1052:            /**
1053:                    This needs to support the possibility of a / or a \ separator.
1054:
1055:                    Returns strFilename after removing all characters before the last
1056:                    occurence of / or \.
1057:             */
1058:            private static final String getBasename(String strFilename) {
1059:                if (strFilename == null) {
1060:                    return strFilename;
1061:                }
1062:
1063:                int intIndex = strFilename.lastIndexOf("/");
1064:
1065:                if ((intIndex == -1)
1066:                        || (strFilename.lastIndexOf("\\") > intIndex)) {
1067:                    intIndex = strFilename.lastIndexOf("\\");
1068:                }
1069:
1070:                if (intIndex != -1) {
1071:                    return strFilename.substring(intIndex + 1);
1072:                } else {
1073:                    return strFilename;
1074:                }
1075:            }
1076:
1077:            /**
1078:                    trimQuotes trims any quotes from the start and end of a string and returns the trimmed string...
1079:             */
1080:            private static final String trimQuotes(String strItem) {
1081:                // Saves having to go any further....
1082:                if ((strItem == null) || (strItem.indexOf("\"") == -1)) {
1083:                    return strItem;
1084:                }
1085:
1086:                // Get rid of any whitespace..
1087:                strItem = strItem.trim();
1088:
1089:                if (strItem.charAt(0) == '\"') {
1090:                    strItem = strItem.substring(1);
1091:                }
1092:
1093:                if (strItem.charAt(strItem.length() - 1) == '\"') {
1094:                    strItem = strItem.substring(0, strItem.length() - 1);
1095:                }
1096:
1097:                return strItem;
1098:            }
1099:
1100:            /**
1101:                    Format of string name=value; name=value;
1102:
1103:                    If not found, will return null.
1104:             */
1105:            private static final String getValue(String strName,
1106:                    String strToDecode) {
1107:                strName = strName + "=";
1108:
1109:                int startIndexOf = 0;
1110:
1111:                while (startIndexOf < strToDecode.length()) {
1112:                    int indexOf = strToDecode.indexOf(strName, startIndexOf);
1113:
1114:                    // Ensure either first name, or a space or ; precedes it.
1115:                    if (indexOf != -1) {
1116:                        if ((indexOf == 0)
1117:                                || Character.isWhitespace(strToDecode
1118:                                        .charAt(indexOf - 1))
1119:                                || (strToDecode.charAt(indexOf - 1) == ';')) {
1120:                            int endIndexOf = strToDecode.indexOf(";", indexOf
1121:                                    + strName.length());
1122:
1123:                            if (endIndexOf == -1) { // May return an empty string...
1124:
1125:                                return strToDecode.substring(indexOf
1126:                                        + strName.length());
1127:                            } else {
1128:                                return strToDecode.substring(indexOf
1129:                                        + strName.length(), endIndexOf);
1130:                            }
1131:                        } else {
1132:                            startIndexOf = indexOf + strName.length();
1133:                        }
1134:                    } else {
1135:                        return null;
1136:                    }
1137:                }
1138:
1139:                return null;
1140:            }
1141:
1142:            /**
1143:             * <I>Tomcat's ServletInputStream.readLine(byte[],int,int)  Slightly Modified to utilise in.read()</I>
1144:             * <BR>
1145:             * Reads the input stream, one line at a time. Starting at an
1146:             * offset, reads bytes into an array, until it reads a certain number
1147:             * of bytes or reaches a newline character, which it reads into the
1148:             * array as well.
1149:             *
1150:             * <p>This method <u><b>does not</b></u> returns -1 if it reaches the end of the input
1151:             * stream before reading the maximum number of bytes, it returns -1, if no bytes read.
1152:             *
1153:             * @param b                 an array of bytes into which data is read
1154:             *
1155:             * @param off                 an integer specifying the character at which
1156:             *                                        this method begins reading
1157:             *
1158:             * @param len                an integer specifying the maximum number of
1159:             *                                        bytes to read
1160:             *
1161:             * @return                        an integer specifying the actual number of bytes
1162:             *                                        read, or -1 if the end of the stream is reached
1163:             *
1164:             * @exception IOException        if an input or output exception has occurred
1165:             *
1166:
1167:                    Note: We have a problem with Tomcat reporting an erroneous number of bytes, so we need to check this.
1168:                    This is the method where we get an infinite loop, but only with binary files.
1169:             */
1170:            private int readLine(InputStream in, byte[] b, int off, int len)
1171:                    throws IOException {
1172:                if (len <= 0) {
1173:                    return 0;
1174:                }
1175:
1176:                int count = 0;
1177:                int c;
1178:
1179:                while ((c = in.read()) != -1) {
1180:                    b[off++] = (byte) c;
1181:                    count++;
1182:
1183:                    if ((c == '\n') || (count == len)) {
1184:                        break;
1185:                    }
1186:                }
1187:
1188:                return (count > 0) ? count : (-1);
1189:            }
1190:
1191:            /**
1192:                    Use when debugging this object.
1193:             */
1194:            protected void debug(String x) {
1195:                if (debug != null) {
1196:                    debug.println(x);
1197:                    debug.flush();
1198:                }
1199:            }
1200:
1201:            /**
1202:                    For debugging.
1203:
1204:                    Be aware that if you have a form with multiple FILE input types of the same name, only the first one
1205:                    will actually be returned from the getFileParameter(...) method, which all the file access methods call.
1206:
1207:                    So if your upload file was actually uploaded against the second file input field, then it will not be accessible,
1208:                    via the methods.
1209:             */
1210:            public String getHtmlTable() {
1211:                StringBuffer sbReturn = new StringBuffer();
1212:
1213:                sbReturn.append("<h2>Parameters</h2>");
1214:                sbReturn
1215:                        .append("\n<table border=3><tr><td><b>Name</b></td><td><b>Value</b></td></tr>");
1216:
1217:                for (Enumeration e = getParameterNames(); e.hasMoreElements();) {
1218:                    String strName = (String) e.nextElement();
1219:                    sbReturn.append("\n<tr>" + "<td>" + strName + "</td>");
1220:
1221:                    sbReturn.append("<td><table border=1><tr>");
1222:
1223:                    for (Enumeration f = getURLParameters(strName); f
1224:                            .hasMoreElements();) {
1225:                        String value = (String) f.nextElement();
1226:                        sbReturn.append("<td>" + value + "</td>");
1227:                    }
1228:
1229:                    sbReturn.append("</tr></table></td></tr>");
1230:                }
1231:
1232:                sbReturn.append("</table>");
1233:
1234:                sbReturn.append("<h2>File Parameters</h2>");
1235:
1236:                sbReturn
1237:                        .append("\n<table border=2><tr><td><b>Name</b></td><td><b>Filename</b></td><td><b>Path</b></td><td><b>Content Type</b></td><td><b>Size</b></td></tr>");
1238:
1239:                for (Enumeration e = getFileParameterNames(); e
1240:                        .hasMoreElements();) {
1241:                    String strName = (String) e.nextElement();
1242:
1243:                    sbReturn
1244:                            .append("\n<tr>"
1245:                                    + "<td>"
1246:                                    + strName
1247:                                    + "</td>"
1248:                                    + "<td>"
1249:                                    + ((getFileSystemName(strName) != null) ? getFileSystemName(strName)
1250:                                            : "") + "</td>");
1251:
1252:                    if (loadIntoMemory) {
1253:                        sbReturn
1254:                                .append("<td>"
1255:                                        + ((getFileSize(strName) > 0) ? "<i>in memory</i>"
1256:                                                : "") + "</td>");
1257:                    } else {
1258:                        sbReturn
1259:                                .append("<td>"
1260:                                        + ((getFile(strName) != null) ? getFile(
1261:                                                strName).getAbsolutePath()
1262:                                                : "") + "</td>");
1263:                    }
1264:
1265:                    sbReturn
1266:                            .append("<td>"
1267:                                    + ((getContentType(strName) != null) ? getContentType(strName)
1268:                                            : "")
1269:                                    + "</td>"
1270:                                    + "<td>"
1271:                                    + ((getFileSize(strName) != -1) ? (getFileSize(strName) + "")
1272:                                            : "") + "</td>" + "</tr>");
1273:                }
1274:
1275:                sbReturn.append("</table>");
1276:
1277:                return sbReturn.toString();
1278:            }
1279:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.