KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SnowMailClient > utils > storage > Backup


1 package SnowMailClient.utils.storage;
2
3 import SnowMailClient.SnowMailClientApp;
4 import snow.utils.gui.*;
5 import snow.Language.Language;
6 import snow.utils.storage.*;
7 import java.util.*;
8 import java.util.zip.*;
9 import java.io.*;
10 import javax.swing.*;
11 import java.text.*;
12
13 /**
14   Todo: ## verify that destination is not in the backuped folders !!
15 */

16 public final class Backup implements Vectorizable
17 {
18   long lastBackup = 0;
19   long minTimeBetweenTwoBackups = 1000*60*5; // 5 minutes
20
private String JavaDoc destinationBackupFolder = "";
21   boolean isAutomaticBackupEnabled = true;
22
23   public Backup()
24   {
25      if(System.getProperty("os.name", "Windows").indexOf("Windows")>0)
26      {
27         destinationBackupFolder = "c:/SnowMailBackup/";
28      }
29      else
30      {
31         // linux
32
destinationBackupFolder = System.getProperty("user.home",".")
33                        + File.pathSeparator + "SnowMailBackup" + File.pathSeparator;
34      }
35   } // Constructor
36

37   public String JavaDoc getBackupDestinationDirectory()
38   {
39     return destinationBackupFolder;
40   }
41
42   public void setBackupDestination(String JavaDoc destinationBackupFolder)
43   {
44     this.destinationBackupFolder = destinationBackupFolder;
45   }
46
47   public boolean isAutomaticBackupEnabled()
48   {
49     return isAutomaticBackupEnabled;
50   }
51
52   public void setIsAutomaticBackupEnabled(boolean is)
53   {
54     isAutomaticBackupEnabled = is;
55   }
56
57   public synchronized void checkDoBackup()
58   {
59      long now = new Date().getTime();
60      if(isAutomaticBackupEnabled && (now-lastBackup > minTimeBetweenTwoBackups))
61      {
62         doBackupNow();
63      }
64      else
65      {
66         System.out.println("No backup to do, last was made = "+new Date(lastBackup));
67      }
68   }
69
70
71
72   public synchronized void doBackupNow()
73   {
74     if( SwingUtilities.isEventDispatchThread() )
75     {
76        throw new RuntimeException JavaDoc("Must be called from another thread than EDT");
77     }
78
79     File destFolder = new File(destinationBackupFolder);
80     if(!destFolder.exists())
81     {
82        destFolder.mkdirs();
83     }
84
85     File backupFile = new File(destinationBackupFolder, getActualBackupName()+"SnowMailBackup.zip");
86     final ProgressModalDialog progress = new ProgressModalDialog(SnowMailClientApp.getInstance(), "Backup", false, false);
87     progress.setCommentLabel(Language.translate("Saving opened folders")+"...");
88     progress.start();
89
90
91     SnowMailClientApp.getInstance().saveAllMails(false);
92
93     progress.setCommentLabel(backupFile.getAbsolutePath());
94
95
96     synchronized( FileUtils.getLockForFileAccess() )
97     {
98       FileOutputStream fos = null;
99       ZipOutputStream zos = null;
100       try
101       {
102         fos = new FileOutputStream(backupFile);
103         zos = new ZipOutputStream(fos);
104         List<File> allFiles = new Vector<File>();
105         File rootFile = SnowMailClientApp.getInstance().getSnowMailRoot();
106         FileUtils.getAllFilesRecurse(rootFile, allFiles);
107         progress.setProgressBounds(allFiles.size());
108
109         for(int i=0; i<allFiles.size(); i++)
110         {
111            if(progress.wasCancelled())
112            {
113              break;
114            }
115
116            File file = allFiles.get(i);
117            progress.setProgressValue(i, ""+file.getName());
118            String JavaDoc relativeName = file.getAbsolutePath();
119            relativeName = relativeName.substring(
120               rootFile.getParentFile().getAbsolutePath().length()+1,
121               relativeName.length());
122
123            FileUtils.addToZip(zos, file, relativeName);
124         }
125
126       }
127       catch(Exception JavaDoc e)
128       {
129         e.printStackTrace();
130       }
131       finally
132       {
133         FileUtils.closeIgnoringExceptions(zos);
134         FileUtils.closeIgnoringExceptions(fos);
135
136         progress.closeDialog();
137
138         if(progress.wasCancelled())
139         {
140            backupFile .delete ();
141            return;
142         }
143       }
144     }
145
146     lastBackup = new Date().getTime();
147
148     organizeBackupArchive(new File(destinationBackupFolder));
149   }
150
151
152   private void organizeBackupArchive(File base)
153   {
154      //1) list all backup files
155
Vector<File> allBackups = new Vector<File>();
156      getAllBackups(base, allBackups);
157      //System.out.println("There are "+allBackups.size()+" backups to reorganize.");
158

159      if(allBackups.size()<3)
160      {
161        return;
162      }
163
164
165      // 2) sort, first = last backup
166
Collections.sort(allBackups, new Comparator<File>()
167      {
168         public int compare(File file1, File file2)
169         {
170            if(file1.lastModified() == file2.lastModified()) return 0;
171            if(file1.lastModified() > file2.lastModified()) return -1;
172            return 1;
173         }
174      });
175
176      long lastBackupTime = allBackups.firstElement().lastModified();
177      long oldestBackupTime = allBackups.lastElement().lastModified();
178      //System.out.println("Oldest backup = "+new Date(oldestBackupTime));
179
//System.out.println("Last backup (Age=0) = "+new Date(lastBackupTime));
180

181      // Sort in the various categories (age 0 is the youngest archive)
182
//
183
Vector<File> youngerThanHour = new Vector<File>(); // keep all (usually 1)
184
Vector<File> youngerThanDay = new Vector<File>(); // keep at most one each 3 hour (max 6)
185
Vector<File> youngerThanWeek = new Vector<File>(); // keep at most one each day (max 7)
186
Vector<File> youngerThanMonth = new Vector<File>(); // keep at most one each week (max 5)
187
Vector<File> olderThanMonth = new Vector<File>(); // keep at most one per month (12 per year)
188

189      for(int i=0; i<allBackups.size()-1; i++)
190      {
191         File file = allBackups.elementAt(i);
192         long time = file.lastModified();
193
194         // 1 find age category (day, week, month)
195
long ageFromNowSec = (lastBackupTime-time)/1000;
196         //System.out.println("Age = "+ageFromNowSec+" s");
197

198
199         if(ageFromNowSec<3600)
200         {
201            youngerThanHour.add(file);
202         }
203         else if(ageFromNowSec<24*3600)
204         {
205            youngerThanDay.add(file);
206         }
207         else if(ageFromNowSec<7*24*3600)
208         {
209            youngerThanWeek.add(file);
210         }
211         else if(ageFromNowSec<30*24*3600)
212         {
213            youngerThanMonth.add(file);
214         }
215         else
216         {
217            olderThanMonth.add(file);
218         }
219      }
220
221      if(false)
222      {
223        System.out.println("Backup structure before reordering\n<begin>");
224        System.out.println(" younger than 1 hour : "+youngerThanHour.size());
225        System.out.println(" younger than 1 day : "+youngerThanDay.size());
226        System.out.println(" younger than 1 week : "+youngerThanWeek.size());
227        System.out.println(" younger than 1 month : "+youngerThanMonth.size());
228        System.out.println(" older than 1 month : "+olderThanMonth.size());
229        System.out.println("<end>");
230      }
231
232      purge(youngerThanDay, 3600* 3);
233      purge(youngerThanWeek, 3600*24);
234      purge(youngerThanMonth, 3600*24* 7);
235      purge(olderThanMonth, 3600*24*30);
236
237   }
238
239   /**
240   */

241   private void purge(Vector<File> files, long minDistanceSec)
242   {
243      if(files.size()<3) return; // requires at least tree, otherwise keep all (0 or 1 or 2)
244

245      long t0 = files.lastElement().lastModified(); // oldest backup
246

247      for(int i=files.size()-2; i>=1; i--) // keep the first and the last
248
{
249         File file = files.elementAt(i);
250         //System.out.println("Purging "+file);
251

252         long ti = file.lastModified();
253         long distSec = (ti-t0)/1000;
254         if(distSec < minDistanceSec)
255         {
256           //System.out.println(" Deleting "+file);
257
if(!file.delete()) {file.deleteOnExit();}
258         }
259         else
260         {
261           // keep
262
t0 = ti;
263         }
264      }
265   }
266
267
268   private void getAllBackups(File folder, Vector<File> files)
269   {
270      File[] backupFiles = folder.listFiles(new FilenameFilter()
271      {
272        public boolean accept(File dir, String JavaDoc name)
273        {
274           return name.toUpperCase().endsWith("SNOWMAILBACKUP.ZIP");
275        }
276      });
277
278     files.addAll(Arrays.asList(backupFiles));
279   }
280
281
282
283   public String JavaDoc getActualBackupName()
284   {
285      SimpleDateFormat sdf = new SimpleDateFormat("yyyy MM dd HH'h'mm", Locale.ENGLISH);
286      String JavaDoc userName = System.getProperty("user.name", "home");
287      return sdf.format(new Date()) + " ("+userName+")";
288   }
289
290   // Vectorizable
291
//
292

293   public Vector<Object JavaDoc> getVectorRepresentation() throws VectorizeException
294   {
295      Vector<Object JavaDoc> v = new Vector<Object JavaDoc>();
296      v.addElement(2); //0: version
297
v.addElement(destinationBackupFolder);
298      v.addElement(minTimeBetweenTwoBackups);
299      v.addElement(lastBackup);
300      v.addElement(isAutomaticBackupEnabled);
301      return v;
302   }
303
304   public void createFromVectorRepresentation(Vector<Object JavaDoc> v) throws VectorizeException
305   {
306      int version = (Integer JavaDoc) v.get(0);
307      if(version==1)
308      {
309         destinationBackupFolder = (String JavaDoc) v.get(1);
310         minTimeBetweenTwoBackups = (Long JavaDoc) v.get(2);
311         lastBackup = (Long JavaDoc) v.elementAt(3);
312      }
313      else if(version==2)
314      {
315         destinationBackupFolder = (String JavaDoc) v.get(1);
316         minTimeBetweenTwoBackups = (Long JavaDoc) v.get(2);
317         lastBackup = (Long JavaDoc) v.get(3);
318         isAutomaticBackupEnabled = (Boolean JavaDoc) v.get(4);
319      }
320      else
321      {
322         throw new VectorizeException("Bad version "+version);
323      }
324   }
325
326
327
328 } // Backup
Popular Tags