You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/10/03 19:26:21 UTC
[isis] 01/01: ISIS-1974: also processes domain types,
introduces notion
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch ISIS-1974
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 0e19b194cbf7978b70c23028cbd87f684094ce2a
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Oct 3 18:54:15 2018 +0100
ISIS-1974: also processes domain types, introduces notion
of stub processing vs complete
---
.../java/org/apache/isis/applib/AppManifest.java | 27 +++++-
.../metamodel/specloader/SpecificationLoader.java | 108 ++++++++++++---------
.../IsisComponentProvider.java | 8 ++
3 files changed, 98 insertions(+), 45 deletions(-)
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
index 22c4fe4..ba1d991 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
@@ -32,7 +32,6 @@ import java.util.Set;
import javax.jdo.annotations.PersistenceCapable;
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import org.reflections.vfs.SystemDir;
import org.reflections.vfs.Vfs;
@@ -245,6 +244,32 @@ public interface AppManifest {
urlTypes.addAll(Arrays.asList(Vfs.DefaultUrlTypes.values()));
return urlTypes;
+
+ }
+
+ private Set<Class<?>> domainObjectTypes;
+ private Set<Class<?>> viewModelTypes;
+ private Set<Class<?>> xmlElementTypes;
+
+ public Set<Class<?>> getDomainObjectTypes() {
+ return domainObjectTypes;
+ }
+ public void setDomainObjectTypes(final Set<Class<?>> domainObjectTypes) {
+ this.domainObjectTypes = domainObjectTypes;
+ }
+
+ public Set<Class<?>> getViewModelTypes() {
+ return viewModelTypes;
+ }
+ public void setViewModelTypes(final Set<Class<?>> viewModelTypes) {
+ this.viewModelTypes = viewModelTypes;
+ }
+
+ public Set<Class<?>> getXmlElementTypes() {
+ return xmlElementTypes;
+ }
+ public void setXmlElementTypes(final Set<Class<?>> xmlElementTypes) {
+ this.xmlElementTypes = xmlElementTypes;
}
//endregion
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index 7e52cf6..2120843 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
@@ -21,7 +21,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
@@ -188,8 +187,24 @@ public class SpecificationLoader implements ApplicationScopedComponent {
state = State.CACHING;
- loadSpecificationsForServices();
- loadSpecificationsForMixins();
+ // need to completely load services and mixins (synchronously)
+ loadSpecificationsFor(
+ allServiceClasses(),
+ NatureOfService.DOMAIN, IntrospectionStrategy.STUB);
+ loadSpecificationsFor(
+ AppManifest.Registry.instance().getMixinTypes(),
+ null, IntrospectionStrategy.STUB);
+
+ loadSpecificationsFor(
+ AppManifest.Registry.instance().getDomainObjectTypes(),
+ null, IntrospectionStrategy.STUB);
+ loadSpecificationsFor(
+ AppManifest.Registry.instance().getViewModelTypes(),
+ null, IntrospectionStrategy.STUB);
+ loadSpecificationsFor(
+ AppManifest.Registry.instance().getXmlElementTypes(),
+ null, IntrospectionStrategy.STUB);
+
cacheBySpecId();
state = State.INTROSPECTING;
@@ -218,35 +233,22 @@ public class SpecificationLoader implements ApplicationScopedComponent {
}
- private void loadSpecificationsForServices() {
- final Properties metadataProperties = new Properties();
-
- List<Class<?>> classes = allServiceClasses();
- for (final Class<?> serviceClass : classes) {
- final DomainService domainService = serviceClass.getAnnotation(DomainService.class);
- final NatureOfService nature = domainService != null ? domainService.nature() : NatureOfService.DOMAIN;
- // will 'markAsService'
- ObjectSpecification objectSpecification = internalLoadSpecification(serviceClass, nature);
-
- facetProcessorObjectSpecId.process(
- serviceClass, metadataProperties,
- MethodRemoverConstants.NULL, objectSpecification);
+ private void loadSpecificationsFor(
+ final Collection<Class<?>> domainTypes,
+ final NatureOfService natureOfServiceFallback,
+ final IntrospectionStrategy introspectionStrategy) {
+ if(domainTypes == null || domainTypes.isEmpty()) {
+ return;
}
- }
-
- private void loadSpecificationsForMixins() {
final Properties metadataProperties = new Properties();
+ for (final Class<?> domainType : domainTypes) {
+
+ ObjectSpecification objectSpecification =
+ internalLoadSpecification(domainType, natureOfServiceFallback, introspectionStrategy);
- final Set<Class<?>> mixinTypes = AppManifest.Registry.instance().getMixinTypes();
- if(mixinTypes == null) {
- return;
- }
- for (final Class<?> mixinType : mixinTypes) {
- ObjectSpecification objectSpecification = internalLoadSpecification(mixinType);
facetProcessorObjectSpecId.process(
- mixinType, metadataProperties,
+ domainType, metadataProperties,
MethodRemoverConstants.NULL, objectSpecification);
-
}
}
@@ -388,22 +390,26 @@ public class SpecificationLoader implements ApplicationScopedComponent {
return spec;
}
+ enum IntrospectionStrategy {STUB, COMPLETE}
private ObjectSpecification internalLoadSpecification(final Class<?> type) {
- // superclasses tend to be loaded via this method, implicitly.
- // what can happen is that a subclass domain service, eg a fake one such as FakeLocationLookupService
- // can be registered first prior to the "real" implementation. As belt-n-braces, if that superclass is
- // annotated using @DomainService, then we ensure its own spec is created correctly as a service spec.
- final DomainService domainServiceIfAny = type.getAnnotation(DomainService.class);
- final NatureOfService natureOfServiceIfAny = domainServiceIfAny != null ? domainServiceIfAny.nature() : null;
- return internalLoadSpecification(type, natureOfServiceIfAny);
+ return internalLoadSpecification(type, null, IntrospectionStrategy.COMPLETE);
}
- private ObjectSpecification internalLoadSpecification(final Class<?> type, final NatureOfService nature) {
+ private ObjectSpecification internalLoadSpecification(
+ final Class<?> type,
+ final NatureOfService natureFallback,
+ final IntrospectionStrategy introspectionStrategy) {
+
final Class<?> substitutedType = classSubstitutor.getClass(type);
- return substitutedType != null ? loadSpecificationForSubstitutedClass(substitutedType, nature) : null;
+ return substitutedType != null
+ ? loadSpecificationForSubstitutedClass(substitutedType, natureFallback, introspectionStrategy)
+ : null;
}
- private ObjectSpecification loadSpecificationForSubstitutedClass(final Class<?> type, final NatureOfService nature) {
+ private ObjectSpecification loadSpecificationForSubstitutedClass(
+ final Class<?> type,
+ final NatureOfService natureFallback,
+ final IntrospectionStrategy introspectionStrategy) {
Assert.assertNotNull(type);
final String typeName = type.getName();
@@ -412,12 +418,14 @@ public class SpecificationLoader implements ApplicationScopedComponent {
return spec;
}
- return loadSpecificationForSubstitutedClassSynchronized(type, nature);
+ return loadSpecificationForSubstitutedClassSynchronized(type, natureFallback, introspectionStrategy);
}
+
private synchronized ObjectSpecification loadSpecificationForSubstitutedClassSynchronized(
final Class<?> type,
- final NatureOfService natureOfService) {
+ final NatureOfService natureOfServiceFallback,
+ final IntrospectionStrategy introspectionStrategy) {
final String typeName = type.getName();
final ObjectSpecification spec = cache.get(typeName);
@@ -425,13 +433,16 @@ public class SpecificationLoader implements ApplicationScopedComponent {
// because caller isn't synchronized.
return spec;
}
- final ObjectSpecification specification = createSpecification(type, natureOfService);
+
+ final ObjectSpecification specification = createSpecification(type, natureOfServiceFallback);
// put into the cache prior to introspecting, to prevent
// infinite loops
cache.cache(typeName, specification);
- introspectIfRequired(specification);
+ if(introspectionStrategy == IntrospectionStrategy.COMPLETE) {
+ introspectIfRequired(specification);
+ }
return specification;
}
@@ -466,23 +477,32 @@ public class SpecificationLoader implements ApplicationScopedComponent {
*/
private ObjectSpecification createSpecification(
final Class<?> cls,
- final NatureOfService natureOfServiceIfAny) {
+ final NatureOfService fallback) {
// ... and create the specs
if (FreeStandingList.class.isAssignableFrom(cls)) {
- return new ObjectSpecificationOnStandaloneList(servicesInjector,
- facetProcessor);
+ return new ObjectSpecificationOnStandaloneList(servicesInjector, facetProcessor);
} else {
final ConfigurationServiceInternal configService = servicesInjector.lookupService(
ConfigurationServiceInternal.class);
final FacetedMethodsBuilderContext facetedMethodsBuilderContext =
new FacetedMethodsBuilderContext(
this, facetProcessor, layoutMetadataReaders, configService);
+
+ final NatureOfService natureOfServiceIfAny = natureOfServiceFrom(cls, fallback);
+
return new ObjectSpecificationDefault(cls, facetedMethodsBuilderContext,
servicesInjector, facetProcessor, natureOfServiceIfAny);
}
}
+ private NatureOfService natureOfServiceFrom(
+ final Class<?> type,
+ final NatureOfService fallback) {
+ final DomainService domainServiceIfAny = type.getAnnotation(DomainService.class);
+ return domainServiceIfAny != null ? domainServiceIfAny.nature() : fallback;
+ }
+
private Class<?> loadBuiltIn(final String className) throws ClassNotFoundException {
final Class<?> builtIn = ClassUtil.getBuiltIn(className);
if (builtIn != null) {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
index 9773fa9..1e69806 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
@@ -26,6 +26,7 @@ import java.util.Set;
import javax.annotation.Nullable;
import javax.jdo.annotations.PersistenceCapable;
+import javax.xml.bind.annotation.XmlElement;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
@@ -43,6 +44,7 @@ import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.Mixin;
import org.apache.isis.applib.annotation.Nature;
+import org.apache.isis.applib.annotation.ViewModel;
import org.apache.isis.applib.fixturescripts.FixtureScript;
import org.apache.isis.applib.services.classdiscovery.ClassDiscoveryServiceUsingReflections;
import org.apache.isis.core.commons.config.IsisConfiguration;
@@ -161,6 +163,9 @@ public abstract class IsisComponentProvider {
}))
);
+ final Set<Class<?>> viewModelTypes = reflections.getTypesAnnotatedWith(ViewModel.class);
+ final Set<Class<?>> xmlElementTypes = reflections.getTypesAnnotatedWith(XmlElement.class);
+
// add in any explicitly registered services...
domainServiceTypes.addAll(appManifest.getAdditionalServices());
@@ -182,6 +187,9 @@ public abstract class IsisComponentProvider {
registry.setPersistenceCapableTypes(within(packagesWithDotSuffix, persistenceCapableTypes));
registry.setFixtureScriptTypes(within(packagesWithDotSuffix, fixtureScriptTypes));
registry.setMixinTypes(within(packagesWithDotSuffix, mixinTypes));
+ registry.setDomainObjectTypes(within(packagesWithDotSuffix, domainObjectTypes));
+ registry.setViewModelTypes(within(packagesWithDotSuffix, viewModelTypes));
+ registry.setXmlElementTypes(within(packagesWithDotSuffix, xmlElementTypes));
}
static <T> Set<Class<? extends T>> within(