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/05 12:07:08 UTC
[isis] 01/01: ISIS-1974: forward ports improvements on
parallelisation bootstrapping from master up to v2
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git
commit f231b6fbbfe9ee96d986508e051e5d085d469d7e
Merge: 9f262ab 4919e6c
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Fri Oct 5 12:41:45 2018 +0100
ISIS-1974: forward ports improvements on parallelisation bootstrapping from master up to v2
.../java/org/apache/isis/applib/AppManifest.java | 26 +++
.../applib/services/registry/ServiceRegistry.java | 11 +-
.../apache/isis/schema/utils/CommonDtoUtils.java | 2 +
...assFacetOnActionFromConfiguredRegexFactory.java | 3 +-
.../core/metamodel/services/ServicesInjector.java | 3 -
.../specloader/SpecificationCacheDefault.java | 26 ++-
.../metamodel/specloader/SpecificationLoader.java | 187 ++++++++++++++-------
.../classsubstitutor/ClassSubstitutor.java | 15 +-
.../specloader/specimpl/FacetedMethodsBuilder.java | 6 +-
.../specimpl/dflt/ObjectSpecificationDefault.java | 6 +-
.../dflt/ProgrammingModelForObjectSpecIdFacet.java | 45 -----
.../specloader/SpecificationCacheDefaultTest.java | 3 +-
.../SpecificationLoaderTestAbstract.java | 13 +-
core/pom.xml | 3 +
.../IsisComponentProvider.java | 10 +-
15 files changed, 225 insertions(+), 134 deletions(-)
diff --cc core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
index fdb9b2a,ba1d991..9d84fbf
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
@@@ -227,8 -234,143 +227,34 @@@ public interface AppManifest
public void setDomainServiceTypes(final Set<Class<?>> domainServiceTypes) {
this.domainServiceTypes = domainServiceTypes;
}
- //endregion
-
- //region > urlTypes
- public List<Vfs.UrlType> getUrlTypes() {
- final List<Vfs.UrlType> urlTypes = Lists.newArrayList();
- urlTypes.add(new EmptyIfFileEndingsUrlType(".pom", ".jnilib", "QTJava.zip"));
- urlTypes.add(new JettyConsoleUrlType());
- 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
+
- private static class EmptyIfFileEndingsUrlType implements Vfs.UrlType {
-
- private final List<String> fileEndings;
-
- private EmptyIfFileEndingsUrlType(final String... fileEndings) {
- this.fileEndings = Lists.newArrayList(fileEndings);
- }
-
- public boolean matches(URL url) {
- final String protocol = url.getProtocol();
- final String externalForm = url.toExternalForm();
- if (!protocol.equals("file")) {
- return false;
- }
- for (String fileEnding : fileEndings) {
- if (externalForm.endsWith(fileEnding))
- return true;
- }
- return false;
- }
-
- public Vfs.Dir createDir(final URL url) throws Exception {
- return emptyVfsDir(url);
- }
-
- private static Vfs.Dir emptyVfsDir(final URL url) {
- return new Vfs.Dir() {
- @Override
- public String getPath() {
- return url.toExternalForm();
- }
-
- @Override
- public Iterable<Vfs.File> getFiles() {
- return Collections.emptyList();
- }
-
- @Override
- public void close() {
- //
- }
- };
- }
- }
-
- private static class JettyConsoleUrlType implements Vfs.UrlType {
- public boolean matches(URL url) {
- final String protocol = url.getProtocol();
- final String externalForm = url.toExternalForm();
- final boolean matches = protocol.equals("file") && externalForm.contains("jetty-console") && externalForm.contains("-any-") && externalForm.endsWith("webapp/WEB-INF/classes/");
- return matches;
- }
-
- public Vfs.Dir createDir(final URL url) throws Exception {
- return new SystemDir(getFile(url));
- }
-
- /**
- * try to get {@link java.io.File} from url
- *
- * <p>
- * Copied from {@link Vfs} (not publicly accessible)
- * </p>
- */
- static java.io.File getFile(URL url) {
- java.io.File file;
- String path;
-
- try {
- path = url.toURI().getSchemeSpecificPart();
- if ((file = new java.io.File(path)).exists()) return file;
- } catch (URISyntaxException e) {
- }
-
- try {
- path = URLDecoder.decode(url.getPath(), "UTF-8");
- if (path.contains(".jar!")) path = path.substring(0, path.lastIndexOf(".jar!") + ".jar".length());
- if ((file = new java.io.File(path)).exists()) return file;
-
- } catch (UnsupportedEncodingException e) {
- }
-
- try {
- path = url.toExternalForm();
- if (path.startsWith("jar:")) path = path.substring("jar:".length());
- if (path.startsWith("file:")) path = path.substring("file:".length());
- if (path.contains(".jar!")) path = path.substring(0, path.indexOf(".jar!") + ".jar".length());
- if ((file = new java.io.File(path)).exists()) return file;
-
- path = path.replace("%20", " ");
- if ((file = new java.io.File(path)).exists()) return file;
-
- } catch (Exception e) {
- }
-
- return null;
- }
- }
}
public static class Util {
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/registry/ServiceRegistry.java
index b533b30,882c92d..2ff7363
--- a/core/applib/src/main/java/org/apache/isis/applib/services/registry/ServiceRegistry.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/registry/ServiceRegistry.java
@@@ -30,38 -26,10 +30,41 @@@ public interface ServiceRegistry
@Programmatic
<T> T injectServicesInto(final T domainObject);
+
+ /**
+ * @return Stream of all currently registered service instances.
+ */
+ @Programmatic
+ Stream<Object> streamServices();
+
+ @Programmatic
+ <T> Stream<T> streamServices(Class<T> serviceClass);
+
+ /**
+ * Returns the first registered domain service implementing the requested type.
+ *
+ * <p>
+ * Typically there will only ever be one domain service implementing a given type,
- * (eg {@link PublishingService}), but for some services there can be more than one
- * (eg {@link ExceptionRecognizer}).
- *
- * @see #lookupServices(Class)
++ * (eg {@link org.apache.isis.applib.services.repository.RepositoryService}), but for some services there can be
++ * more than one (eg {@link ExceptionRecognizer}).
+ */
@Programmatic
- <T> T lookupService(Class<T> service);
+ public default <T> Optional<T> lookupService(final Class<T> serviceClass) {
+ return streamServices(serviceClass)
+ .findFirst();
+ }
@Programmatic
- <T> Iterable<T> lookupServices(Class<T> service);
++ public default boolean isService(final Class<?> serviceClass) {
++ return lookupService(serviceClass).isPresent();
++ }
+
++ @Programmatic
+ public default <T> T lookupServiceElseFail(final Class<T> serviceClass) {
+ return streamServices(serviceClass)
+ .findFirst()
+ .orElseThrow(()->
+ new IllegalStateException("Could not locate service of type '" + serviceClass + "'"));
+ }
+
}
diff --cc core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java
index 53dc2df,81d552d..579d90d
--- a/core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java
+++ b/core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java
@@@ -59,43 -57,53 +59,45 @@@ import org.joda.time.LocalTime
public final class CommonDtoUtils {
- //region > PARAM_DTO_TO_NAME, PARAM_DTO_TO_TYPE
-
- public static final Function<ParamDto, String> PARAM_DTO_TO_NAME = new Function<ParamDto, String>() {
- @Override public String apply(final ParamDto paramDto) {
- return paramDto.getName();
- }
- };
- public static final Function<ParamDto, ValueType> PARAM_DTO_TO_TYPE = new Function<ParamDto, ValueType>() {
- @Override public ValueType apply(final ParamDto paramDto) {
- return paramDto.getType();
- }
- };
- //endregion
-
- //region > asValueType
- private final static ImmutableMap<Class<?>, ValueType> valueTypeByClass =
- new ImmutableMap.Builder<Class<?>, ValueType>()
- .put(String.class, ValueType.STRING)
- .put(byte.class, ValueType.BYTE)
- .put(Byte.class, ValueType.BYTE)
- .put(short.class, ValueType.SHORT)
- .put(Short.class, ValueType.SHORT)
- .put(int.class, ValueType.INT)
- .put(Integer.class, ValueType.INT)
- .put(long.class, ValueType.LONG)
- .put(Long.class, ValueType.LONG)
- .put(char.class, ValueType.CHAR)
- .put(Character.class, ValueType.CHAR)
- .put(boolean.class, ValueType.BOOLEAN)
- .put(Boolean.class, ValueType.BOOLEAN)
- .put(float.class, ValueType.FLOAT)
- .put(Float.class, ValueType.FLOAT)
- .put(double.class, ValueType.DOUBLE)
- .put(Double.class, ValueType.DOUBLE)
- .put(BigInteger.class, ValueType.BIG_INTEGER)
- .put(BigDecimal.class, ValueType.BIG_DECIMAL)
- .put(DateTime.class, ValueType.JODA_DATE_TIME)
- .put(LocalDateTime.class, ValueType.JODA_LOCAL_DATE_TIME)
- .put(LocalDate.class, ValueType.JODA_LOCAL_DATE)
- .put(LocalTime.class, ValueType.JODA_LOCAL_TIME)
- .put(java.sql.Timestamp.class, ValueType.JAVA_SQL_TIMESTAMP)
- .put(Blob.class, ValueType.BLOB)
- .put(Clob.class, ValueType.CLOB)
- .build();
+ // -- PARAM_DTO_TO_NAME, PARAM_DTO_TO_TYPE
+
+ public static final Function<ParamDto, String> PARAM_DTO_TO_NAME = ParamDto::getName;
+ public static final Function<ParamDto, ValueType> PARAM_DTO_TO_TYPE = ParamDto::getType;
+
+ // -- asValueType
+ private final static Map<Class<?>, ValueType> valueTypeByClass =
+ _Maps.unmodifiableEntries(
+ entry(String.class, ValueType.STRING),
+ entry(String.class, ValueType.STRING),
+ entry(byte.class, ValueType.BYTE),
+ entry(Byte.class, ValueType.BYTE),
+ entry(short.class, ValueType.SHORT),
+ entry(Short.class, ValueType.SHORT),
+ entry(int.class, ValueType.INT),
+ entry(Integer.class, ValueType.INT),
+ entry(long.class, ValueType.LONG),
+ entry(Long.class, ValueType.LONG),
+ entry(char.class, ValueType.CHAR),
+ entry(Character.class, ValueType.CHAR),
+ entry(boolean.class, ValueType.BOOLEAN),
+ entry(Boolean.class, ValueType.BOOLEAN),
+ entry(float.class, ValueType.FLOAT),
+ entry(Float.class, ValueType.FLOAT),
+ entry(double.class, ValueType.DOUBLE),
+ entry(Double.class, ValueType.DOUBLE),
+ entry(BigInteger.class, ValueType.BIG_INTEGER),
+ entry(BigDecimal.class, ValueType.BIG_DECIMAL),
+ entry(DateTime.class, ValueType.JODA_DATE_TIME),
+ entry(LocalDateTime.class, ValueType.JODA_LOCAL_DATE_TIME),
+ entry(LocalDate.class, ValueType.JODA_LOCAL_DATE),
+ entry(LocalTime.class, ValueType.JODA_LOCAL_TIME),
+ entry(java.sql.Timestamp.class, ValueType.JAVA_SQL_TIMESTAMP),
+ entry(Blob.class, ValueType.BLOB),
+ entry(Clob.class, ValueType.CLOB)
+ );
+ public static Collection<Class<?>> VALUE_TYPES = valueTypeByClass.keySet();
+
public static ValueType asValueType(final Class<?> type) {
final ValueType valueType = valueTypeByClass.get(type);
if (valueType != null) {
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
index a3ed62b,81c23d2..7b95188
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
@@@ -499,10 -584,10 +499,7 @@@ public class ServicesInjector implement
public DeploymentCategoryProvider getDeploymentCategoryProvider() {
return deploymentCategoryProvider != null
? deploymentCategoryProvider
- : (deploymentCategoryProvider = lookupServiceElseFail(DeploymentCategoryProvider.class));
+ : (deploymentCategoryProvider = lookupServiceElseFail(DeploymentCategoryProvider.class));
}
-
--
- //endregion
--
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefault.java
index a55ea74,7de1890..0f53f69
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefault.java
@@@ -27,12 -28,20 +27,20 @@@ import org.apache.isis.commons.internal
import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
- import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
- import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
+ /**
+ * This is populated in two parts.
+ *
+ * Initially the #specByClassName is populated using {@link #cache(String, ObjectSpecification)}. This allows
+ * {@link #allSpecifications()} to return a list of specs.
+ *
+ * Later on, {@link #init(Map)} is called which populates #classNameBySpecId.
+ *
+ * TODO: the information passed to #init actually comes from the cache itself (the caller calls #allSpecifications() first) so this could be simplified
+ */
class SpecificationCacheDefault {
-
- private final Map<String, ObjectSpecification> specByClassName = Maps.newHashMap();
+
+ private final Map<String, ObjectSpecification> specByClassName = _Maps.newHashMap();
private Map<ObjectSpecId, String> classNameBySpecId;
public ObjectSpecification get(final String className) {
@@@ -62,12 -71,10 +70,11 @@@
}
/**
- * Populated as a result of running {@link MetaModelValidator#validate(ValidationFailures)} validation} after
- * xxxallxxx most specs have been loaded.
*/
- void setCacheBySpecId(final Map<ObjectSpecId, ObjectSpecification> specById) {
- this.classNameBySpecId = _Maps.newHashMap();
+ synchronized void init(final Map<ObjectSpecId, ObjectSpecification> specById) {
- final Map<ObjectSpecId, String> classNameBySpecId = Maps.newHashMap();
- final Map<String, ObjectSpecification> specByClassName = Maps.newHashMap();
++ final Map<ObjectSpecId, String> classNameBySpecId = _Maps.newHashMap();
++ final Map<String, ObjectSpecification> specByClassName = _Maps.newHashMap();
+
for (ObjectSpecId objectSpecId : specById.keySet()) {
final ObjectSpecification objectSpec = specById.get(objectSpecId);
final String className = objectSpec.getCorrespondingClass().getName();
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index c7c01a9,244ac15..fafcd4b
--- 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
@@@ -17,12 -17,18 +17,13 @@@
package org.apache.isis.core.metamodel.specloader;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
- import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
++import java.util.function.Predicate;
++import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@@ -40,9 -44,9 +41,8 @@@ import org.apache.isis.core.commons.exc
import org.apache.isis.core.commons.lang.ClassUtil;
import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facets.FacetFactory;
- import org.apache.isis.core.metamodel.facets.MethodRemoverConstants;
import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
-import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader;
import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.core.metamodel.services.ServicesInjector;
import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
@@@ -167,16 -176,59 +155,53 @@@ public class SpecificationLoader implem
state = State.CACHING;
- loadSpecificationsForServices();
- loadSpecificationsForMixins();
- cacheBySpecId();
+ // need to completely load services and mixins (synchronously)
- final List<ObjectSpecification> specificationsFromRegistry = Lists.newArrayList();
++ final List<ObjectSpecification> specificationsFromRegistry = _Lists.newArrayList();
+
+ loadSpecificationsFor(
+ CommonDtoUtils.VALUE_TYPES, null,
+ IntrospectionStrategy.STUB, specificationsFromRegistry);
+ loadSpecificationsFor(
- allServiceClasses(), NatureOfService.DOMAIN,
++ streamServiceClasses().collect(Collectors.toList()), NatureOfService.DOMAIN,
+ IntrospectionStrategy.STUB, specificationsFromRegistry);
+ loadSpecificationsFor(
+ AppManifest.Registry.instance().getMixinTypes(), null,
+ IntrospectionStrategy.STUB, specificationsFromRegistry);
+ loadSpecificationsFor(
+ AppManifest.Registry.instance().getDomainObjectTypes(), null,
+ IntrospectionStrategy.STUB, specificationsFromRegistry);
+ loadSpecificationsFor(
+ AppManifest.Registry.instance().getViewModelTypes(), null,
+ IntrospectionStrategy.STUB, specificationsFromRegistry);
+ loadSpecificationsFor(
+ AppManifest.Registry.instance().getXmlElementTypes(), null,
+ IntrospectionStrategy.STUB, specificationsFromRegistry);
state = State.INTROSPECTING;
+ final Collection<ObjectSpecification> cachedSpecifications = allCachedSpecifications();
+
+
+ // for debugging only
+ LOG.info(String.format(
+ "specificationsFromRegistry.size = %d ; cachedSpecifications.size = %d",
+ specificationsFromRegistry.size(), cachedSpecifications.size()));
+
- ImmutableList<ObjectSpecification> registryNotCached = FluentIterable.from(specificationsFromRegistry)
- .filter(new Predicate<ObjectSpecification>() {
- @Override
- public boolean apply(final ObjectSpecification objectSpecification) {
- return !cachedSpecifications.contains(objectSpecification);
- }
- }).toList();
- ImmutableList<ObjectSpecification> cachedNotRegistry = FluentIterable.from(cachedSpecifications)
- .filter(new Predicate<ObjectSpecification>() {
- @Override
- public boolean apply(final ObjectSpecification objectSpecification) {
- return !specificationsFromRegistry.contains(objectSpecification);
- }
- }).toList();
++ List<ObjectSpecification> registryNotCached = specificationsFromRegistry.stream()
++ .filter(spec -> !cachedSpecifications.contains(spec))
++ .collect(Collectors.toList());
++ List<ObjectSpecification> cachedNotRegistry = cachedSpecifications.stream()
++ .filter(spec -> !specificationsFromRegistry.contains(spec))
++ .collect(Collectors.toList());
+
+ LOG.info(String.format(
+ "registryNotCached.size = %d ; cachedNotRegistry.size = %d",
+ registryNotCached.size(), cachedNotRegistry.size()));
+
- final Collection<ObjectSpecification> objectSpecifications = allSpecifications();
- final List<Callable<Object>> callables = Lists.newArrayList();
+
+ final List<Callable<Object>> callables = _Lists.newArrayList();
- for (final ObjectSpecification specification : objectSpecifications) {
+ for (final ObjectSpecification specification : specificationsFromRegistry) {
++
Callable<Object> callable = new Callable<Object>() {
@Override
public Object call() {
@@@ -195,39 -247,47 +220,44 @@@
List<Future<Object>> futures = threadPoolSupport.invokeAll(callables);
threadPoolSupport.joinGatherFailures(futures);
- }
- private void loadSpecificationsForServices() {
- streamServiceClasses()
- .forEach(serviceClass->{
- 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,
- MethodRemoverConstants.NULL, objectSpecification);
- });
+ // for debugging only
+ final Collection<ObjectSpecification> cachedSpecificationsAfter = allCachedSpecifications();
- ImmutableList<ObjectSpecification> cachedAfterNotBefore = FluentIterable.from(cachedSpecificationsAfter)
- .filter(new Predicate<ObjectSpecification>() {
- @Override
- public boolean apply(final ObjectSpecification objectSpecification) {
- return !cachedSpecifications.contains(objectSpecification);
- }
- }).toList();
++ List<ObjectSpecification> cachedAfterNotBefore = cachedSpecificationsAfter.stream()
++ .filter(spec -> !cachedSpecifications.contains(spec))
++ .collect(Collectors.toList());
+ LOG.info(String.format("cachedSpecificationsAfter.size = %d ; cachedAfterNotBefore.size = %d",
+ cachedSpecificationsAfter.size(), cachedAfterNotBefore.size()));
+
+
+ // only after full introspection has occured do we cache ObjectSpecifications
+ // by their ObjectSpecId.
+ // the cache (SpecificationCacheDefault will fail-fast as not initialized
+ cacheBySpecId(specificationsFromRegistry);
+
}
- private void loadSpecificationsForMixins() {
+ private void loadSpecificationsFor(
+ final Collection<Class<?>> domainTypes,
+ final NatureOfService natureOfServiceFallback,
+ final IntrospectionStrategy introspectionStrategy,
+ final List<ObjectSpecification> appendTo) {
- final Set<Class<?>> mixinTypes = AppManifest.Registry.instance().getMixinTypes();
- if(mixinTypes == null) {
- return;
- }
- for (final Class<?> mixinType : mixinTypes) {
- ObjectSpecification objectSpecification = internalLoadSpecification(mixinType);
- facetProcessorObjectSpecId.process(
- mixinType,
- MethodRemoverConstants.NULL, objectSpecification);
+ for (final Class<?> domainType : domainTypes) {
+ ObjectSpecification objectSpecification =
+ internalLoadSpecification(domainType, natureOfServiceFallback, introspectionStrategy);
+
+ if(objectSpecification != null) {
+ appendTo.add(objectSpecification);
+ }
}
}
- private void cacheBySpecId() {
++
+ private void cacheBySpecId(final Collection<ObjectSpecification> objectSpecifications) {
- final Map<ObjectSpecId, ObjectSpecification> specById = Maps.newHashMap();
+ final Map<ObjectSpecId, ObjectSpecification> specById = _Maps.newHashMap();
- for (final ObjectSpecification objSpec : allCachedSpecifications()) {
+ for (final ObjectSpecification objSpec : objectSpecifications) {
final ObjectSpecId objectSpecId = objSpec.getSpecId();
if (objectSpecId == null) {
continue;
@@@ -435,14 -524,16 +484,16 @@@
// ... 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(
+ final ConfigurationServiceInternal configService = servicesInjector.lookupServiceElseFail(
ConfigurationServiceInternal.class);
final FacetedMethodsBuilderContext facetedMethodsBuilderContext =
new FacetedMethodsBuilderContext(
- this, facetProcessor, layoutMetadataReaders, configService);
+ this, facetProcessor, configService);
+
+ final NatureOfService natureOfServiceIfAny = natureOfServiceFrom(cls, fallback);
+
return new ObjectSpecificationDefault(cls, facetedMethodsBuilderContext,
servicesInjector, facetProcessor, natureOfServiceIfAny);
}
@@@ -560,9 -669,14 +618,12 @@@
return cache.get(fullyQualifiedClassName) != null;
}
- //endregion
-
- //region > lookupBySpecId
+ // -- lookupBySpecId
@Programmatic
public ObjectSpecification lookupBySpecId(ObjectSpecId objectSpecId) {
+ if(!cache.isInitialized()) {
+ throw new IllegalStateException("Internal cache not yet initialized");
+ }
final ObjectSpecification objectSpecification = cache.getByObjectType(objectSpecId);
if(objectSpecification == null) {
// fallback
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/classsubstitutor/ClassSubstitutor.java
index 31e461d,df2ac9a..cf1255b
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/classsubstitutor/ClassSubstitutor.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/classsubstitutor/ClassSubstitutor.java
@@@ -114,10 -114,23 +114,23 @@@ public class ClassSubstitutor
return true;
}
- return classesToIgnore.contains(cls) || classNamesToIgnore.contains(cls.getCanonicalName());
+ try{
+ return classesToIgnore.contains(cls) || classNamesToIgnore.contains(cls.getCanonicalName());
+ } catch(java.lang.NoClassDefFoundError e) {
+
+ try{
+ if(cls.isAnonymousClass()) {
+ return shouldIgnore(cls.getSuperclass());
+ } else {
+ return false;
+ }
+ } catch(java.lang.NoClassDefFoundError ex) {
+ return true;
+ }
+ }
}
- //endregion
+
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index d562294,119c8f4..e0ca905
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
@@@ -161,9 -162,14 +161,14 @@@ public class ObjectSpecificationDefaul
updateInterfaces(interfaceSpecList);
}
+ updateAssociationsAndActions();
+ }
+
+ private synchronized void updateAssociationsAndActions() {
+
// associations and actions
if(isNotIntrospected()) {
- final List<ObjectAssociation> associations = createAssociations(metadataProperties);
+ final List<ObjectAssociation> associations = createAssociations();
sortAndUpdateAssociations(associations);
}
diff --cc core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefaultTest.java
index eba6176,9cf8ce8..ac05bb2
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefaultTest.java
@@@ -107,10 -106,10 +106,10 @@@ public class SpecificationCacheDefaultT
@Test
public void getByObjectType_whenSet() {
- Map<ObjectSpecId, ObjectSpecification> specByObjectType = Maps.newHashMap();
+ Map<ObjectSpecId, ObjectSpecification> specByObjectType = _Maps.newHashMap();
specByObjectType.put(ObjectSpecId.of("CUS"), customerSpec);
- specificationCache.setCacheBySpecId(specByObjectType);
+ specificationCache.init(specByObjectType);
final ObjectSpecification objectSpec = specificationCache.getByObjectType(ObjectSpecId.of("CUS"));
assertSame(objectSpec, customerSpec);
diff --cc core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderTestAbstract.java
index 907ce73,8e386f2..d697f59
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderTestAbstract.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderTestAbstract.java
@@@ -19,19 -19,18 +19,20 @@@
package org.apache.isis.core.metamodel.specloader;
- import org.apache.isis.commons.internal.collections._Lists;
-import com.google.common.collect.Lists;
--
import org.jmock.Expectations;
import org.jmock.auto.Mock;
+import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
++import org.apache.isis.applib.AppManifest;
import org.apache.isis.applib.services.grid.GridService;
import org.apache.isis.applib.services.message.MessageService;
++import org.apache.isis.commons.internal.collections._Lists;
++import org.apache.isis.commons.internal.collections._Sets;
import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
import org.apache.isis.core.commons.config.IsisConfigurationDefault;
import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
@@@ -113,6 -114,6 +114,14 @@@ public abstract class SpecificationLoad
stubServicesInjector.addFallbackIfRequired(SpecificationLoader.class, specificationLoader);
++ AppManifest.Registry.instance().setDomainServiceTypes(_Sets.newHashSet());
++ AppManifest.Registry.instance().setFixtureScriptTypes(_Sets.newHashSet());
++ AppManifest.Registry.instance().setDomainObjectTypes(_Sets.newHashSet());
++ AppManifest.Registry.instance().setMixinTypes(_Sets.newHashSet());
++ AppManifest.Registry.instance().setViewModelTypes(_Sets.newHashSet());
++ AppManifest.Registry.instance().setPersistenceCapableTypes(_Sets.newHashSet());
++ AppManifest.Registry.instance().setXmlElementTypes(_Sets.newHashSet());
++
specificationLoader.init();
specification = loadSpecification(specificationLoader);
diff --cc core/pom.xml
index 4fc7a63,88e31a9..300893d
--- a/core/pom.xml
+++ b/core/pom.xml
@@@ -46,9 -46,12 +46,12 @@@
<inceptionYear>2010</inceptionYear>
<properties>
- <revision>1.0.0-SNAPSHOT</revision>
+ <revision>2.0.0-M2-SNAPSHOT</revision>
<isis.version>${revision}</isis.version>
+ <isis.skipTests>false</isis.skipTests>
+ <maven.test.skip>${isis.skipTests}</maven.test.skip>
+
<jar-plugin.automaticModuleName>org.apache.isis.core</jar-plugin.automaticModuleName>
<git-plugin.propertiesDir>org/apache/isis/core</git-plugin.propertiesDir>
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
index 4f8f514,1e69806..52e8e19
--- 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
@@@ -23,21 -23,30 +23,24 @@@ import java.util.Collection
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
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;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import org.reflections.Reflections;
-import org.reflections.vfs.Vfs;
import org.apache.isis.applib.AppManifest;
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.commons.internal.base._NullSafe;
+import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.collections._Sets;
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.config.IsisConfigurationDefault;
import org.apache.isis.core.commons.factory.InstanceUtil;
@@@ -125,31 -133,39 +128,34 @@@ public abstract class IsisComponentProv
}
private void findAndRegisterTypes(final AppManifest appManifest) {
- final Iterable<String> modulePackages = modulePackageNamesFrom(appManifest);
+ final Stream<String> modulePackages = modulePackageNamesFrom(appManifest);
final AppManifest.Registry registry = AppManifest.Registry.instance();
- final List<String> moduleAndFrameworkPackages = Lists.newArrayList();
+ final List<String> moduleAndFrameworkPackages = _Lists.newArrayList();
moduleAndFrameworkPackages.addAll(AppManifest.Registry.FRAMEWORK_PROVIDED_SERVICES);
- Iterables.addAll(moduleAndFrameworkPackages, modulePackages);
+
+ modulePackages.forEach(moduleAndFrameworkPackages::add);
- Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
+ final ClassDiscovery discovery = ClassDiscoveryPlugin.get().discover(moduleAndFrameworkPackages);
- final Reflections reflections = new Reflections(moduleAndFrameworkPackages);
+ final Set<Class<?>> domainServiceTypes = discovery.getTypesAnnotatedWith(DomainService.class);
+ final Set<Class<?>> persistenceCapableTypes = PersistenceCapableTypeFinder.find(discovery);
+ final Set<Class<? extends FixtureScript>> fixtureScriptTypes = discovery.getSubTypesOf(FixtureScript.class);
- final Set<Class<?>> domainServiceTypes = reflections.getTypesAnnotatedWith(DomainService.class);
- final Set<Class<?>> persistenceCapableTypes = reflections.getTypesAnnotatedWith(PersistenceCapable.class);
- final Set<Class<? extends FixtureScript>> fixtureScriptTypes = reflections.getSubTypesOf(FixtureScript.class);
+ final Set<Class<?>> mixinTypes = _Sets.newHashSet();
+ mixinTypes.addAll(discovery.getTypesAnnotatedWith(Mixin.class));
- final Set<Class<?>> mixinTypes = Sets.newHashSet();
- mixinTypes.addAll(reflections.getTypesAnnotatedWith(Mixin.class));
+ final Set<Class<?>> domainObjectTypes = discovery.getTypesAnnotatedWith(DomainObject.class);
+ domainObjectTypes.stream()
+ .filter(input -> {
+ final DomainObject annotation = input.getAnnotation(DomainObject.class);
+ return annotation.nature() == Nature.MIXIN;
+ })
+ .forEach(mixinTypes::add);
- final Set<Class<?>> domainObjectTypes = reflections.getTypesAnnotatedWith(DomainObject.class);
- mixinTypes.addAll(
- Lists.newArrayList(Iterables.filter(domainObjectTypes, new Predicate<Class<?>>() {
- @Override
- public boolean apply(@Nullable final Class<?> input) {
- if(input == null) { return false; }
- final DomainObject annotation = input.getAnnotation(DomainObject.class);
- return annotation.nature() == Nature.MIXIN;
- }
- }))
- );
-
- final Set<Class<?>> viewModelTypes = reflections.getTypesAnnotatedWith(ViewModel.class);
- final Set<Class<?>> xmlElementTypes = reflections.getTypesAnnotatedWith(XmlElement.class);
++ final Set<Class<?>> viewModelTypes = discovery.getTypesAnnotatedWith(ViewModel.class);
++ final Set<Class<?>> xmlElementTypes = discovery.getTypesAnnotatedWith(XmlElement.class);
+
// add in any explicitly registered services...
domainServiceTypes.addAll(appManifest.getAdditionalServices());