View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.filter.codec.serialization;
21  
22  import java.io.DataInput;
23  import java.io.DataInputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.ObjectInput;
27  import java.io.StreamCorruptedException;
28  
29  import org.apache.mina.core.buffer.BufferDataException;
30  import org.apache.mina.core.buffer.IoBuffer;
31  
32  /**
33   * An {@link ObjectInput} and {@link InputStream} that can read the objects encoded
34   * by {@link ObjectSerializationEncoder}.
35   *
36   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
37   */
38  public class ObjectSerializationInputStream extends InputStream implements ObjectInput {
39  
40      private final DataInputStream in;
41  
42      private final ClassLoader classLoader;
43  
44      private int maxObjectSize = 1048576;
45  
46      /**
47       * Create a new instance of an ObjectSerializationInputStream
48       * @param in The {@link InputStream} to use
49       */
50      public ObjectSerializationInputStream(InputStream in) {
51          this(in, null);
52      }
53  
54      /**
55       * Create a new instance of an ObjectSerializationInputStream
56       * @param in The {@link InputStream} to use
57       * @param classLoader The class loader to use
58       */
59      public ObjectSerializationInputStream(InputStream in, ClassLoader classLoader) {
60          if (in == null) {
61              throw new IllegalArgumentException("in");
62          }
63          
64          if (classLoader == null) {
65              classLoader = Thread.currentThread().getContextClassLoader();
66          }
67  
68          if (in instanceof DataInputStream) {
69              this.in = (DataInputStream) in;
70          } else {
71              this.in = new DataInputStream(in);
72          }
73  
74          this.classLoader = classLoader;
75      }
76  
77      /**
78       * @return the allowed maximum size of the object to be decoded.
79       * If the size of the object to be decoded exceeds this value, this
80       * decoder will throw a {@link BufferDataException}.  The default
81       * value is <tt>1048576</tt> (1MB).
82       */
83      public int getMaxObjectSize() {
84          return maxObjectSize;
85      }
86  
87      /**
88       * Sets the allowed maximum size of the object to be decoded.
89       * If the size of the object to be decoded exceeds this value, this
90       * decoder will throw a {@link BufferDataException}.  The default
91       * value is <tt>1048576</tt> (1MB).
92       * 
93       * @param maxObjectSize The maximum decoded object size
94       */
95      public void setMaxObjectSize(int maxObjectSize) {
96          if (maxObjectSize <= 0) {
97              throw new IllegalArgumentException("maxObjectSize: " + maxObjectSize);
98          }
99  
100         this.maxObjectSize = maxObjectSize;
101     }
102 
103     /**
104      * {@inheritDoc}
105      */
106     @Override
107     public int read() throws IOException {
108         return in.read();
109     }
110 
111     /**
112      * {@inheritDoc}
113      */
114     public Object readObject() throws ClassNotFoundException, IOException {
115         int objectSize = in.readInt();
116         if (objectSize <= 0) {
117             throw new StreamCorruptedException("Invalid objectSize: " + objectSize);
118         }
119         if (objectSize > maxObjectSize) {
120             throw new StreamCorruptedException("ObjectSize too big: " + objectSize + " (expected: <= " + maxObjectSize
121                     + ')');
122         }
123 
124         IoBuffer buf = IoBuffer.allocate(objectSize + 4, false);
125         buf.putInt(objectSize);
126         in.readFully(buf.array(), 4, objectSize);
127         buf.position(0);
128         buf.limit(objectSize + 4);
129 
130         return buf.getObject(classLoader);
131     }
132 
133     /**
134      * {@inheritDoc}
135      */
136     public boolean readBoolean() throws IOException {
137         return in.readBoolean();
138     }
139 
140     /**
141      * {@inheritDoc}
142      */
143     public byte readByte() throws IOException {
144         return in.readByte();
145     }
146 
147     /**
148      * {@inheritDoc}
149      */
150     public char readChar() throws IOException {
151         return in.readChar();
152     }
153 
154     /**
155      * {@inheritDoc}
156      */
157     public double readDouble() throws IOException {
158         return in.readDouble();
159     }
160 
161     /**
162      * {@inheritDoc}
163      */
164     public float readFloat() throws IOException {
165         return in.readFloat();
166     }
167 
168     /**
169      * {@inheritDoc}
170      */
171     public void readFully(byte[] b) throws IOException {
172         in.readFully(b);
173     }
174 
175     /**
176      * {@inheritDoc}
177      */
178     public void readFully(byte[] b, int off, int len) throws IOException {
179         in.readFully(b, off, len);
180     }
181 
182     /**
183      * {@inheritDoc}
184      */
185     public int readInt() throws IOException {
186         return in.readInt();
187     }
188 
189     /**
190      * @see DataInput#readLine()
191      * @deprecated
192      */
193     @Deprecated
194     public String readLine() throws IOException {
195         return in.readLine();
196     }
197 
198     /**
199      * {@inheritDoc}
200      */
201     public long readLong() throws IOException {
202         return in.readLong();
203     }
204 
205     /**
206      * {@inheritDoc}
207      */
208     public short readShort() throws IOException {
209         return in.readShort();
210     }
211 
212     /**
213      * {@inheritDoc}
214      */
215     public String readUTF() throws IOException {
216         return in.readUTF();
217     }
218 
219     /**
220      * {@inheritDoc}
221      */
222     public int readUnsignedByte() throws IOException {
223         return in.readUnsignedByte();
224     }
225 
226     /**
227      * {@inheritDoc}
228      */
229     public int readUnsignedShort() throws IOException {
230         return in.readUnsignedShort();
231     }
232 
233     /**
234      * {@inheritDoc}
235      */
236     public int skipBytes(int n) throws IOException {
237         return in.skipBytes(n);
238     }
239 }