View Javadoc
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  		// If we are ignoring the file system, just query the main cache
29  		if (ignoreFileSystem) {
30  			return loader.load(key);
31  		}
32  
33  		// Otherwise check the file system first
34  		// Convert the key into a filename
35  		File file = keyConverter.apply(key);
36  
37  		// If the file exists, load the value from there
38  		if (file.exists()) {
39  			return fileCache.load(file);
40  		}
41  
42  		// Query the main cache
43  		V value = loader.load(key);
44  
45  		// Store the value to the file system
46  		fileCache.store(file, value);
47  
48  		// Return the value
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 }