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/05/03 16:06:25 UTC

[isis] branch master updated: ISIS-2641: a bit of SpecLoader housekeeping

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 3f9baa3  ISIS-2641: a bit of SpecLoader housekeeping
3f9baa3 is described below

commit 3f9baa3435295e316e27bbc228e768878eac1a27
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon May 3 18:06:07 2021 +0200

    ISIS-2641: a bit of SpecLoader housekeeping
---
 .../org/apache/isis/commons/collections/Can.java   | 13 ++++
 .../apache/isis/commons/collections/Can_Empty.java |  5 ++
 .../isis/core/metamodel/spec/Hierarchical.java     |  6 +-
 .../core/metamodel/spec/feature/ObjectAction.java  |  2 -
 .../specimpl/ObjectSpecificationAbstract.java      | 76 ++++++++--------------
 .../testspec/ObjectSpecificationStub.java          | 12 ++--
 6 files changed, 53 insertions(+), 61 deletions(-)

diff --git a/commons/src/main/java/org/apache/isis/commons/collections/Can.java b/commons/src/main/java/org/apache/isis/commons/collections/Can.java
index 1790538..30d27b4 100644
--- a/commons/src/main/java/org/apache/isis/commons/collections/Can.java
+++ b/commons/src/main/java/org/apache/isis/commons/collections/Can.java
@@ -487,6 +487,19 @@ extends Iterable<T>, Comparable<Can<T>>, Serializable {
     // -- MANIPULATION
     
     Can<T> add(T element);
+    
+    /**
+     * Adds the specified element to the list if it is not already present.  
+     * @param element
+     * @return same or new instance
+     */
+    default Can<T> addUnique(@NonNull T element) {
+        if(contains(element)) {
+            return this;
+        }
+        return add(element);
+    }
+   
     Can<T> addAll(Can<T> other);
     
     /**
diff --git a/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java b/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
index 304e839..1bf8c6a 100644
--- a/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
+++ b/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
@@ -135,6 +135,11 @@ final class Can_Empty<T> implements Can<T> {
     }
     
     @Override
+    public Can<T> addUnique(@NonNull T element) {
+        return Can.ofSingleton(element);
+    }
+    
+    @Override
     public Can<T> addAll(@NonNull Can<T> other) {
         return other;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Hierarchical.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Hierarchical.java
index c30ac93..74e5fa5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Hierarchical.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Hierarchical.java
@@ -19,7 +19,7 @@
 
 package org.apache.isis.core.metamodel.spec;
 
-import java.util.Collection;
+import org.apache.isis.commons.collections.Can;
 
 public interface Hierarchical {
 
@@ -33,7 +33,7 @@ public interface Hierarchical {
      * Get the set of specifications for all the interfaces that the class
      * represented by this specification implements.
      */
-    Collection<ObjectSpecification> interfaces();
+    Can<ObjectSpecification> interfaces();
 
     /**
      * Determines if this specification represents the same specification, or a
@@ -55,7 +55,7 @@ public interface Hierarchical {
      * Get the set of specifications for the subclasses of the class
      * represented by this specification
      */
-    Collection<ObjectSpecification> subclasses(Depth depth);
+    Can<ObjectSpecification> subclasses(Depth depth);
 
     /**
      * Get the specification for this specification's class's superclass.
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
index 88a0e95..5a42745 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
@@ -207,8 +207,6 @@ public interface ObjectAction extends ObjectMember {
     /**
      * Returns a {@link Stream} of {@link ObjectActionParameter} as per
      * {@link #getParameters()}.
-     *
-     * @return
      */
     default Stream<ObjectActionParameter> streamParameters() {
         return getParameters().stream();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index 5290521..a51fdb9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -21,7 +21,6 @@ package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
@@ -35,6 +34,7 @@ import javax.enterprise.inject.Vetoed;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.metamodel.BeanSort;
+import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.base._NullSafe;
@@ -96,50 +96,41 @@ public abstract class ObjectSpecificationAbstract
 extends ObjectMemberContainer
 implements ObjectSpecification {
 
-
+    /** 
+     * @implNote thread-safe
+     */
     private static class Subclasses {
-        private final Set<ObjectSpecification> classes = _Sets.newConcurrentHashSet();
+        
+        // List performs better compared to a Set, when the number of elements is low
+        private Can<ObjectSpecification> classes = Can.empty();
+        private final Object $lock = new Object();
 
         public void addSubclass(final ObjectSpecification subclass) {
-            classes.add(subclass);
+            synchronized($lock) {
+                classes = classes.addUnique(subclass);    
+            }
         }
 
         public boolean hasSubclasses() {
-            return !classes.isEmpty();
+            synchronized($lock) {
+                return classes.isNotEmpty();
+            }
         }
 
-        public Collection<ObjectSpecification> toCollection() {
-            return Collections.unmodifiableSet(classes); //just a view, thread-safe only if classes is thread-safe
+        public Can<ObjectSpecification> snapshot() {
+            synchronized($lock) {
+                return classes;
+            }
         }
     }
-
-//XXX drop-in for the above, rather a question which performs better 
-//    private static class Subclasses {
-//        private final List<ObjectSpecification> classes = new ArrayList<>();
-//
-//        public void addSubclass(final ObjectSpecification subclass) {
-//            if(classes.contains(subclass)) {
-//                return;
-//            }
-//            classes.add(subclass);
-//        }
-//
-//        public boolean hasSubclasses() {
-//            return !classes.isEmpty();
-//        }
-//
-//        public List<ObjectSpecification> toCollection() {
-//            return Collections.unmodifiableList(classes);
-//        }
-//    }
     
     
-    // -- fields
-
-    //protected final ServiceInjector servicesInjector;
+    // -- FIELDS
 
     private final PostProcessor postProcessor;
     private final FacetProcessor facetProcessor;
+    
+    @Getter private final BeanSort beanSort;
 
     // -- ASSOCIATIONS
     
@@ -169,8 +160,8 @@ implements ObjectSpecification {
     private final List<ObjectSpecification> interfaces = _Lists.newArrayList();
     
     // defensive immutable lazy copy of interfaces
-    private final _Lazy<List<ObjectSpecification>> unmodifiableInterfaces = 
-            _Lazy.threadSafe(()->Collections.unmodifiableList(new ArrayList<>(interfaces)));
+    private final _Lazy<Can<ObjectSpecification>> unmodifiableInterfaces = 
+            _Lazy.threadSafe(()->Can.ofCollection(interfaces));
     
     
     
@@ -627,14 +618,14 @@ implements ObjectSpecification {
     }
 
     @Override
-    public Collection<ObjectSpecification> interfaces() {
+    public Can<ObjectSpecification> interfaces() {
         return unmodifiableInterfaces.get();
     }
 
     @Override
-    public Collection<ObjectSpecification> subclasses(final Depth depth) {
+    public Can<ObjectSpecification> subclasses(final Depth depth) {
         if (depth == Depth.DIRECT) {
-            return directSubclasses.toCollection();
+            return directSubclasses.snapshot();
         }
 
         // depth == Depth.TRANSITIVE)
@@ -642,7 +633,7 @@ implements ObjectSpecification {
             transitiveSubclasses = transitiveSubclasses();
         }
 
-        return transitiveSubclasses.toCollection();
+        return transitiveSubclasses.snapshot();
     }
 
     private synchronized Subclasses transitiveSubclasses() {
@@ -866,19 +857,6 @@ implements ObjectSpecification {
         return new ObjectValidityContext(targetAdapter, getIdentifier(), interactionInitiatedBy);
     }
 
-    //@Setter(AccessLevel.PROTECTED)
-    @Getter
-    private final BeanSort beanSort;
-
-//    @Override
-//    public BeanSort getBeanSort() {
-//        if(beanSort==null) {
-//            setBeanSort(sortOf(this));
-//        }
-//        return beanSort;
-//    }
-
-
     // -- convenience isXxx (looked up from facets)
     @Override
     public boolean isImmutable() {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
index 06f9e04..c4d97c3 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
@@ -20,16 +20,15 @@
 package org.apache.isis.core.metamodel.testspec;
 
 import java.lang.reflect.Method;
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
-import java.util.Set;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.metamodel.BeanSort;
+import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.consent.Consent;
@@ -59,7 +58,6 @@ implements ObjectSpecification {
 
     private ObjectAction action;
     public List<ObjectAssociation> fields = _Lists.newArrayList();
-    private Set<ObjectSpecification> subclasses = Collections.emptySet();
     private String title;
     /**
      * lazily derived, see {@link #getLogicalType()} 
@@ -216,8 +214,8 @@ implements ObjectSpecification {
     }
 
     @Override
-    public List<ObjectSpecification> interfaces() {
-        return Collections.emptyList();
+    public Can<ObjectSpecification> interfaces() {
+        return Can.empty();
     }
 
     @Override
@@ -241,8 +239,8 @@ implements ObjectSpecification {
     }
 
     @Override
-    public Set<ObjectSpecification> subclasses(final Depth depth) {
-        return subclasses;
+    public Can<ObjectSpecification> subclasses(final Depth depth) {
+        return Can.empty();
     }
 
     @Override