11package restx ;
22
33import com .google .common .base .Optional ;
4+ import com .google .common .base .Predicate ;
45import com .google .common .collect .ImmutableMap ;
56import com .google .common .io .ByteStreams ;
67import com .google .common .io .Resources ;
1011
1112import java .io .IOException ;
1213import java .net .URL ;
14+ import java .util .Collections ;
15+ import java .util .List ;
1316
1417import static com .google .common .base .Preconditions .checkNotNull ;
1518
@@ -35,17 +38,60 @@ public class ResourcesRoute implements RestxRoute, RestxHandler {
3538 */
3639 private final String baseResourcePath ;
3740 private final ImmutableMap <String , String > aliases ;
41+ private final List <CachedResourcePolicy > cachedResourcePolicies ;
42+
43+ public static class ResourceInfo {
44+ String contentType ;
45+ String path ;
46+
47+ public ResourceInfo (String contentType , String path ) {
48+ this .contentType = contentType ;
49+ this .path = path ;
50+ }
51+
52+ public String getContentType () {
53+ return contentType ;
54+ }
55+
56+ public String getPath () {
57+ return path ;
58+ }
59+ }
60+
61+ public static class CachedResourcePolicy {
62+ Predicate <ResourceInfo > matcher ;
63+ String cacheValue ;
64+
65+ public CachedResourcePolicy (Predicate <ResourceInfo > matcher , String cacheValue ) {
66+ this .matcher = matcher ;
67+ this .cacheValue = cacheValue ;
68+ }
69+
70+ public boolean matches (String contentType , String path ) {
71+ return matcher .apply (new ResourceInfo (contentType , path ));
72+ }
73+
74+ public String getCacheValue () {
75+ return cacheValue ;
76+ }
77+ }
78+
3879
3980 public ResourcesRoute (String name , String baseRestPath , String baseResourcePath ) {
4081 this (name , baseRestPath , baseResourcePath , ImmutableMap .<String , String >of ());
4182 }
4283
4384 public ResourcesRoute (String name , String baseRestPath , String baseResourcePath , ImmutableMap <String , String > aliases ) {
85+ this (name , baseRestPath , baseResourcePath , aliases , Collections .<CachedResourcePolicy >emptyList ());
86+ }
87+
88+ public ResourcesRoute (String name , String baseRestPath , String baseResourcePath , ImmutableMap <String , String > aliases , List <CachedResourcePolicy > cachedResourcePolicies ) {
4489 this .name = checkNotNull (name );
4590 this .baseRestPath = ("/" + checkNotNull (baseRestPath ) + "/" ).replaceAll ("/+" , "/" );
4691 this .baseResourcePath = checkNotNull (baseResourcePath )
4792 .replace ('.' , '/' ).replaceAll ("^/" , "" ).replaceAll ("/$" , "" ) + "/" ;
4893 this .aliases = checkNotNull (aliases );
94+ this .cachedResourcePolicies = cachedResourcePolicies ;
4995 }
5096
5197 @ Override
@@ -71,13 +117,27 @@ public void handle(RestxRequestMatch match, RestxRequest req, RestxResponse resp
71117 );
72118 resp .setLogLevel (RestxLogLevel .QUIET );
73119 resp .setStatus (HttpStatus .OK );
74- resp .setContentType (HTTP .getContentTypeFromExtension (relativePath ).or ("application/octet-stream" ));
120+ String contentType = HTTP .getContentTypeFromExtension (relativePath ).or ("application/octet-stream" );
121+ Optional <CachedResourcePolicy > cachedResourcePolicy = cachePolicyMatching (contentType , relativePath );
122+ if (cachedResourcePolicy .isPresent ()) {
123+ resp .setHeader ("Cache-Control" , cachedResourcePolicy .get ().getCacheValue ());
124+ }
125+ resp .setContentType (contentType );
75126 Resources .asByteSource (resource ).copyTo (resp .getOutputStream ());
76127 } catch (IllegalArgumentException e ) {
77128 notFound (resp , relativePath );
78129 }
79130 }
80131
132+ private Optional <CachedResourcePolicy > cachePolicyMatching (String contentType , String path ) {
133+ for (CachedResourcePolicy cachedResourcePolicy : cachedResourcePolicies ){
134+ if (cachedResourcePolicy .matches (contentType , path )){
135+ return Optional .of (cachedResourcePolicy );
136+ }
137+ }
138+ return Optional .absent ();
139+ }
140+
81141 private void notFound (RestxResponse resp , String relativePath ) throws IOException {
82142 resp .setStatus (HttpStatus .NOT_FOUND );
83143 resp .setContentType ("text/plain" );
0 commit comments