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/02/25 10:55:37 UTC

[sling-org-apache-sling-models-impl] branch master updated: SLING-11133: cache models by picked implementation type (#35)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 031c0eb  SLING-11133: cache models by picked implementation type (#35)
031c0eb is described below

commit 031c0ebd71bbc03ab7821fe6acc9f08241a90641
Author: Dirk Rudolph <dr...@adobe.com>
AuthorDate: Fri Feb 25 11:55:31 2022 +0100

    SLING-11133: cache models by picked implementation type (#35)
---
 .../sling/models/impl/ModelAdapterFactory.java     |  6 +-
 .../org/apache/sling/models/impl/CachingTest.java  | 66 +++++++++++++++++++---
 .../classes/CachedModelWithAdapterTypes12.java     | 32 +++++++++++
 .../classes/CachedModelWithAdapterTypes23.java     | 34 +++++++++++
 .../models/testmodels/interfaces/AdapterType1.java | 20 +++++++
 .../models/testmodels/interfaces/AdapterType2.java | 20 +++++++
 .../models/testmodels/interfaces/AdapterType3.java | 20 +++++++
 7 files changed, 187 insertions(+), 11 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..b3b90ff 100644
--- a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
+++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
@@ -387,7 +387,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
 
             if (modelAnnotation.cache()) {
                 adaptableCache = getOrCreateCache(adaptable);
-                SoftReference<Object> softReference = adaptableCache.get(requestedType);
+                SoftReference<Object> softReference = adaptableCache.get(modelClass.getType());
                 if (softReference != null) {
                     ModelType cachedObject = (ModelType) softReference.get();
                     if (cachedObject != null) {
@@ -416,7 +416,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));
+                            adaptableCache.put(modelClass.getType(), new SoftReference<>(model));
                         }
 
                         result = new Result<>(model);
@@ -428,7 +428,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()));
+                            adaptableCache.put(modelClass.getType(), new SoftReference<>(result.getValue()));
                         }
                     } catch (Exception e) {
                         String msg = String.format("Unable to create model %s", modelClass.getType());
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..e02eb44 100644
--- a/src/test/java/org/apache/sling/models/impl/CachingTest.java
+++ b/src/test/java/org/apache/sling/models/impl/CachingTest.java
@@ -32,9 +32,17 @@ import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
 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.spi.ImplementationPicker;
 import org.apache.sling.models.testmodels.classes.CachedModel;
+import org.apache.sling.models.testmodels.classes.CachedModelWithAdapterTypes12;
+import org.apache.sling.models.testmodels.classes.CachedModelWithAdapterTypes23;
 import org.apache.sling.models.testmodels.classes.UncachedModel;
+import org.apache.sling.models.testmodels.interfaces.AdapterType1;
+import org.apache.sling.models.testmodels.interfaces.AdapterType2;
+import org.apache.sling.models.testmodels.interfaces.AdapterType3;
 import org.apache.sling.servlethelpers.MockSlingHttpServletRequest;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -60,8 +68,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.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(
+            CachedModelWithAdapterTypes12.class,
+            CachedModelWithAdapterTypes12.class, AdapterType1.class, AdapterType2.class);
+        factory.adapterImplementations.addAll(
+            CachedModelWithAdapterTypes23.class,
+            CachedModelWithAdapterTypes23.class, AdapterType2.class, AdapterType3.class);
 
         when(request.getAttribute("testValue")).thenReturn("test");
         requestWrapper = new SlingHttpServletRequestWrapper(request);
@@ -120,8 +137,10 @@ public class CachingTest {
 
     @Test
     public void testCachedInterface() {
-        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(request, org.apache.sling.models.testmodels.interfaces.CachedModel.class);
+        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(request,
+            org.apache.sling.models.testmodels.interfaces.CachedModel.class);
 
         assertSame(cached1, cached2);
         assertEquals("test", cached1.getTestValue());
@@ -132,8 +151,10 @@ public class CachingTest {
 
     @Test
     public void testNoCachedInterface() {
-        org.apache.sling.models.testmodels.interfaces.UncachedModel uncached1 = factory.getAdapter(request, org.apache.sling.models.testmodels.interfaces.UncachedModel.class);
-        org.apache.sling.models.testmodels.interfaces.UncachedModel uncached2 = factory.getAdapter(request, org.apache.sling.models.testmodels.interfaces.UncachedModel.class);
+        org.apache.sling.models.testmodels.interfaces.UncachedModel uncached1 = factory.getAdapter(request,
+            org.apache.sling.models.testmodels.interfaces.UncachedModel.class);
+        org.apache.sling.models.testmodels.interfaces.UncachedModel uncached2 = factory.getAdapter(request,
+            org.apache.sling.models.testmodels.interfaces.UncachedModel.class);
 
         assertNotSame(uncached1, uncached2);
         assertEquals("test", uncached1.getTestValue());
@@ -164,8 +185,10 @@ public class CachingTest {
 
     @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);
+        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);
 
         assertSame(cached1, cached2);
         assertEquals("test", cached1.getTestValue());
@@ -173,5 +196,32 @@ public class CachingTest {
 
         verify(request, times(1)).getAttribute("testValue");
     }
+
+    @Test
+    public void testCachedModelWithAdapterTypes() {
+        // test 2 model implementations that share a common adapter type, with an implementation picker that selects exactly one of the
+        // implementations for the common adapter type. verify that the models are cached accordingly
+        factory.bindImplementationPicker(
+            (adapterType, impls, adaptable) -> {
+                if (AdapterType1.class.equals(adapterType)) {
+                    return CachedModelWithAdapterTypes12.class;
+                } else if (AdapterType2.class.equals(adapterType) || AdapterType3.class.equals(adapterType)) {
+                    return CachedModelWithAdapterTypes23.class;
+                } else {
+                    return null;
+                }
+            },
+            new ServicePropertiesMap(2, 0));
+
+        CachedModelWithAdapterTypes12 byImpl12 = factory.getAdapter(request, CachedModelWithAdapterTypes12.class);
+        CachedModelWithAdapterTypes23 byImpl23 = factory.getAdapter(request, CachedModelWithAdapterTypes23.class);
+        AdapterType1 byAdapterType1 = factory.getAdapter(request, AdapterType1.class);
+        AdapterType2 byAdapterType2 = factory.getAdapter(request, AdapterType2.class);
+        AdapterType3 byAdapterType3 = factory.getAdapter(request, AdapterType3.class);
+
+        assertSame(byImpl12, byAdapterType1);
+        assertSame(byImpl23, byAdapterType2);
+        assertSame(byImpl23, byAdapterType3);
+    }
 }
 
diff --git a/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithAdapterTypes12.java b/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithAdapterTypes12.java
new file mode 100644
index 0000000..fbcef3f
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithAdapterTypes12.java
@@ -0,0 +1,32 @@
+/*
+ * 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.models.annotations.Model;
+import org.apache.sling.models.testmodels.interfaces.AdapterType1;
+import org.apache.sling.models.testmodels.interfaces.AdapterType2;
+
+@Model(
+    adaptables = SlingHttpServletRequest.class,
+    adapters = { AdapterType1.class, AdapterType2.class },
+    cache = true
+)
+public class CachedModelWithAdapterTypes12 implements AdapterType1, AdapterType2 {
+
+
+}
diff --git a/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithAdapterTypes23.java b/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithAdapterTypes23.java
new file mode 100644
index 0000000..3222b5c
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/testmodels/classes/CachedModelWithAdapterTypes23.java
@@ -0,0 +1,34 @@
+/*
+ * 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.AdapterType1;
+import org.apache.sling.models.testmodels.interfaces.AdapterType2;
+import org.apache.sling.models.testmodels.interfaces.AdapterType3;
+
+@Model(
+    adaptables = SlingHttpServletRequest.class,
+    adapters = { AdapterType2.class, AdapterType3.class },
+    cache = true
+)
+public class CachedModelWithAdapterTypes23 implements AdapterType2, AdapterType3 {
+
+
+}
diff --git a/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType1.java b/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType1.java
new file mode 100644
index 0000000..74ba097
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType1.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 AdapterType1 {
+}
diff --git a/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType2.java b/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType2.java
new file mode 100644
index 0000000..ccd9d75
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType2.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 AdapterType2 {
+}
diff --git a/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType3.java b/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType3.java
new file mode 100644
index 0000000..c629012
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/testmodels/interfaces/AdapterType3.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 AdapterType3 {
+}