1 package org.kuali.common.devops.cache;
2
3 import static org.kuali.common.util.base.Precondition.checkNotNull;
4
5 import java.io.File;
6 import java.util.Set;
7
8 import javax.validation.ConstraintViolation;
9
10 import org.kuali.common.core.build.ViolationsBuilder;
11 import org.kuali.common.core.validate.annotation.IdiotProofImmutable;
12
13 import com.google.common.base.Function;
14 import com.google.common.cache.CacheLoader;
15
16 @IdiotProofImmutable
17 public final class FileSystemCache<K, V> extends CacheLoader<K, V> {
18
19 private final PersistentCache<File, V> fileCache;
20 private final CacheLoader<K, V> loader;
21 private final Function<K, File> keyConverter;
22 private final boolean ignoreFileSystem;
23
24 @Override
25 public V load(K key) throws Exception {
26 checkNotNull(key, "key");
27
28
29 if (ignoreFileSystem) {
30 return loader.load(key);
31 }
32
33
34
35 File file = keyConverter.apply(key);
36
37
38 if (file.exists()) {
39 return fileCache.load(file);
40 }
41
42
43 V value = loader.load(key);
44
45
46 fileCache.store(file, value);
47
48
49 return value;
50 }
51
52 public PersistentCache<File, V> getFileCache() {
53 return fileCache;
54 }
55
56 public Function<K, File> getKeyConverter() {
57 return keyConverter;
58 }
59
60 public boolean isIgnoreFileSystem() {
61 return ignoreFileSystem;
62 }
63
64 private FileSystemCache(Builder<K, V> builder) {
65 this.fileCache = builder.fileCache;
66 this.loader = builder.loader;
67 this.keyConverter = builder.keyConverter;
68 this.ignoreFileSystem = builder.ignoreFileSystem;
69 }
70
71 public static <K, V> Builder<K, V> builder() {
72 return new Builder<K, V>();
73 }
74
75 public static class Builder<K, V> extends ViolationsBuilder<FileSystemCache<K, V>> {
76
77 private PersistentCache<File, V> fileCache;
78 private CacheLoader<K, V> loader;
79 private Function<K, File> keyConverter;
80 private boolean ignoreFileSystem;
81
82 private FileSystemCache<K, V> make() {
83 return new FileSystemCache<K, V>(this);
84 }
85
86 @Override
87 public Set<ConstraintViolation<FileSystemCache<K, V>>> violations() {
88 return violations(make());
89 }
90
91 @Override
92 public FileSystemCache<K, V> build() {
93 return validate(make());
94 }
95
96 public Builder<K, V> fileCache(PersistentCache<File, V> fileCache) {
97 this.fileCache = fileCache;
98 return this;
99 }
100
101 public Builder<K, V> loader(CacheLoader<K, V> loader) {
102 this.loader = loader;
103 return this;
104 }
105
106 public Builder<K, V> keyConverter(Function<K, File> keyConverter) {
107 this.keyConverter = keyConverter;
108 return this;
109 }
110
111 public Builder<K, V> ignoreFileSystem(boolean ignoreFileSystem) {
112 this.ignoreFileSystem = ignoreFileSystem;
113 return this;
114 }
115
116 public PersistentCache<File, V> getFileCache() {
117 return fileCache;
118 }
119
120 public void setFileCache(PersistentCache<File, V> fileCache) {
121 this.fileCache = fileCache;
122 }
123
124 public CacheLoader<K, V> getLoader() {
125 return loader;
126 }
127
128 public void setLoader(CacheLoader<K, V> loader) {
129 this.loader = loader;
130 }
131
132 public Function<K, File> getKeyConverter() {
133 return keyConverter;
134 }
135
136 public void setKeyConverter(Function<K, File> keyConverter) {
137 this.keyConverter = keyConverter;
138 }
139
140 public boolean isIgnoreFileSystem() {
141 return ignoreFileSystem;
142 }
143
144 public void setIgnoreFileSystem(boolean ignoreFileSystem) {
145 this.ignoreFileSystem = ignoreFileSystem;
146 }
147
148 }
149
150 public CacheLoader<K, V> getLoader() {
151 return loader;
152 }
153
154 }