From 811a2359345952e3c801d5f2e3ba04c67547b8cd Mon Sep 17 00:00:00 2001
From: Tahseen <tahseen@article.com>
Date: Mon, 19 Jun 2017 15:25:05 -0700
Subject: [PATCH] Allow customization of @CacheFor cache key #1133

---
 framework/src/play/cache/CacheFor.java              |  1 +
 framework/src/play/cache/CacheKeyGenerator.java     | 10 ++++++++++
 .../src/play/cache/DefaultCacheKeyGenerator.java    | 13 +++++++++++++
 framework/src/play/mvc/ActionInvoker.java           | 12 ++++++++----
 4 files changed, 32 insertions(+), 4 deletions(-)
 create mode 100644 framework/src/play/cache/CacheKeyGenerator.java
 create mode 100644 framework/src/play/cache/DefaultCacheKeyGenerator.java

diff --git a/framework/src/play/cache/CacheFor.java b/framework/src/play/cache/CacheFor.java
index 700c08f636..88b2acf72c 100644
--- a/framework/src/play/cache/CacheFor.java
+++ b/framework/src/play/cache/CacheFor.java
@@ -17,4 +17,5 @@
 public @interface CacheFor {
     String value() default "1h";
     String id() default "";
+    Class<? extends CacheKeyGenerator> generator() default DefaultCacheKeyGenerator.class;
 }
diff --git a/framework/src/play/cache/CacheKeyGenerator.java b/framework/src/play/cache/CacheKeyGenerator.java
new file mode 100644
index 0000000000..6e1a19f383
--- /dev/null
+++ b/framework/src/play/cache/CacheKeyGenerator.java
@@ -0,0 +1,10 @@
+package play.cache;
+
+import play.mvc.Http.Request;
+
+/**
+ * Allow custom cache key to be used by applications.
+ */
+public interface CacheKeyGenerator {
+	public String generate(Request request);
+}
\ No newline at end of file
diff --git a/framework/src/play/cache/DefaultCacheKeyGenerator.java b/framework/src/play/cache/DefaultCacheKeyGenerator.java
new file mode 100644
index 0000000000..669c95499a
--- /dev/null
+++ b/framework/src/play/cache/DefaultCacheKeyGenerator.java
@@ -0,0 +1,13 @@
+package play.cache;
+
+import play.mvc.Http.Request;
+
+/**
+ * The Default Cache Key Generator
+ */
+public class DefaultCacheKeyGenerator implements CacheKeyGenerator {
+	@Override
+	public String generate(Request request) {
+		return "urlcache:" + request.url + request.querystring;
+	}
+}
\ No newline at end of file
diff --git a/framework/src/play/mvc/ActionInvoker.java b/framework/src/play/mvc/ActionInvoker.java
index 3e5085a2b4..ebbabe6ed7 100644
--- a/framework/src/play/mvc/ActionInvoker.java
+++ b/framework/src/play/mvc/ActionInvoker.java
@@ -147,11 +147,15 @@ public static void invoke(Http.Request request, Http.Response response) {
 
                 // Check the cache (only for GET or HEAD)
                 if ((request.method.equals("GET") || request.method.equals("HEAD")) && actionMethod.isAnnotationPresent(CacheFor.class)) {
-                    cacheKey = actionMethod.getAnnotation(CacheFor.class).id();
+                    CacheFor cacheFor = actionMethod.getAnnotation(CacheFor.class);;
+                    cacheKey = cacheFor.id();
                     if ("".equals(cacheKey)) {
-                        cacheKey = "urlcache:" + request.url + request.querystring;
+                        // Generate a cache key for this request
+                        cacheKey = cacheFor.generator().newInstance().generate(request);
+                    }
+                    if(cacheKey != null && !"".equals(cacheKey)) {
+                    	actionResult = (Result) Cache.get(cacheKey);
                     }
-                    actionResult = (Result) Cache.get(cacheKey);
                 }
 
                 if (actionResult == null) {
@@ -161,7 +165,7 @@ public static void invoke(Http.Request request, Http.Response response) {
             } catch (Result result) {
                 actionResult = result;
                 // Cache it if needed
-                if (cacheKey != null) {
+                if (cacheKey != null && !"".equals(cacheKey)) {
                     Cache.set(cacheKey, actionResult, actionMethod.getAnnotation(CacheFor.class).value());
                 }
             } catch (JavaExecutionException e) {