KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > cofax > cms > MultipartRequest


1 package org.cofax.cms;
2
3 import java.util.Hashtable JavaDoc;
4 import java.io.BufferedOutputStream JavaDoc;
5 import java.io.BufferedInputStream JavaDoc;
6 import java.io.InputStream JavaDoc;
7 import java.io.PrintWriter JavaDoc;
8 import java.io.FileOutputStream JavaDoc;
9 import java.io.IOException JavaDoc;
10 import java.util.Enumeration JavaDoc;
11 import java.io.File JavaDoc;
12
13 /**
14  * A MuliPart form data parser. Parses an input stream and writes out any files
15  * found, making available a hashtable of other url parameters.
16  *
17  * <BR>
18  * <BR>
19  * Copyright (C)2000 Jason Pell. <BR>
20  * Note: restraints have been added to this class so it does not throw errors
21  * when trying to check a key/ value combination where key does not exist. This
22  * class also now returns a hashtable that is populated with filename/ location
23  * in addition to any other HTTPRequest variables that already existed in the
24  * querystring. - Charles Harvey.
25  *
26  * <PRE>
27  *
28  * This program is free software; you can redistribute it and/or modify it under
29  * the terms of the GNU General Public License as published by the Free Software
30  * Foundation; either version 2 of the License, or (at your option) any later
31  * version. <BR>
32  * This program is distributed in the hope that it will be useful, but WITHOUT
33  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
35  * details. <BR>
36  * You should have received a copy of the GNU General Public License along with
37  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
38  * Place - Suite 330, Boston, MA 02111-1307, USA. <BR>
39  * Email: jasonpell@hotmail.com Url:
40  * http://www.geocities.com/SiliconValley/Haven/9778
41  *
42  * </PRE>
43  *
44  * @author Jason Pell
45  *
46  * @version 1.13 If an upload directory is not specified, then all file contents
47  * are sent into oblivion, but the rest of the parsing works as normal.
48  * @version 1.12 Fix, was allowing zero length files. Will not even create the
49  * output file until there is something to write. getFile(String) now
50  * returns null, if a zero length file was specified. 06/11/2000
51  * @version 1.11 Fix, in case Content-type is not specified.
52  * @version 1.1 Removed dependence on Servlets. Now passes in a generic
53  * InputStream instead. "Borrowed" readLine from Tomcat 3.1
54  * ServletInputStream class, so we can remove some of the dependencies
55  * on ServletInputStream. Fixed bug where a empty INPUT TYPE="FILE"
56  * value, would cause an exception.
57  * @version 1.0 Initial Release.
58  */

