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/02 09:57:45 UTC

[isis] branch master updated: ISIS-2640: add new BeanSort: VETOED

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 9f25f84  ISIS-2640: add new BeanSort: VETOED
9f25f84 is described below

commit 9f25f8438f37a9ff5db8d2e77c83eb837e560eb5
Author: ahuber@apache.org <ah...@luna>
AuthorDate: Sun May 2 11:57:27 2021 +0200

    ISIS-2640: add new BeanSort: VETOED
    
    also inspect types for @Profile annotations
---
 .../isis/applib/services/metamodel/BeanSort.java   | 14 ++++++++-
 .../IsisBeanFactoryPostProcessorForSpring.java     | 30 ++++++++++++++-----
 .../core/config/beans/IsisBeanTypeClassifier.java  | 12 +++++++-
 .../config/beans/IsisBeanTypeClassifierImpl.java   | 34 ++++++++++++++++------
 .../config/beans/IsisBeanTypeRegistryDefault.java  |  1 +
 .../beans/IsisComponentScanInterceptorImpl.java    |  1 -
 .../ApplicationFeatureRepositoryDefault.java       | 13 +++++----
 7 files changed, 81 insertions(+), 24 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/BeanSort.java b/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/BeanSort.java
index d2e88e0..aff3ce2 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/BeanSort.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/BeanSort.java
@@ -18,6 +18,10 @@
  */
 package org.apache.isis.applib.services.metamodel;
 
+import javax.enterprise.inject.Vetoed;
+
+import org.springframework.context.annotation.Profile;
+
 /**
  * Top level object classification.
  * 
@@ -66,6 +70,10 @@ public enum BeanSort {
      * Container of objects.
      */
     COLLECTION,
+    /**
+     * Type must not be added to the meta-model, eg. by means of {@link Vetoed} or {@link Profile} 
+     */
+    VETOED, 
     UNKNOWN;
 
     // -- SIMPLE PREDICATES
@@ -94,6 +102,9 @@ public enum BeanSort {
         return this == ENTITY;
     }
     
