001: // Copyright (C) 1998-2001 by Jason Hunter <jhunter_AT_acm_DOT_org>.
002: // All rights reserved. Use of this class is limited.
003: // Please see the LICENSE for more information.
004:
005: package com.oreilly.servlet;
006:
007: import java.io.*;
008: import java.util.*;
009: import javax.servlet.*;
010: import javax.servlet.http.*;
011:
012: import java.util.Enumeration;
013: import java.util.Map;
014:
015: import java.security.Principal;
016:
017: import com.oreilly.servlet.multipart.MultipartParser;
018: import com.oreilly.servlet.multipart.Part;
019: import com.oreilly.servlet.multipart.FilePart;
020: import com.oreilly.servlet.multipart.ParamPart;
021: import com.oreilly.servlet.multipart.FileRenamePolicy;
022:
023: /**
024: * A utility class to handle <code>multipart/form-data</code> requests,
025: * the kind of requests that support file uploads. This class emulates the
026: * interface of <code>HttpServletRequest</code>, making it familiar to use.
027: * It uses a "push" model where any incoming files are read and saved directly
028: * to disk in the constructor. If you wish to have more flexibility, e.g.
029: * write the files to a database, use the "pull" model
030: * <code>MultipartParser</code> instead.
031: * <p>
032: * This class can receive arbitrarily large files (up to an artificial limit
033: * you can set), and fairly efficiently too.
034: * It cannot handle nested data (multipart content within multipart content).
035: * It <b>can</b> now with the latest release handle internationalized content
036: * (such as non Latin-1 filenames).
037: * <p>
038: * To avoid collisions and have fine control over file placement, there's a
039: * constructor variety that takes a pluggable FileRenamePolicy implementation.
040: * A particular policy can choose to rename or change the location of the file
041: * before it's written.
042: * <p>
043: * See the included upload.war for an example of how to use this class.
044: * <p>
045: * The full file upload specification is contained in experimental RFC 1867,
046: * available at <a href="http://www.ietf.org/rfc/rfc1867.txt">
047: * http://www.ietf.org/rfc/rfc1867.txt</a>.
048: *
049: * @see MultipartParser
050: *
051: * @author Jason Hunter
052: * @author Geoff Soutter
053: * @version 1.11, 2002/11/01, combine query string params in param list<br>
054: * @version 1.10, 2002/05/27, added access to the original file names<br>
055: * @version 1.9, 2002/04/30, added support for file renaming, thanks to
056: * Changshin Lee<br>
057: * @version 1.8, 2002/04/30, added support for internationalization, thanks to
058: * Changshin Lee<br>
059: * @version 1.7, 2001/02/07, made fields protected to increase user flexibility<br>
060: * @version 1.6, 2000/07/21, redid internals to use MultipartParser,
061: * thanks to Geoff Soutter<br>
062: * @version 1.5, 2000/02/04, added auto MacBinary decoding for IE on Mac<br>
063: * @version 1.4, 2000/01/05, added getParameterValues(),
064: * WebSphere 2.x getContentType() workaround,
065: * stopped writing empty "unknown" file<br>
066: * @version 1.3, 1999/12/28, IE4 on Win98 lastIndexOf("boundary=")
067: * workaround<br>
068: * @version 1.2, 1999/12/20, IE4 on Mac readNextPart() workaround<br>
069: * @version 1.1, 1999/01/15, JSDK readLine() bug workaround<br>
070: * @version 1.0, 1998/09/18<br>
071: */
072: public class MultipartRequest implements HttpServletRequest {
073:
074: private static final int DEFAULT_MAX_POST_SIZE = 1024 * 1024; // 1 Meg
075:
076: protected Hashtable parameters = new Hashtable(); // name - Vector of values
077: protected Hashtable files = new Hashtable(); // name - UploadedFile
078: protected Cookie[] cookies;
079: protected Locale requestlocale;
080: protected String sessionid;
081: protected String encoding;
082: protected String servletpath;
083: protected String requesturi;
084: protected String remoteuser;
085: protected String querystr;
086: protected String ctxpath;
087: protected String trnpath;
088: protected String pathinfo;
089: protected String formmethod;
090: protected String contenttype;
091: protected int contentlength;
092: protected StringBuffer requesturl;
093: protected String savedir;
094: protected boolean bRequestedSessionIdFromURL;
095: protected boolean bRequestedSessionIdFromCookie;
096: protected boolean bRequestedSessionIdValid;
097:
098: /**
099: * Constructs a new MultipartRequest to handle the specified request,
100: * saving any uploaded files to the given directory, and limiting the
101: * upload size to 1 Megabyte. If the content is too large, an
102: * IOException is thrown. This constructor actually parses the
103: * <tt>multipart/form-data</tt> and throws an IOException if there's any
104: * problem reading or parsing the request.
105: *
106: * @param request the servlet request.
107: * @param saveDirectory the directory in which to save any uploaded files.
108: * @exception IOException if the uploaded content is larger than 1 Megabyte
109: * or there's a problem reading or parsing the request.
110: */
111: public MultipartRequest(HttpServletRequest request,
112: String saveDirectory) throws IOException {
113: this (request, saveDirectory, DEFAULT_MAX_POST_SIZE);
114: }
115:
116: /**
117: * Constructs a new MultipartRequest to handle the specified request,
118: * saving any uploaded files to the given directory, and limiting the
119: * upload size to the specified length. If the content is too large, an
120: * IOException is thrown. This constructor actually parses the
121: * <tt>multipart/form-data</tt> and throws an IOException if there's any
122: * problem reading or parsing the request.
123: *
124: * @param request the servlet request.
125: * @param saveDirectory the directory in which to save any uploaded files.
126: * @param maxPostSize the maximum size of the POST content.
127: * @exception IOException if the uploaded content is larger than
128: * <tt>maxPostSize</tt> or there's a problem reading or parsing the request.
129: */
130: public MultipartRequest(HttpServletRequest request,
131: String saveDirectory, int maxPostSize) throws IOException {
132: this (request, saveDirectory, maxPostSize, null, null);
133: }
134:
135: /**
136: * Constructs a new MultipartRequest to handle the specified request,
137: * saving any uploaded files to the given directory, and limiting the
138: * upload size to the specified length. If the content is too large, an
139: * IOException is thrown. This constructor actually parses the
140: * <tt>multipart/form-data</tt> and throws an IOException if there's any
141: * problem reading or parsing the request.
142: *
143: * @param request the servlet request.
144: * @param saveDirectory the directory in which to save any uploaded files.
145: * @param encoding the encoding of the response, such as ISO-8859-1
146: * @exception IOException if the uploaded content is larger than
147: * 1 Megabyte or there's a problem reading or parsing the request.
148: */
149: public MultipartRequest(HttpServletRequest request,
150: String saveDirectory, String encoding) throws IOException {
151: this (request, saveDirectory, DEFAULT_MAX_POST_SIZE, encoding,
152: null);
153: }
154:
155: /**
156: * Constructs a new MultipartRequest to handle the specified request,
157: * saving any uploaded files to the given directory, and limiting the
158: * upload size to the specified length. If the content is too large, an
159: * IOException is thrown. This constructor actually parses the
160: * <tt>multipart/form-data</tt> and throws an IOException if there's any
161: * problem reading or parsing the request.
162: *
163: * @param request the servlet request.
164: * @param saveDirectory the directory in which to save any uploaded files.
165: * @param maxPostSize the maximum size of the POST content.
166: * @param encoding the encoding of the response, such as ISO-8859-1
167: * @exception IOException if the uploaded content is larger than
168: * <tt>maxPostSize</tt> or there's a problem reading or parsing the request.
169: */
170: public MultipartRequest(HttpServletRequest request,
171: String saveDirectory, int maxPostSize,
172: FileRenamePolicy policy) throws IOException {
173: this (request, saveDirectory, maxPostSize, null, policy);
174: }
175:
176: /**
177: * Constructs a new MultipartRequest to handle the specified request,
178: * saving any uploaded files to the given directory, and limiting the
179: * upload size to the specified length. If the content is too large, an
180: * IOException is thrown. This constructor actually parses the
181: * <tt>multipart/form-data</tt> and throws an IOException if there's any
182: * problem reading or parsing the request.
183: *
184: * @param request the servlet request.
185: * @param saveDirectory the directory in which to save any uploaded files.
186: * @param maxPostSize the maximum size of the POST content.
187: * @param encoding the encoding of the response, such as ISO-8859-1
188: * @exception IOException if the uploaded content is larger than
189: * <tt>maxPostSize</tt> or there's a problem reading or parsing the request.
190: */
191: public MultipartRequest(HttpServletRequest request,
192: String saveDirectory, int maxPostSize, String encoding)
193: throws IOException {
194: this (request, saveDirectory, maxPostSize, encoding, null);
195: }
196:
197: /**
198: * Constructs a new MultipartRequest to handle the specified request,
199: * saving any uploaded files to the given directory, and limiting the
200: * upload size to the specified length. If the content is too large, an
201: * IOException is thrown. This constructor actually parses the
202: * <tt>multipart/form-data</tt> and throws an IOException if there's any
203: * problem reading or parsing the request.
204: *
205: * To avoid file collisions, this constructor takes an implementation of the
206: * FileRenamePolicy interface to allow a pluggable rename policy.
207: *
208: * @param request the servlet request.
209: * @param saveDirectory the directory in which to save any uploaded files.
210: * @param maxPostSize the maximum size of the POST content.
211: * @param encoding the encoding of the response, such as ISO-8859-1
212: * @param policy a pluggable file rename policy
213: * @exception IOException if the uploaded content is larger than
214: * <tt>maxPostSize</tt> or there's a problem reading or parsing the request.
215: */
216: public MultipartRequest(HttpServletRequest request,
217: String saveDirectory, int maxPostSize, String encoding,
218: FileRenamePolicy policy) throws IOException {
219: // Sanity check values
220: if (request == null)
221: throw new IllegalArgumentException("request cannot be null");
222: if (saveDirectory == null)
223: throw new IllegalArgumentException(
224: "saveDirectory cannot be null");
225: if (maxPostSize <= 0) {
226: throw new IllegalArgumentException(
227: "maxPostSize must be positive");
228: }
229:
230: requestlocale = request.getLocale();
231: encoding = request.getCharacterEncoding();
232: sessionid = request.getRequestedSessionId();
233: requesturl = request.getRequestURL();
234: requesturi = request.getRequestURI();
235: remoteuser = request.getRemoteUser();
236: querystr = request.getQueryString();
237: ctxpath = request.getContextPath();
238: trnpath = request.getPathTranslated();
239: pathinfo = request.getPathInfo();
240: servletpath = request.getServletPath();
241: formmethod = request.getMethod();
242: cookies = request.getCookies();
243:
244: // Save the dir
245: File dir = new File(saveDirectory);
246:
247: // Check saveDirectory is truly a directory
248: if (!dir.isDirectory())
249: throw new IllegalArgumentException("Not a directory: "
250: + saveDirectory);
251:
252: // Check saveDirectory is writable
253: if (!dir.canWrite())
254: throw new IllegalArgumentException("Not writable: "
255: + saveDirectory);
256:
257: savedir = saveDirectory;
258:
259: // Parse the incoming multipart, storing files in the dir provided,
260: // and populate the meta objects which describe what we found
261: MultipartParser parser = new MultipartParser(request,
262: maxPostSize, true, true, encoding);
263:
264: // Some people like to fetch query string parameters from
265: // MultipartRequest, so here we make that possible. Thanks to
266: // Ben Johnson, ben.johnson@merrillcorp.com, for the idea.
267: if (request.getQueryString() != null) {
268: // Let HttpUtils create a name->String[] structure
269: Hashtable queryParameters = HttpUtils
270: .parseQueryString(request.getQueryString());
271: // For our own use, name it a name->Vector structure
272: Enumeration queryParameterNames = queryParameters.keys();
273: while (queryParameterNames.hasMoreElements()) {
274: Object paramName = queryParameterNames.nextElement();
275: String[] values = (String[]) queryParameters
276: .get(paramName);
277: Vector newValues = new Vector();
278: for (int i = 0; i < values.length; i++) {
279: newValues.add(values[i]);
280: }
281: parameters.put(paramName, newValues);
282: }
283: }
284:
285: Part part;
286: while ((part = parser.readNextPart()) != null) {
287: String name = part.getName();
288: if (part.isParam()) {
289: // It's a parameter part, add it to the vector of values
290: ParamPart paramPart = (ParamPart) part;
291: String value = paramPart.getStringValue();
292: Vector existingValues = (Vector) parameters.get(name);
293: if (existingValues == null) {
294: existingValues = new Vector();
295: parameters.put(name, existingValues);
296: }
297: existingValues.addElement(value);
298: } else if (part.isFile()) {
299: // It's a file part
300: FilePart filePart = (FilePart) part;
301: String fileName = filePart.getFileName();
302: if (fileName != null) {
303: filePart.setRenamePolicy(policy); // null policy is OK
304: // The part actually contained a file
305: filePart.writeTo(dir);
306: files.put(name, new UploadedFile(dir.toString(),
307: filePart.getFileName(), fileName, filePart
308: .getContentType()));
309: } else {
310: // The field did not contain a file
311: files.put(name, new UploadedFile(null, null, null,
312: null));
313: }
314: }
315: }
316: bRequestedSessionIdFromURL = request
317: .isRequestedSessionIdFromURL();
318: bRequestedSessionIdFromCookie = request
319: .isRequestedSessionIdFromCookie();
320: bRequestedSessionIdValid = request.isRequestedSessionIdValid();
321: }
322:
323: /**
324: * Constructor with an old signature, kept for backward compatibility.
325: * Without this constructor, a servlet compiled against a previous version
326: * of this class (pre 1.4) would have to be recompiled to link with this
327: * version. This constructor supports the linking via the old signature.
328: * Callers must simply be careful to pass in an HttpServletRequest.
329: *
330: */
331: public MultipartRequest(ServletRequest request, String saveDirectory)
332: throws IOException {
333: this ((HttpServletRequest) request, saveDirectory);
334: }
335:
336: /**
337: * Constructor with an old signature, kept for backward compatibility.
338: * Without this constructor, a servlet compiled against a previous version
339: * of this class (pre 1.4) would have to be recompiled to link with this
340: * version. This constructor supports the linking via the old signature.
341: * Callers must simply be careful to pass in an HttpServletRequest.
342: *
343: */
344: public MultipartRequest(ServletRequest request,
345: String saveDirectory, int maxPostSize) throws IOException {
346: this ((HttpServletRequest) request, saveDirectory, maxPostSize);
347: }
348:
349: public Cookie[] getCookies() {
350: return cookies;
351: }
352:
353: public Locale getLocale() {
354: return requestlocale;
355: }
356:
357: /**
358: * Returns the names of all the parameters as an Enumeration of
359: * Strings. It returns an empty Enumeration if there are no parameters.
360: *
361: * @return the names of all the parameters as an Enumeration of Strings.
362: */
363: public Enumeration getParameterNames() {
364: return parameters.keys();
365: }
366:
367: /**
368: * @return number of uploaded files
369: */
370:
371: public int getFileCount() {
372: int iCount = 0;
373: Enumeration oFiles = files.keys();
374: Object oFileName;
375:
376: while (oFiles.hasMoreElements()) {
377: oFileName = oFiles.nextElement();
378: if (null != oFileName)
379: if (!oFileName.equals(""))
380: iCount++;
381: } // wend
382: return iCount;
383: } // getFileCount
384:
385: /**
386: * Returns the names of all the uploaded files as an Enumeration of
387: * Strings. It returns an empty Enumeration if there are no uploaded
388: * files. Each file name is the name specified by the form, not by
389: * the user.
390: *
391: * @return the names of all the uploaded files as an Enumeration of Strings.
392: */
393: public Enumeration getFileNames() {
394: return files.keys();
395: }
396:
397: /**
398: * Returns the value of the named parameter as a String, or null if
399: * the parameter was not sent or was sent without a value. The value
400: * is guaranteed to be in its normal, decoded form. If the parameter
401: * has multiple values, only the last one is returned (for backward
402: * compatibility). For parameters with multiple values, it's possible
403: * the last "value" may be null.
404: *
405: * @param name the parameter name.
406: * @return the parameter value.
407: */
408: public String getParameter(String name) {
409: try {
410: Vector values = (Vector) parameters.get(name);
411: if (values == null || values.size() == 0) {
412: return null;
413: }
414: String value = (String) values.elementAt(values.size() - 1);
415: return value;
416: } catch (Exception e) {
417: return null;
418: }
419: }
420:
421: /**
422: * Returns the values of the named parameter as a String array, or null if
423: * the parameter was not sent. The array has one entry for each parameter
424: * field sent. If any field was sent without a value that entry is stored
425: * in the array as a null. The values are guaranteed to be in their
426: * normal, decoded form. A single value is returned as a one-element array.
427: *
428: * @param name the parameter name.
429: * @return the parameter values.
430: */
431: public String[] getParameterValues(String name) {
432: try {
433: Vector values = (Vector) parameters.get(name);
434: if (values == null || values.size() == 0) {
435: return null;
436: }
437: String[] valuesArray = new String[values.size()];
438: values.copyInto(valuesArray);
439: return valuesArray;
440: } catch (Exception e) {
441: return null;
442: }
443: }
444:
445: /**
446: * Returns the filesystem name of the specified file, or null if the
447: * file was not included in the upload. A filesystem name is the name
448: * specified by the user. It is also the name under which the file is
449: * actually saved.
450: *
451: * @param name the file name.
452: * @return the filesystem name of the file.
453: */
454: public String getFilesystemName(String name) {
455: try {
456: UploadedFile file = (UploadedFile) files.get(name);
457: return file.getFilesystemName(); // may be null
458: } catch (Exception e) {
459: return null;
460: }
461: }
462:
463: /**
464: * Returns the original filesystem name of the specified file (before any
465: * renaming policy was applied), or null if the file was not included in
466: * the upload. A filesystem name is the name specified by the user.
467: *
468: * @param name the file name.
469: * @return the original file name of the file.
470: */
471: public String getOriginalFileName(String name) {
472: try {
473: UploadedFile file = (UploadedFile) files.get(name);
474: return file.getOriginalFileName(); // may be null
475: } catch (Exception e) {
476: return null;
477: }
478: }
479:
480: public String getCharacterEncoding() {
481: return encoding;
482: }
483:
484: /**
485: * Returns the content type of the specified file (as supplied by the
486: * client browser), or null if the file was not included in the upload.
487: *
488: * @param name the file name.
489: * @return the content type of the file.
490: */
491: public String getContentType(String name) {
492: try {
493: UploadedFile file = (UploadedFile) files.get(name);
494: return file.getContentType(); // may be null
495: } catch (Exception e) {
496: return null;
497: }
498: }
499:
500: /**
501: * Returns a File object for the specified file saved on the server's
502: * filesystem, or null if the file was not included in the upload.
503: * @param name the file name.
504: * @return a File object for the named file.
505: */
506: public File getFile(String name) {
507: try {
508: UploadedFile file = (UploadedFile) files.get(name);
509: return file.getFile(); // may be null
510: } catch (Exception e) {
511: return null;
512: }
513: }
514:
515: /**
516: * Returns a File object for the specified uploaded file
517: * @param number int [0..getFileCount()-1]
518: * @return File
519: */
520: public File getFile(int number) {
521: UploadedFile file = null;
522: Enumeration fileenum = files.elements();
523: try {
524: for (int f = 0; f < getFileCount(); f++)
525: file = (UploadedFile) fileenum.nextElement();
526: return file.getFile(); // may be null
527: } catch (Exception e) {
528: return null;
529: }
530: } // getFile
531:
532: public String getContentType() {
533: return contenttype;
534: }
535:
536: public int getContentLength() {
537: return contentlength;
538: }
539:
540: /**
541: * <p>Returns the part of this request's URL that calls the servlet.</p>
542: * Returns the part of this request's URL that calls the servlet.
543: * This includes either the servlet name or a path to the servlet,
544: * but does not include any extra path information or a query string.
545: * Same as the value of the CGI variable SCRIPT_NAME.
546: * @return String containing the name or path of the servlet being called,
547: * as specified in the request URL, decoded.
548: */
549: public String getServletPath() {
550: return servletpath;
551: }
552:
553: public String getContextPath() {
554: return ctxpath;
555: }
556:
557: public String getPathInfo() {
558: return pathinfo;
559: }
560:
561: public String getPathTranslated() {
562: return trnpath;
563: }
564:
565: public String getMethod() {
566: return formmethod;
567: }
568:
569: public String getRemoteUser() {
570: return remoteuser;
571: }
572:
573: public String getRequestURI() {
574: return requesturi;
575: }
576:
577: public StringBuffer getRequestURL() {
578: return requesturl;
579: }
580:
581: public String getRequestedSessionId() {
582: return sessionid;
583: }
584:
585: public String getQueryString() {
586: return querystr;
587: }
588:
589: public boolean isRequestedSessionIdFromURL() {
590: return bRequestedSessionIdFromURL;
591: }
592:
593: public boolean isRequestedSessionIdFromUrl() {
594: return bRequestedSessionIdFromURL;
595: }
596:
597: public boolean isRequestedSessionIdFromCookie() {
598: return bRequestedSessionIdFromCookie;
599: }
600:
601: public boolean isRequestedSessionIdValid() {
602: return bRequestedSessionIdValid;
603: }
604:
605: public Enumeration getAttributeNames() {
606: throw new RuntimeException(
607: "HttpServletRequest.getAttributeNames() method not implemented for MultipartRequest");
608: }
609:
610: public Object getAttribute(String sAttrName) {
611: throw new RuntimeException(
612: "HttpServletRequest.getAttribute() method not implemented for MultipartRequest");
613: }
614:
615: public void setAttribute(String sAttrName, Object sAttrVal) {
616: throw new RuntimeException(
617: "HttpServletRequest.setAttribute() method not implemented for MultipartRequest");
618: }
619:
620: public void removeAttribute(String sAttrName) {
621: throw new RuntimeException(
622: "HttpServletRequest.removeAttribute() method not implemented for MultipartRequest");
623: }
624:
625: public Enumeration getLocales() {
626: throw new RuntimeException(
627: "HttpServletRequest.getLocales() method not implemented for MultipartRequest");
628: }
629:
630: public boolean isSecure() {
631: throw new RuntimeException(
632: "HttpServletRequest.isSecure() method not implemented for MultipartRequest");
633: }
634:
635: public String getAuthType() {
636: throw new RuntimeException(
637: "HttpServletRequest.getAuthType() method not implemented for MultipartRequest");
638: }
639:
640: public int getLocalPort() {
641: throw new RuntimeException(
642: "HttpServletRequest.getLocalPort() method not implemented for MultipartRequest");
643: }
644:
645: public String getProtocol() {
646: throw new RuntimeException(
647: "HttpServletRequest.getProtocol() method not implemented for MultipartRequest");
648: }
649:
650: public Map getParameterMap() {
651: throw new RuntimeException(
652: "HttpServletRequest.getParameterMap() method not implemented for MultipartRequest");
653: }
654:
655: public String getScheme() {
656: throw new RuntimeException(
657: "HttpServletRequest.getScheme() method not implemented for MultipartRequest");
658: }
659:
660: public String getServerName() {
661: throw new RuntimeException(
662: "HttpServletRequest.getServerName() method not implemented for MultipartRequest");
663: }
664:
665: public int getServerPort() {
666: throw new RuntimeException(
667: "HttpServletRequest.getServerPort() method not implemented for MultipartRequest");
668: }
669:
670: public int getRemotePort() {
671: throw new RuntimeException(
672: "HttpServletRequest.getRemotePort() method not implemented for MultipartRequest");
673: }
674:
675: public String getLocalAddr() {
676: throw new RuntimeException(
677: "HttpServletRequest.getLocalAddr() method not implemented for MultipartRequest");
678: }
679:
680: public String getLocalName() {
681: throw new RuntimeException(
682: "HttpServletRequest.getLocalName() method not implemented for MultipartRequest");
683: }
684:
685: public String getRemoteAddr() {
686: throw new RuntimeException(
687: "HttpServletRequest.getRemoteAddr() method not implemented for MultipartRequest");
688: }
689:
690: public String getRemoteHost() {
691: throw new RuntimeException(
692: "HttpServletRequest.getRemoteHost() method not implemented for MultipartRequest");
693: }
694:
695: public HttpSession getSession() {
696: throw new RuntimeException(
697: "HttpServletRequest.getSession() method not implemented for MultipartRequest");
698: }
699:
700: public HttpSession getSession(boolean b) {
701: throw new RuntimeException(
702: "HttpServletRequest.getSession() method not implemented for MultipartRequest");
703: }
704:
705: public Principal getUserPrincipal() {
706: throw new RuntimeException(
707: "HttpServletRequest.getUserPrincipal() method not implemented for MultipartRequest");
708: }
709:
710: public String getRealPath(String s) {
711: throw new RuntimeException(
712: "HttpServletRequest.getRealPath() method not implemented for MultipartRequest");
713: }
714:
715: public RequestDispatcher getRequestDispatcher(String s) {
716: throw new RuntimeException(
717: "HttpServletRequest.getRequestDispatcher() method not implemented for MultipartRequest");
718: }
719:
720: public boolean isUserInRole(String role) {
721: throw new RuntimeException(
722: "HttpServletRequest.isUserInRole() method not implemented for MultipartRequest");
723: }
724:
725: public String getHeader(String hname) {
726: throw new RuntimeException(
727: "HttpServletRequest.getHeader() method not implemented for MultipartRequest");
728: }
729:
730: public Enumeration getHeaders(String hname) {
731: throw new RuntimeException(
732: "HttpServletRequest.getHeaders() method not implemented for MultipartRequest");
733: }
734:
735: public int getIntHeader(String hname) {
736: throw new RuntimeException(
737: "HttpServletRequest.getIntHeader() method not implemented for MultipartRequest");
738: }
739:
740: public long getDateHeader(String hname) {
741: throw new RuntimeException(
742: "HttpServletRequest.getDateHeader() method not implemented for MultipartRequest");
743: }
744:
745: public Enumeration getHeaderNames() {
746: throw new RuntimeException(
747: "HttpServletRequest.getHeaderNames() method not implemented for MultipartRequest");
748: }
749:
750: public BufferedReader getReader() {
751: throw new RuntimeException(
752: "HttpServletRequest.getReader() method not implemented for MultipartRequest");
753: }
754:
755: public ServletInputStream getInputStream() {
756: throw new RuntimeException(
757: "HttpServletRequest.getInputStream() method not implemented for MultipartRequest");
758: }
759:
760: public void setCharacterEncoding(String sEncoding) {
761: throw new RuntimeException(
762: "HttpServletRequest.setCharacterEncoding() method not implemented for MultipartRequest");
763: }
764:
765: }
766:
767: // A class to hold information about an uploaded file.
768: //
769: class UploadedFile {
770:
771: private String dir;
772: private String filename;
773: private String original;
774: private String type;
775:
776: UploadedFile(String dir, String filename, String original,
777: String type) {
778: this .dir = dir;
779: this .filename = filename;
780: this .original = original;
781: this .type = type;
782: }
783:
784: public String getContentType() {
785: return type;
786: }
787:
788: public String getFilesystemName() {
789: return filename;
790: }
791:
792: public String getOriginalFileName() {
793: return original;
794: }
795:
796: public File getFile() {
797: if (dir == null || filename == null) {
798: return null;
799: } else {
800: return new File(dir + File.separator + filename);
801: }
802: }
803:
804: }
|