SLING-9781 - [Sling Models] Caching doesn't work with Wrapped requests (#20)
- use original sling request when caching models adapted from a wrapped request
diff --git a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
index 5425832..c61e230 100644
--- a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
+++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
@@ -365,9 +365,14 @@
boolean isAdaptable = false;
Model modelAnnotation = modelClass.getModelAnnotation();
+ Object cacheKey = adaptable;
if (modelAnnotation.cache()) {
- Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
+ if (adaptable instanceof ServletRequestWrapper) {
+ cacheKey = unwrapRequest((ServletRequest) adaptable);
+ }
+
+ Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(cacheKey);
if (adaptableCache != null) {
SoftReference<Object> softReference = adaptableCache.get(requestedType);
if (softReference != null) {
@@ -399,10 +404,10 @@
ModelType model = (ModelType) Proxy.newProxyInstance(modelClass.getType().getClassLoader(), new Class<?>[] { modelClass.getType() }, handlerResult.getValue());
if (modelAnnotation.cache()) {
- Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
+ Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(cacheKey);
if (adaptableCache == null) {
adaptableCache = Collections.synchronizedMap(new WeakHashMap<Class<?>, SoftReference<Object>>());
- adapterCache.put(adaptable, adaptableCache);
+ adapterCache.put(cacheKey, adaptableCache);
}
adaptableCache.put(requestedType, new SoftReference<Object>(model));
}
@@ -416,10 +421,10 @@
result = createObject(adaptable, modelClass);
if (result.wasSuccessful() && modelAnnotation.cache()) {
- Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
+ Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(cacheKey);
if (adaptableCache == null) {
adaptableCache = Collections.synchronizedMap(new WeakHashMap<Class<?>, SoftReference<Object>>());
- adapterCache.put(adaptable, adaptableCache);
+ adapterCache.put(cacheKey, adaptableCache);
}
adaptableCache.put(requestedType, new SoftReference<Object>(result.getValue()));
}
diff --git a/src/test/java/org/apache/sling/models/impl/CachingTest.java b/src/test/java/org/apache/sling/models/impl/CachingTest.java
index f8d9d4a..2af2fa5 100644
--- a/src/test/java/org/apache/sling/models/impl/CachingTest.java
+++ b/src/test/java/org/apache/sling/models/impl/CachingTest.java
@@ -22,6 +22,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import javax.servlet.ServletRequestWrapper;
+
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.impl.injectors.RequestAttributeInjector;
import org.apache.sling.models.testmodels.classes.CachedModel;
@@ -38,6 +40,9 @@
@Mock
private SlingHttpServletRequest request;
+ @Mock
+ private ServletRequestWrapper requestWrapper;
+
private ModelAdapterFactory factory;
@Before
@@ -48,6 +53,7 @@
org.apache.sling.models.testmodels.interfaces.CachedModel.class, org.apache.sling.models.testmodels.interfaces.UncachedModel.class);
when(request.getAttribute("testValue")).thenReturn("test");
+ when(requestWrapper.getRequest()).thenReturn(request);
}
@Test
@@ -97,4 +103,28 @@
verify(request, times(2)).getAttribute("testValue");
}
+
+ @Test
+ public void testCachedClassWithRequestWrapper() {
+ CachedModel cached1 = factory.getAdapter(request, CachedModel.class);
+ CachedModel cached2 = factory.getAdapter(requestWrapper, CachedModel.class);
+
+ assertTrue(cached1 == cached2);
+ assertEquals("test", cached1.getTestValue());
+ assertEquals("test", cached2.getTestValue());
+
+ verify(request, times(1)).getAttribute("testValue");
+ }
+
+ @Test
+ public void testCachedInterfaceWithRequestWrapper() {
+ org.apache.sling.models.testmodels.interfaces.CachedModel cached1 = factory.getAdapter(request, org.apache.sling.models.testmodels.interfaces.CachedModel.class);
+ org.apache.sling.models.testmodels.interfaces.CachedModel cached2 = factory.getAdapter(requestWrapper, org.apache.sling.models.testmodels.interfaces.CachedModel.class);
+
+ assertTrue(cached1 == cached2);
+ assertEquals("test", cached1.getTestValue());
+ assertEquals("test", cached2.getTestValue());
+
+ verify(request, times(1)).getAttribute("testValue");
+ }
}