+    public boolean isVetoed() {
+        return this == VETOED;
+    }
     
     public boolean isUnknown() {
         return this == UNKNOWN;
@@ -103,7 +114,8 @@ public enum BeanSort {
 
     public boolean isToBeIntrospected() {
 
-        if(isUnknown()) {
+        if(isVetoed()
+                || isUnknown()) {
             return false;
         }
         if(this == MANAGED_BEAN_NOT_CONTRIBUTING) {
diff --git a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanFactoryPostProcessorForSpring.java b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanFactoryPostProcessorForSpring.java
index 40a88ef..efab140 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanFactoryPostProcessorForSpring.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanFactoryPostProcessorForSpring.java
@@ -18,12 +18,16 @@
  */
 package org.apache.isis.core.config.beans;
 
+import java.util.Objects;
+
 import javax.inject.Named;
 
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Import;
 import org.springframework.stereotype.Component;
@@ -54,17 +58,27 @@ import lombok.extern.log4j.Log4j2;
 })
 @Log4j2
 public class IsisBeanFactoryPostProcessorForSpring
-implements BeanFactoryPostProcessor {
+implements 
+    BeanFactoryPostProcessor,
+    ApplicationContextAware {
 
-    private final IsisBeanTypeClassifier isisBeanTypeClassifier = 
-            IsisBeanTypeClassifier.createInstance();
-    
-    private final IsisComponentScanInterceptor isisComponentScanInterceptor = 
-            IsisComponentScanInterceptor.createInstance(isisBeanTypeClassifier);
+    private IsisBeanTypeClassifier isisBeanTypeClassifier;
+    private IsisComponentScanInterceptor isisComponentScanInterceptor; 
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        val environment = applicationContext.getEnvironment();
+        isisBeanTypeClassifier = IsisBeanTypeClassifier.createInstance(environment);
+        isisComponentScanInterceptor = IsisComponentScanInterceptor.createInstance(isisBeanTypeClassifier);
+    }
     
     @Override
     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
         
+        // make sure we have an applicationContext before calling post processing
+        Objects.requireNonNull(isisBeanTypeClassifier, 
+                "postProcessBeanFactory() called before app-ctx was made available"); 
+        
         val registry = (BeanDefinitionRegistry) beanFactory;
         
         for (String beanDefinitionName : registry.getBeanDefinitionNames()) {
@@ -106,7 +120,9 @@ implements BeanFactoryPostProcessor {
     
     @Bean
     public IsisBeanTypeClassifier getIsisBeanTypeClassifier() {
-        return isisBeanTypeClassifier;
+        return isisBeanTypeClassifier!=null
+                ? isisBeanTypeClassifier
+                : (isisBeanTypeClassifier = IsisBeanTypeClassifier.createInstance()); // JUnit support
     }
     
     @Bean("isis.bean-meta-data")
diff --git a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifier.java b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifier.java
index 8321609..fb8e43d 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifier.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifier.java
@@ -18,10 +18,13 @@
  */
 package org.apache.isis.core.config.beans;
 
+import org.springframework.core.env.Environment;
+
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.context._Plugin;
 
+import lombok.NonNull;
 import lombok.Value;
 
 /**
@@ -41,8 +44,15 @@ public interface IsisBeanTypeClassifier {
 
     // -- FACTORY
     
+    /**
+     * in support of JUnit testing
+     */
     static IsisBeanTypeClassifier createInstance() {
-        return new IsisBeanTypeClassifierImpl();
+        return new IsisBeanTypeClassifierImpl(Can.empty());
+    }
+    
+    static IsisBeanTypeClassifier createInstance(final @NonNull Environment environment) {
+        return new IsisBeanTypeClassifierImpl(Can.ofArray(environment.getActiveProfiles()));
     }
     
     // -- LOOKUP
diff --git a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifierImpl.java b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifierImpl.java
index 148a737..770e732 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifierImpl.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifierImpl.java
@@ -26,35 +26,45 @@ import javax.enterprise.inject.Vetoed;
 import javax.persistence.Entity;
 import javax.persistence.Table;
 
+import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
 
-import static org.apache.isis.commons.internal.base._With.requires;
 import static org.apache.isis.commons.internal.reflection._Annotations.findNearestAnnotation;
 
 import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-@NoArgsConstructor(access = AccessLevel.PACKAGE) 
+@RequiredArgsConstructor(access = AccessLevel.PACKAGE) 
 //@Log4j2
 final class IsisBeanTypeClassifierImpl 
 implements IsisBeanTypeClassifier {
 
+    private final Can<String> activeProfiles;
     private final Can<IsisBeanTypeClassifier> classifierPlugins = IsisBeanTypeClassifier.get();
     
     @Override
-    public BeanClassification classify(Class<?> type) {
+    public BeanClassification classify(final @NonNull Class<?> type) {
 
-        requires(type, "type");
-        
-        if(findNearestAnnotation(type, Vetoed.class).isPresent()) {
-            return BeanClassification.selfManaged(BeanSort.UNKNOWN); // reject
+        if(findNearestAnnotation(type, Vetoed.class).isPresent()
+                || findNearestAnnotation(type, Programmatic.class).isPresent()) {
+            return BeanClassification.selfManaged(BeanSort.VETOED); // reject
+        }
+
+        val profiles = Can.ofArray(findNearestAnnotation(type, Profile.class)
+                .map(Profile::value)
+                .orElse(null));
+        if(profiles.isNotEmpty()
+                && !profiles.stream().anyMatch(this::isProfileActive)) {
+            return BeanClassification.selfManaged(BeanSort.VETOED); // reject
         }
 
         val aDomainService = findNearestAnnotation(type, DomainService.class);
@@ -161,6 +171,12 @@ implements IsisBeanTypeClassifier {
         }
         return null;
     }
-
+    
+    //XXX yet this is a naive implementation, not evaluating any expression logic like eg. @Profile("!dev")
+    //either we find a Spring Boot utility class that does this logic for us, or we make it clear with the 
+    //docs, that we have only limited support for the @Profile annotation
+    private boolean isProfileActive(final String profile) {
+        return activeProfiles.contains(profile);
+    }
 
 }
\ No newline at end of file
diff --git a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistryDefault.java b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistryDefault.java
index b50e859..17b3c87 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistryDefault.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistryDefault.java
@@ -108,6 +108,7 @@ public class IsisBeanTypeRegistryDefault implements IsisBeanTypeRegistry {
             case MANAGED_BEAN_NOT_CONTRIBUTING:
             case COLLECTION:
             case VALUE:
+            case VETOED:
             case UNKNOWN:
                 return;
             }    
diff --git a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisComponentScanInterceptorImpl.java b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisComponentScanInterceptorImpl.java
index 8dac5ae..bc8ef93 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisComponentScanInterceptorImpl.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisComponentScanInterceptorImpl.java
@@ -73,7 +73,6 @@ implements IsisComponentScanInterceptor {
     public void intercept(ScannedTypeMetaData typeMeta) {
         
         val classOrFailure = typeMeta.getUnderlyingClassOrFailure();
-        
         if(classOrFailure.isFailure()) {
             log.warn(classOrFailure.getFailure());
             return;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
index 2c5f4c2..ddf6d8e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
@@ -330,15 +330,18 @@ implements ApplicationFeatureRepository {
 
     protected boolean exclude(final ObjectSpecification spec) {
 
-        val excluded = spec.isMixin() || spec.isAbstract() ||
-                spec.getBeanSort().isUnknown() ||
-                isBuiltIn(spec) ||
-                isHidden(spec);
+        val excluded = spec.isMixin() 
+                || spec.isAbstract() 
+                || spec.getBeanSort().isVetoed()
+                || spec.getBeanSort().isUnknown() 
+                || isBuiltIn(spec) 
+                || isHidden(spec);
 
         if(excluded && log.isDebugEnabled()) {
-            log.debug("{} excluded because: abstract:{} unknown-sort:{} builtIn:{} hidden:{}",
+            log.debug("{} excluded because: abstract:{} vetoed:{} unknown-sort:{} builtIn:{} hidden:{}",
                     spec.getCorrespondingClass().getSimpleName(),
                     spec.isAbstract(),
+                    spec.getBeanSort().isVetoed(),
                     spec.getBeanSort().isUnknown(),
                     isBuiltIn(spec),
                     isHidden(spec)