You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/04/19 09:05:08 UTC

[isis] branch master updated: ISIS-2618: use a shared post-construct method cache that is also thread-safe

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

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 64534e5  ISIS-2618: use a shared post-construct method cache that is also thread-safe
64534e5 is described below

commit 64534e55e8526526699b7f1a26459f783a2e9eba
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Apr 19 11:04:49 2021 +0200

    ISIS-2618: use a shared post-construct method cache that is also
    thread-safe
---
 .../DomainObjectAnnotationFacetFactory.java        | 12 +++++----
 .../recreatable/RecreatableObjectFacetFactory.java | 13 +++++-----
 .../core/metamodel/methods/MethodByClassMap.java   | 30 ++++++++++++++++++++++
 .../core/metamodel/methods/MethodFinderUtils.java  |  2 +-
 .../dflt/ProgrammingModelFacetsJava8.java          |  9 +++++--
 .../metamodel/facets/MethodFinderUtilsTest.java    | 15 ++++++-----
 ...oicesFacetFromBoundedAnnotationFactoryTest.java |  3 ++-
 .../DomainObjectAnnotationFacetFactoryTest.java    |  3 ++-
 .../ObjectTypeAnnotationFacetFactoryTest.java      |  3 ++-
 .../RecreatableObjectFacetFactoryTest.java         |  3 ++-
 10 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index 76dfe0f..9f2d592 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -20,7 +20,6 @@ package org.apache.isis.core.metamodel.facets.object.domainobject;
 
 import java.lang.reflect.Method;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -41,7 +40,6 @@ import org.apache.isis.applib.events.lifecycle.ObjectUpdatedEvent;
 import org.apache.isis.applib.events.lifecycle.ObjectUpdatingEvent;
 import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.mixins.system.HasInteractionId;
-import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Multimaps;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -72,6 +70,7 @@ import org.apache.isis.core.metamodel.facets.object.domainobject.recreatable.Rec
 import org.apache.isis.core.metamodel.facets.object.mixin.MetaModelValidatorForMixinTypes;
 import org.apache.isis.core.metamodel.facets.object.mixin.MixinFacetForDomainObjectAnnotation;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.metamodel.methods.MethodByClassMap;
 import org.apache.isis.core.metamodel.methods.MethodFinderUtils;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -81,6 +80,7 @@ import org.apache.isis.core.metamodel.util.EventUtil;
 
 import static org.apache.isis.commons.internal.base._NullSafe.stream;
 
+import lombok.NonNull;
 import lombok.val;
 
 public class DomainObjectAnnotationFacetFactory 
@@ -93,8 +93,10 @@ implements
     private final MetaModelValidatorForMixinTypes mixinTypeValidator =
             new MetaModelValidatorForMixinTypes("@DomainObject#nature=MIXIN");
 
