Skip to content

Commit

Permalink
CAUSEWAY-2297: CausewayBeanTypeRegistry encapsulation
Browse files Browse the repository at this point in the history
  • Loading branch information
andi-huber committed Nov 11, 2024
1 parent 7d4f5ea commit ee48579
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ public class CausewayBeanFactoryPostProcessorForSpring
ApplicationContextAware {

private CausewayBeanTypeClassifier causewayBeanTypeClassifier;
private Can<CausewayBeanMetaData> componentScanResult;
private Can<CausewayBeanMetaData> componentScanResult = Can.empty();

@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
causewayBeanTypeClassifier = CausewayBeanTypeClassifier.createInstance(applicationContext);
this.causewayBeanTypeClassifier = CausewayBeanTypeClassifier.createInstance(applicationContext);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,36 @@
*/
package org.apache.causeway.core.config.beans;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.commons.internal.collections._Maps;

import lombok.Getter;
import lombok.NonNull;

/**
* Holds the set of domain services, persistent entities and fixture scripts etc., but not values.
* @since 2.0
* Holds discovered domain types grouped by bean-sort.
*/
public class CausewayBeanTypeRegistry {

/**
* (immutable) scan result, as used by the SpecificationLoader for introspection
*/
private final Can<CausewayBeanMetaData> introspectableTypes;
private final Map<Class<?>, CausewayBeanMetaData> introspectableTypesByClass = new HashMap<>();

// -- DISTINCT CATEGORIES OF BEAN SORTS

private final Map<Class<?>, CausewayBeanMetaData> managedBeansContributing = new HashMap<>();
private final Map<Class<?>, CausewayBeanMetaData> entityTypes = new HashMap<>();
private final Map<Class<?>, CausewayBeanMetaData> viewmodelTypes = new HashMap<>();
private final Map<Class<?>, CausewayBeanMetaData> mixinTypes = new HashMap<>();
private final Map<Class<?>, CausewayBeanMetaData> valueTypes = new HashMap<>();

// -- CONSTRUCTOR

public CausewayBeanTypeRegistry(final @NonNull Can<CausewayBeanMetaData> introspectableTypes) {
Expand All @@ -58,10 +70,10 @@ public CausewayBeanTypeRegistry(final @NonNull Can<CausewayBeanMetaData> introsp
entityTypes.put(cls, typeMeta);
return;
case VIEW_MODEL:
viewModelTypes.put(cls, typeMeta);
viewmodelTypes.put(cls, typeMeta);
return;
case VALUE:
discoveredValueTypes.put(cls, typeMeta);
valueTypes.put(cls, typeMeta);
return;

// skip introspection for these
Expand All @@ -73,34 +85,52 @@ public CausewayBeanTypeRegistry(final @NonNull Can<CausewayBeanMetaData> introsp
return;
}
});

}

// -- SHORTCUTS

public Stream<Class<?>> streamMixinTypes() {
return getMixinTypes().keySet().stream();
}

// -- LOOKUPS

// -- SIZE

public int managedBeansContributingCount() { return managedBeansContributing.size(); }
public int entityTypeCount() { return entityTypes.size(); }
public int viewmodelTypeCount() { return viewmodelTypes.size(); }
public int mixinTypeCount() { return mixinTypes.size(); }
public int valueTypeCount() { return valueTypes.size(); }

// -- STREAM

public Stream<CausewayBeanMetaData> streamIntrospectableTypes() { return introspectableTypes.stream(); }
public Stream<Class<?>> streamManagedBeansContributing() { return managedBeansContributing.keySet().stream(); }
public Stream<Class<?>> streamEntityTypes() { return entityTypes.keySet().stream(); }
public Stream<Class<?>> streamViewmodelTypes() { return entityTypes.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()); }

// -- LOOKUP

/**
* If given type is part of the meta-model and is available for injection,
* returns the <em>Managed Bean's</em> name (id) as
* recognized by the IoC container.
*/
public Optional<String> lookupManagedBeanNameForType(final Class<?> type) {
return Optional.ofNullable(getManagedBeansContributing().get(type))
return Optional.ofNullable(managedBeansContributing.get(type))
.map(CausewayBeanMetaData::getBeanName);
}

public boolean containsManagedBeansContributing(@NonNull Class<?> type) {
return managedBeansContributing.containsKey(type);
}

