001: /***
002: * jwma Java WebMail
003: * Copyright (c) 2000-2003 jwma team
004: *
005: * jwma is free software; you can distribute and use this source
006: * under the terms of the BSD-style license received along with
007: * the distribution.
008: ***/package dtw.webmail.util;
009:
010: import java.io.*;
011: import javax.activation.DataSource;
012:
013: import org.apache.log4j.Logger;
014:
015: /**
016: * Class that provides a MultipartInputStream by wrapping
017: * an existant InputStream.<br>
018: * It implements size limit checking and serves as a
019: * <tt>DataSource</tt> for handling with
020: * Mail API (or other JAF aware) classes.
021: *
022: * @author Dieter Wimberger
023: * @version 0.9.7 07/02/2003
024: */
025: public class MultipartInputStream extends FilterInputStream implements
026: DataSource {
027:
028: //logging
029: private static Logger log = Logger
030: .getLogger(MultipartInputStream.class);
031:
032: //instance attributes
033: private int m_Limit;
034: private String m_ContentType;
035: private int m_BytesRead = 0;
036:
037: /**
038: * Constructs a <tt>MultipartInputStream</tt> instance.
039: *
040: * @param in the InputStream this instance reads from.
041: * @param ctype the content type of the incoming request as <tt>
042: * String</tt>. Important because it contains the parts border!
043: * @param readlimit the maximum size of the complete request data as
044: * <tt>int</tt>.
045: *
046: * @return the newly created <tt>MultipartInputStream</tt> instance.
047: */
048: public MultipartInputStream(InputStream in, String ctype,
049: int readlimit) {
050: super ((InputStream) in);
051: m_ContentType = ctype;
052: m_Limit = readlimit;
053: }//constructor
054:
055: /**
056: * Returns the name of this instance as <tt>String</tt>.
057: * <p>(DataSource implementation)
058: *
059: * @return the name as <tt>String</tt>
060: */
061: public String getName() {
062: return ("form_data");
063: }//getName
064:
065: /**
066: * Returns the content type of this instance as
067: * <tt>String</tt>.
068: * <p>(DataSource implementation)
069: * <p><i><b>Note:</b>the <tt>String</tt> contains the parts border!</i>
070: *
071: * @return the content type as <tt>String</tt>
072: */
073: public String getContentType() {
074: return m_ContentType;
075: }//getContentType
076:
077: /**
078: * Returns this <tt>MultipartInputStream</tt> instance as
079: * <tt>InputStream</tt>.
080: * <p>(DataSource implementation)
081: *
082: * @return this instance as <tt>InputStream</tt>.
083: * @throws IOException if impossible.
084: */
085: public InputStream getInputStream() throws IOException {
086:
087: return (InputStream) this ;
088: }//getInputStream
089:
090: /**
091: * Throws an IOException in this implementation, because
092: * this instance represents a read-only <tt>DataSource</tt>.
093: * <p>(DataSource implementation)
094: *
095: * @return an <tt>OutputStream</tt> instance for writing
096: * to this <tt>DataSource</tt>.
097: * @throws IOException if impossible.
098: */
099: public OutputStream getOutputStream() throws IOException {
100:
101: throw new IOException("Cannot output to this source.");
102: }//getOutputStream
103:
104: /**
105: * Reads the next byte of data from the input stream. The value byte is
106: * returned as an <tt>int</tt> in the range <tt>0</tt> to
107: * <tt>255</tt>. If no byte is available because the end of the stream
108: * has been reached, the value <tt>-1</tt> is returned. This method
109: * blocks until input data is available, the end of the stream is detected,
110: * or an exception is thrown.
111: *
112: * @return the next byte of data, or <tt>-1</tt> if the end of the
113: * stream is reached.
114: * @exception IOException if an I/O error occurs.
115: */
116: public int read() throws IOException {
117: m_BytesRead++;
118: checkLimit();
119: return super .read();
120: }//read
121:
122: /**
123: * Reads up to <tt>len</tt> bytes of data from this input stream
124: * into an array of bytes. This method blocks until some input is
125: * available.
126: * <p>
127: * This method simply performs <tt>in.read(b, off, len)</tt>
128: * and returns the result.
129: *
130: * @param b the buffer into which the data is read.
131: * @param off the start offset of the data.
132: * @param len the maximum number of bytes read.
133: * @return the total number of bytes read into the buffer, or
134: * <tt>-1</tt> if there is no more data because the end of
135: * the stream has been reached.
136: * @exception IOException if an I/O error occurs.
137: * @see java.io.FilterInputStream#in
138: */
139: public int read(byte b[], int off, int len) throws IOException {
140: m_BytesRead += len;
141: checkLimit();
142: return super .read(b, off, len);
143: }//read
144:
145: /**
146: * Checks if the size limit is exceeded, throwing
147: * an IOException if so.
148: *
149: * @throws IOException if the limit is exceeded.
150: */
151: private void checkLimit() throws IOException {
152:
153: if (m_BytesRead > m_Limit) {
154: throw new IOException("Input limit exceeded.");
155: }
156: }//checkLimit
157:
158: }//class MultipartInputStream
|