Updates
[debian/openrocket] / src / net / sf / openrocket / util / OpenFileWorker.java
1 package net.sf.openrocket.util;
2
3 import java.io.BufferedInputStream;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.FilterInputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.InterruptedIOException;
10
11 import javax.swing.SwingWorker;
12
13 import net.sf.openrocket.document.OpenRocketDocument;
14 import net.sf.openrocket.file.GeneralRocketLoader;
15 import net.sf.openrocket.file.RocketLoader;
16
17
18 /**
19  * A SwingWorker thread that opens a rocket design file.
20  * 
21  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
22  */
23 public class OpenFileWorker extends SwingWorker<OpenRocketDocument, Void> {
24
25         private static final RocketLoader ROCKET_LOADER = new GeneralRocketLoader();
26
27         private final File file;
28         
29         public OpenFileWorker(File file) {
30                 this.file = file;
31         }
32         
33         
34         @Override
35         protected OpenRocketDocument doInBackground() throws Exception {
36                 ProgressInputStream is = new ProgressInputStream(
37                                 new BufferedInputStream(new FileInputStream(file)));
38                 try {
39                         return ROCKET_LOADER.load(is);
40                 } finally {
41                         try {
42                                 is.close();
43                         } catch (Exception e) {
44                                 System.err.println("Error closing file: ");
45                                 e.printStackTrace();
46                         }
47                 }
48         }
49
50         
51         
52
53         private class ProgressInputStream extends FilterInputStream {
54
55                 private final int size;
56                 private int readBytes = 0;
57                 private int progress = -1;
58                 
59                 protected ProgressInputStream(InputStream in) {
60                         super(in);
61                         int s;
62                         try {
63                                 s = in.available();
64                         } catch (IOException e) {
65                                 System.err.println("ERROR estimating available bytes!");
66                                 s = 0;
67                         }
68                         size = s;
69                 }
70
71                 
72                 
73                 @Override
74                 public int read() throws IOException {
75                         int c = in.read();
76                         if (c >= 0) {
77                                 readBytes++;
78                                 setProgress();
79                         }
80                         if (isCancelled()) {
81                                 throw new InterruptedIOException("OpenFileWorker was cancelled");
82                         }
83                         return c;
84                 }
85
86                 @Override
87                 public int read(byte[] b, int off, int len) throws IOException {
88                         int n = in.read(b, off, len);
89                         if (n > 0) {
90                                 readBytes += n;
91                                 setProgress();
92                         }
93                         if (isCancelled()) {
94                                 throw new InterruptedIOException("OpenFileWorker was cancelled");
95                         }
96                         return n;
97                 }
98
99                 @Override
100                 public int read(byte[] b) throws IOException {
101                         int n = in.read(b);
102                         if (n > 0) {
103                                 readBytes += n;
104                                 setProgress();
105                         }
106                         if (isCancelled()) {
107                                 throw new InterruptedIOException("OpenFileWorker was cancelled");
108                         }
109                         return n;
110                 }
111
112                 @Override
113                 public long skip(long n) throws IOException {
114                         long nr = in.skip(n);
115                         if (nr > 0) {
116                                 readBytes += nr;
117                                 setProgress();
118                         }
119                         if (isCancelled()) {
120                                 throw new InterruptedIOException("OpenFileWorker was cancelled");
121                         }
122                         return nr;
123                 }
124                 
125                 @Override
126                 public synchronized void reset() throws IOException {
127                         in.reset();
128                         readBytes = size - in.available();
129                         setProgress();
130                         if (isCancelled()) {
131                                 throw new InterruptedIOException("OpenFileWorker was cancelled");
132                         }
133                 }
134
135                 
136                 
137                 private void setProgress() {
138                         int p = MathUtil.clamp(readBytes * 100 / size, 0, 100);
139                         if (progress != p) {
140                                 progress = p;
141                                 OpenFileWorker.this.setProgress(progress);
142                         }
143                 }
144         }
145 }