59
60 public class MultipartRequest {
61     // If not null, send debugging out here.
62
private PrintWriter JavaDoc debug = null;
63
64     private Hashtable JavaDoc htParameters = null;
65
66     private Hashtable JavaDoc htFiles = null;
67
68     private String JavaDoc strBoundary = null;
69
70     // If this Directory spec remains null, writing of files will be disabled...
71
private File JavaDoc fileOutPutDirectory = null;
72
73     private long intContentLength = -1;
74
75     private long intTotalRead = -1;
76
77     /**
78      * Prevent a denial of service by defining this, will never read more data.
79      * If Content-Length is specified to be more than this, will throw an
80      * exception.
81      */

82     public static final int MAX_READ_BYTES = 2 * (1024 * 1024); // 2MB!
83

84     /**
85      * Defines the number of bytes to read per readLine call. 128K
86      */

87     public static final int READ_LINE_BLOCK = 1024 * 128;
88
89     /**
90      * Store a read from the input stream here. Global so we do not keep
91      * creating new arrays each read.
92      */

93     private byte[] blockOfBytes = null;
94
95     /**
96      * Define the array indexes for the htFiles Object array.
97      */

98     private static final int FILENAME = 0;
99
100     private static final int CONTENT_TYPE = 1;
101
102     private static final int SIZE = 2;
103
104     /**
105      * Constructor.
106      *
107      * @param strContentTypeText
108      * The &quot;Content-Type&quot; HTTP header value.
109      * @param intContentLength
110      * The &quot;Content-Length&quot; HTTP header value.
111      * @param in
112      * The InputStream to read and parse.
113      * @param strSaveDirectory
114      * The temporary directory to save the file from where they can
115      * then be moved to wherever by the calling process. <b>If you
116      * specify <u>null</u> for this parameter, then any files
117      * uploaded will be silently ignored.</b>
118      *
119      * @exception IllegalArgumentException
120      * If the strContentTypeText does not contain a Content-Type
121      * of "multipart/form-data" or the boundary is not found.
122      * @exception IOException
123      * If the intContentLength is higher than MAX_READ_BYTES or
124      * strSaveDirectory is invalid or cannot be written to.
125      *
126      * @see #MAX_READ_BYTES
127      */

128     public MultipartRequest(String JavaDoc strContentTypeText, int intContentLength, InputStream JavaDoc in, String JavaDoc strSaveDirectory) throws IllegalArgumentException JavaDoc,
129             IOException JavaDoc {
130         this(null, strContentTypeText, intContentLength, in, strSaveDirectory);
131     }
132
133     /**
134      * Constructor.
135      *
136      * @param debug
137      * A PrintWriter that can be used for debugging.
138      * @param strContentTypeText
139      * The &quot;Content-Type&quot; HTTP header value.
140      * @param intContentLength
141      * The &quot;Content-Length&quot; HTTP header value.
142      * @param in
143      * The InputStream to read and parse.
144      * @param strSaveDirectory
145      * The temporary directory to save the file from where they can
146      * then be moved to wherever by the calling process. <b>If you
147      * specify <u>null</u> for this parameter, then any files
148      * uploaded will be silently ignored.</B>
149      *
150      * @exception IllegalArgumentException
151      * If the strContentTypeText does not contain a Content-Type
152      * of "multipart/form-data" or the boundary is not found.
153      * @exception IOException
154      * If the intContentLength is higher than MAX_READ_BYTES or
155      * strSaveDirectory is invalid or cannot be written to.
156      *
157      * @see #MAX_READ_BYTES
158      */

159     public MultipartRequest(PrintWriter JavaDoc debug, String JavaDoc strContentTypeText, int intContentLength, InputStream JavaDoc in, String JavaDoc strSaveDirectory)
160             throws IllegalArgumentException JavaDoc, IOException JavaDoc {
161
162         this.debug = debug;
163
164         if (strContentTypeText != null && strContentTypeText.startsWith("multipart/form-data") && strContentTypeText.indexOf("boundary=") != -1) {
165             strBoundary = strContentTypeText.substring(strContentTypeText.indexOf("boundary=") + "boundary=".length()).trim();
166         } else {
167             throw new IllegalArgumentException JavaDoc("Invalid Content Type.");
168         }
169
170         this.intContentLength = intContentLength;
171         if (intContentLength > CofaxToolsServlet.uploadMaxSize * 1000 * 1000)
172             throw new IOException JavaDoc("Invalid Content Length: " + intContentLength);
173
174         // Instantiate the hashtable...
175
htParameters = new Hashtable JavaDoc();
176         htFiles = new Hashtable JavaDoc();
177
178         blockOfBytes = new byte[READ_LINE_BLOCK];
179
180         // IF strSaveDirectory == NULL, then we should ignore any files
181
// uploaded.
182
if (strSaveDirectory != null) {
183             CofaxToolsUtil.log("directory is " + strSaveDirectory);
184             fileOutPutDirectory = new File JavaDoc(strSaveDirectory);
185             if (!fileOutPutDirectory.exists()) {
186                 throw new IOException JavaDoc("Multipart Directory does not exist.");
187             }
188
189             if (!fileOutPutDirectory.canWrite()) {
190                 throw new IOException JavaDoc("Multipart Directory cannot be written to.");
191             }
192         }
193
194         // Now parse the data.
195
parse(new BufferedInputStream JavaDoc(in));
196
197         // No need for this once parse is complete.
198
this.blockOfBytes = null;
199         this.debug = null;
200         this.strBoundary = null;
201     }
202
203     /**
204      * If an error occurs will return null.
205      */

206     public String JavaDoc getURLParameter(String JavaDoc strParameter) {
207         return (String JavaDoc) htParameters.get(strParameter);
208     }
209
210     /**
211      * An enumeration of all URL Parameters for the current HTTP Request.
212      */

213     public Enumeration JavaDoc getParameterNames() {
214         return htParameters.keys();
215     }
216
217     public Enumeration JavaDoc getFileParameterNames() {
218         return htFiles.keys();
219     }
220
221     /**
222      * Returns the Content-Type of a file.
223      */

224     public String JavaDoc getContentType(String JavaDoc strName) {
225         Object JavaDoc[] objArray = (Object JavaDoc[]) htFiles.get(strName);
226         if (objArray != null && objArray[CONTENT_TYPE] != null)
227             return (String JavaDoc) objArray[CONTENT_TYPE];
228         else
229             return null;
230     }
231
232     /**
233      * Because the strSaveDirectory you specify is really only the temporary
234      * location to stream the files to, we want a way to get at the files
235      * contents to put it in the correct location. Once you have a File
236      * reference, you can copy/move the file elsewhere. <i>Return a null file
237      * reference if a call to getFileSize(strName) returns zero.</i>
238      *
239      * @see #getFileSize(java.lang.String)
240      */

241     public File JavaDoc getFile(String JavaDoc strName) {
242         String JavaDoc filename = getFileSystemName(strName);
243         // Fix: If fileOutPutDirectory is null, then we are ignoring any file
244
// contents, so we must return null.
245
if (filename != null && getFileSize(strName) > 0 && fileOutPutDirectory != null)
246             return new File JavaDoc(fileOutPutDirectory, filename);
247         else
248             return null;
249     }
250
251     /**
252      * Returns the File System name of a file.
253      */

254     public String JavaDoc getFileSystemName(String JavaDoc strName) {
255         Object JavaDoc[] objArray = (Object JavaDoc[]) htFiles.get(strName);
256         if (objArray != null && objArray[FILENAME] != null)
257             return (String JavaDoc) objArray[FILENAME];
258         else
259             return null;
260     }
261
262     /**
263      * Returns the File Size of a file.
264      *
265      * @return -1 if file size not defined.
266      */

267     public long getFileSize(String JavaDoc strName) {
268         Object JavaDoc[] objArray = (Object JavaDoc[]) htFiles.get(strName);
269         if (objArray != null && objArray[SIZE] != null)
270             return ((Long JavaDoc) objArray[SIZE]).longValue();
271         else
272             return (long) -1;
273     }
274
275     private void parse(InputStream JavaDoc in) throws IOException JavaDoc {
276         String JavaDoc strContentType = null;
277         String JavaDoc strName = null;
278         String JavaDoc strFilename = null;
279         String JavaDoc strLine = null;
280         int read = -1;
281
282         // First run through, check that the first line is a boundary, otherwise
283
// throw a exception as format incorrect.
284
read = readLine(in, blockOfBytes);
285         strLine = read > 0 ? new String JavaDoc(blockOfBytes, 0, read) : null;
286
287         // Must be boundary at top of loop, otherwise we have finished.
288
if (strLine == null || strLine.indexOf(this.strBoundary) == -1)
289             throw new IOException JavaDoc("Invalid Form Data, no boundary encountered.");
290
291         // At the top of loop, we assume that the Content-Disposition line is
292
// next, otherwise we are at the end.
293
while (true) {
294             // Get Content-Disposition line.
295
read = readLine(in, blockOfBytes);
296             if (read <= 0)
297                 break; // Nothing to do.
298
else {
299                 strLine = new String JavaDoc(blockOfBytes, 0, read);
300
301                 // TODO: Improve performance by getting both the name and
302
// filename from strLine in one go...
303
strName = trimQuotes(getValue("name", strLine));
304                 // If this is not null, it indicates that we are processing a
305
// filename.
306
strFilename = trimQuotes(getValue("filename", strLine));
307                 // Now if not null, strip it of any directory information.
308

309                 if (strFilename != null) {
310
311                     htParameters.put(strName, strFilename);
312                     // Fix: did not check whether filename was empty string
313
// indicating FILE contents were not passed.
314
if (strFilename.length() > 0) {
315                         // Need to get the content type.
316
read = readLine(in, blockOfBytes);
317                         strLine = read > 0 ? new String JavaDoc(blockOfBytes, 0, read) : null;
318                         strContentType = "application/octet-stream";
319                         // Fix 1.11: If not null AND strLine.length() is long
320
// enough.
321
if (strLine != null && strLine.length() > "Content-Type: ".length())
322                             strContentType = strLine.substring("Content-Type: ".length());// Changed
323
// 1.13
324
} else
325                         readLine(in, blockOfBytes);
326                 }
327                 ;
328                 // Ignore next line, as it should be blank.
329
readLine(in, blockOfBytes);
330
331                 // No filename specified at all.
332
if (strFilename == null) {
333                     // Fix: In case readParameter(in) returned null.
334
String JavaDoc param = readParameter(in);
335                     if ((param != null) && (strName != null)) {
336                         htParameters.put(strName, param);
337                     } else if ((param == null) && (strName != null)) {
338                         htParameters.put(strName, "");
339                     }
340                 } else {
341                     if (strFilename.length() > 0) {
342                         // Get the BASENAME version of strFilename.
343
strFilename = getBasename(strFilename);
344
345                         // Read the file.
346
long filesize = readAndWriteFile(in, strFilename);
347                         if (filesize > 0)
348                             htFiles.put(strName, new Object JavaDoc[] { strFilename, strContentType, new Long JavaDoc(filesize) });
349                         else
350                             // Zero length file.
351
htFiles.put(strName, new Object JavaDoc[] { strFilename, null, new Long JavaDoc(0) });
352                     } else // Fix: FILE INPUT TYPE, but no file passed as
353
// input...
354
{
355                         htFiles.put(strName, new Object JavaDoc[] { null, null, null });
356                         readLine(in, blockOfBytes);
357                     }
358                 }
359             }
360         }// while
361
}
362
363     /**
364      * Read parameters, assume already passed Content-Disposition and blank
365      * line.
366      *
367      * @return the value read in.
368      */

369     private String JavaDoc readParameter(InputStream JavaDoc in) throws IOException JavaDoc {
370         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
371         int read = -1;
372
373         while (true) {
374             read = readLine(in, blockOfBytes);
375             if (read < 0)
376                 throw new IOException JavaDoc("Stream ended prematurely.");
377             else if (read < blockOfBytes.length && new String JavaDoc(blockOfBytes, 0, read).indexOf(this.strBoundary) != -1)
378                 break; // Boundary found, we need to finish up.
379
else
380                 buf.append(getCharArray(blockOfBytes, read));
381         }
382
383         if (buf.length() > 0)
384             buf.setLength(getLengthMinusEnding(buf));
385         return buf.toString();
386     }
387
388     /**
389      * Read a Multipart section that is a file type. Assumes that the
390      * Content-Disposition/Content-Type and blank line have already been
391      * processed. So we read until we hit a boundary, then close file and
392      * return.
393      *
394      * @exception IOException
395      * if an error occurs writing the file.
396      *
397      * @return the number of bytes read.
398      */

399     private long readAndWriteFile(InputStream JavaDoc in, String JavaDoc strFilename) throws IOException JavaDoc {
400         // Open the file for writing.
401
BufferedOutputStream JavaDoc file = null;
402
403         long fileSize = 0;
404         int read = -1;
405         // If not null, write it.
406
byte[] endOfLineBytes = null;
407
408         while (true) {
409             read = readLine(in, blockOfBytes);
410
411             if (read < 0) {
412                 // file may not have been created.
413
if (file != null) {
414                     file.flush();
415                     file.close();
416                 }
417                 throw new IOException JavaDoc("Stream ended prematurely.");
418             } else if (read < blockOfBytes.length && new String JavaDoc(blockOfBytes, 0, read).indexOf(this.strBoundary) != -1) {
419                 // We have found the boundary, so we need to finish up.
420
if (file != null) {
421                     file.flush();
422                     file.close();
423                 }
424                 break;
425             } else {
426                 // Get length of new line minus ending.
427
int length = getLengthMinusEnding(blockOfBytes, read);
428
429                 // Only create the file if more than zero bytes read. Create
430
// file here, as we most likely have something to write.
431
// FIX: Do not bother opening a file if output directory is
432
// invalid.
433
if (file == null && fileOutPutDirectory != null && (endOfLineBytes != null || length > 0))
434                     file = new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(new File JavaDoc(fileOutPutDirectory, strFilename)));
435
436                 // Write previous end of line, if appropriate.
437
if (endOfLineBytes != null) {
438                     // Fix...
439
if (file != null) {
440                         file.write(endOfLineBytes);
441                         // Update file size.
442
fileSize += endOfLineBytes.length;
443                     }
444                 }
445
446                 // int length = getLengthMinusEnding(blockOfBytes, read);
447
if (length > 0) {
448                     // Fix...
449
if (file != null) {
450                         file.write(blockOfBytes, 0, length);
451                         // Update file size.
452
fileSize += length;
453                     }
454                 }
455
456                 // Now store the line ending, so we can spew it out if not at
457
// the boundary.
458
if (endOfLineBytes == null || endOfLineBytes.length != read - length)
459                     endOfLineBytes = new byte[read - length];
460                 System.arraycopy(blockOfBytes, length, endOfLineBytes, 0, endOfLineBytes.length);
461             }
462         }
463
464         return fileSize;
465     }
466
467     /**
468      * Returns the length of the line minus line ending.
469      *
470      * @param endOfArray
471      * This is because in many cases the byteLine will have garbage
472      * data at the end, so we act as though the actual end of the
473      * array is this parameter. If you want to process the complete
474      * byteLine, specify byteLine.length as the endOfArray parameter.
475      */

