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 <[email protected]> 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 { +}
