You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2024/11/13 14:05:00 UTC
(causeway) branch 2297-beansort created (now 858fc3a791e)
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a change to branch 2297-beansort
in repository https://gitbox.apache.org/repos/asf/causeway.git
at 858fc3a791e CAUSEWAY-2297: rethinking BeanSort
This branch includes the following new commits:
new d990433d3d3 CAUSEWAY-2297: removes recently introduced BeanInternal
new 858fc3a791e CAUSEWAY-2297: rethinking BeanSort
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(causeway) 01/02: CAUSEWAY-2297: removes recently introduced BeanInternal
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 2297-beansort
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit d990433d3d3fb1bc4951cca5071eff227e59f029
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Nov 13 14:42:21 2024 +0100
CAUSEWAY-2297: removes recently introduced BeanInternal
---
.../causeway/applib/annotation/Programmatic.java | 2 +-
commons/src/main/java/module-info.java | 1 -
.../commons/internal/annotations/BeanInternal.java | 47 ----------------------
3 files changed, 1 insertion(+), 49 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Programmatic.java b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Programmatic.java
index 81d3bd633c8..2c175cb01d3 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Programmatic.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Programmatic.java
@@ -26,7 +26,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Indicates that an property, collection or action is to be called
+ * Indicates that a property, collection or action is to be called
* programmatically and should be ignored from the metamodel.
*
* <p>
diff --git a/commons/src/main/java/module-info.java b/commons/src/main/java/module-info.java
index d5b114ad131..88e426e4f8f 100644
--- a/commons/src/main/java/module-info.java
+++ b/commons/src/main/java/module-info.java
@@ -29,7 +29,6 @@ module org.apache.causeway.commons {
exports org.apache.causeway.commons.tabular;
// internals exported as well
exports org.apache.causeway.commons.internal;
- exports org.apache.causeway.commons.internal.annotations;
exports org.apache.causeway.commons.internal.assertions;
exports org.apache.causeway.commons.internal.base;
exports org.apache.causeway.commons.internal.binding;
diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/annotations/BeanInternal.java b/commons/src/main/java/org/apache/causeway/commons/internal/annotations/BeanInternal.java
deleted file mode 100644
index ca7e453477e..00000000000
--- a/commons/src/main/java/org/apache/causeway/commons/internal/annotations/BeanInternal.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.causeway.commons.internal.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.stereotype.Component;
-
-/**
- * Indicates that the class is a Spring managed bean,
- * intended for framework internal use.
- * <p>
- * The specification-loader should skip introspection of those types.
- * However, those types are considered to be injectable.
- * Hence the service registry should be aware of those.
- * <p>
- * {@link BeanInternal} intentionally is NOT meta annotated with {@link Component},
- * to specifically allow for the light weight use case
- * of instances being generated by {@link Bean} annotated factory methods.
- */
-@Inherited
-@Target({ ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface BeanInternal {
-
-}
(causeway) 02/02: CAUSEWAY-2297: rethinking BeanSort
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 2297-beansort
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 858fc3a791ee29fcdeb64e0e1b112948e6548e83
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Nov 13 15:04:45 2024 +0100
CAUSEWAY-2297: rethinking BeanSort
---
.../applib/services/metamodel/BeanSort.java | 165 ++++++++++++---------
.../commons/internal/reflection/_ClassCache.java | 62 +++++---
.../beans/CausewayBeanFactoryPostProcessor.java | 12 ++
.../core/config/beans/CausewayBeanMetaData.java | 76 +++++++++-
.../config/beans/CausewayBeanTypeClassifier.java | 42 +++---
.../config/beans/CausewayBeanTypeRegistry.java | 16 +-
.../config/beans/CausewayComponentCollector.java | 4 +-
.../progmodel/ProgrammingModelConstants.java | 39 +++--
.../_testing/MetaModelContext_forTesting.java | 2 +-
.../core/metamodel/commons/MetaModelVisitor.java | 2 +-
.../core/metamodel/context/MetaModelContext.java | 4 +-
.../metamodel/object/_ManagedObjectService.java | 9 ++
.../metamodel/objectmanager/ObjectManager.java | 4 +-
.../memento/ObjectDementifierFactory.java | 2 +-
.../postprocessors/all/SanityChecksValidator.java | 4 +-
.../param/ChoicesAndDefaultsPostProcessor.java | 4 +-
.../classsubstitutor/ClassSubstitutorAbstract.java | 2 +-
.../ClassSubstitutorForDomainObjects.java | 12 ++
.../wrapper/WrapperFactoryDefault.java | 2 +-
.../viewer/wicket/ui/pages/PageAbstract.java | 2 +-
20 files changed, 314 insertions(+), 151 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/metamodel/BeanSort.java b/api/applib/src/main/java/org/apache/causeway/applib/services/metamodel/BeanSort.java
index 21959d10f9f..2b507155b45 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/services/metamodel/BeanSort.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/services/metamodel/BeanSort.java
@@ -18,9 +18,14 @@
*/
package org.apache.causeway.applib.services.metamodel;
+import javax.imageio.spi.ServiceRegistry;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.apache.causeway.applib.annotation.Programmatic;
+import org.apache.causeway.applib.services.factory.FactoryService;
/**
* Top level object classification.
@@ -34,7 +39,7 @@ public enum BeanSort {
* Includes classes annotated with {@code @DomainObject}, when *not* associated
* with a persistence layer. <p> see also {@link #ENTITY}
*/
- VIEW_MODEL,
+ VIEW_MODEL(new BeanPolicy(BeanPolicy.INTROSPECTION | BeanPolicy.WRAPPING | BeanPolicy.ELEMENTTYPE | BeanPolicy.NON_SUBSTITUTABLE)),
/**
* Persistable object, associated with a persistence layer/context.
* <p>
@@ -42,110 +47,130 @@ public enum BeanSort {
* with a persistence layer. <p> see also {@link #VIEW_MODEL}
*
*/
- ENTITY,
+ ENTITY(new BeanPolicy(BeanPolicy.INTROSPECTION | BeanPolicy.WRAPPING | BeanPolicy.ELEMENTTYPE | BeanPolicy.NON_SUBSTITUTABLE)),
/**
* Injectable object, associated with a lifecycle context
* (application-scoped, request-scoped, ...).
* <p>
+ * In other words: Indicates that the class is a Spring managed bean,
+ * which IS also contributing to the UI or WEB API. Hence needs introspection.
+ * <p>
+ * The {@link ServiceRegistry} must be aware.
+ * <p>
* to be introspected: YES
*/
- MANAGED_BEAN_CONTRIBUTING,
+ MANAGED_BEAN_CONTRIBUTING(new BeanPolicy(BeanPolicy.INTROSPECTION | BeanPolicy.INJECTABLE | BeanPolicy.WRAPPING | BeanPolicy.NON_SUBSTITUTABLE)),
/**
* Injectable object, associated with a lifecycle context
* (application-scoped, request-scoped, ...).
* <p>
+ * In other words: Indicates that the class is a Spring managed bean,
+ * which is NOT contributing to the UI or WEB API. Hence not introspected.
+ * <p>
+ * The {@link ServiceRegistry} must be aware regardless.
+ * <p>
+ * This is also the fallback {@link BeanSort} for beans originating from {@link Bean} annotated factory methods,
+ * when the bean class itself declares no annotations.
+ * <p>
* to be introspected: NO
*/
- MANAGED_BEAN_NOT_CONTRIBUTING,
+ MANAGED_BEAN_NOT_CONTRIBUTING(new BeanPolicy(BeanPolicy.INJECTABLE | BeanPolicy.WRAPPING | BeanPolicy.NON_SUBSTITUTABLE)),
/**
* Object associated with an <i>entity</i>, <i>viewmodel</i> or <i>domain-service</i>
* to act as contributer of a single <i>domain-action</i> or
* <i>domain-property</i> or <i>domain-collection</i>.
*/
- MIXIN,
+ MIXIN(new BeanPolicy(BeanPolicy.INTROSPECTION | BeanPolicy.WRAPPING)),
/**
* Immutable, serializable object.
+ * Values (including enums) my have object support methods, hence needs introspection.
*/
- VALUE,
+ VALUE(new BeanPolicy(BeanPolicy.INTROSPECTION | BeanPolicy.ELEMENTTYPE)),
/**
* Container of objects.
*/
- COLLECTION,
+ COLLECTION(new BeanPolicy(0)),
/**
- * A non concrete type, that is a placeholder for a its concrete implementer.
+ * A non concrete type, that is a placeholder for a concrete implementer.
+ * <p>
+ * E.g. action return types or collection element types could be interfaces or abstract types
+ * (as discovered by reflection during introspection)
*/
- ABSTRACT,
+ ABSTRACT(new BeanPolicy(BeanPolicy.INTROSPECTION | BeanPolicy.ELEMENTTYPE)),
+ /**
+ * Type must NOT be added to the meta-model, eg. by means of
+ * {@link org.apache.causeway.applib.annotation.Domain.Exclude} or {@link Programmatic}.
+ * Consequently the specification-loader should skip introspection of those types.
+ * <p>
+ * In other words: Indicates that the class is some bean,
+ * which is NOT contributing to the UI or WEB API, and
+ * also NOT managed by Spring.
+ * <p>
+ * {@link ServiceRegistry} will NOT be aware.
+ * <p>
+ * {@link FactoryService#create(Class)} will nevertheless support
+ * those programmatic beans. They may have injection points that need resolving.
+ */
+ PROGRAMMATIC(new BeanPolicy(BeanPolicy.WRAPPING)),
/**
* Type must not be added to the meta-model, eg. by means of
- * {@link org.apache.causeway.applib.annotation.Domain.Exclude}, {@link Profile} or {@link Programmatic}
+ * {@link javax.enterprise.inject.Vetoed} or {@link Profile}.
+ * Consequently the specification-loader should skip introspection of those types.
+ * If discovered by Spring during class-path scanning, we remove the corresponding {@link BeanDefinition}.
+ * <p>
+ * {@link ServiceRegistry} must not be aware of those types.
+ * <p>
+ * {@link FactoryService#getOrCreate(Class)} must fail for those types.
*/
- VETOED,
- UNKNOWN;
+ @SuppressWarnings("javadoc")
+ VETOED(new BeanPolicy(0)),
+ UNKNOWN(new BeanPolicy(BeanPolicy.ELEMENTTYPE));
+
+ public record BeanPolicy(int flags) {
+ final static int INTROSPECTION = 0x01;
+ final static int INJECTABLE = 0x02;
+ final static int WRAPPING = 0x04;
+ final static int ELEMENTTYPE = 0x08;
+ final static int NON_SUBSTITUTABLE = 0x10;
+ /**
+ * Enables meta-model introspection.
+ * Potentially contributes to the UI or Web API.
+ */
+ public boolean isIntrospectionAllowed() { return (flags & INTROSPECTION) !=0; }
+ /**
+ * Contributes actions, members and/or object support to the UI or Web API.
+ */
+ public boolean contributesToUiOrWebApi() { return isIntrospectionAllowed(); } // seems to be just a synonym
+ public boolean isInjectable() { return (flags & INJECTABLE) !=0; }
+ public boolean isWrappingSupported() { return (flags & WRAPPING) !=0; }
+ public boolean isAllowedAsMemberElementType() { return (flags & ELEMENTTYPE) !=0; }
+ public boolean isNotSubstitutable() { return (flags & NON_SUBSTITUTABLE) !=0; }
+ }
- // -- SIMPLE PREDICATES
+ // -- POLICY
- public boolean isManagedBeanContributing() {
- return this == MANAGED_BEAN_CONTRIBUTING;
- }
+ private final BeanPolicy policy;
+ private BeanSort(final BeanPolicy policy) { this.policy = policy;}
+ public BeanPolicy policy() { return policy; }
- public boolean isManagedBeanNotContributing() {
- return this == MANAGED_BEAN_NOT_CONTRIBUTING;
- }
+ // -- PREDICATES
+
+ public boolean isManagedBeanContributing() { return this == MANAGED_BEAN_CONTRIBUTING; }
+ public boolean isManagedBeanNotContributing() { return this == MANAGED_BEAN_NOT_CONTRIBUTING; }
+ public boolean isMixin() { return this == MIXIN; }
+ public boolean isViewModel() { return this == VIEW_MODEL; }
+ public boolean isValue() { return this == VALUE; }
+ public boolean isCollection() { return this == COLLECTION; }
+ public boolean isEntity() { return this == ENTITY; }
+ public boolean isAbstract() { return this == ABSTRACT; }
+ public boolean isProgrammatic() { return this == PROGRAMMATIC; }
+ public boolean isVetoed() { return this == VETOED; }
+ public boolean isUnknown() { return this == UNKNOWN; }
+ @Deprecated
public boolean isManagedBeanAny() {
return this == MANAGED_BEAN_CONTRIBUTING
|| this == MANAGED_BEAN_NOT_CONTRIBUTING;
}
- public boolean isMixin() {
- return this == MIXIN;
- }
-
- public boolean isViewModel() {
- return this == VIEW_MODEL;
- }
-
- public boolean isValue() {
- return this == VALUE;
- }
-
- public boolean isCollection() {
- return this == COLLECTION;
- }
-
- public boolean isEntity() {
- return this == ENTITY;
- }
-
- public boolean isAbstract() {
- return this == ABSTRACT;
- }
-
- public boolean isVetoed() {
- return this == VETOED;
- }
-
- public boolean isUnknown() {
- return this == UNKNOWN;
- }
-
- // -- HIGHER LEVEL PREDICATES
-
- public boolean isToBeIntrospected() {
-
- if(isVetoed()
- || isUnknown()
- || isCollection()
- || this == MANAGED_BEAN_NOT_CONTRIBUTING) {
- return false;
- }
-
- return true;
- }
-
- public boolean isWrappingSupported() {
- return isMixin() || isViewModel() || isEntity() || isManagedBeanAny();
- }
-
- // ...
}
diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java b/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java
index d5caeba430c..95340488015 100644
--- a/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java
+++ b/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java
@@ -38,7 +38,7 @@ import jakarta.inject.Named;
import jakarta.xml.bind.annotation.XmlRootElement;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.lang.Nullable;
@@ -46,7 +46,6 @@ import org.springframework.lang.Nullable;
import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.functional.Try;
import org.apache.causeway.commons.internal._Constants;
-import org.apache.causeway.commons.internal.annotations.BeanInternal;
import org.apache.causeway.commons.internal.assertions._Assert;
import org.apache.causeway.commons.internal.base._Casts;
import org.apache.causeway.commons.internal.base._Lazy;
@@ -60,6 +59,8 @@ import org.apache.causeway.commons.internal.reflection._GenericResolver.Resolved
import org.apache.causeway.commons.semantics.AccessorSemantics;
import lombok.AccessLevel;
+import lombok.Builder;
+import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@@ -81,6 +82,24 @@ import lombok.SneakyThrows;
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public final class _ClassCache implements AutoCloseable {
+ @Builder(builderMethodName = "builderPlain")
+ public record Options(
+ @Nullable ClassLoader classLoader,
+ @NonNull Can<Class<? extends Annotation>> annotationsVetoingIntrospection) {
+ public static OptionsBuilder builder() {
+ return builderPlain()
+ .classLoader(_Context.getDefaultClassLoader())
+ .annotationsVetoingIntrospection(Can.empty());
+ }
+ public void install() {
+ _Context.put(_ClassCache.Options.class, this, true);
+ }
+ static Options fallback() { return builder().build(); }
+ static Options getInstance() {
+ return _Context.computeIfAbsent(Options.class, Options::fallback);
+ }
+ }
+
public enum Attribute {
/**
* Corresponds to the bean name of Spring managed beans.
@@ -93,17 +112,17 @@ public final class _ClassCache implements AutoCloseable {
}
public static _ClassCache getInstance() {
- return _Context.computeIfAbsent(_ClassCache.class, ()->new _ClassCache(_Context.getDefaultClassLoader()));
+ return _Context.computeIfAbsent(_ClassCache.class, ()->new _ClassCache(Options.getInstance()));
}
/**
* JUnit support.
*/
public static void invalidate() {
- _Context.put(_ClassCache.class, new _ClassCache(_Context.getDefaultClassLoader()), true);
+ _Context.put(_ClassCache.class, new _ClassCache(Options.getInstance()), true);
}
- private final @Nullable ClassLoader classLoader;
+ private final Options options;
public void add(final Class<?> type) {
classModel(type);
@@ -261,11 +280,19 @@ public final class _ClassCache implements AutoCloseable {
MergedAnnotations mergedAnnotations,
/** explicit name if any */
@Nullable String named,
+ /**
+ * if true, type is NOT contributing to the UI or WEB API,
+ * consequently will NOT introspect
+ */
+ boolean hasIntrospectionVetoingSemantics,
Map<Attribute, String> attributeMap) {
- static ClassModelHead create(final Class<?> type) {
+ static ClassModelHead create(final Class<?> type, final Options options) {
var mergedAnnotations = MergedAnnotations.from(type, SearchStrategy.TYPE_HIERARCHY);
- return new ClassModelHead(mergedAnnotations, _ClassCacheUtil.inferName(type, mergedAnnotations),
+ return new ClassModelHead(mergedAnnotations,
+ _ClassCacheUtil.inferName(type, mergedAnnotations),
+ options.annotationsVetoingIntrospection()
+ .anyMatch(annotationType->mergedAnnotations.get(annotationType).isPresent()),
new ConcurrentHashMap<>());
}
@@ -281,14 +308,6 @@ public final class _ClassCache implements AutoCloseable {
return mergedAnnotations.get(annotationType).isPresent();
}
- /**
- * whether type is annotated with {@link BeanInternal} or {@link Configuration}
- */
- public boolean hasInternalBeanSemantics() {
- return hasAnnotation(BeanInternal.class)
- || hasAnnotation(Configuration.class);
- }
-
/**
* whether type is annotated with {@link XmlRootElement}
*/
@@ -304,6 +323,12 @@ public final class _ClassCache implements AutoCloseable {
&& !_ClassCacheUtil.isJdoEmbeddedOnly(mergedAnnotations);
}
+ public Can<String> springProfiles() {
+ var profileAnnot = mergedAnnotations.get(Profile.class);
+ if(!profileAnnot.isPresent()) return Can.empty();
+ return Can.ofArray(profileAnnot.getStringArray("value"));
+ }
+
}
private record ClassModelBody(
@@ -329,7 +354,8 @@ public final class _ClassCache implements AutoCloseable {
Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap());
private static ClassModelBody create(final Class<?> type, final ClassModelHead head) {
- if(head.hasInternalBeanSemantics()) return EMPTY; //skip further inspection
+
+ if(head.hasIntrospectionVetoingSemantics) return EMPTY; //skip further inspection
var body = new ClassModelBody(Can.ofArray(type.getDeclaredFields()));
@@ -457,7 +483,7 @@ public final class _ClassCache implements AutoCloseable {
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private Class<?> reloadType(final Class<?> _type) {
- return Optional.ofNullable(classLoader)
+ return Optional.ofNullable(options.classLoader())
.filter(cl->!_type.isPrimitive())
.filter(cl->!_Reflect.isJavaApiClass(_type))
.filter(cl->!cl.equals(_type.getClassLoader()))
@@ -469,7 +495,7 @@ public final class _ClassCache implements AutoCloseable {
private ClassModel inspectType(final Class<?> _type) {
final Class<?> type = reloadType(_type);
- var head = ClassModelHead.create(type);
+ var head = ClassModelHead.create(type, options);
return new ClassModel(head, _Lazy.threadSafe(()->ClassModelBody.create(type, head)));
}
diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanFactoryPostProcessor.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanFactoryPostProcessor.java
index d31888f7152..02caf8457b7 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanFactoryPostProcessor.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanFactoryPostProcessor.java
@@ -39,8 +39,10 @@ import org.apache.causeway.applib.annotation.DomainService;
import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.commons.internal.base._Timing;
+import org.apache.causeway.commons.internal.reflection._ClassCache;
import org.apache.causeway.core.config.CausewayModuleCoreConfig;
import org.apache.causeway.core.config.beans.aoppatch.AopPatch;
+import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants;
import lombok.extern.log4j.Log4j2;
@@ -72,6 +74,7 @@ implements
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
this.causewayBeanTypeClassifier = new CausewayBeanTypeClassifier(applicationContext);
+ installClassCashOptions();
}
@Override
@@ -115,4 +118,13 @@ implements
return new CausewayBeanTypeRegistry(componentScanResult);
}
+ private void installClassCashOptions() {
+ _ClassCache.Options.builder()
+ .annotationsVetoingIntrospection(
+ Can.ofArray(ProgrammingModelConstants.TypeProgrammaticMarker.values())
+ .map(ProgrammingModelConstants.TypeProgrammaticMarker::getAnnotationType))
+ .build()
+ .install();
+ }
+
}
diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanMetaData.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanMetaData.java
index 5c5fbc09487..b3bfe0d1d69 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanMetaData.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanMetaData.java
@@ -31,7 +31,7 @@ public record CausewayBeanMetaData(
@NonNull BeanSort beanSort,
@NonNull DiscoveredBy discoveredBy,
@NonNull ManagedBy managedBy,
- @NonNull PersistenceStack persistenceStack)
+ @NonNull PersistenceStack persistenceStack)
implements Serializable {
public enum PersistenceStack {
@@ -51,14 +51,14 @@ implements Serializable {
return _Strings.capitalize(_Strings.lower(name()));
}
}
-
+
public enum DiscoveredBy {
CAUSEWAY,
SPRING;
boolean isCauseway() { return this == CAUSEWAY; }
boolean isSpring() { return this == SPRING; }
}
-
+
public enum ManagedBy {
NONE,
CAUSEWAY,
@@ -72,7 +72,7 @@ implements Serializable {
public boolean isPersistence() { return this == PERSISTENCE; }
public boolean isUnspecified() { return this == UNSPECIFIED; }
}
-
+
public Class<?> getCorrespondingClass() {
return logicalType.correspondingClass();
}
@@ -83,6 +83,64 @@ implements Serializable {
// -- FACTORIES
+ public static CausewayBeanMetaData vetoed(
+ final @NonNull LogicalType logicalType,
+ final @NonNull DiscoveredBy discoveredBy) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.VETOED, discoveredBy, ManagedBy.NONE, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData value(
+ final @NonNull LogicalType logicalType,
+ final @NonNull DiscoveredBy discoveredBy) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.VALUE, discoveredBy, ManagedBy.UNSPECIFIED, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData collection(
+ final @NonNull LogicalType logicalType,
+ final @NonNull DiscoveredBy discoveredBy) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.COLLECTION, discoveredBy, ManagedBy.UNSPECIFIED, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData interfaceOrAbstract(
+ final @NonNull LogicalType logicalType,
+ final @NonNull DiscoveredBy discoveredBy) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.ABSTRACT, discoveredBy, ManagedBy.UNSPECIFIED, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData viewModel(
+ final @NonNull LogicalType logicalType,
+ final @NonNull DiscoveredBy discoveredBy) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.VIEW_MODEL, discoveredBy, ManagedBy.CAUSEWAY, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData entity(
+ final @NonNull LogicalType logicalType,
+ final @NonNull DiscoveredBy discoveredBy,
+ final @NonNull PersistenceStack persistenceStack) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.ENTITY, discoveredBy, ManagedBy.PERSISTENCE, persistenceStack);
+ }
+ public static CausewayBeanMetaData mixin(
+ final @NonNull LogicalType logicalType,
+ final @NonNull DiscoveredBy discoveredBy) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.MIXIN, discoveredBy, ManagedBy.CAUSEWAY, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData programmatic(
+ final @NonNull LogicalType logicalType) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.PROGRAMMATIC, DiscoveredBy.CAUSEWAY, ManagedBy.CAUSEWAY, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData springContributing(
+ final @NonNull LogicalType logicalType) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.MANAGED_BEAN_CONTRIBUTING, DiscoveredBy.SPRING, ManagedBy.SPRING, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData springNotContributing(
+ final @NonNull LogicalType logicalType) {
+ return new CausewayBeanMetaData(logicalType, BeanSort.MANAGED_BEAN_NOT_CONTRIBUTING, DiscoveredBy.SPRING, ManagedBy.SPRING, PersistenceStack.NONE);
+ }
+ public static CausewayBeanMetaData unspecified(
+ final @NonNull LogicalType logicalType,
+ final @NonNull DiscoveredBy discoveredBy,
+ final @NonNull BeanSort beanSort) {
+ return new CausewayBeanMetaData(logicalType, beanSort, discoveredBy, ManagedBy.UNSPECIFIED, PersistenceStack.NONE);
+ }
+
+ // -- FACTORIES
+
+ @Deprecated
public static CausewayBeanMetaData notManaged(
final @NonNull DiscoveredBy discoveredBy,
final @NonNull BeanSort beanSort,
@@ -90,20 +148,23 @@ implements Serializable {
return new CausewayBeanMetaData(logicalType, beanSort, discoveredBy, ManagedBy.NONE, PersistenceStack.NONE);
}
+ @Deprecated
public static CausewayBeanMetaData causewayManaged(
final @NonNull DiscoveredBy discoveredBy,
final @NonNull BeanSort beanSort,
final @NonNull LogicalType logicalType) {
return new CausewayBeanMetaData(logicalType, beanSort, discoveredBy, ManagedBy.CAUSEWAY, PersistenceStack.NONE);
}
-
+
+ @Deprecated
public static CausewayBeanMetaData springManaged(
final @NonNull DiscoveredBy discoveredBy,
final @NonNull BeanSort beanSort,
final @NonNull LogicalType logicalType) {
return new CausewayBeanMetaData(logicalType, beanSort, discoveredBy, ManagedBy.SPRING, PersistenceStack.NONE);
}
-
+
+ @Deprecated
public static CausewayBeanMetaData entity(
final @NonNull DiscoveredBy discoveredBy,
final @NonNull PersistenceStack persistenceStack,
@@ -112,8 +173,9 @@ implements Serializable {
}
/**
- * If discovered by Spring, let Spring decide whether it wants to manage this type. We do not interfere.
+ * If discovered by Spring, let Spring decide whether it wants to manage this type. We do not interfere.
*/
+ @Deprecated
public static CausewayBeanMetaData unspecified(
final @NonNull DiscoveredBy discoveredBy,
final @NonNull BeanSort beanSort,
diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifier.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifier.java
index 35ec8ae6e05..213a4cc82bb 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifier.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifier.java
@@ -31,48 +31,48 @@ import org.springframework.util.ClassUtils;
import org.apache.causeway.applib.annotation.DomainObject;
import org.apache.causeway.applib.annotation.DomainService;
+import org.apache.causeway.applib.annotation.Programmatic;
import org.apache.causeway.applib.id.LogicalType;
import org.apache.causeway.applib.services.metamodel.BeanSort;
import org.apache.causeway.commons.collections.Can;
-import org.apache.causeway.commons.internal.annotations.BeanInternal;
import org.apache.causeway.commons.internal.reflection._Annotations;
import org.apache.causeway.commons.internal.reflection._ClassCache;
import org.apache.causeway.commons.semantics.CollectionSemantics;
import org.apache.causeway.core.config.beans.CausewayBeanMetaData.DiscoveredBy;
import org.apache.causeway.core.config.beans.CausewayBeanMetaData.PersistenceStack;
-import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.TypeExcludeMarker;
+import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.TypeVetoMarker;
import lombok.NonNull;
-@BeanInternal
+@Programmatic
public record CausewayBeanTypeClassifier(
@NonNull Can<String> activeProfiles,
@NonNull _ClassCache classCache) {
-
+
// -- CONSTRUCTION
-
+
CausewayBeanTypeClassifier(final ApplicationContext applicationContext) {
this(Can.ofArray(applicationContext.getEnvironment().getActiveProfiles()));
}
-
- CausewayBeanTypeClassifier(Can<String> activeProfiles) {
+
+ CausewayBeanTypeClassifier(final Can<String> activeProfiles) {
this(activeProfiles, _ClassCache.getInstance());
}
// -- CLASSIFY
-
+
/**
- * Classify {@link LogicalType} as detected and named by either Causeway or Spring.
+ * Classify {@link LogicalType} as detected and named by either Causeway or Spring.
* <p>
* Typically Causeway we will use a different fallback naming strategy for 'unnamed' types,
- * that is, it uses the fully qualified class name.
- *
- * @param logicalType with name as either forced by Causeway or suggested by Spring
+ * that is, it uses the fully qualified class name.
+ *
+ * @param logicalType with name as either forced by Causeway or suggested by Spring
*/
public CausewayBeanMetaData classify(@NonNull final LogicalType logicalType, final DiscoveredBy discoveredBy) {
-
+
var type = logicalType.correspondingClass();
-
+
Supplier<LogicalType> named = ()->discoveredBy.isSpring()
? LogicalType.infer(type) // use only if discovered by Spring but NOT managed by Spring
: logicalType; // name is already inferred, when discovered by Causeway
@@ -99,7 +99,7 @@ public record CausewayBeanTypeClassifier(
}
// handle vetoing ...
- if(TypeExcludeMarker.anyMatchOn(type)) {
+ if(TypeVetoMarker.anyMatchOn(type)) {
return CausewayBeanMetaData.notManaged(discoveredBy, BeanSort.VETOED, named.get()); // reject
}
@@ -115,16 +115,16 @@ public record CausewayBeanTypeClassifier(
if(org.apache.causeway.applib.ViewModel.class.isAssignableFrom(type)) {
return CausewayBeanMetaData.causewayManaged(discoveredBy, BeanSort.VIEW_MODEL, named.get());
}
-
+
var typeHead = classCache().head(type);
-
+
// value types
if(typeHead.hasAnnotation(org.apache.causeway.applib.annotation.Value.class)) {
return CausewayBeanMetaData.notManaged(discoveredBy, BeanSort.VALUE, named.get());
}
-
+
// internal bean types
- if(typeHead.hasInternalBeanSemantics()) {
+ if(typeHead.hasIntrospectionVetoingSemantics()) {
return CausewayBeanMetaData.springManaged(discoveredBy, BeanSort.MANAGED_BEAN_NOT_CONTRIBUTING, logicalType);
}
@@ -139,8 +139,8 @@ public record CausewayBeanTypeClassifier(
}
if(typeHead.hasAnnotation(Entity.class)) {
return CausewayBeanMetaData.entity(discoveredBy, PersistenceStack.JPA, named.get());
- }
-
+ }
+
// domain object
var aDomainObject = typeHead.annotation(DomainObject.class).orElse(null);
if(aDomainObject!=null) {
diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeRegistry.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeRegistry.java
index 651c091dd6c..db963dfc7ee 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeRegistry.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeRegistry.java
@@ -25,8 +25,8 @@ import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
+import org.apache.causeway.applib.annotation.Programmatic;
import org.apache.causeway.commons.collections.Can;
-import org.apache.causeway.commons.internal.annotations.BeanInternal;
import org.apache.causeway.core.config.beans.CausewayBeanMetaData.PersistenceStack;
import lombok.NonNull;
@@ -34,7 +34,7 @@ import lombok.NonNull;
/**
* Holds discovered domain types grouped by bean-sort.
*/
-@BeanInternal
+@Programmatic
public class CausewayBeanTypeRegistry {
/**
@@ -59,7 +59,7 @@ public class CausewayBeanTypeRegistry {
introspectableTypes.forEach(typeMeta->{
var cls = typeMeta.getCorrespondingClass();
-
+
introspectableTypesByClass.put(typeMeta.getCorrespondingClass(), typeMeta);
switch (typeMeta.beanSort()) {
@@ -89,9 +89,9 @@ public class CausewayBeanTypeRegistry {
}
});
}
-
+
// -- SIZE
-
+
public int managedBeansContributingCount() { return managedBeansContributing.size(); }
public int entityTypeCount() { return entityTypes.size(); }
public int viewmodelTypeCount() { return viewmodelTypes.size(); }
@@ -106,7 +106,7 @@ public class CausewayBeanTypeRegistry {
public Stream<Class<?>> streamViewmodelTypes() { return viewmodelTypes.keySet().stream(); }
public Stream<Class<?>> streamMixinTypes() { return mixinTypes.keySet().stream(); }
public Stream<Class<?>> streamValueTypes() { return valueTypes.keySet().stream(); }
-
+
// -- AS SET
public Set<Class<?>> entityTypeSet() { return Collections.unmodifiableSet(entityTypes.keySet()); }
@@ -122,8 +122,8 @@ public class CausewayBeanTypeRegistry {
return Optional.ofNullable(managedBeansContributing.get(type))
.map(CausewayBeanMetaData::getBeanName);
}
-
- public boolean containsManagedBeansContributing(@NonNull Class<?> type) {
+
+ public boolean containsManagedBeansContributing(@NonNull final Class<?> type) {
return managedBeansContributing.containsKey(type);
}
diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayComponentCollector.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayComponentCollector.java
index bd16af4db73..4c57f279eb9 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayComponentCollector.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayComponentCollector.java
@@ -67,7 +67,7 @@ record CausewayComponentCollector(
switch (typeMeta.managedBy()) {
case NONE, CAUSEWAY, PERSISTENCE -> {
registry.removeBeanDefinition(beanDefinitionName);
- log.debug("vetoing bean {}", beanDefinitionName);
+ log.debug("removing bean from spring registry {}", beanDefinitionName);
}
case UNSPECIFIED, SPRING -> {
if(isRenamed) {
@@ -95,7 +95,7 @@ record CausewayComponentCollector(
private CausewayBeanMetaData collectBeanClass(final LogicalType logicalType) {
var typeMeta = causewayBeanTypeClassifier.classify(logicalType, DiscoveredBy.SPRING);
var beanSort = typeMeta.beanSort();
- if(beanSort.isToBeIntrospected()) {
+ if(beanSort.policy().isIntrospectionAllowed()) {
var beanClass = logicalType.correspondingClass();
introspectableTypes.put(beanClass, typeMeta);
if(log.isDebugEnabled()) {
diff --git a/core/config/src/main/java/org/apache/causeway/core/config/progmodel/ProgrammingModelConstants.java b/core/config/src/main/java/org/apache/causeway/core/config/progmodel/ProgrammingModelConstants.java
index 945c3239b54..a4ba48eb9c2 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/progmodel/ProgrammingModelConstants.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/progmodel/ProgrammingModelConstants.java
@@ -35,7 +35,9 @@ import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.stream.Stream;
+import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Repository;
import org.apache.causeway.applib.Identifier;
import org.apache.causeway.applib.annotation.Domain;
@@ -52,6 +54,7 @@ import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
import org.apache.causeway.commons.internal.reflection._Annotations;
import org.apache.causeway.commons.internal.reflection._ClassCache;
+import org.apache.causeway.commons.internal.reflection._ClassCache.ClassModelHead;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedConstructor;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod;
import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade;
@@ -67,21 +70,39 @@ import lombok.RequiredArgsConstructor;
public final class ProgrammingModelConstants {
- // -- TYPE EXCLUDE MARKERS
+ // -- TYPE MARKERS
@Getter
@RequiredArgsConstructor
- public enum TypeExcludeMarker {
- DOMAIN_EXCLUDE(Domain.Exclude.class)
- //,VETO(javax.enterprise.inject.Vetoed.class)
+ public enum TypeVetoMarker {
+ //VETO(javax.enterprise.inject.Vetoed.class)
;
private final Class<? extends Annotation> annotationType;
- public static boolean anyMatchOn(final Class<?> type) {
- for(TypeExcludeMarker excludeMarker : TypeExcludeMarker.values()) {
- if(_Annotations.synthesize(type, excludeMarker.getAnnotationType()).isPresent()) {
- return true;
- }
+ public static boolean anyMatchOn(final ClassModelHead typeHead) {
+ for(TypeVetoMarker marker : TypeVetoMarker.values()) {
+ if(typeHead.hasAnnotation(marker.annotationType)) return true;
+ }
+ return false;
+ }
+
+ public static boolean anyMatchOn(final Class<?> cls) {
+ return anyMatchOn(_ClassCache.getInstance().head(cls));
+ }
+ }
+
+ @Getter
+ @RequiredArgsConstructor
+ public enum TypeProgrammaticMarker {
+ SPRING_CONFIG(Configuration.class),
+ SPRING_REPOSITORY(Repository.class),
+ DOMAIN_EXCLUDE(Domain.Exclude.class),
+ ;
+ private final Class<? extends Annotation> annotationType;
+
+ public static boolean anyMatchOn(final ClassModelHead typeHead) {
+ for(TypeProgrammaticMarker marker : TypeProgrammaticMarker.values()) {
+ if(typeHead.hasAnnotation(marker.annotationType)) return true;
}
return false;
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/_testing/MetaModelContext_forTesting.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/_testing/MetaModelContext_forTesting.java
index e0ec4ec11f6..dce69411935 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/_testing/MetaModelContext_forTesting.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/_testing/MetaModelContext_forTesting.java
@@ -558,7 +558,7 @@ extends MetaModelContext {
private Optional<ServiceInstance> toServiceInstance(final _SingletonBeanProvider managedBeanAdapter) {
var servicePojo = managedBeanAdapter.getInstanceElseFail();
- if(ProgrammingModelConstants.TypeExcludeMarker.anyMatchOn(managedBeanAdapter.getBeanClass())) {
+ if(ProgrammingModelConstants.TypeVetoMarker.anyMatchOn(managedBeanAdapter.getBeanClass())) {
return Optional.empty();
}
return getSpecificationLoader()
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/commons/MetaModelVisitor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/commons/MetaModelVisitor.java
index d24f8f73400..aebc1317115 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/commons/MetaModelVisitor.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/commons/MetaModelVisitor.java
@@ -53,7 +53,7 @@ public interface MetaModelVisitor {
*/
public final static Predicate<ObjectSpecification> SKIP_ABSTRACT =
spec->!spec.isAbstract()
- && spec.getBeanSort().isToBeIntrospected();
+ && spec.getBeanSort().policy().isIntrospectionAllowed();
/** types pass this filter, if is NOT a mixin */
public final static Predicate<ObjectSpecification> SKIP_MIXINS =
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/MetaModelContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/MetaModelContext.java
index cacd91b0e46..4e338fe7772 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/MetaModelContext.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/MetaModelContext.java
@@ -23,15 +23,15 @@ import java.util.concurrent.atomic.AtomicReference;
import org.springframework.lang.Nullable;
+import org.apache.causeway.applib.annotation.Programmatic;
import org.apache.causeway.applib.services.i18n.TranslationService;
-import org.apache.causeway.commons.internal.annotations.BeanInternal;
import org.apache.causeway.commons.internal.assertions._Assert;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
/**
* @since 2.0
*/
-@BeanInternal
+@Programmatic
public abstract class MetaModelContext implements HasMetaModelContext {
@Override
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectService.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectService.java
index b852235e538..94da8163cd4 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectService.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectService.java
@@ -56,6 +56,15 @@ extends _ManagedObjectSpecified {
this.pojo = assertCompliance(pojo);
}
+// _ManagedObjectService(
+// final ObjectSpecification spec,
+// final Object pojo) {
+// super(ManagedObject.Specialization.SERVICE, spec);
+// _Assert.assertTrue(spec.isInjectable(), ()->"type %s must be injectable to be considered a service; bean-sort: %s"
+// .formatted(pojo.getClass(), spec.getBeanSort()));
+// this.pojo = assertCompliance(pojo);
+// }
+
@Override
public Optional<Bookmark> getBookmark() {
return bookmarkLazy.get();
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/ObjectManager.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/ObjectManager.java
index 1037ded3c12..f7bc02587cc 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/ObjectManager.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/ObjectManager.java
@@ -25,12 +25,12 @@ import jakarta.inject.Named;
import org.springframework.lang.Nullable;
+import org.apache.causeway.applib.annotation.Programmatic;
import org.apache.causeway.applib.exceptions.unrecoverable.BookmarkNotFoundException;
import org.apache.causeway.applib.query.Query;
import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.handler.ChainOfResponsibility;
-import org.apache.causeway.commons.internal.annotations.BeanInternal;
import org.apache.causeway.commons.internal.assertions._Assert;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
@@ -58,7 +58,7 @@ import lombok.NonNull;
*
* @since 2.0
*/
-@BeanInternal
+@Programmatic
@Named(CausewayModuleCoreMetamodel.NAMESPACE + ".ObjectManager")
public record ObjectManager(
MetaModelContext mmc,
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectDementifierFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectDementifierFactory.java
index 3d032f99433..28139e6ba2e 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectDementifierFactory.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectDementifierFactory.java
@@ -52,7 +52,7 @@ public record ObjectDementifierFactory() {
var spec = request.objectSpecification();
var mmc = spec.getMetaModelContext();
// intercept when managed by Spring
- return spec.getBeanSort().isManagedBeanAny()
+ return spec.getBeanSort().policy().isInjectable()
? mmc.lookupServiceAdapterById(request.memento().logicalType().logicalName())
: mmc.getObjectManager().loadObjectElseFail(request.memento().bookmark());
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/all/SanityChecksValidator.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/all/SanityChecksValidator.java
index c6dcfed8270..d51959c2afc 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/all/SanityChecksValidator.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/all/SanityChecksValidator.java
@@ -96,9 +96,7 @@ implements
final ObjectSpecification elementType) {
if(elementType == null
- || elementType.getBeanSort().isManagedBeanAny()
- || elementType.getBeanSort().isMixin()
- || elementType.getBeanSort().isVetoed()) {
+ || !elementType.getBeanSort().policy().isAllowedAsMemberElementType()) {
ValidationFailureUtils.raiseInvalidMemberElementType(facetHolder, declaringType, elementType);
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
index a68d235df6e..3eadcc9e70a 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
@@ -232,9 +232,7 @@ extends MetaModelPostProcessorAbstract {
private void checkParamHasChoicesOrAutoCompleteWhenRequired(final ObjectActionParameter param) {
var elementType = param.getElementType();
if(elementType == null
- || elementType.getBeanSort().isManagedBeanAny()
- || elementType.getBeanSort().isMixin()
- || elementType.getBeanSort().isVetoed()) {
+ || !elementType.getBeanSort().policy().isAllowedAsMemberElementType()) {
// ignore, as these cases are covered later by meta-model validation
return;
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java
index ddaabcf0cee..babf513204e 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java
@@ -128,7 +128,7 @@ public abstract class ClassSubstitutorAbstract implements ClassSubstitutor {
}
// ignore vetoed types
- if(ProgrammingModelConstants.TypeExcludeMarker.anyMatchOn(cls)) {
+ if(ProgrammingModelConstants.TypeVetoMarker.anyMatchOn(cls)) {
return true;
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/classsubstitutor/ClassSubstitutorForDomainObjects.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/classsubstitutor/ClassSubstitutorForDomainObjects.java
index 4cb7efa50ae..651bb9fd6b2 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/classsubstitutor/ClassSubstitutorForDomainObjects.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/classsubstitutor/ClassSubstitutorForDomainObjects.java
@@ -60,4 +60,16 @@ public class ClassSubstitutorForDomainObjects implements ClassSubstitutor {
return Substitution.passThrough(); // indifferent
}
+// @Override
+// public Substitution getSubstitution(@NonNull final Class<?> cls) {
+// var notSubstitutable = causewayBeanTypeRegistry.lookupIntrospectableType(cls)
+// .map(CausewayBeanMetaData::beanSort)
+// .map(BeanSort::policy)
+// .map(BeanPolicy::isNotSubstitutable)
+// .orElse(false);
+// return notSubstitutable
+// ? Substitution.neverReplaceClass()
+// : Substitution.passThrough(); // indifferent
+// }
+
}
diff --git a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/WrapperFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/WrapperFactoryDefault.java
index 44a98da2981..67f18af9453 100644
--- a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/WrapperFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/WrapperFactoryDefault.java
@@ -561,7 +561,7 @@ implements WrapperFactory, HasMetaModelContext {
var adapter = getObjectManager().adapt(domainObject);
if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)
- || !adapter.getSpecification().getBeanSort().isWrappingSupported()) {
+ || !adapter.getSpecification().getBeanSort().policy().isWrappingSupported()) {
throw _Exceptions.illegalArgument("Cannot wrap an object of type %s",
domainObject.getClass().getName());
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/PageAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/PageAbstract.java
index 42d09284787..6c4e8f74d41 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/PageAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/PageAbstract.java
@@ -418,7 +418,7 @@ implements ActionPromptProvider {
}
var dialogMode =
- sort.isManagedBeanAny()
+ sort.policy().isInjectable()
? getWicketViewerSettings().getDialogModeForMenu()
: getWicketViewerSettings().getDialogMode();
switch (dialogMode) {