Updates
[debian/openrocket] / src / net / sf / openrocket / util / SaveFileWorker.java
1 package net.sf.openrocket.util;
2
3 import java.io.BufferedOutputStream;
4 import java.io.File;
5 import java.io.FileOutputStream;
6 import java.io.FilterOutputStream;
7 import java.io.IOException;
8 import java.io.InterruptedIOException;
9 import java.io.OutputStream;
10
11 import javax.swing.SwingWorker;
12
13 import net.sf.openrocket.document.OpenRocketDocument;
14 import net.sf.openrocket.file.RocketSaver;
15
16 public class SaveFileWorker extends SwingWorker<Void, Void> {
17
18         private final OpenRocketDocument document;
19         private final File file;
20         private final RocketSaver saver;
21         
22         public SaveFileWorker(OpenRocketDocument document, File file, RocketSaver saver) {
23                 this.document = document;
24                 this.file = file;
25                 this.saver = saver;
26         }
27         
28         
29         @Override
30         protected Void doInBackground() throws Exception {
31                 ProgressOutputStream os = new ProgressOutputStream(
32                                 new BufferedOutputStream(new FileOutputStream(file)), 
33                                 (int)saver.estimateFileSize(document, document.getDefaultStorageOptions()));
34                 
35                 try {
36                         saver.save(os, document);
37                 } finally {
38                         try {
39                                 os.close();
40                         } catch (Exception e) {
41                                 System.err.println("Error closing file: ");
42                                 e.printStackTrace();
43                         }
44                 }
45                 return null;
46         }
47         
48         
49         private class ProgressOutputStream extends FilterOutputStream {
50
51                 private final int totalBytes;
52                 private int writtenBytes = 0;
53                 private int progress = -1;
54                 
55                 public ProgressOutputStream(OutputStream out, int estimate) {
56                         super(out);
57                         this.totalBytes = estimate;
58                 }
59
60                 @Override
61                 public void write(byte[] b, int off, int len) throws IOException {
62                         out.write(b, off, len);
63                         writtenBytes += len;
64                         setProgress();
65                         if (isCancelled()) {
66                                 throw new InterruptedIOException("SaveFileWorker was cancelled");
67                         }
68                 }
69
70                 @Override
71                 public void write(byte[] b) throws IOException {
72                         out.write(b);
73                         writtenBytes += b.length;
74                         setProgress();
75                         if (isCancelled()) {
76                                 throw new InterruptedIOException("SaveFileWorker was cancelled");
77                         }
78                 }
79
80                 @Override
81                 public void write(int b) throws IOException {
82                         out.write(b);
83                         writtenBytes++;
84                         setProgress();
85                         if (isCancelled()) {
86                                 throw new InterruptedIOException("SaveFileWorker was cancelled");
87                         }
88                 }
89                 
90                 
91                 private void setProgress() {
92                         int p = MathUtil.clamp(writtenBytes * 100 / totalBytes, 0, 100);
93                         if (progress != p) {
94                                 progress = p;
95                                 SaveFileWorker.this.setProgress(progress);
96                         }
97                 }
98         }
99 }