-    public DomainObjectAnnotationFacetFactory() {
+    public DomainObjectAnnotationFacetFactory(
+            final @NonNull MethodByClassMap postConstructMethodsCache) {
         super(FeatureType.OBJECTS_ONLY);
+        this.postConstructMethodsCache = postConstructMethodsCache;
     }
 
     @Override
@@ -535,11 +537,11 @@ implements
 
     // //////////////////////////////////////
 
-    private final Map<Class<?>, Optional<Method>> postConstructMethods = _Maps.newHashMap();
+    private final MethodByClassMap postConstructMethodsCache;
 
     @Override
     public Method postConstructMethodFor(final Object pojo) {
-        return MethodFinderUtils.findAnnotatedMethod(pojo, PostConstruct.class, postConstructMethods);
+        return MethodFinderUtils.findAnnotatedMethod(pojo, PostConstruct.class, postConstructMethodsCache);
     }
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
index 4488a40..244fc48 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
@@ -20,15 +20,12 @@
 package org.apache.isis.core.metamodel.facets.object.recreatable;
 
 import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Optional;
 
 import javax.annotation.PostConstruct;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.isis.applib.RecreatableDomainObject;
 import org.apache.isis.applib.ViewModel;
-import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
@@ -37,10 +34,12 @@ import org.apache.isis.core.metamodel.facets.Annotations;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.PostConstructMethodCache;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.metamodel.methods.MethodByClassMap;
 import org.apache.isis.core.metamodel.methods.MethodFinderUtils;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.specloader.validator.ValidationFailure;
 
+import lombok.NonNull;
 import lombok.val;
 
 public class RecreatableObjectFacetFactory
@@ -49,8 +48,10 @@ implements
     MetaModelRefiner, 
     PostConstructMethodCache {
 
-    public RecreatableObjectFacetFactory() {
+    public RecreatableObjectFacetFactory(
+            final @NonNull MethodByClassMap postConstructMethodsCache) {
         super(FeatureType.OBJECTS_ONLY);
+        this.postConstructMethodsCache = postConstructMethodsCache;
     }
 
     /**
@@ -121,11 +122,11 @@ implements
 
     // //////////////////////////////////////
 
-    private final Map<Class<?>, Optional<Method>> postConstructMethods = _Maps.newHashMap();
+    private final MethodByClassMap postConstructMethodsCache;
 
     @Override
     public Method postConstructMethodFor(final Object pojo) {
-        return MethodFinderUtils.findAnnotatedMethod(pojo, PostConstruct.class, postConstructMethods);
+        return MethodFinderUtils.findAnnotatedMethod(pojo, PostConstruct.class, postConstructMethodsCache);
     }
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodByClassMap.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodByClassMap.java
new file mode 100644
index 0000000..978bbc3
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodByClassMap.java
@@ -0,0 +1,30 @@
+/*
+ *  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.isis.core.metamodel.methods;
+
+import java.lang.reflect.Method;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+public final class MethodByClassMap 
+extends ConcurrentHashMap<Class<?>, Optional<Method>> {
+
+    private static final long serialVersionUID = 1L;
+    
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderUtils.java
index f97c3f5..a4e1a37 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderUtils.java
@@ -190,7 +190,7 @@ public final class MethodFinderUtils {
     public static Method findAnnotatedMethod(
             final Object pojo,
             final Class<? extends Annotation> annotationClass,
-            final Map<Class<?>, Optional<Method>> methods) {
+            final MethodByClassMap methods) {
 
         val clz = pojo.getClass();
         val annotatedMethodIfAny = 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java
index e8dbd98..8f55ad8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java
@@ -140,11 +140,14 @@ import org.apache.isis.core.metamodel.facets.value.timestampsql.JavaSqlTimeStamp
 import org.apache.isis.core.metamodel.facets.value.url.URLValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.uuid.UUIDValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.methods.MemberSupportAnnotationEnforcesSupportingMethodValidator;
+import org.apache.isis.core.metamodel.methods.MethodByClassMap;
 import org.apache.isis.core.metamodel.methods.OrphanedSupportingMethodValidator;
 import org.apache.isis.core.metamodel.postprocessors.param.DeriveFacetsPostProcessor;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract;
 import org.apache.isis.core.metamodel.services.title.TitlesAndTranslationsValidator;
 
+import lombok.val;
+
 public final class ProgrammingModelFacetsJava8 extends ProgrammingModelAbstract {
 
     public ProgrammingModelFacetsJava8(ServiceInjector serviceInjector) {
@@ -232,11 +235,13 @@ public final class ProgrammingModelFacetsJava8 extends ProgrammingModelAbstract
         addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, HiddenObjectFacetViaMethodFactory.class);
         addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, DisabledObjectFacetViaMethodFactory.class);
 
-        addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, RecreatableObjectFacetFactory.class);
+        val postConstructMethodsCache = new MethodByClassMap();
+        
+        addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new RecreatableObjectFacetFactory(postConstructMethodsCache));
         addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, JaxbFacetFactory.class);
 
         // must come after RecreatableObjectFacetFactory
-        addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, DomainObjectAnnotationFacetFactory.class);
+        addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new DomainObjectAnnotationFacetFactory(postConstructMethodsCache));
 
         // must come after the property/collection accessor+mutator facet factories
         addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, ActionAnnotationFacetFactory.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/MethodFinderUtilsTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/MethodFinderUtilsTest.java
index 96c53fb..0c57bc7 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/MethodFinderUtilsTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/MethodFinderUtilsTest.java
@@ -19,7 +19,6 @@
 package org.apache.isis.core.metamodel.facets;
 
 import java.lang.reflect.Method;
-import java.util.Map;
 import java.util.Optional;
 
 import javax.annotation.PostConstruct;
@@ -31,9 +30,11 @@ import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.core.metamodel.methods.MethodByClassMap;
 import org.apache.isis.core.metamodel.methods.MethodFinderUtils;
 
+import lombok.val;
+
 public class MethodFinderUtilsTest {
 
     public static class NoPostConstruct {
@@ -47,8 +48,9 @@ public class MethodFinderUtilsTest {
     @Test
     public void whenExists() throws Exception {
 
-        final Map<Class<?>, Optional<Method>> cache = _Maps.newHashMap();
-        final Method method = MethodFinderUtils.findAnnotatedMethod(new WithPostConstruct(), PostConstruct.class, cache);
+        val cache = new MethodByClassMap();
+        final Method method = MethodFinderUtils
+                .findAnnotatedMethod(new WithPostConstruct(), PostConstruct.class, cache );
 
         assertThat(method, is(not(nullValue())));
         final Optional<Method> actual = cache.get(WithPostConstruct.class);
@@ -60,8 +62,9 @@ public class MethodFinderUtilsTest {
     @Test
     public void whenDoesNotExist() throws Exception {
 
-        final Map<Class<?>, Optional<Method>> cache = _Maps.newHashMap();
-        final Method method = MethodFinderUtils.findAnnotatedMethod(new NoPostConstruct(), PostConstruct.class, cache);
+        val cache = new MethodByClassMap();
+        final Method method = MethodFinderUtils
+                .findAnnotatedMethod(new NoPostConstruct(), PostConstruct.class, cache);
 
         assertThat(method, is(nullValue()));
         final Optional<Method> actual = cache.get(NoPostConstruct.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ChoicesFacetFromBoundedAnnotationFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ChoicesFacetFromBoundedAnnotationFactoryTest.java
index 16065fc..d69019d 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ChoicesFacetFromBoundedAnnotationFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ChoicesFacetFromBoundedAnnotationFactoryTest.java
@@ -26,6 +26,7 @@ import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryTest;
 import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
 import org.apache.isis.core.metamodel.facets.object.choices.ChoicesFacetFromBoundedAbstract;
 import org.apache.isis.core.metamodel.facets.objectvalue.choices.ChoicesFacet;
+import org.apache.isis.core.metamodel.methods.MethodByClassMap;
 
 public class ChoicesFacetFromBoundedAnnotationFactoryTest extends AbstractFacetFactoryTest {
 
@@ -35,7 +36,7 @@ public class ChoicesFacetFromBoundedAnnotationFactoryTest extends AbstractFacetF
     protected void setUp() throws Exception {
         super.setUp();
 
-        facetFactory = new DomainObjectAnnotationFacetFactory();
+        facetFactory = new DomainObjectAnnotationFacetFactory(new MethodByClassMap());
     }
 
     @Override
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
index e799160..b915730 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
@@ -58,6 +58,7 @@ import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFac
 import org.apache.isis.core.metamodel.facets.object.publish.entitychange.EntityChangePublishingFacet;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.choices.ChoicesFacet;
+import org.apache.isis.core.metamodel.methods.MethodByClassMap;
 
 import lombok.val;
 
@@ -67,7 +68,7 @@ public class DomainObjectAnnotationFacetFactoryTest extends AbstractFacetFactory
 
     @Before
     public void setUp() throws Exception {
-        facetFactory = new DomainObjectAnnotationFacetFactory();
+        facetFactory = new DomainObjectAnnotationFacetFactory(new MethodByClassMap());
         facetFactory.setMetaModelContext(super.metaModelContext);
     }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
index 3b50a6c..634d467 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
@@ -32,6 +32,7 @@ import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.core.metamodel.facets.ObjectSpecIdFacetFactory.ProcessObjectSpecIdContext;
 import org.apache.isis.core.metamodel.facets.object.domainobject.objectspecid.ObjectSpecIdFacetForDomainObjectAnnotation;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
+import org.apache.isis.core.metamodel.methods.MethodByClassMap;
 
 public class ObjectTypeAnnotationFacetFactoryTest extends AbstractFacetFactoryJUnit4TestCase {
 
@@ -39,7 +40,7 @@ public class ObjectTypeAnnotationFacetFactoryTest extends AbstractFacetFactoryJU
 
     @Before
     public void setUp() throws Exception {
-        facetFactory = new DomainObjectAnnotationFacetFactory();
+        facetFactory = new DomainObjectAnnotationFacetFactory(new MethodByClassMap());
     }
 
     @Test
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactoryTest.java
index 296f711..99c5305 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactoryTest.java
@@ -24,6 +24,7 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryTest;
 import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.metamodel.methods.MethodByClassMap;
 
 public class RecreatableObjectFacetFactoryTest extends AbstractFacetFactoryTest {
 
@@ -33,7 +34,7 @@ public class RecreatableObjectFacetFactoryTest extends AbstractFacetFactoryTest
     protected void setUp() throws Exception {
         super.setUp();
 
-        facetFactory = new RecreatableObjectFacetFactory();
+        facetFactory = new RecreatableObjectFacetFactory(new MethodByClassMap());
     }
 
     @Override