You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by di...@apache.org on 2022/01/19 11:03:49 UTC

[sling-org-apache-sling-models-impl] 01/01: SLING-11074: cache model for all adapter types

This is an automated email from the ASF dual-hosted git repository.

diru pushed a commit to branch issue/SLING-11074
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git

commit b602365975f9184ffdf2ec0c626dc8161c8675e8
Author: Dirk Rudolph <dr...@adobe.com>
AuthorDate: Wed Jan 19 12:03:17 2022 +0100

    SLING-11074: cache model for all adapter types
---
 .../sling/models/impl/ModelAdapterFactory.java     | 18 +++++++++++--
 .../org/apache/sling/models/impl/CachingTest.java  | 26 ++++++++++++++++--
 .../classes/CachedModelWithMultipleAdapters.java   | 31 ++++++++++++++++++++++
 .../CachedModelWithMultipleAdaptersA.java          | 20 ++++++++++++++
 .../CachedModelWithMultipleAdaptersB.java          | 20 ++++++++++++++
 5 files changed, 111 insertions(+), 4 deletions(-)

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 a534adf..563c116 100644
--- a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
+++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
@@ -35,6 +35,7 @@ import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -416,7 +417,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
                         ModelType model = (ModelType) Proxy.newProxyInstance(modelClass.getType().getClassLoader(), new Class<?>[] { modelClass.getType() }, handlerResult.getValue());
 
                         if (modelAnnotation.cache() && adaptableCache != null) {
-                            adaptableCache.put(requestedType, new SoftReference<Object>(model));
+                            addToAdaptableCache(adaptableCache, model, requestedType, modelAnnotation);
                         }
 
                         result = new Result<>(model);
@@ -428,7 +429,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
                         result = createObject(adaptable, modelClass);
 
                         if (result.wasSuccessful() && modelAnnotation.cache() && adaptableCache != null) {
-                            adaptableCache.put(requestedType, new SoftReference<Object>(result.getValue()));
+                            addToAdaptableCache(adaptableCache, result.getValue(), requestedType, modelAnnotation);
                         }
                     } catch (Exception e) {
                         String msg = String.format("Unable to create model %s", modelClass.getType());
@@ -452,6 +453,19 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
         return null;
     }
 
+    private void addToAdaptableCache(Map<Class<?>, SoftReference<Object>> adaptableCache, Object model, Class<?> requestedType,
+        Model modelAnnotation) {
+        SoftReference<Object> ref = new SoftReference<>(model);
+        // cache for the requested type
+        adaptableCache.put(requestedType, ref);
+        // and cache for any additional adapter types
+        if (modelAnnotation.adapters() != null) {
+            for (Class<?> adapterType : modelAnnotation.adapters()) {
+                adaptableCache.put(adapterType, ref);
+            }
+        }
+    }
+
     private interface InjectCallback {
         /**
          * Is called each time when the given value should be injected into the given element
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 ac37d55..c2f7c85 100644
--- a/src/test/java/org/apache/sling/models/impl/CachingTest.java
+++ b/src/test/java/org/apache/sling/models/impl/CachingTest.java
@@ -33,7 +33,10 @@ import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.models.impl.injectors.RequestAttributeInjector;
 import org.apache.sling.models.impl.injectors.ValueMapInjector;
 import org.apache.sling.models.testmodels.classes.CachedModel;
+import org.apache.sling.models.testmodels.classes.CachedModelWithMultipleAdapters;
 import org.apache.sling.models.testmodels.classes.UncachedModel;
+import org.apache.sling.models.testmodels.interfaces.CachedModelWithMultipleAdaptersA;
+import org.apache.sling.models.testmodels.interfaces.CachedModelWithMultipleAdaptersB;
 import org.apache.sling.servlethelpers.MockSlingHttpServletRequest;
 import org.junit.Before;
 import org.junit.Test;
@@ -60,8 +63,17 @@ public class CachingTest {
         factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new RequestAttributeInjector(), new ServicePropertiesMap(0, 0));
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(1, 1));
-        factory.adapterImplementations.addClassesAsAdapterAndImplementation(CachedModel.class, UncachedModel.class,
-                org.apache.sling.models.testmodels.interfaces.CachedModel.class, org.apache.sling.models.testmodels.interfaces.UncachedModel.class);
+        factory.bindImplementationPicker(new FirstImplementationPicker(), new ServicePropertiesMap(2,Integer.MAX_VALUE));
+        factory.adapterImplementations.addClassesAsAdapterAndImplementation(
+            CachedModel.class,
+            UncachedModel.class,
+            org.apache.sling.models.testmodels.interfaces.CachedModel.class,
+            org.apache.sling.models.testmodels.interfaces.UncachedModel.class);
+        factory.adapterImplementations.addAll(
+            CachedModelWithMultipleAdapters.class,
+            CachedModelWithMultipleAdapters.class,
+            CachedModelWithMultipleAdaptersA.class,
+            CachedModelWithMultipleAdaptersB.class);
 
         when(request.getAttribute("testValue")).thenReturn("test");
         requestWrapper = new SlingHttpServletRequestWrapper(request);
@@ -173,5 +185,15 @@ public class CachingTest {
 
         verify(request, times(1)).getAttribute("testValue");
     }
+
+    @Test
+    public void testCachedWithMultipleAdapters() {
+        CachedModelWithMultipleAdapters cached1 = factory.getAdapter(request, CachedModelWithMultipleAdapters.class);
+        CachedModelWithMultipleAdaptersA cached2 = factory.getAdapter(request, CachedModelWithMultipleAdaptersA.class);
+        CachedModelWithMultipleAdaptersB cached3 = factory.getAdapter(request, CachedModelWithMultipleAdaptersB.class);
+
+        assertSame(cached1, cached2);
+        assertSame(cached2, cached3);
+    }
 }
 
diff --git a/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithMultipleAdapters.java b/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithMultipleAdapters.java
new file mode 100644
index 0000000..275be5a
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithMultipleAdapters.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.models.testmodels.classes;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.testmodels.interfaces.CachedModelWithMultipleAdaptersA;
+import org.apache.sling.models.testmodels.interfaces.CachedModelWithMultipleAdaptersB;
+
+@Model(
+    adaptables = {SlingHttpServletRequest.class, Resource.class},
+    adapters = { CachedModelWithMultipleAdaptersA.class, CachedModelWithMultipleAdaptersB.class },
+    cache = true)
+public class CachedModelWithMultipleAdapters implements CachedModelWithMultipleAdaptersA, CachedModelWithMultipleAdaptersB {
+
+}
diff --git a/src/test/java/org/apache/sling/models/testmodels/interfaces/CachedModelWithMultipleAdaptersA.java b/src/test/java/org/apache/sling/models/testmodels/interfaces/CachedModelWithMultipleAdaptersA.java
new file mode 100644
index 0000000..fe93b82
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/testmodels/interfaces/CachedModelWithMultipleAdaptersA.java
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.models.testmodels.interfaces;
+
+public interface CachedModelWithMultipleAdaptersA {
+}
diff --git a/src/test/java/org/apache/sling/models/testmodels/interfaces/CachedModelWithMultipleAdaptersB.java b/src/test/java/org/apache/sling/models/testmodels/interfaces/CachedModelWithMultipleAdaptersB.java
new file mode 100644
index 0000000..6ded363
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/testmodels/interfaces/CachedModelWithMultipleAdaptersB.java
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.models.testmodels.interfaces;
+
+public interface CachedModelWithMultipleAdaptersB {
+}