001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.util;
018
019import java.io.File;
020import java.io.FileDescriptor;
021import java.io.FileNotFoundException;
022import java.io.IOException;
023import java.io.RandomAccessFile;
024import java.nio.channels.FileChannel;
025
026public class RecoverableRandomAccessFile implements java.io.DataOutput, java.io.DataInput, java.io.Closeable {
027
028    private static final boolean SKIP_METADATA_UPDATE =
029        Boolean.getBoolean("org.apache.activemq.kahaDB.files.skipMetadataUpdate");
030
031    RandomAccessFile raf;
032    File file;
033    String mode;
034
035    public RecoverableRandomAccessFile(File file, String mode) throws FileNotFoundException {
036        this.file = file;
037        this.mode = mode;
038        raf = new RandomAccessFile(file, mode);
039    }
040
041    public RecoverableRandomAccessFile(String name, String mode) throws FileNotFoundException {
042        this.file = new File(name);
043        this.mode = mode;
044        raf = new RandomAccessFile(file, mode);
045    }
046
047    protected RandomAccessFile getRaf() throws IOException {
048        if (raf == null) {
049            raf = new RandomAccessFile(file, mode);
050        }
051        return raf;
052    }
053
054    protected void handleException() throws IOException {
055        try {
056            if (raf != null) {
057                raf.close();
058            }
059        } catch (Throwable ignore) {
060        } finally {
061            raf = null;
062        }
063    }
064
065    @Override
066    public void close() throws IOException {
067        if (raf != null) {
068            raf.close();
069        }
070    }
071
072    @Override
073    public void readFully(byte[] bytes) throws IOException {
074        try {
075            getRaf().readFully(bytes);
076        } catch (IOException ioe) {
077            handleException();
078            throw ioe;
079        }
080    }
081
082    @Override
083    public void readFully(byte[] bytes, int i, int i2) throws IOException {
084        try {
085            getRaf().readFully(bytes, i, i2);
086        } catch (IOException ioe) {
087            handleException();
088            throw ioe;
089        }
090    }
091
092    @Override
093    public int skipBytes(int i) throws IOException {
094        try {
095            return getRaf().skipBytes(i);
096        } catch (IOException ioe) {
097            handleException();
098            throw ioe;
099        }
100    }
101
102    @Override
103    public boolean readBoolean() throws IOException {
104        try {
105            return getRaf().readBoolean();
106        } catch (IOException ioe) {
107            handleException();
108            throw ioe;
109        }
110    }
111
112    @Override
113    public byte readByte() throws IOException {
114        try {
115            return getRaf().readByte();
116        } catch (IOException ioe) {
117            handleException();
118            throw ioe;
119        }
120    }
121
122    @Override
123    public int readUnsignedByte() throws IOException {
124        try {
125            return getRaf().readUnsignedByte();
126        } catch (IOException ioe) {
127            handleException();
128            throw ioe;
129        }
130    }
131
132    @Override
133    public short readShort() throws IOException {
134        try {
135            return getRaf().readShort();
136        } catch (IOException ioe) {
137            handleException();
138            throw ioe;
139        }
140    }
141
142    @Override
143    public int readUnsignedShort() throws IOException {
144        try {
145            return getRaf().readUnsignedShort();
146        } catch (IOException ioe) {
147            handleException();
148            throw ioe;
149        }
150    }
151
152    @Override
153    public char readChar() throws IOException {
154        try {
155            return getRaf().readChar();
156        } catch (IOException ioe) {
157            handleException();
158            throw ioe;
159        }
160    }
161
162    @Override
163    public int readInt() throws IOException {
164        try {
165            return getRaf().readInt();
166        } catch (IOException ioe) {
167            handleException();
168            throw ioe;
169        }
170    }
171
172    @Override
173    public long readLong() throws IOException {
174        try {
175            return getRaf().readLong();
176        } catch (IOException ioe) {
177            handleException();
178            throw ioe;
179        }
180    }
181
182    @Override
183    public float readFloat() throws IOException {
184        try {
185            return getRaf().readFloat();
186        } catch (IOException ioe) {
187            handleException();
188            throw ioe;
189        }
190    }
191
192    @Override
193    public double readDouble() throws IOException {
194        try {
195            return getRaf().readDouble();
196        } catch (IOException ioe) {
197            handleException();
198            throw ioe;
199        }
200    }
201
202    @Override
203    public String readLine() throws IOException {
204        try {
205            return getRaf().readLine();
206        } catch (IOException ioe) {
207            handleException();
208            throw ioe;
209        }
210    }
211
212    @Override
213    public String readUTF() throws IOException {
214        try {
215            return getRaf().readUTF();
216        } catch (IOException ioe) {
217            handleException();
218            throw ioe;
219        }
220    }
221
222    @Override
223    public void write(int i) throws IOException {
224        try {
225            getRaf().write(i);
226        } catch (IOException ioe) {
227            handleException();
228            throw ioe;
229        }
230    }
231
232    @Override
233    public void write(byte[] bytes) throws IOException {
234        try {
235            getRaf().write(bytes);
236        } catch (IOException ioe) {
237            handleException();
238            throw ioe;
239        }
240    }
241
242    @Override
243    public void write(byte[] bytes, int i, int i2) throws IOException {
244        try {
245            getRaf().write(bytes, i, i2);
246        } catch (IOException ioe) {
247            handleException();
248            throw ioe;
249        }
250    }
251
252    @Override
253    public void writeBoolean(boolean b) throws IOException {
254        try {
255            getRaf().writeBoolean(b);
256        } catch (IOException ioe) {
257            handleException();
258            throw ioe;
259        }
260    }
261
262    @Override
263    public void writeByte(int i) throws IOException {
264        try {
265            getRaf().writeByte(i);
266        } catch (IOException ioe) {
267            handleException();
268            throw ioe;
269        }
270    }
271
272    @Override
273    public void writeShort(int i) throws IOException {
274        try {
275            getRaf().writeShort(i);
276        } catch (IOException ioe) {
277            handleException();
278            throw ioe;
279        }
280    }
281
282    @Override
283    public void writeChar(int i) throws IOException {
284        try {
285            getRaf().writeChar(i);
286        } catch (IOException ioe) {
287            handleException();
288            throw ioe;
289        }
290    }
291
292    @Override
293    public void writeInt(int i) throws IOException {
294        try {
295            getRaf().writeInt(i);
296        } catch (IOException ioe) {
297            handleException();
298            throw ioe;
299        }
300    }
301
302    @Override
303    public void writeLong(long l) throws IOException {
304        try {
305            getRaf().writeLong(l);
306        } catch (IOException ioe) {
307            handleException();
308            throw ioe;
309        }
310    }
311
312    @Override
313    public void writeFloat(float v) throws IOException {
314        try {
315            getRaf().writeFloat(v);
316        } catch (IOException ioe) {
317            handleException();
318            throw ioe;
319        }
320    }
321
322    @Override
323    public void writeDouble(double v) throws IOException {
324        try {
325            getRaf().writeDouble(v);
326        } catch (IOException ioe) {
327            handleException();
328            throw ioe;
329        }
330    }
331
332    @Override
333    public void writeBytes(String s) throws IOException {
334        try {
335            getRaf().writeBytes(s);
336        } catch (IOException ioe) {
337            handleException();
338            throw ioe;
339        }
340    }
341
342    @Override
343    public void writeChars(String s) throws IOException {
344        try {
345            getRaf().writeChars(s);
346        } catch (IOException ioe) {
347            handleException();
348            throw ioe;
349        }
350    }
351
352    @Override
353    public void writeUTF(String s) throws IOException {
354        try {
355            getRaf().writeUTF(s);
356        } catch (IOException ioe) {
357            handleException();
358            throw ioe;
359        }
360    }
361
362
363    //RAF methods
364    public long length() throws IOException {
365        try {
366            return getRaf().length();
367        } catch (IOException ioe) {
368            handleException();
369            throw ioe;
370        }
371    }
372
373    public void setLength(long length) throws IOException {
374        throw new IllegalStateException("File size is pre allocated");
375    }
376
377    public void seek(long pos) throws IOException {
378        try {
379            getRaf().seek(pos);
380        } catch (IOException ioe) {
381            handleException();
382            throw ioe;
383        }
384    }
385
386    public FileDescriptor getFD() throws IOException {
387        try {
388            return getRaf().getFD();
389        } catch (IOException ioe) {
390            handleException();
391            throw ioe;
392        }
393    }
394
395    public void sync() throws IOException {
396        try {
397            getRaf().getChannel().force(!SKIP_METADATA_UPDATE);;
398        } catch (IOException ioe) {
399            handleException();
400            throw ioe;
401        }
402    }
403
404    public FileChannel getChannel() throws IOException {
405        try {
406            return getRaf().getChannel();
407        } catch (IOException ioe) {
408            handleException();
409            throw ioe;
410        }
411    }
412
413    public int read(byte[] b, int off, int len) throws IOException {
414        try {
415            return getRaf().read(b, off, len);
416        } catch (IOException ioe) {
417            handleException();
418            throw ioe;
419        }
420    }
421
422    public int read(byte[] b) throws IOException {
423        try {
424            return getRaf().read(b);
425        } catch (IOException ioe) {
426            handleException();
427            throw ioe;
428        }
429    }
430}