JAL-3130 adapted getdown src. attempt 2. first attempt failed due to cp'ed .git files
[jalview.git] / getdown / src / getdown / core / src / main / java / com / threerings / getdown / cache / GarbageCollector.java
1 //
2 // Getdown - application installer, patcher and launcher
3 // Copyright (C) 2004-2018 Getdown authors
4 // https://github.com/threerings/getdown/blob/master/LICENSE
5
6 package com.threerings.getdown.cache;
7
8 import java.io.File;
9 import com.threerings.getdown.util.FileUtil;
10
11 /**
12  * Collects elements in the {@link ResourceCache cache} which became unused and deletes them
13  * afterwards.
14  */
15 public class GarbageCollector
16 {
17     /**
18      * Collect and delete the garbage in the cache.
19      */
20     public static void collect (File cacheDir, final long retentionPeriodMillis)
21     {
22         FileUtil.walkTree(cacheDir, new FileUtil.Visitor() {
23             @Override public void visit (File file) {
24                 File cachedFile = getCachedFile(file);
25                 File lastAccessedFile = getLastAccessedFile(file);
26                 if (!cachedFile.exists() || !lastAccessedFile.exists()) {
27                     if (cachedFile.exists()) {
28                         FileUtil.deleteHarder(cachedFile);
29                     } else {
30                         FileUtil.deleteHarder(lastAccessedFile);
31                     }
32                 } else if (shouldDelete(lastAccessedFile, retentionPeriodMillis)) {
33                     FileUtil.deleteHarder(lastAccessedFile);
34                     FileUtil.deleteHarder(cachedFile);
35                 }
36
37                 File folder = file.getParentFile();
38                 if (folder != null) {
39                     String[] children = folder.list();
40                     if (children != null && children.length == 0) {
41                         FileUtil.deleteHarder(folder);
42                     }
43                 }
44             }
45         });
46     }
47
48     /**
49      * Collect and delete garbage in the native cache. It tries to find a jar file with a matching
50      * last modified file, and deletes the entire directory accordingly.
51      */
52     public static void collectNative (File cacheDir, final long retentionPeriodMillis)
53     {
54         File[] subdirs = cacheDir.listFiles();
55         if (subdirs != null) {
56             for (File dir : subdirs) {
57                 if (dir.isDirectory()) {
58                     // Get all the native jars in the directory (there should only be one)
59                     for (File file : dir.listFiles()) {
60                         if (!file.getName().endsWith(".jar")) {
61                             continue;
62                         }
63                         File cachedFile = getCachedFile(file);
64                         File lastAccessedFile = getLastAccessedFile(file);
65                         if (!cachedFile.exists() || !lastAccessedFile.exists() ||
66                             shouldDelete(lastAccessedFile, retentionPeriodMillis)) {
67                             FileUtil.deleteDirHarder(dir);
68                         }
69                     }
70                 } else {
71                     // @TODO There shouldn't be any loose files in native/ but if there are then
72                     // what? Delete them? file.delete();
73                 }
74             }
75         }
76     }
77
78     private static boolean shouldDelete (File lastAccessedFile, long retentionMillis)
79     {
80         return System.currentTimeMillis() - lastAccessedFile.lastModified() > retentionMillis;
81     }
82
83     private static File getLastAccessedFile (File file)
84     {
85         return isLastAccessedFile(file) ? file : new File(
86             file.getParentFile(), file.getName() + ResourceCache.LAST_ACCESSED_FILE_SUFFIX);
87     }
88
89     private static boolean isLastAccessedFile (File file)
90     {
91         return file.getName().endsWith(ResourceCache.LAST_ACCESSED_FILE_SUFFIX);
92     }
93
94     private static File getCachedFile (File file)
95     {
96         return !isLastAccessedFile(file) ? file : new File(
97             file.getParentFile(), file.getName().substring(0, file.getName().lastIndexOf(".")));
98     }
99 }