/**
* Returns 'JDO' or 'JPA' based on metadata found during {@link CausewayBeanTypeClassifier type-classification}.
* If no (concrete) entity type is found, returns 'UNSPECIFIED'.
* @implNote assumes that there can be only one persistence stack
*/
public PersistenceStack determineCurrentPersistenceStack() {
return getEntityTypes().values().stream()
return entityTypes.values().stream()
.map(meta->meta.getPersistenceStack())
.filter(Optional::isPresent)
.map(Optional::get)
Expand All @@ -109,41 +139,8 @@ public PersistenceStack determineCurrentPersistenceStack() {
.orElse(PersistenceStack.UNSPECIFIED);
}


/**
* (immutable) scan result, as used by the SpecificationLoader for introspection
*/
private final Can<CausewayBeanMetaData> introspectableTypes;

private final Map<Class<?>, CausewayBeanMetaData> introspectableTypesByClass = _Maps.newHashMap();

// -- DISTINCT CATEGORIES OF BEAN SORTS

@Getter
private final Map<Class<?>, CausewayBeanMetaData> managedBeansContributing = new HashMap<>();

@Getter
private final Map<Class<?>, CausewayBeanMetaData> entityTypes = new HashMap<>();

@Getter
private final Map<Class<?>, CausewayBeanMetaData> mixinTypes = new HashMap<>();

@Getter
private final Map<Class<?>, CausewayBeanMetaData> viewModelTypes = new HashMap<>();

@Getter
private final Map<Class<?>, CausewayBeanMetaData> discoveredValueTypes = new HashMap<>();

// -- LOOKUPS

public Optional<CausewayBeanMetaData> lookupIntrospectableType(final Class<?> type) {
return Optional.ofNullable(introspectableTypesByClass.get(type));
}

// -- ITERATORS

public Stream<CausewayBeanMetaData> streamIntrospectableTypes() {
return _NullSafe.stream(introspectableTypes);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ private Map<String, _SingletonBeanProvider> enumerateContributingDomainServices(
}

private Predicate<_SingletonBeanProvider> contributes() {
var managedBeansContributing = causewayBeanTypeRegistry.getManagedBeansContributing().keySet();
return singletonProvider->singletonProvider!=null
? managedBeansContributing.contains(singletonProvider.getBeanClass()) // do not register unknown sort
? causewayBeanTypeRegistry.containsManagedBeansContributing(singletonProvider.getBeanClass())
// do not register unknown sort
: false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ public void createMetaModel() {

Stream
.concat(
causewayBeanTypeRegistry.getDiscoveredValueTypes().keySet().stream(),
causewayBeanTypeRegistry.streamValueTypes(),
valueSemanticsResolver.get().streamClassesWithValueSemantics())
.forEach(valueClass -> {
var valueSpec = loadSpecification(valueClass, IntrospectionState.NOT_INTROSPECTED);
Expand Down Expand Up @@ -294,17 +294,17 @@ public void createMetaModel() {
log.info(" - introspecting {} value types", valueTypeSpecs.size());
introspect(Can.ofCollection(valueTypeSpecs.values()), IntrospectionState.FULLY_INTROSPECTED);

log.info(" - introspecting {} mixins", causewayBeanTypeRegistry.getMixinTypes().size());
log.info(" - introspecting {} mixins", causewayBeanTypeRegistry.mixinTypeCount());
introspect(Can.ofCollection(mixinSpecs), IntrospectionState.FULLY_INTROSPECTED);

log.info(" - introspecting {} managed beans contributing (domain services)",
causewayBeanTypeRegistry.getManagedBeansContributing().size());
causewayBeanTypeRegistry.managedBeansContributingCount());

log.info(" - introspecting {} entities ({})",
causewayBeanTypeRegistry.getEntityTypes().size(),
causewayBeanTypeRegistry.entityTypeCount(),
causewayBeanTypeRegistry.determineCurrentPersistenceStack().name());

log.info(" - introspecting {} view models", causewayBeanTypeRegistry.getViewModelTypes().size());
log.info(" - introspecting {} view models", causewayBeanTypeRegistry.viewmodelTypeCount());

serviceRegistry.lookupServiceElseFail(MenuBarsService.class).menuBars();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ public HomePageResolverServiceDefault(

@PostConstruct
public void init() {
var viewModelTypes = causewayBeanTypeRegistry.getViewModelTypes();
viewModelTypeForHomepage = viewModelTypes.keySet().stream()
viewModelTypeForHomepage = causewayBeanTypeRegistry.streamViewmodelTypes()
.filter(viewModelType -> _Annotations.isPresent(viewModelType, HomePage.class))
.findFirst();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ public Stream<ObjectSpecification> streamEntities() {
}

public Stream<Class<?>> streamEntityClasses() {
return beanTypeRegistry.getEntityTypes().keySet()
.stream()
return beanTypeRegistry.streamEntityTypes()
//TODO perhaps externalize sorting
.sorted((a, b)->a.getSimpleName().compareTo(b.getSimpleName()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@
import org.apache.causeway.persistence.jdo.spring.integration.TransactionAwarePersistenceManagerFactoryProxy;

import lombok.SneakyThrows;

import lombok.extern.log4j.Log4j2;

/**
Expand Down Expand Up @@ -246,19 +245,14 @@ private static void notifyJdoEntityDiscoveryListeners(
final List<JdoEntityDiscoveryListener> jdoEntityDiscoveryListeners,
final DatanucleusSettings dnSettings) {

if(_NullSafe.isEmpty(jdoEntityDiscoveryListeners)) {
return;
}
if(_NullSafe.isEmpty(jdoEntityDiscoveryListeners)) return;
// assuming, as we instantiate a DN PMF, all entities discovered are JDO entities
var jdoEntityTypes = beanTypeRegistry.getEntityTypes();
if(_NullSafe.isEmpty(jdoEntityTypes)) {
return;
}
var jdoEntityTypesView = Collections.unmodifiableSet(jdoEntityTypes.keySet());
if(beanTypeRegistry.entityTypeCount()==0) return;
var jdoEntityTypes = beanTypeRegistry.entityTypeSet();
var dnProps = Collections.unmodifiableMap(dnSettings.getAsProperties());
jdoEntityDiscoveryListeners
.forEach(listener->
listener.onEntitiesDiscovered(pmf, jdoEntityTypesView, dnProps));
listener.onEntitiesDiscovered(pmf, jdoEntityTypes, dnProps));
}

/**
Expand Down Expand Up @@ -301,7 +295,7 @@ private static PersistenceUnitMetaData createDefaultPersistenceUnit (
var pumd = new PersistenceUnitMetaData(
"dynamic-unit", "RESOURCE_LOCAL", null);
pumd.setExcludeUnlistedClasses(false);
beanTypeRegistry.getEntityTypes().keySet().stream()
beanTypeRegistry.streamEntityTypes()
.map(Class::getName)
.forEach(pumd::addClassName);
return pumd;
Expand Down

0 comments on commit ee48579

Please sign in to comment.