476     private static final int getLengthMinusEnding(byte byteLine[], int endOfArray) {
477         if (byteLine == null)
478             return 0;
479
480         if (endOfArray >= 2 && byteLine[endOfArray - 2] == '\r' && byteLine[endOfArray - 1] == '\n')
481             return endOfArray - 2;
482         else if (endOfArray >= 1 && byteLine[endOfArray - 1] == '\n' || byteLine[endOfArray - 1] == '\r')
483             return endOfArray - 1;
484         else
485             return endOfArray;
486     }
487
488     private static final int getLengthMinusEnding(StringBuffer JavaDoc buf) {
489         if (buf.length() >= 2 && buf.charAt(buf.length() - 2) == '\r' && buf.charAt(buf.length() - 1) == '\n')
490             return buf.length() - 2;
491         else if (buf.length() >= 1 && buf.charAt(buf.length() - 1) == '\n' || buf.charAt(buf.length() - 1) == '\r')
492             return buf.length() - 1;
493         else
494             return buf.length();
495     }
496
497     /**
498      * Converts a byte array, byte by byte to a string. The new String(byte[])
499      * method causes problems, because it does not include the line ending (if
500      * it occurs in the byte[]) in the new String, so we had to replace with
501      * getCharArray which does a byte[] by byte conversion. The length of the
502      * char[] returned will be (length<=0?byteLine.length: length)
503      */

