Source Code Cross Referenced for MultipartRequest.java in  » Web-Framework » Millstone » org » millstone » webadapter » 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 » Web Framework » Millstone » org.millstone.webadapter 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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