Skip to content

Commit a7d395f

Browse files
author
Mattia Bertorello
committed
Add cache.json file and improve stability
1 parent 00818af commit a7d395f

File tree

3 files changed

+509
-67
lines changed

3 files changed

+509
-67
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
package cc.arduino.utils.network;
2+
3+
import java.util.regex.Matcher;
4+
import java.util.regex.Pattern;
5+
6+
/**
7+
* Represents a HTTP Cache-Control response header and parses it from string.
8+
*
9+
* <p>Note: This class ignores <tt>1#field-name</tt> parameter for
10+
* <tt>private</tt> and <tt>no-cache</tt> directive and cache extensions.</p>
11+
*
12+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">HTTP/1.1 section 14.9</a>
13+
*/
14+
public class CacheControl {
15+
16+
17+
// copied from org.apache.abdera.protocol.util.CacheControlUtil
18+
private static final Pattern PATTERN
19+
= Pattern.compile("\\s*([\\w\\-]+)\\s*(=)?\\s*(\\-?\\d+|\\\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)+\\\")?\\s*");
20+
21+
/**
22+
* Corresponds to the <tt>max-age</tt> cache control directive.
23+
* The default value is <tt>-1</tt>, i.e. not specified.
24+
*
25+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
26+
*/
27+
private int maxAge = -1;
28+
29+
/**
30+
* Corresponds to the <tt>s-maxage</tt> cache control directive.
31+
* The default value is <tt>-1</tt>, i.e. not specified.
32+
*
33+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
34+
*/
35+
private int sMaxAge = -1;
36+
37+
/**
38+
* Whether the <tt>must-revalidate</tt> directive is specified.
39+
* The default value is <tt>false</tt>.
40+
*
41+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
42+
*/
43+
private boolean isMustRevalidate = false;
44+
45+
/**
46+
* Whether the <tt>no-cache</tt> directive is specified.
47+
* The default value is <tt>false</tt>.
48+
*
49+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
50+
*/
51+
private boolean isNoCache = false;
52+
53+
/**
54+
* Whether the <tt>no-store</tt> directive is specified.
55+
* The default value is <tt>false</tt>.
56+
*
57+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2">HTTP/1.1 section 14.9.2</a>
58+
*/
59+
private boolean isNoStore = false;
60+
61+
/**
62+
* Whether the <tt>no-transform</tt> directive is specified.
63+
* The default value is <tt>false</tt>.
64+
*
65+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5">HTTP/1.1 section 14.9.5</a>
66+
*/
67+
private boolean isNoTransform = false;
68+
69+
/**
70+
* Whether the <tt>private</tt> directive is specified.
71+
* The default value is <tt>false</tt>.
72+
*
73+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
74+
*/
75+
private boolean isPrivate = false;
76+
77+
/**
78+
* Whether the <tt>public</tt> directive is specified.
79+
* The default value is <tt>false</tt>.
80+
*
81+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
82+
*/
83+
private boolean isPublic = false;
84+
85+
/**
86+
* Whether the <tt>proxy-revalidate</tt> directive is specified.
87+
* The default value is <tt>false</tt>.
88+
*
89+
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
90+
*/
91+
private boolean isProxyRevalidate = false;
92+
93+
94+
/**
95+
* Creates a new instance of CacheControl by parsing the supplied string.
96+
*
97+
* @param value A value the Cache-Control header.
98+
*/
99+
public static CacheControl valueOf(String value) {
100+
CacheControl cc = new CacheControl();
101+
102+
if (value != null) {
103+
Matcher matcher = PATTERN.matcher(value);
104+
while (matcher.find()) {
105+
switch (matcher.group(1).toLowerCase()) {
106+
case "max-age":
107+
cc.setMaxAge(Integer.parseInt(matcher.group(3))); break;
108+
case "s-maxage":
109+
cc.setSMaxAge(Integer.parseInt(matcher.group(3))); break;
110+
case "must-revalidate":
111+
cc.setMustRevalidate(true); break;
112+
case "no-cache":
113+
cc.setNoCache(true); break;
114+
case "no-store":
115+
cc.setNoStore(true); break;
116+
case "no-transform":
117+
cc.setNoTransform(true); break;
118+
case "private":
119+
cc.setPrivate(true); break;
120+
case "public":
121+
cc.setPublic(true); break;
122+
case "proxy-revalidate":
123+
cc.setProxyRevalidate(true); break;
124+
default: //ignore
125+
}
126+
}
127+
}
128+
return cc;
129+
}
130+
131+
/**
132+
* Returns <tt>max-age</tt>, or <tt>s-maxage</tt> according to whether
133+
* considering a shared cache, or a private cache. If shared cache and the
134+
* <tt>s-maxage</tt> is negative (i.e. not set), then returns
135+
* <tt>max-age</tt> instead.
136+
*
137+
* @param sharedCache <tt>true</tt> for a shared cache,
138+
* or <tt>false</tt> for a private cache
139+
* @return A {@link #maxAge}, or {@link #sMaxAge} according to the given
140+
* sharedCache argument.
141+
*/
142+
public int getMaxAge(boolean sharedCache) {
143+
if (sharedCache) {
144+
return sMaxAge >= 0 ? sMaxAge : maxAge;
145+
} else {
146+
return maxAge;
147+
}
148+
}
149+
150+
public void setMaxAge(int maxAge) {
151+
this.maxAge = maxAge;
152+
}
153+
154+
public int getMaxAge() {
155+
return maxAge;
156+
}
157+
158+
public int getSMaxAge() {
159+
return sMaxAge;
160+
}
161+
162+
public void setSMaxAge(int sMaxAge) {
163+
this.sMaxAge = sMaxAge;
164+
}
165+
166+
public boolean isMustRevalidate() {
167+
return isMustRevalidate;
168+
}
169+
170+
public void setMustRevalidate(boolean mustRevalidate) {
171+
isMustRevalidate = mustRevalidate;
172+
}
173+
174+
public boolean isNoCache() {
175+
return isNoCache;
176+
}
177+
178+
public void setNoCache(boolean noCache) {
179+
isNoCache = noCache;
180+
}
181+
182+
public boolean isNoStore() {
183+
return isNoStore;
184+
}
185+
186+
public void setNoStore(boolean noStore) {
187+
isNoStore = noStore;
188+
}
189+
190+
public boolean isNoTransform() {
191+
return isNoTransform;
192+
}
193+
194+
public void setNoTransform(boolean noTransform) {
195+
isNoTransform = noTransform;
196+
}
197+
198+
public boolean isPrivate() {
199+
return isPrivate;
200+
}
201+
202+
public void setPrivate(boolean aPrivate) {
203+
isPrivate = aPrivate;
204+
}
205+
206+
public boolean isPublic() {
207+
return isPublic;
208+
}
209+
210+
public void setPublic(boolean aPublic) {
211+
isPublic = aPublic;
212+
}
213+
214+
public boolean isProxyRevalidate() {
215+
return isProxyRevalidate;
216+
}
217+
218+
public void setProxyRevalidate(boolean proxyRevalidate) {
219+
isProxyRevalidate = proxyRevalidate;
220+
}
221+
222+
@Override
223+
public String toString() {
224+
return "CacheControl{" +
225+
"maxAge=" + maxAge +
226+
", sMaxAge=" + sMaxAge +
227+
", isMustRevalidate=" + isMustRevalidate +
228+
", isNoCache=" + isNoCache +
229+
", isNoStore=" + isNoStore +
230+
", isNoTransform=" + isNoTransform +
231+
", isPrivate=" + isPrivate +
232+
", isPublic=" + isPublic +
233+
", isProxyRevalidate=" + isProxyRevalidate +
234+
'}';
235+
}
236+
}