504     private static final char[] getCharArray(byte byteLine[], int length) {
505         if (byteLine == null)
506             return null;
507
508         // Get the correct length.
509
if (length <= 0)
510             length = byteLine.length;
511
512         char[] charArray = new char[length];
513         for (int i = 0; i < length; i++)
514             charArray[i] = (char) byteLine[i];
515
516         return charArray;
517     }
518
519     /**
520      * Reads at most READ_BLOCK blocks of data, or a single line whichever is
521      * smaller. Returns -1, if nothing to read, or we have reached the specified
522      * content-length.
523      *
524      * Assumes that bytToBeRead.length indicates the block size to read.
525      *
526      * @return -1 if stream has ended, before a newline encountered (should
527      * never happen) OR we have read past the Content-Length specified.
528      * (Should also not happen). Otherwise return the number of
529      * characters read. You can test whether the number returned is less
530      * than bytesToBeRead.length, which indicates that we have read the
531      * last line of a file or parameter or a border line, or some other
532      * formatting stuff.
533      */

534     private int readLine(InputStream JavaDoc in, byte[] bytesToBeRead) throws IOException JavaDoc {
535         // Ensure that there is still stuff to read...
536
if (intTotalRead >= intContentLength)
537             return -1;
538
539         // Get the length of what we are wanting to read.
540
int length = bytesToBeRead.length;
541
542         // End of content, but some servers (apparently) may not realise this
543
// and end the InputStream, so
544
// we cover ourselves this way.
545
if (length > (intContentLength - intTotalRead))
546             length = (int) (intContentLength - intTotalRead); // So we only
547
// read the data
548
// that is left.
549

550         int result = readLine(in, bytesToBeRead, 0, length);
551         // Only if we get a complete line read, otherwise something weird has
552
// happened, such as the end of stream.
553
if (result > 0)
554             intTotalRead += result;
555
556         return result;
557     }
558
559     /**
560      * This needs to support the possibility of a / or a \ separator.
561      *
562      * Returns strFilename after removing all characters before the last
563      * occurence of / or \.
564      */

