This is an automated email from the ASF dual-hosted git repository. diru pushed a commit to branch issue/SLING-11133 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git
commit 6bab3139ab6be2bd6b3b195067cb5e1df29705dc Author: Dirk Rudolph <[email protected]> AuthorDate: Thu Feb 10 13:53:41 2022 +0100 SLING-11133: cache models by picked implementation type --- .../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 { +}
