Skip to content

Commit c3b2c3e

Browse files
committed
Added delete; fixed parsing, matching, and display bugs
1 parent d11c416 commit c3b2c3e

File tree

1 file changed

+113
-110
lines changed

1 file changed

+113
-110
lines changed

src/main/java/org/xmlresolver/apps/cachectrl/CacheCtrl.java

Lines changed: 113 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import com.beust.jcommander.ParameterException;
1212
import com.beust.jcommander.Parameters;
1313
import org.xmlresolver.ResolverFeature;
14-
import org.xmlresolver.ResourceConnection;
1514
import org.xmlresolver.XMLResolverConfiguration;
1615
import org.xmlresolver.cache.CacheEntry;
1716
import org.xmlresolver.cache.CacheInfo;
@@ -23,9 +22,7 @@
2322
import java.text.DateFormat;
2423
import java.text.SimpleDateFormat;
2524
import java.util.ArrayList;
26-
import java.util.Calendar;
2725
import java.util.Date;
28-
import java.util.GregorianCalendar;
2926
import java.util.HashMap;
3027
import java.util.regex.Matcher;
3128
import java.util.regex.Pattern;
@@ -35,6 +32,9 @@
3532
* @author ndw
3633
*/
3734
public class CacheCtrl {
35+
// Hack to print the cache directory at most once.
36+
private static boolean showCacheDirectory = true;
37+
3838
public static void main(String[] args) {
3939
CacheCtrl app = new CacheCtrl();
4040
app.process(args);
@@ -46,13 +46,15 @@ private void process(String[] args) {
4646
CommandInspect cinspect = new CommandInspect();
4747
CommandCreate ccreate = new CommandCreate();
4848
CommandUpdate cupdate = new CommandUpdate();
49+
CommandDelete cdelete = new CommandDelete();
4950
CommandFlush cflush = new CommandFlush();
5051
JCommander jc = JCommander.newBuilder()
5152
.addObject(cmain)
5253
.addCommand("show", cshow)
5354
.addCommand("inspect", cinspect)
5455
.addCommand("create", ccreate)
5556
.addCommand("update", cupdate)
57+
.addCommand("delete", cdelete)
5658
.addCommand("flush", cflush)
5759
.build();
5860

@@ -78,6 +80,9 @@ private void process(String[] args) {
7880
case "update":
7981
update(cmain, cupdate);
8082
break;
83+
case "delete":
84+
delete(cmain, cdelete);
85+
break;
8186
case "flush":
8287
flush(cmain, cflush);
8388
break;
@@ -114,7 +119,7 @@ private void show(CommandMain main, CommandShow command) {
114119
String regex = ".*";
115120
if (command.regex != null) {
116121
regex = command.regex;
117-
System.out.println("Showing all cache entries matching '" + regex + "'");
122+
System.out.println("Showing cache entries matching '" + regex + "'");
118123
}
119124

120125
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
@@ -125,6 +130,7 @@ private void show(CommandMain main, CommandShow command) {
125130
entrystr = entrystr.substring(0, pos);
126131

127132
count += 1;
133+
128134
Matcher matcher = pattern.matcher(entrystr);
129135
if (matcher.find()) {
130136
if (main.verbose) {
@@ -147,7 +153,9 @@ private void show(CommandMain main, CommandShow command) {
147153
}
148154
}
149155

150-
if (!".*".equals(regex)) {
156+
if (match == count) {
157+
System.out.println(count + " " + (count == 1 ? "entry" : "entries"));
158+
} else {
151159
System.out.println(match + " of " + count + " entries match");
152160
}
153161
}
@@ -181,7 +189,7 @@ private void inspect(CommandMain main) {
181189
for (CacheEntry entry : cache.entries()) {
182190
CacheInfo info = null;
183191
for (CacheInfo cached : caching) {
184-
if (cached.uriPattern.matcher(entry.uri.toString()).find()) {
192+
if (info == null && cached.uriPattern.matcher(entry.uri.toString()).find()) {
185193
info = cached;
186194
}
187195
}
@@ -199,13 +207,74 @@ private void inspect(CommandMain main) {
199207
space = stats.get(info.pattern).space;
200208
System.out.println(" Files: " + formatSpace(space) + " in " + count + " "
201209
+ (count == 1 ? "entry" : "entries"));
202-
System.out.println(" Limits: " + formatSpace(info.cacheSpace) + ", " + info.cacheSize + " "
210+
System.out.print(" Limits: " + formatSpace(info.cacheSpace) + ", " + info.cacheSize + " "
203211
+ (info.cacheSize == 1 ? "entry" : "entries"));
212+
System.out.print(", delete wait " + formatDuration(info.deleteWait));
213+
if (info.maxAge >= 0) {
214+
System.out.print(", max age: " + formatDuration(info.maxAge));
215+
}
216+
System.out.println();
204217
stats.put(info.pattern, new CacheStatistics(info));
205218
}
206219
}
207220
}
208221

222+
private String formatDuration(long seconds) {
223+
if (seconds < 0) {
224+
return "" + seconds;
225+
} else if (seconds == 0) {
226+
return "0s";
227+
}
228+
229+
long d = 0;
230+
long h = 0;
231+
long m = 0;
232+
233+
if (seconds >= 3600 * 24) {
234+
long msec = seconds;
235+
seconds = seconds % (3600 * 24);
236+
msec = msec - seconds;
237+
d = msec / (3600 * 24);
238+
}
239+
240+
if (seconds >= 3600) {
241+
long hsec = seconds;
242+
seconds = seconds % 3600;
243+
hsec = hsec - seconds;
244+
h = hsec / 3600;
245+
}
246+
247+
if (seconds >= 60) {
248+
long msec = seconds;
249+
seconds = seconds % 60;
250+
msec = msec - seconds;
251+
m = msec / 60;
252+
}
253+
254+
StringBuilder sb = new StringBuilder();
255+
if (d != 0) {
256+
sb.append(d);
257+
sb.append("d");
258+
}
259+
260+
if (h != 0 || m != 0 || seconds != 0) {
261+
if (h != 0) {
262+
sb.append(h);
263+
sb.append("h");
264+
}
265+
if (m != 0) {
266+
sb.append(m);
267+
sb.append("m");
268+
}
269+
if (seconds != 0 || m != 0) {
270+
sb.append(seconds);
271+
sb.append("s");
272+
}
273+
}
274+
275+
return sb.toString();
276+
}
277+
209278
private void create(CommandMain main, CommandCreate command) {
210279
ResourceCache cache = getResourceCache(main);
211280
for (CacheInfo info : cache.getCacheInfoList()) {
@@ -230,34 +299,38 @@ private void update(CommandMain main, CommandUpdate command) {
230299
inspect(main);
231300
}
232301

233-
private void flush(CommandMain main, CommandFlush command) {
234-
if (command.pattern == null && command.regex == null) {
235-
throw new ParameterException("You must specify at least one of -pattern and -regex");
236-
}
302+
private void createOrUpdate(ResourceCache cache, CommandMain main, CommandCreate command) {
303+
long deleteWait = CacheParser.parseTimeLong(command.deleteWait, ResourceCache.deleteWait);
304+
long cacheSize = CacheParser.parseSizeLong(command.size, ResourceCache.cacheSize);
305+
long cacheSpace = CacheParser.parseSizeLong(command.space, ResourceCache.cacheSpace);
306+
long maxAge = CacheParser.parseTimeLong(command.age, ResourceCache.maxAge);
307+
308+
cache.removeCacheInfo(command.pattern);
309+
cache.addCacheInfo(command.pattern, command.include, deleteWait, cacheSize, cacheSpace, maxAge);
310+
}
237311

312+
private void delete(CommandMain main, CommandDelete command) {
238313
ResourceCache cache = getResourceCache(main);
239-
CacheInfo info = null;
240-
if (command.pattern != null) {
241-
for (CacheInfo cinfo : cache.getCacheInfoList()) {
242-
if (command.pattern.equals(cinfo.pattern)) {
243-
info = cinfo;
244-
}
245-
}
246-
if (info == null) {
247-
throw new ParameterException("Cannot flush pattern '" + command.pattern + "', it doesn't exist");
248-
}
314+
boolean found = false;
315+
for (CacheInfo info : cache.getCacheInfoList()) {
316+
found = found || info.pattern.equals(command.pattern);
317+
}
318+
if (!found) {
319+
throw new ParameterException("Cannot delete '" + command.pattern + "', it doesn't exist");
249320
}
321+
cache.removeCacheInfo(command.pattern);
322+
inspect(main);
323+
}
324+
325+
private void flush(CommandMain main, CommandFlush command) {
326+
ResourceCache cache = getResourceCache(main);
250327

251328
String regex = ".*";
252329
if (command.regex != null) {
253330
regex = command.regex;
254331
}
255332

256333
long count = 0;
257-
Pattern infopattern = null;
258-
if (info != null) {
259-
infopattern = Pattern.compile(info.pattern, Pattern.CASE_INSENSITIVE);
260-
}
261334
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
262335
for (CacheEntry entry : cache.entries()) {
263336
// Hack out the arrow pointer
@@ -266,13 +339,7 @@ private void flush(CommandMain main, CommandFlush command) {
266339
entrystr = entrystr.substring(0, pos);
267340

268341
Matcher matcher = pattern.matcher(entrystr);
269-
boolean matches = matcher.find();
270-
if (infopattern != null) {
271-
matcher = infopattern.matcher(entrystr);
272-
matches = matches && matcher.find();
273-
}
274-
275-
if (matches) {
342+
if (matcher.find()) {
276343
File centry = new File(entry.entry.baseURI.getPath());
277344
if (centry.exists()) {
278345
if (!centry.delete()) {
@@ -294,16 +361,6 @@ private void flush(CommandMain main, CommandFlush command) {
294361
System.out.println("Flushed " + count + " entries");
295362
}
296363

297-
private void createOrUpdate(ResourceCache cache, CommandMain main, CommandCreate command) {
298-
long deleteWait = CacheParser.parseTimeLong(command.deleteWait, ResourceCache.deleteWait);
299-
long cacheSize = CacheParser.parseLong(command.size, ResourceCache.cacheSize);
300-
long cacheSpace = CacheParser.parseSizeLong(command.space, ResourceCache.cacheSpace);
301-
long maxAge = CacheParser.parseTimeLong(command.age, ResourceCache.maxAge);
302-
303-
cache.removeCacheInfo(command.pattern);
304-
cache.addCacheInfo(command.pattern, command.include, deleteWait, cacheSize, cacheSpace, maxAge);
305-
}
306-
307364
private String formatSpace(long space) {
308365
float gigabyte = 1024 * 1000 * 1000;
309366
float megabyte = 1024 * 1000;
@@ -334,6 +391,9 @@ private String formatTime(long time) {
334391

335392
private ResourceCache getResourceCache(CommandMain main) {
336393
XMLResolverConfiguration config = new XMLResolverConfiguration();
394+
if (main.cacheDirectory != null) {
395+
config.setFeature(ResolverFeature.CACHE_DIRECTORY, main.cacheDirectory);
396+
}
337397
ResourceCache cache = config.getFeature(ResolverFeature.CACHE);
338398
if (cache.directory() == null) {
339399
if (main.cacheDirectory == null) {
@@ -342,73 +402,13 @@ private ResourceCache getResourceCache(CommandMain main) {
342402
throw new ParameterException("Failed to initialize cache: " + main.cacheDirectory);
343403
}
344404
}
345-
System.out.println("Cache directory: " + cache.directory());
346-
return cache;
347-
}
348405

349-
private String showTime(long cacheTime) {
350-
String[] months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
351-
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
352-
353-
GregorianCalendar cacheDate = new GregorianCalendar();
354-
cacheDate.setTimeInMillis(cacheTime);
355-
356-
String result = cacheDate.get(Calendar.DAY_OF_MONTH) + " ";
357-
result += months[cacheDate.get(Calendar.MONTH)] + " ";
358-
result += cacheDate.get(Calendar.YEAR) + " at ";
359-
if (cacheDate.get(Calendar.HOUR) < 10) { result += "0"; }
360-
result += cacheDate.get(Calendar.HOUR) + ":";
361-
if (cacheDate.get(Calendar.MINUTE) < 10) { result += "0"; }
362-
result += cacheDate.get(Calendar.MINUTE) + ":";
363-
if (cacheDate.get(Calendar.SECOND) < 10) { result += "0"; }
364-
result += cacheDate.get(Calendar.SECOND);
365-
366-
return result;
367-
}
368-
369-
private void checkLastModified(CacheEntry entry) {
370-
String uri = entry.uri.toString();
371-
if (uri.startsWith("file:")) {
372-
File src = new File(entry.uri.getPath());
373-
if (!src.exists()) {
374-
System.out.println("\tFile does not exist");
375-
} else {
376-
System.out.println("\tLast modified on " + showTime(src.lastModified()));
377-
if (src.lastModified() > entry.time) {
378-
System.out.println("\tEXPIRED");
379-
}
380-
}
381-
return;
382-
} else if (!uri.startsWith("http:") && !uri.startsWith("https:")) {
383-
System.out.println("\tCan't check age of actual resource.");
384-
return;
385-
}
386-
387-
ResourceConnection rconn = new ResourceConnection(entry.uri.toASCIIString());
388-
rconn.close();
389-
long lastModified = rconn.getLastModified();
390-
String etag = rconn.getEtag();
391-
if (rconn.getStatusCode() != 200) {
392-
System.out.println("\tHTTP returned " + rconn.getStatusCode());
393-
}
394-
395-
if (lastModified <= 0) {
396-
System.out.println("\tServer did not report last-modified");
397-
} else {
398-
System.out.println("\tLast modified on " + showTime(lastModified));
399-
}
400-
401-
if (etag != null && entry.etag() != null) {
402-
if (etag.equals(entry.etag())) {
403-
System.out.println("\tEtags match: " + etag);
404-
} else {
405-
System.out.println("\tEtags don't match: " + entry.etag() + " ≠ " + etag);
406-
}
406+
if (CacheCtrl.showCacheDirectory) {
407+
System.out.println("Cache directory: " + cache.directory());
408+
CacheCtrl.showCacheDirectory = false;
407409
}
408410

409-
if (lastModified > entry.time) {
410-
System.out.println("\tEXPIRED");
411-
}
411+
return cache;
412412
}
413413

414414
// ============================================================
@@ -463,12 +463,15 @@ private class CommandUpdate extends CommandCreate {
463463
// The same parameters, the only difference is whether or not it must exist or must not exist
464464
}
465465

466-
@Parameters(separators = ":", commandDescription = "Flush the cache")
467-
private class CommandFlush {
468-
@Parameter(names = "-pattern", description = "The URI regular expression pattern")
466+
@Parameters(separators = ":", commandDescription = "Create a new cache configuration")
467+
private class CommandDelete {
468+
@Parameter(names = "-pattern", description = "The URI regular expression pattern", required = true)
469469
public String pattern;
470+
}
470471

471-
@Parameter(names = {"-regex", "-r"}, description = "A regular expression to filter the entries shown")
472+
@Parameters(separators = ":", commandDescription = "Flush the cache")
473+
private class CommandFlush {
474+
@Parameter(names = {"-regex", "-r"}, description = "A regular expression to filter the entries shown", required = true)
472475
private String regex;
473476
}
474477

0 commit comments

Comments
 (0)