565     private static final String JavaDoc getBasename(String JavaDoc strFilename) {
566         if (strFilename == null)
567             return strFilename;
568
569         int intIndex = strFilename.lastIndexOf("/");
570         if (intIndex == -1 || strFilename.lastIndexOf("\\") > intIndex)
571             intIndex = strFilename.lastIndexOf("\\");
572
573         if (intIndex != -1)
574             return strFilename.substring(intIndex + 1);
575         else
576             return strFilename;
577     }
578
579     /**
580      * trimQuotes trims any quotes from the start and end of a string and
581      * returns the trimmed string...
582      */

583     private static final String JavaDoc trimQuotes(String JavaDoc strItem) {
584         // Saves having to go any further....
585
if (strItem == null || strItem.indexOf("\"") == -1)
586             return strItem;
587
588         // Get rid of any whitespace..
589
strItem = strItem.trim();
590
591         if (strItem.charAt(0) == '\"')
592             strItem = strItem.substring(1);
593
594         if (strItem.charAt(strItem.length() - 1) == '\"')
595             strItem = strItem.substring(0, strItem.length() - 1);
596
597         return strItem;
598     }
599
600     /**
601      * Format of string name=value; name=value;
602      *
603      * If not found, will return null.
604      */

605     private static final String JavaDoc getValue(String JavaDoc strName, String JavaDoc strToDecode) {
606         strName = strName + "=";
607
608         int startIndexOf = 0;
609         while (startIndexOf < strToDecode.length()) {
610             int indexOf = strToDecode.indexOf(strName, startIndexOf);
611             // Ensure either first name, or a space or ; precedes it.
612
if (indexOf != -1) {
613                 if (indexOf == 0 || Character.isWhitespace(strToDecode.charAt(indexOf - 1)) || strToDecode.charAt(indexOf - 1) == ';') {
614                     int endIndexOf = strToDecode.indexOf(";", indexOf + strName.length());
615                     if (endIndexOf == -1) // May return an empty string...
616
return strToDecode.substring(indexOf + strName.length());
617                     else
618                         return strToDecode.substring(indexOf + strName.length(), endIndexOf);
619                 } else
620                     startIndexOf = indexOf + strName.length();
621             } else
622                 return null;
623         }
624         return null;
625     }
626
627     /**
628      * <I>Tomcat's ServletInputStream.readLine(byte[],int,int) Slightly Modified
629      * to utilise in.read()</I> <BR>
630      * Reads the input stream, one line at a time. Starting at an offset, reads
631      * bytes into an array, until it reads a certain number of bytes or reaches
632      * a newline character, which it reads into the array as well.
633      *
634      * <p>
635      * This method returns -1 if it reaches the end of the input stream before
636      * reading the maximum number of bytes.
637      *
638      * @param b
639      * an array of bytes into which data is read
640      *
641      * @param off
642      * an integer specifying the character at which this method
643      * begins reading
644      *
645      * @param len
646      * an integer specifying the maximum number of bytes to read
647      *
648      * @return an integer specifying the actual number of bytes read, or -1 if
649      * the end of the stream is reached
650      *
651      * @exception IOException
652      * if an input or output exception has occurred
653      *
654      */

