This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/isis.git
commit 31fdc2ec9d50b0b06e23b3ffb31e6a56f47ec83d Author: danhaywood <d...@haywood-associates.co.uk> AuthorDate: Tue Dec 3 09:39:56 2019 +0000 ISIS-2197: ClassSubstitutor is now Spring-managed. --- .../facets/object/mixin/MixinIntendedAs.java | 15 +++-- .../facets/param/name/ParameterNameFacetTest.java | 7 ++- ...jectSpecIdFacetDerivedFromClassNameFactory.java | 11 +++- .../progmodel/ProgrammingModelAbstract.java | 9 +++ .../dflt/ProgrammingModelFacetsJava8.java | 8 ++- .../classsubstitutor/ClassSubstitutor.java | 41 ++++++++++++ .../ClassSubstitutorAbstract.java} | 73 +++++++++------------- .../classsubstitutor/ClassSubstitutorDefault.java | 62 ++++++++++++++++++ .../isis/metamodel/spec/ObjectSpecification.java | 3 +- .../specloader/ProgrammingModelServiceDefault.java | 4 +- .../metamodel/specloader/SpecificationLoader.java | 3 +- .../specloader/SpecificationLoaderDefault.java | 8 +-- .../specloader/specimpl/FacetedMethodsBuilder.java | 17 ++--- .../specimpl/dflt/ObjectSpecificationDefault.java | 16 ++--- .../ViewModelSemanticCheckingFacetFactoryTest.java | 4 +- ...SpecIdFacetDerivedFromClassNameFactoryTest.java | 1 + .../SpecificationLoaderTestAbstract.java | 10 +-- .../ClassSubstitutorTest_getClass.java | 4 +- .../JdoDiscriminatorAnnotationFacetFactory.java | 24 ++++--- 19 files changed, 227 insertions(+), 93 deletions(-) diff --git a/core/detached-tests/src/test/java/org/apache/isis/metamodel/facets/object/mixin/MixinIntendedAs.java b/core/detached-tests/src/test/java/org/apache/isis/metamodel/facets/object/mixin/MixinIntendedAs.java index 05de7e6..e3f9c30 100644 --- a/core/detached-tests/src/test/java/org/apache/isis/metamodel/facets/object/mixin/MixinIntendedAs.java +++ b/core/detached-tests/src/test/java/org/apache/isis/metamodel/facets/object/mixin/MixinIntendedAs.java @@ -20,6 +20,10 @@ package org.apache.isis.metamodel.facets.object.mixin; import java.lang.reflect.Method; +import org.apache.isis.applib.services.inject.ServiceInjector; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.Matchers; import org.mockito.Mockito; import org.apache.isis.applib.Identifier; @@ -39,10 +43,10 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModelInitFilterDefault; import org.apache.isis.metamodel.progmodels.dflt.ProgrammingModelFacetsJava8; import org.apache.isis.metamodel.services.title.TitleServiceDefault; -import static org.mockito.Mockito.when; - import lombok.val; +import static org.mockito.Mockito.*; + abstract class MixinIntendedAs { protected ProgrammingModelFacetsJava8 programmingModel; @@ -50,8 +54,10 @@ abstract class MixinIntendedAs { protected void setUp() throws Exception { - programmingModel = new ProgrammingModelFacetsJava8(); - + val mockServiceInjector = Mockito.mock(ServiceInjector.class); + when(mockServiceInjector.injectServicesInto(ArgumentMatchers.any())).thenAnswer(i -> i.getArguments()[0]); + programmingModel = new ProgrammingModelFacetsJava8(mockServiceInjector); + val mockTranslationService = Mockito.mock(TranslationService.class); when(mockTranslationService.getMode()).thenReturn(Mode.DISABLED); @@ -62,6 +68,7 @@ abstract class MixinIntendedAs { .programmingModel(programmingModel) .translationService(mockTranslationService) .titleService(new TitleServiceDefault()) + .serviceInjector(mockServiceInjector) .build(); ((ProgrammingModelAbstract)programmingModel) diff --git a/core/detached-tests/src/test/java/org/apache/isis/metamodel/facets/param/name/ParameterNameFacetTest.java b/core/detached-tests/src/test/java/org/apache/isis/metamodel/facets/param/name/ParameterNameFacetTest.java index 9a2aed9..28c6ae7 100644 --- a/core/detached-tests/src/test/java/org/apache/isis/metamodel/facets/param/name/ParameterNameFacetTest.java +++ b/core/detached-tests/src/test/java/org/apache/isis/metamodel/facets/param/name/ParameterNameFacetTest.java @@ -20,6 +20,7 @@ package org.apache.isis.metamodel.facets.param.name; import java.lang.reflect.Method; +import org.apache.isis.applib.services.inject.ServiceInjector; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -33,6 +34,7 @@ import org.apache.isis.metamodel.facets.all.named.NamedFacet; import org.apache.isis.metamodel.progmodel.ProgrammingModelAbstract; import org.apache.isis.metamodel.progmodel.ProgrammingModelInitFilterDefault; import org.apache.isis.metamodel.progmodels.dflt.ProgrammingModelFacetsJava8; +import org.mockito.Mockito; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -49,7 +51,10 @@ public class ParameterNameFacetTest extends AbstractFacetFactoryJUnit4TestCase { @Before public void setUp() throws Exception { - programmingModel = new ProgrammingModelFacetsJava8(); + + val mockServiceInjector = Mockito.mock(ServiceInjector.class); + + programmingModel = new ProgrammingModelFacetsJava8(mockServiceInjector); val metaModelContext = MetaModelContext_forTesting.builder().build(); diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java index da8c887..1032b42 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java @@ -21,6 +21,7 @@ package org.apache.isis.metamodel.facets.object.objectspecid.classname; import java.util.stream.Stream; +import javax.inject.Inject; import javax.xml.bind.annotation.XmlType; import org.apache.isis.applib.annotation.NatureOfService; @@ -33,20 +34,23 @@ import org.apache.isis.metamodel.facets.ObjectSpecIdFacetFactory; import org.apache.isis.metamodel.facets.object.domainservice.DomainServiceFacet; import org.apache.isis.metamodel.facets.object.objectspecid.ObjectSpecIdFacet; import org.apache.isis.metamodel.progmodel.ProgrammingModel; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutorDefault; import org.apache.isis.metamodel.spec.ObjectSpecification; import org.apache.isis.metamodel.spec.feature.Contributed; import org.apache.isis.metamodel.spec.feature.ObjectAction; -import org.apache.isis.metamodel.specloader.classsubstitutor.ClassSubstitutor; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutor; import org.apache.isis.metamodel.specloader.validator.MetaModelValidator; import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting; +import lombok.Setter; import lombok.val; public class ObjectSpecIdFacetDerivedFromClassNameFactory extends FacetFactoryAbstract implements MetaModelRefiner, ObjectSpecIdFacetFactory { - private final ClassSubstitutor classSubstitutor = new ClassSubstitutor(); + @Inject + private ClassSubstitutor classSubstitutor = new ClassSubstitutorDefault(); // default for testing purposes only, overwritten in prod public ObjectSpecIdFacetDerivedFromClassNameFactory() { super(FeatureType.OBJECTS_ONLY); @@ -61,6 +65,9 @@ implements MetaModelRefiner, ObjectSpecIdFacetFactory { } final Class<?> cls = processClassContext.getCls(); final Class<?> substitutedClass = classSubstitutor.getClass(cls); + if(substitutedClass == null) { + return; + } final ObjectSpecIdFacet objectSpecIdFacet = createObjectSpecIdFacet(facetHolder, substitutedClass); FacetUtil.addFacet(objectSpecIdFacet); diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodel/ProgrammingModelAbstract.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodel/ProgrammingModelAbstract.java index 238b873..8b691d9 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodel/ProgrammingModelAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodel/ProgrammingModelAbstract.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.function.Supplier; import java.util.stream.Stream; +import org.apache.isis.applib.services.inject.ServiceInjector; import org.apache.isis.commons.internal.collections._Lists; import org.apache.isis.commons.internal.collections._Multimaps; import org.apache.isis.commons.internal.collections._Multimaps.SetMultimap; @@ -44,10 +45,16 @@ import lombok.val; public abstract class ProgrammingModelAbstract implements ProgrammingModel { + private final ServiceInjector serviceInjector; + private List<FacetFactory> unmodifiableFactories; private List<MetaModelValidator> unmodifiableValidators; private List<ObjectSpecificationPostProcessor> unmodifiablePostProcessors; + public ProgrammingModelAbstract(final ServiceInjector serviceInjector) { + this.serviceInjector = serviceInjector; + } + /** * Finalizes the factory collection, can not be modified afterwards. * @param filter - the final programming model will only contain factories accepted by this filter @@ -84,6 +91,7 @@ public abstract class ProgrammingModelAbstract implements ProgrammingModel { Marker ... markers) { assertNotInitialized(); + serviceInjector.injectServicesInto(instance); val factoryEntry = ProgrammingModelEntry.of(instance, markers); factoryEntriesByOrder.putElement(order, factoryEntry); } @@ -95,6 +103,7 @@ public abstract class ProgrammingModelAbstract implements ProgrammingModel { Marker... markers) { assertNotInitialized(); + serviceInjector.injectServicesInto(instance); val validatorEntry = ProgrammingModelEntry.of(instance, markers); validatorEntriesByOrder.putElement(order, validatorEntry); } diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java index f500dc9..be2ff1c 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java @@ -17,6 +17,7 @@ package org.apache.isis.metamodel.progmodels.dflt; +import org.apache.isis.applib.services.inject.ServiceInjector; import org.apache.isis.metamodel.facets.actions.action.ActionAnnotationFacetFactory; import org.apache.isis.metamodel.facets.actions.action.ActionChoicesForCollectionParameterFacetFactory; import org.apache.isis.metamodel.facets.actions.defaults.method.ActionDefaultsFacetViaMethodFactory; @@ -151,9 +152,10 @@ import org.apache.isis.metamodel.services.title.TitlesAndTranslationsValidator; @SuppressWarnings("deprecation") public final class ProgrammingModelFacetsJava8 extends ProgrammingModelAbstract { - - public ProgrammingModelFacetsJava8() { - + + public ProgrammingModelFacetsJava8(ServiceInjector serviceInjector) { + super(serviceInjector); + // must be first, so any Facets created can be replaced by other // FacetFactorys later. addFactory(FacetProcessingOrder.A1_FALLBACK_DEFAULTS, FallbackFacetFactory.class); diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutor.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutor.java new file mode 100644 index 0000000..0f26fe7 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutor.java @@ -0,0 +1,41 @@ +/* + * 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.isis.metamodel.services.classsubstitutor; + +import java.util.Set; + +import org.apache.isis.applib.annotation.Programmatic; +import org.apache.isis.commons.internal.base._Blackhole; +import org.apache.isis.commons.internal.collections._Sets; +import org.apache.isis.metamodel.commons.ClassUtil; +import org.apache.isis.metamodel.specloader.classsubstitutor.ProxyEnhanced; +import org.springframework.stereotype.Component; + +import lombok.val; + +import javax.annotation.PostConstruct; + +/** + * Provides capability to translate or ignore classes. + */ +public interface ClassSubstitutor { + + Class<?> getClass(Class<?> type); +} diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/classsubstitutor/ClassSubstitutor.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java similarity index 72% rename from core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/classsubstitutor/ClassSubstitutor.java rename to core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java index 9109e87..6b33b9f 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/classsubstitutor/ClassSubstitutor.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java @@ -17,7 +17,9 @@ * under the License. */ -package org.apache.isis.metamodel.specloader.classsubstitutor; +package org.apache.isis.metamodel.services.classsubstitutor; + +import lombok.val; import java.util.Set; @@ -25,46 +27,20 @@ import org.apache.isis.applib.annotation.Programmatic; import org.apache.isis.commons.internal.base._Blackhole; import org.apache.isis.commons.internal.collections._Sets; import org.apache.isis.metamodel.commons.ClassUtil; +import org.apache.isis.metamodel.specloader.classsubstitutor.ProxyEnhanced; +import org.springframework.stereotype.Component; -import lombok.val; - -/** - * Provides capability to translate or ignore classes. - */ -public class ClassSubstitutor { - - // -- constructor - - public ClassSubstitutor() { - ignore("org.apache.isis.applib.DomainObjectContainer"); //TODO [ahuber] still required? - - // ignore cglib - ignore("net.sf.cglib.proxy.Factory"); - ignore("net.sf.cglib.proxy.MethodProxy"); - ignore("net.sf.cglib.proxy.Callback"); - - // ignore javassist - ignore("javassist.util.proxy.ProxyObject"); - ignore("javassist.util.proxy.MethodHandler"); - - ignore("org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator"); - - ignorePackage("com.fasterxml.jackson."); - ignorePackage("com.google.gson."); - - } - - - // -- getClass(Class) +public abstract class ClassSubstitutorAbstract implements ClassSubstitutor { + @Override public Class<?> getClass(final Class<?> cls) { if (cls == null) { return null; } - // ignore datanucleus proxies - if(cls.getName().startsWith("org.datanucleus")) { + if(proxyPackageNamesToSkip.stream() + .anyMatch(packageName -> cls.getName().startsWith(packageName))) { return getClass(cls.getSuperclass()); } @@ -86,15 +62,15 @@ public class ClassSubstitutor { if (ClassUtil.directlyImplements(cls, ProxyEnhanced.class)) { return getClass(cls.getSuperclass()); } - + try { // guard against cannot introspect - _Blackhole.consume(cls.getMethods()); + _Blackhole.consume(cls.getMethods()); } catch (Throwable e) { classesToIgnore.add(cls); return null; } - + return cls; } @@ -103,20 +79,29 @@ public class ClassSubstitutor { private final Set<Class<?>> classesToIgnore = _Sets.newConcurrentHashSet(); private final Set<String> classNamesToIgnore = _Sets.newHashSet(); private final Set<String> packageNamesToIgnore = _Sets.newHashSet(); + private final Set<String> proxyPackageNamesToSkip = _Sets.newHashSet(); /** * For any classes registered as ignored, {@link #getClass(Class)} will * return <tt>null</tt>. */ - private void ignore(final String className) { + protected void ignoreClass(final String className) { classNamesToIgnore.add(className); } - - private void ignorePackage(final String packageName) { + + protected void ignorePackage(final String packageName) { packageNamesToIgnore.add(packageName); } + /** + * Any classes in these package represent a proxy (eg DN-enhanced bytecode). + * We skip the proxy class itself but traverse up to the supertype. + */ + protected void skipProxyPackage(final String packageName) { + proxyPackageNamesToSkip.add(packageName); + } + private boolean shouldIgnore(final Class<?> cls) { if (cls.isArray()) { return shouldIgnore(cls.getComponentType()); @@ -128,14 +113,14 @@ public class ClassSubstitutor { } val className = cls.getName(); - + try{ - return classesToIgnore.contains(cls) + return classesToIgnore.contains(cls) || classNamesToIgnore.contains(cls.getCanonicalName()) || packageNamesToIgnore.stream().anyMatch(className::startsWith) ; - - } catch(java.lang.NoClassDefFoundError e) { + + } catch(NoClassDefFoundError e) { try{ if(cls.isAnonymousClass()) { @@ -143,7 +128,7 @@ public class ClassSubstitutor { } else { return false; } - } catch(java.lang.NoClassDefFoundError ex) { + } catch(NoClassDefFoundError ex) { return true; } } diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutorDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutorDefault.java new file mode 100644 index 0000000..7e5638c --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/classsubstitutor/ClassSubstitutorDefault.java @@ -0,0 +1,62 @@ +/* + * 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.isis.metamodel.services.classsubstitutor; + +import org.springframework.stereotype.Component; + +@Component +public class ClassSubstitutorDefault extends ClassSubstitutorAbstract { + + public ClassSubstitutorDefault() { + + ignoreCglib(); + ignoreJavassist(); + ignoreSpringFramework(); + ignoreJacksonAndGson(); + skipDataNucleusProxy(); + + } + + protected void ignoreCglib() { + ignoreClass("net.sf.cglib.proxy.Factory"); + ignoreClass("net.sf.cglib.proxy.MethodProxy"); + ignoreClass("net.sf.cglib.proxy.Callback"); + } + + protected void ignoreJavassist() { + ignoreClass("javassist.util.proxy.ProxyObject"); + ignoreClass("javassist.util.proxy.MethodHandler"); + } + + protected void ignoreSpringFramework() { + ignoreClass("org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator"); + } + + protected void ignoreJacksonAndGson() { + ignorePackage("com.fasterxml.jackson."); + ignorePackage("com.google.gson."); + } + + protected void skipDataNucleusProxy() { + skipProxyPackage("org.datanucleus."); + } + + +} diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/spec/ObjectSpecification.java index 765be38..4b06c42 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/spec/ObjectSpecification.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/spec/ObjectSpecification.java @@ -30,7 +30,6 @@ import org.apache.isis.applib.annotation.DomainObject; import org.apache.isis.commons.exceptions.IsisException; import org.apache.isis.commons.internal.collections._Streams; import org.apache.isis.commons.internal.ioc.BeanSort; -import org.apache.isis.metamodel.adapter.ObjectAdapter; import org.apache.isis.metamodel.consent.Consent; import org.apache.isis.metamodel.consent.InteractionInitiatedBy; import org.apache.isis.metamodel.consent.InteractionResult; @@ -57,7 +56,7 @@ import org.apache.isis.metamodel.spec.feature.ObjectActionContainer; import org.apache.isis.metamodel.spec.feature.ObjectAssociationContainer; import org.apache.isis.metamodel.spec.feature.ObjectMember; import org.apache.isis.metamodel.specloader.SpecificationLoader; -import org.apache.isis.metamodel.specloader.classsubstitutor.ClassSubstitutor; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutor; import org.apache.isis.metamodel.specloader.specimpl.IntrospectionState; import org.apache.isis.metamodel.specloader.specimpl.MixedInMember; import org.apache.isis.security.authentication.AuthenticationSession; diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/ProgrammingModelServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/ProgrammingModelServiceDefault.java index 9c97e08..b1ec9e1 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/ProgrammingModelServiceDefault.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/ProgrammingModelServiceDefault.java @@ -20,6 +20,7 @@ package org.apache.isis.metamodel.specloader; import javax.inject.Inject; +import org.apache.isis.applib.services.inject.ServiceInjector; import org.springframework.stereotype.Service; import org.apache.isis.applib.services.registry.ServiceRegistry; @@ -44,6 +45,7 @@ public class ProgrammingModelServiceDefault implements ProgrammingModelService { // -- HELPER + @Inject private ServiceInjector serviceInjector; @Inject private ServiceRegistry serviceRegistry; @Inject private ProgrammingModelInitFilter programmingModelInitFilter; @Inject private MetaModelContext metaModelContext; @@ -55,7 +57,7 @@ public class ProgrammingModelServiceDefault implements ProgrammingModelService { log.info("About to create the ProgrammingModel."); - val programmingModel = new ProgrammingModelFacetsJava8(); + val programmingModel = new ProgrammingModelFacetsJava8(serviceInjector); // from all plugins out there, add their contributed FacetFactories, Validators // and PostProcessors to the programming model diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoader.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoader.java index d7f1dcf..12b3c04 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoader.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoader.java @@ -26,6 +26,7 @@ import javax.annotation.Nullable; import org.apache.isis.metamodel.progmodel.ProgrammingModel; import org.apache.isis.metamodel.spec.ObjectSpecId; import org.apache.isis.metamodel.spec.ObjectSpecification; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutor; import org.apache.isis.metamodel.specloader.specimpl.IntrospectionState; import org.apache.isis.metamodel.specloader.validator.MetaModelValidator; import org.apache.isis.metamodel.specloader.validator.ValidationFailures; @@ -93,7 +94,7 @@ public interface SpecificationLoader { * * <p> * It is possible for this method to return <tt>null</tt>, for example if - * the configured {@link org.apache.isis.metamodel.specloader.classsubstitutor.ClassSubstitutor} + * the configured {@link ClassSubstitutor} * has filtered out the class. * * @return {@code null} if {@code domainType==null} diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java index 95b4747..d27e63a 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java @@ -41,10 +41,11 @@ import org.apache.isis.metamodel.facetapi.Facet; import org.apache.isis.metamodel.progmodel.ProgrammingModel; import org.apache.isis.metamodel.progmodel.ProgrammingModelService; import org.apache.isis.metamodel.progmodels.dflt.ProgrammingModelFacetsJava8; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutorDefault; import org.apache.isis.metamodel.spec.FreeStandingList; import org.apache.isis.metamodel.spec.ObjectSpecId; import org.apache.isis.metamodel.spec.ObjectSpecification; -import org.apache.isis.metamodel.specloader.classsubstitutor.ClassSubstitutor; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutor; import org.apache.isis.metamodel.specloader.facetprocessor.FacetProcessor; import org.apache.isis.metamodel.specloader.postprocessor.PostProcessor; import org.apache.isis.metamodel.specloader.specimpl.IntrospectionState; @@ -85,8 +86,7 @@ public class SpecificationLoaderDefault implements SpecificationLoader { @Inject private IsisSystemEnvironment isisSystemEnvironment; @Inject private ServiceRegistry serviceRegistry; @Inject private IsisBeanTypeRegistryHolder isisBeanTypeRegistryHolder; - - private final ClassSubstitutor classSubstitutor = new ClassSubstitutor(); + @Inject private ClassSubstitutor classSubstitutor = new ClassSubstitutorDefault(); // default for testing purposes only, overwritten in prod private ProgrammingModel programmingModel; private FacetProcessor facetProcessor; @@ -358,7 +358,7 @@ public class SpecificationLoaderDefault implements SpecificationLoader { metaModelContext, facetProcessor, managedBeanNameIfAny, - postProcessor); + postProcessor, classSubstitutor); } return objectSpec; diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/FacetedMethodsBuilder.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/FacetedMethodsBuilder.java index 8e8d1d7..7d7ea38 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/FacetedMethodsBuilder.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/FacetedMethodsBuilder.java @@ -47,7 +47,7 @@ import org.apache.isis.metamodel.facets.object.mixin.MixinFacet; import org.apache.isis.metamodel.methodutils.MethodScope; import org.apache.isis.metamodel.spec.ObjectSpecification; import org.apache.isis.metamodel.specloader.SpecificationLoader; -import org.apache.isis.metamodel.specloader.classsubstitutor.ClassSubstitutor; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutor; import org.apache.isis.metamodel.specloader.facetprocessor.FacetProcessor; import org.apache.isis.metamodel.specloader.traverser.TypeExtractorMethodReturn; @@ -135,7 +135,7 @@ public class FacetedMethodsBuilder { private final FacetProcessor facetProcessor; - private final ClassSubstitutor classSubstitutor = new ClassSubstitutor(); + private final ClassSubstitutor classSubstitutor; private final SpecificationLoader specificationLoader; @@ -148,21 +148,24 @@ public class FacetedMethodsBuilder { public FacetedMethodsBuilder( final ObjectSpecificationAbstract inspectedTypeSpec, - final FacetProcessor facetProcessor) { - + final FacetProcessor facetProcessor, + final ClassSubstitutor classSubstitutor) { + if (log.isDebugEnabled()) { log.debug("creating JavaIntrospector for {}", inspectedTypeSpec.getFullIdentifier()); } - + + this.facetProcessor = facetProcessor; + this.classSubstitutor = classSubstitutor; + val mmContext = inspectedTypeSpec.getMetaModelContext(); this.inspectedTypeSpec = inspectedTypeSpec; this.introspectedClass = inspectedTypeSpec.getCorrespondingClass(); - + val methodsRemaining = introspectedClass.getMethods(); this.methodRemover = new FacetedMethodsMethodRemover(introspectedClass, methodsRemaining); - this.facetProcessor = facetProcessor; this.specificationLoader = mmContext.getSpecificationLoader(); val isisConfiguration = mmContext.getConfiguration(); diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java index 10e46d0..7a6d209 100644 --- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java +++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java @@ -57,7 +57,7 @@ import org.apache.isis.metamodel.spec.feature.ObjectAction; import org.apache.isis.metamodel.spec.feature.ObjectActionParameter; import org.apache.isis.metamodel.spec.feature.ObjectAssociation; import org.apache.isis.metamodel.spec.feature.ObjectMember; -import org.apache.isis.metamodel.specloader.classsubstitutor.ClassSubstitutor; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutor; import org.apache.isis.metamodel.specloader.facetprocessor.FacetProcessor; import org.apache.isis.metamodel.specloader.postprocessor.PostProcessor; import org.apache.isis.metamodel.specloader.specimpl.FacetedMethodsBuilder; @@ -75,8 +75,6 @@ import lombok.extern.log4j.Log4j2; @Log4j2 public class ObjectSpecificationDefault extends ObjectSpecificationAbstract implements FacetHolder { - private static final ClassSubstitutor classSubstitutor = new ClassSubstitutor(); - private static String determineShortName(final Class<?> introspectedClass) { final String name = introspectedClass.getName(); return name.substring(name.lastIndexOf('.') + 1); @@ -90,7 +88,9 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl private Map<Method, ObjectMember> membersByMethod = null; private final FacetedMethodsBuilder facetedMethodsBuilder; - + private final ClassSubstitutor classSubstitutor; + + /** * available only for managed-beans */ @@ -101,13 +101,15 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl final MetaModelContext metaModelContext, final FacetProcessor facetProcessor, final String nameIfIsManagedBean, - final PostProcessor postProcessor) { + final PostProcessor postProcessor, + final ClassSubstitutor classSubstitutor) { super(correspondingClass, determineShortName(correspondingClass), facetProcessor, postProcessor); setMetaModelContext(metaModelContext); - + this.nameIfIsManagedBean = nameIfIsManagedBean; - this.facetedMethodsBuilder = new FacetedMethodsBuilder(this, facetProcessor); + this.facetedMethodsBuilder = new FacetedMethodsBuilder(this, facetProcessor, classSubstitutor); + this.classSubstitutor = classSubstitutor; facetProcessor.processObjectSpecId(correspondingClass, this); diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java index d735b02..19596dd 100644 --- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java +++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java @@ -52,7 +52,7 @@ public class ViewModelSemanticCheckingFacetFactoryTest { public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES); - @Mock + @Mock @JUnitRuleMockery2.Ignoring private ServiceInjector mockServicesInjector; private MetaModelContext metaModelContext; @@ -60,7 +60,7 @@ public class ViewModelSemanticCheckingFacetFactoryTest { private ValidationFailures processThenValidate(final Class<?> cls) { - val programmingModel = new ProgrammingModelAbstract() {}; + val programmingModel = new ProgrammingModelAbstract(mockServicesInjector) {}; facetFactory.refineProgrammingModel(programmingModel); programmingModel.init(new ProgrammingModelInitFilterDefault(), metaModelContext); diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java index 3c546d3..5542649 100644 --- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java +++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java @@ -19,6 +19,7 @@ package org.apache.isis.metamodel.facets.object.objectspecid; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutorDefault; import org.datanucleus.testing.dom.CustomerAsProxiedByDataNucleus; import org.junit.Before; import org.junit.Test; diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/specloader/SpecificationLoaderTestAbstract.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/specloader/SpecificationLoaderTestAbstract.java index d9d0dc0..b2d533e 100644 --- a/core/metamodel/src/test/java/org/apache/isis/metamodel/specloader/SpecificationLoaderTestAbstract.java +++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/specloader/SpecificationLoaderTestAbstract.java @@ -82,8 +82,7 @@ abstract class SpecificationLoaderTestAbstract { } TitleService mockTitleService() { - val mock = Mockito.mock(TitleService.class); - return mock; + return Mockito.mock(TitleService.class); } TranslationService mockTranslationService() { @@ -92,12 +91,12 @@ abstract class SpecificationLoaderTestAbstract { return mock; } - ServiceInjector getServiceInjector() { + ServiceInjector mockServiceInjector() { return Mockito.mock(ServiceInjector.class); } - + ProgrammingModel getProgrammingModel() { - return new ProgrammingModelFacetsJava8(); + return new ProgrammingModelFacetsJava8(mockServiceInjector()); } } @@ -130,6 +129,7 @@ abstract class SpecificationLoaderTestAbstract { .authenticationSessionProvider(mockAuthenticationSessionProvider = producers.mockAuthenticationSessionProvider()) .singleton(mockMessageService = producers.mockMessageService()) .singleton(mockGridService = producers.mockGridService()) + .serviceInjector(producers.mockServiceInjector()) .build(); specificationLoader = metaModelContext.getSpecificationLoader(); diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/specloader/classsubstitutor/ClassSubstitutorTest_getClass.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/specloader/classsubstitutor/ClassSubstitutorTest_getClass.java index 0513536..818e2e5 100644 --- a/core/metamodel/src/test/java/org/apache/isis/metamodel/specloader/classsubstitutor/ClassSubstitutorTest_getClass.java +++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/specloader/classsubstitutor/ClassSubstitutorTest_getClass.java @@ -19,6 +19,8 @@ package org.apache.isis.metamodel.specloader.classsubstitutor; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutor; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutorDefault; import org.junit.Before; import org.junit.Test; @@ -30,7 +32,7 @@ public class ClassSubstitutorTest_getClass { @Before public void setUp() throws Exception { - classSubstitutor = new ClassSubstitutor(); + classSubstitutor = new ClassSubstitutorDefault(); } public static class SomeDomainObject { diff --git a/core/persistence/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/discriminator/JdoDiscriminatorAnnotationFacetFactory.java b/core/persistence/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/discriminator/JdoDiscriminatorAnnotationFacetFactory.java index 17d01d8..7c9e7f0 100644 --- a/core/persistence/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/discriminator/JdoDiscriminatorAnnotationFacetFactory.java +++ b/core/persistence/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/discriminator/JdoDiscriminatorAnnotationFacetFactory.java @@ -19,6 +19,7 @@ package org.apache.isis.jdo.metamodel.facets.object.discriminator; +import javax.inject.Inject; import javax.jdo.annotations.Discriminator; import org.apache.isis.commons.internal.base._Strings; @@ -31,13 +32,14 @@ import org.apache.isis.metamodel.facets.FacetFactoryAbstract; import org.apache.isis.metamodel.facets.ObjectSpecIdFacetFactory; import org.apache.isis.metamodel.facets.object.objectspecid.ObjectSpecIdFacet; import org.apache.isis.metamodel.facets.object.objectspecid.classname.ObjectSpecIdFacetDerivedFromClassName; -import org.apache.isis.metamodel.specloader.classsubstitutor.ClassSubstitutor; +import org.apache.isis.metamodel.services.classsubstitutor.ClassSubstitutor; public class JdoDiscriminatorAnnotationFacetFactory extends FacetFactoryAbstract implements ObjectSpecIdFacetFactory { - private final ClassSubstitutor classSubstitutor = new ClassSubstitutor(); + @Inject + private ClassSubstitutor classSubstitutor; public JdoDiscriminatorAnnotationFacetFactory() { super(FeatureType.OBJECTS_ONLY); @@ -59,13 +61,17 @@ implements ObjectSpecIdFacetFactory { final FacetHolder facetHolder = processClassContext.getFacetHolder(); final String annotationValue = annotation.value(); - final ObjectSpecIdFacet facet = - !_Strings.isNullOrEmpty(annotationValue) - ? new ObjectSpecIdFacetInferredFromJdoDiscriminatorValueAnnotation( - annotationValue, facetHolder) - : new ObjectSpecIdFacetDerivedFromClassName( - classSubstitutor.getClass(cls).getCanonicalName(), facetHolder); - FacetUtil.addFacet(facet); + final ObjectSpecIdFacet facet; + if (!_Strings.isNullOrEmpty(annotationValue)) { + facet = new ObjectSpecIdFacetInferredFromJdoDiscriminatorValueAnnotation( + annotationValue, facetHolder); + } else { + final Class<?> substitutedClass = classSubstitutor.getClass(cls); + facet = substitutedClass != null + ? new ObjectSpecIdFacetDerivedFromClassName(substitutedClass.getCanonicalName(), facetHolder) + : null; + } + FacetUtil.addFacet(facet); }