Diff for: arduino-core/src/cc/arduino/utils/network/FileDownloader.java

+11-11
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@
3030
package cc.arduino.utils.network;
3131

3232
import org.apache.commons.compress.utils.IOUtils;
33-
import org.slf4j.Logger;
34-
import org.slf4j.LoggerFactory;
35-
import processing.app.BaseNoGui;
33+
import org.apache.logging.log4j.LogManager;
34+
import org.apache.logging.log4j.Logger;
3635
import processing.app.helpers.FileUtils;
3736

3837
import java.io.File;
@@ -48,7 +47,7 @@
4847
import java.util.Optional;
4948

5049
public class FileDownloader extends Observable {
51-
private static Logger log = LoggerFactory.getLogger(FileDownloader.class);
50+
private static Logger log = LogManager.getLogger(FileDownloader.class);
5251

5352
public enum Status {
5453
CONNECTING, //
@@ -146,15 +145,14 @@ private void downloadFile(boolean noResume) throws InterruptedException {
146145
try {
147146
setStatus(Status.CONNECTING);
148147

149-
final File settingsFolder = BaseNoGui.getPlatform().getSettingsFolder();
150-
final String cacheFolder = Paths.get(settingsFolder.getPath(), "cache").toString();
151-
final FileDownloaderCache fileDownloaderCache = FileDownloaderCache.getFileCached(cacheFolder, downloadUrl);
148+
final Optional<FileDownloaderCache.FileCached> fileCached = FileDownloaderCache.getFileCached(downloadUrl);
152149

153-
if (!fileDownloaderCache.isChange()) {
150+
if (fileCached.isPresent() && !fileCached.get().isChange()) {
154151
try {
155152
final Optional<File> fileFromCache =
156-
fileDownloaderCache.getFileFromCache();
153+
fileCached.get().getFileFromCache();
157154
if (fileFromCache.isPresent()) {
155+
log.info("No need to download using cached file: {}", fileCached.get());
158156
FileUtils.copyFile(fileFromCache.get(), outputFile);
159157
setStatus(Status.COMPLETE);
160158
return;
@@ -195,7 +193,7 @@ private void downloadFile(boolean noResume) throws InterruptedException {
195193
synchronized (this) {
196194
stream = connection.getInputStream();
197195
}
198-
byte buffer[] = new byte[10240];
196+
byte[] buffer = new byte[10240];
199197
while (status == Status.DOWNLOADING) {
200198
int read = stream.read(buffer);
201199
if (read == -1)
@@ -216,7 +214,9 @@ private void downloadFile(boolean noResume) throws InterruptedException {
216214
}
217215
// Set the cache whe it finish to download the file
218216
IOUtils.closeQuietly(randomAccessOutputFile);
219-
fileDownloaderCache.fillCache(outputFile);
217+
if (fileCached.isPresent()) {
218+
fileCached.get().updateCacheFile(outputFile);
219+
}
220220
setStatus(Status.COMPLETE);
221221
} catch (InterruptedException e) {
222222
setStatus(Status.CANCELLED);

0 commit comments

Comments
 (0)