655     private int readLine(InputStream JavaDoc in, byte[] b, int off, int len) throws IOException JavaDoc {
656         if (len <= 0)
657             return 0;
658
659         int count = 0, c;
660
661         while ((c = in.read()) != -1) {
662             b[off++] = (byte) c;
663             count++;
664             if (c == '\n' || count == len)
665                 break;
666         }
667         return count > 0 ? count : -1;
668     }
669
670     /**
671      * For debugging.
672      */

673     public String JavaDoc getHtmlTable() {
674         StringBuffer JavaDoc sbReturn = new StringBuffer JavaDoc();
675
676         sbReturn.append("<H1>Parameters</h1>");
677         sbReturn.append("\n<table border=2><tr><td><b>Name</b></td><td><b>Value</b></td></tr>");
678         for (Enumeration JavaDoc e = getParameterNames(); e.hasMoreElements();) {
679             String JavaDoc strName = (String JavaDoc) e.nextElement();
680             sbReturn.append("\n<tr>" + "<td>" + strName + "</td>" + "<td>" + getURLParameter(strName) + "</td>" + "</tr>");
681         }
682         sbReturn.append("</table>");
683
684         sbReturn
685                 .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>");
686         for (Enumeration JavaDoc e = getFileParameterNames(); e.hasMoreElements();) {
687             String JavaDoc strName = (String JavaDoc) e.nextElement();
688
689             sbReturn.append("\n<tr>" + "<td>" + strName + "</td>" + "<td>" + (getFileSystemName(strName) != null ? getFileSystemName(strName) : "") + "</td>"
690                     + "<td>" + (getFile(strName) != null ? getFile(strName).getAbsolutePath() : "") + "</td>" + "<td>"
691                     + (getContentType(strName) != null ? getContentType(strName) : "") + "</td>" + "<td>"
692                     + (getFileSize(strName) != -1 ? getFileSize(strName) + "" : "") + "</td>" + "</tr>");
693         }
694         sbReturn.append("</table>");
695
696         return sbReturn.toString();
697     }
698
699     // For debug.
700
private void debug(String JavaDoc x) {
701         if (debug != null)
702             debug.println(x);
703     }
704 }
705
Popular Tags