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/02/14 13:12:09 UTC
[isis] 01/02: Merge branch 'maint-1.16.1' into master
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 97013ecec28a2987ef8a5f7de1d0460227de8aab
Merge: de41037 392d475
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Feb 14 12:46:22 2018 +0000
Merge branch 'maint-1.16.1' into master
# Conflicts:
# adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action.adoc
# adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-DomainObject_objectType.adoc
# adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Parameter.adoc
# adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-ViewModel_objectType.adoc
# adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BulkInteractionContext.adoc
# adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_CommandService.adoc
# adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_MetamodelService.adoc
# adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_programming-model_actions.adoc
# adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_ui-hints_eager-rendering.adoc
# adocs/documentation/src/main/asciidoc/guides/ugvw/_ugvw_layout_file-based.adoc
# adocs/documentation/src/main/asciidoc/pages/tg/_tg_pet-clinic.adoc
# adocs/documentation/src/main/asciidoc/pages/tg/_tg_stop-scaffolding-start-coding.adoc
# core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
# core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
# core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
# core/applib/src/main/java/org/apache/isis/applib/annotation/CommandExecuteIn.java
# core/applib/src/main/java/org/apache/isis/applib/annotation/InvokeOn.java
# core/applib/src/main/java/org/apache/isis/applib/services/actinvoc/ActionInvocationContext.java
# core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
# core/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService3.java
# core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetForActionAnnotation.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetForCommandAnnotation.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetFromConfiguration.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacetAbstract.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/MustSatisfySpecificationFacetAbstract.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForMustSatisfyAnnotationOnParameter.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForParameterAnnotation.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/command/CommandFacetForPropertyAnnotation.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mustsatisfy/MustSatisfySpecificationFacetForMustSatisfyAnnotationOnProperty.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mustsatisfy/MustSatisfySpecificationFacetForPropertyAnnotation.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternal.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternalNoop.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/xactn/TransactionServiceDefault.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/facetprocessor/FacetProcessor.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
# core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
# core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorHelper.java
# core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderTestAbstract.java
# core/runtime/src/main/java/org/apache/isis/core/runtime/fixturedomainservice/ObjectFixtureFilePersistor.java
# core/runtime/src/main/java/org/apache/isis/core/runtime/fixturedomainservice/ObjectFixtureService.java
# core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
# core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
# core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactoryMetamodelRefiner.java
# core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
# core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/bulk/BulkActionsHelper.java
.../applib/layout/grid/bootstrap3/bootstrap3.xsd | 1 +
.../asciidoc/guides/dg/_dg_asciidoc-syntax.adoc | 47 +-
.../_dg_hints-and-tips_datanucleus-enhancer.adoc | 2 +-
.../main/asciidoc/guides/dg/_dg_ide_eclipse.adoc | 2 +-
.../main/asciidoc/guides/rgant/_rgant-Action.adoc | 21 +-
.../guides/rgant/_rgant-Action_associateWith.adoc | 67 ++
.../guides/rgant/_rgant-Action_command.adoc | 397 +++++++++--
.../guides/rgant/_rgant-Action_hidden.adoc | 2 +-
.../guides/rgant/_rgant-Action_publishing.adoc | 2 +-
.../guides/rgant/_rgant-Discriminator.adoc | 4 +-
..._rgant-DomainObject_autoCompleteRepository.adoc | 2 +-
.../rgant/_rgant-DomainObject_publishing.adoc | 2 +-
.../guides/rgant/_rgant-DomainService.adoc | 2 +-
.../asciidoc/guides/rgant/_rgant-Nullable.adoc | 10 +-
.../guides/rgant/_rgant-Parameter_optionality.adoc | 2 +-
.../guides/rgant/_rgant-PersistenceCapable.adoc | 4 +-
.../asciidoc/guides/rgant/_rgant-Property.adoc | 28 +
.../rgant/_rgant-PropertyLayout_unchanging.adoc | 2 +-
.../guides/rgant/_rgant-Property_command.adoc | 269 ++++++++
.../guides/rgant/_rgant-Property_optionality.adoc | 2 +-
.../guides/rgant/_rgant-Property_publishing.adoc | 2 +-
.../asciidoc/guides/rgant/_rgant-ViewModel.adoc | 2 +-
.../guides/rgcfg/_rgcfg_configuring-core.adoc | 15 +
.../_rgcms_classes_AppManifest2-bootstrapping.adoc | 4 +-
...gcms_classes_domainevent_ActionDomainEvent.adoc | 2 +-
..._classes_domainevent_CollectionDomainEvent.adoc | 2 +-
...ms_classes_domainevent_PropertyDomainEvent.adoc | 2 +-
.../guides/rgcms/_rgcms_classes_layout.adoc | 2 +-
.../rgcms/_rgcms_classes_value-types_Markup.adoc | 2 +-
.../rgcms/_rgcms_methods_reserved_getId.adoc | 2 +-
.../asciidoc/guides/rgcms/_rgcms_schema-chg.adoc | 2 +-
.../asciidoc/guides/rgcms/_rgcms_schema-cmd.adoc | 53 +-
.../guides/rgcms/_rgcms_schema-common.adoc | 77 ++-
.../guides/rgsvc/_rgsvc_application-layer-api.adoc | 14 +-
...lication-layer-api_ActionInvocationContext.adoc | 8 +-
...rgsvc_application-layer-api_CommandContext.adoc | 2 +-
...plication-layer-api_CommandExecutorService.adoc | 45 ++
...rgsvc_application-layer-spi_CommandService.adoc | 33 +-
.../_rgsvc_metadata-api_MetamodelService.adoc | 37 +-
...esentation-layer-spi_ContentMappingService.adoc | 53 +-
...entation-layer-spi_TableColumnOrderService.adoc | 2 +-
...ugfun_building-blocks_events_domain-events.adoc | 2 +-
...un_building-blocks_events_lifecycle-events.adoc | 2 +-
.../_ugfun_building-blocks_events_ui-events.adoc | 4 +-
..._ugfun_getting-started_simpleapp-archetype.adoc | 2 +-
.../ugfun/_ugfun_programming-model_actions.adoc | 21 +-
...fun_programming-model_domain-services_menu.adoc | 14 +-
.../_ugfun_programming-model_inject-services.adoc | 2 +-
.../ugfun/_ugfun_programming-model_mixins.adoc | 2 +-
...fun_programming-model_mixins_inferred-name.adoc | 2 +-
.../ugfun/_ugfun_ui-hints_eager-rendering.adoc | 2 +-
.../_ugfun_ui-hints_object-titles-and-icons.adoc | 6 +-
.../guides/ugodn/_ugodn_hints-and-tips.adoc | 1 +
..._ugodn_hints-and-tips_jdoql-and-timestamps.adoc | 76 +++
..._ugtst_bdd-spec-support_writing-a-bdd-spec.adoc | 28 +-
...gtst_fixture-scripts_ticking-clock-fixture.adoc | 2 +-
.../guides/ugvw/_ugvw_layout_file-based.adoc | 15 +
adocs/documentation/src/main/asciidoc/index.html | 11 +-
.../_migration-notes_1.10.0-to-1.11.0.adoc | 2 +-
.../_migration-notes_1.11.0-to-1.12.0.adoc | 2 +-
.../_migration-notes_1.12.0-to-1.13.0.adoc | 12 +-
.../_migration-notes_1.14.0-to-1.15.0.adoc | 2 +-
.../asciidoc/pages/tg/_tg_pet-clinic-extended.adoc | 13 -
.../src/main/asciidoc/pages/tg/_tg_pet-clinic.adoc | 575 ----------------
.../tg/_tg_stop-scaffolding-start-coding.adoc | 744 ---------------------
.../tutorials/pet-clinic/010-01-login-page.png | Bin 31965 -> 0 bytes
.../tutorials/pet-clinic/010-02-home-page.png | Bin 54415 -> 0 bytes
.../pet-clinic/010-03-prototyping-menu.png | Bin 59183 -> 0 bytes
.../tutorials/pet-clinic/010-04-simpleobjects.png | Bin 57805 -> 0 bytes
.../pet-clinic/010-05-simpleobject-list.png | Bin 29631 -> 0 bytes
.../pet-clinic/020-01-idea-configuration.png | Bin 35012 -> 0 bytes
.../pet-clinic/020-02-idea-configuration.png | Bin 7430 -> 0 bytes
.../030-01-idea-configuration-updated.png | Bin 35122 -> 0 bytes
.../tutorials/pet-clinic/030-02-updated-app.png | Bin 32215 -> 0 bytes
.../040-01-idea-configuration-updated.png | Bin 35349 -> 0 bytes
.../tutorials/pet-clinic/050-01-list-all.png | Bin 33299 -> 0 bytes
.../tutorials/pet-clinic/050-02-view-pet.png | Bin 34270 -> 0 bytes
.../tutorials/pet-clinic/060-01-owners-menu.png | Bin 65309 -> 0 bytes
.../tutorials/pet-clinic/060-02-owners-list.png | Bin 31905 -> 0 bytes
.../tutorials/pet-clinic/060-03-pets-list.png | Bin 36166 -> 0 bytes
.../pet-clinic/060-04-pet-owner-autoComplete.png | Bin 40468 -> 0 bytes
.../images/tutorials/pet-clinic/domain-model.png | Bin 27464 -> 0 bytes
.../src/main/asciidoc/pages/tg/tg.adoc | 683 ++++++++++++++++++-
.../release-notes/_release-notes_1.16.1.adoc | 24 +
.../main/asciidoc/release-notes/release-notes.adoc | 11 +-
.../src/main/asciidoc}/schema/chg/chg-1.1.xsd | 2 +-
.../src/main/asciidoc/schema/chg/chg.xsd | 6 +-
.../asciidoc/schema/cmd/{cmd.xsd => cmd-1.2.xsd} | 10 +-
.../src/main/asciidoc}/schema/cmd/cmd-1.3.xsd | 2 +-
.../src/main/asciidoc/schema/cmd/cmd-1.4.xsd | 39 +-
.../src/main/asciidoc/schema/cmd/cmd.xsd | 51 +-
.../main/asciidoc}/schema/common/common-1.1.xsd | 2 +-
.../src/main/asciidoc/schema/common/common.xsd | 19 +-
.../asciidoc/schema/ixn/{ixn.xsd => ixn-1.1.xsd} | 10 +-
.../src/main/asciidoc}/schema/ixn/ixn-1.2.xsd | 2 +-
.../src/main/asciidoc/schema/ixn/ixn-1.3.xsd | 6 +-
.../src/main/asciidoc/schema/ixn/ixn.xsd | 14 +-
adocs/template/document.html.erb | 5 +-
core/applib/pom.xml | 5 +
.../apache/isis/applib/AppManifestAbstract.java | 33 +-
.../org/apache/isis/applib/PropertyResource.java | 5 +-
.../org/apache/isis/applib/annotation/Action.java | 63 ++
.../isis/applib/annotation/CommandExecuteIn.java | 24 +-
.../apache/isis/applib/annotation/InvokeOn.java | 27 +-
.../apache/isis/applib/annotation/MemberOrder.java | 2 +-
.../apache/isis/applib/annotation/Property.java | 21 +
.../java/org/apache/isis/applib/clock/Clock.java | 18 +-
.../conmap/ContentMappingServiceForCommandDto.java | 152 +++++
.../ContentMappingServiceForCommandsDto.java | 91 +++
.../spi/CommandDtoProcessorService.java} | 23 +-
.../isis/applib/fixtures/TickingFixtureClock.java | 10 +
.../applib/layout/grid/bootstrap3/BS3TabGroup.java | 15 +
.../services/actinvoc/ActionInvocationContext.java | 33 +-
.../isis/applib/services/command/Command.java | 66 +-
.../CommandDtoProcessor.java} | 30 +-
.../CommandDtoProcessorForActionAbstract.java | 41 ++
.../CommandDtoProcessorForPropertyAbstract.java} | 28 +-
.../services/command/CommandExecutorService.java | 44 +-
.../applib/services/command/CommandWithDto.java | 21 +-
.../services/conmap/ContentMappingService.java | 27 +
.../services/eventbus/AbstractDomainEvent.java | 12 +
.../services/layout/Object_rebuildMetamodel.java | 2 +
.../services/metamodel/MetaModelService.java | 3 +
.../queryresultscache/QueryResultsCache.java | 7 +-
.../applib/services/xactn/TransactionService.java | 18 +
.../apache/isis/schema/utils/CommandDtoUtils.java | 36 +
.../apache/isis/schema/utils/CommonDtoUtils.java | 81 ++-
.../eventbus/AbstractDomainEvent_veto_Test.java | 183 +++++
.../isis/schema/utils/CommandDtoUtils_Test.java | 68 ++
...nDtoUtilsTest.java => CommonDtoUtils_Test.java} | 37 +-
core/integtestsupport/pom.xml | 7 +-
core/log4j/pom.xml | 5 +
.../isis/core/runtime/logging/SnapshotServer.java | 16 +-
core/maven-plugin/pom.xml | 3 +
core/metamodel/pom.xml | 24 +
.../commons/config/IsisConfigurationDefault.java | 4 +-
.../configbuilder/IsisConfigurationBuilder.java | 15 +-
.../commons/encoding/DebugDataInputExtended.java | 28 +-
.../commons/encoding/DebugDataOutputExtended.java | 30 +-
.../resource/ResourceStreamSourceAbstract.java | 9 +-
.../ResourceStreamSourceChainOfResponsibility.java | 4 +-
.../resource/ResourceStreamSourceComposite.java | 4 +-
.../isis/core/metamodel/facetapi/FeatureType.java | 21 +-
.../action/ActionAnnotationFacetFactory.java | 30 +-
.../command/CommandFacetForActionAnnotation.java | 26 +-
...ommandFacetForActionAnnotationAsConfigured.java | 7 +-
.../command/CommandFacetFromConfiguration.java | 13 +-
.../facets/actions/command/CommandFacet.java | 2 +
.../actions/command/CommandFacetAbstract.java | 45 +-
.../members/order/MemberOrderFacetAbstract.java | 21 +-
.../MemberOrderFacetForActionAnnotation.java} | 18 +-
.../objectspecid/ObjectSpecIdFacetAbstract.java | 9 +-
.../ObjectSpecIdFacetOnStandaloneList.java} | 13 +-
.../MustSatisfySpecificationFacetAbstract.java | 22 +-
...fySpecificationFacetForParameterAnnotation.java | 2 -
.../property/PropertyAnnotationFacetFactory.java | 2 +-
.../command/CommandFacetForPropertyAnnotation.java | 24 +-
...mandFacetForPropertyAnnotationAsConfigured.java | 5 +-
...sfySpecificationFacetForPropertyAnnotation.java | 2 -
...onParameterDefaultsAndChoicesPostProcessor.java | 156 +++++
...arameterChoicesFacetFromParentedCollection.java | 74 ++
...rameterDefaultsFacetFromParentedCollection.java | 63 ++
...{ProgrammingModel.java => FacetFactorySet.java} | 9 +-
.../ObjectSpecificationPostProcessor.java} | 10 +-
.../metamodel/progmodel/PostProcessorSet.java} | 15 +-
.../core/metamodel/progmodel/ProgrammingModel.java | 62 +-
.../core/metamodel/services/ServicesInjector.java | 4 +-
.../services/appfeat/ApplicationFeatureId.java | 21 +
.../services/grid/GridLoaderServiceDefault.java | 61 +-
.../services/grid/GridSystemServiceAbstract.java | 4 +-
.../metamodel/MetaModelServiceDefault.java | 31 +
.../PersistenceSessionServiceInternal.java | 4 +
.../PersistenceSessionServiceInternalNoop.java | 6 +
.../services/xactn/TransactionServiceDefault.java | 15 +-
.../core/metamodel/spec/ObjectSpecification.java | 68 +-
.../core/metamodel/spec/feature/ObjectAction.java | 52 ++
.../spec/feature/ObjectActionParameter.java | 77 +++
.../metamodel/specloader/ServiceInitializer.java | 4 +-
.../metamodel/specloader/SpecificationLoader.java | 51 +-
.../specloader/facetprocessor/FacetProcessor.java | 10 +-
.../specloader/postprocessor/PostProcessor.java | 59 ++
.../specloader/specimpl/FacetedMethodsBuilder.java | 26 +-
.../specimpl/ObjectSpecificationAbstract.java | 36 +-
.../specimpl/dflt/ObjectSpecificationDefault.java | 7 +-
.../ObjectSpecificationOnStandaloneList.java | 4 +
.../MetaModelValidatorToCheckModuleExtent.java | 153 +++++
...taModelValidatorToCheckObjectSpecIdsUnique.java | 95 +++
.../authentication/standard/SimpleSession.java | 2 +-
.../isis/core/runtime/snapshot/XmlSnapshot.java | 60 +-
.../isis/core/webapp/content/ResourceServlet.java | 14 +-
.../diagnostics/IsisLogOnExceptionFilter.java | 2 +-
.../core/webapp/routing/RedirectToDocsFilter.java | 9 +-
.../isis/progmodels/dflt/JavaReflectorHelper.java | 2 +-
.../dflt/ProgrammingModelFacetsJava5.java | 13 +
.../isis/core/metamodel/services/grid/Foo.java} | 12 +-
.../core/metamodel/services/grid/Foo.layout.xml | 23 +
.../isis/core/metamodel/services/grid/Foo2.java} | 12 +-
.../services/grid/Foo2.layout.fallback.xml | 23 +
.../isis/core/metamodel/services/grid/Foo3.java} | 12 +-
.../services/grid/Foo3.layout.fallback.xml | 23 +
.../core/metamodel/services/grid/Foo3.layout.xml | 23 +
.../isis/core/metamodel/services/grid/Foo4.java} | 12 +-
...dLoaderServiceDefault_resourceNameFor_Test.java | 58 ++
.../SpecificationLoaderTestAbstract.java | 2 +-
.../specimpl/ObjectMemberAbstractTest.java | 18 +
.../testspec/ObjectSpecificationStub.java | 14 +
core/pom.xml | 79 ++-
core/runtime/pom.xml | 17 +-
.../fixtures/FixturesInstallerDelegate.java | 4 +-
.../FixturesInstallerFromConfiguration.java | 2 +-
.../HeadlessWithBootstrappingAbstract.java | 4 +-
.../apache/isis/core/runtime/memento/Memento.java | 18 +-
.../runtime/persistence/adapter/PojoAdapter.java | 4 +-
.../runner/opts/OptionHandlerAppManifest.java | 2 +-
.../runner/opts/OptionHandlerFixtureAbstract.java | 2 +-
.../runner/opts/OptionHandlerInitParameters.java | 4 +-
.../runner/opts/OptionHandlerSystemProperties.java | 4 +-
.../core/runtime/services/ServiceInstantiator.java | 6 +-
.../ServicesInstallerFromConfiguration.java | 2 +-
...cesInstallerFromConfigurationAndAnnotation.java | 2 +-
.../background/BackgroundCommandExecution.java | 258 +------
.../background/CommandExecutionAbstract.java | 69 ++
.../background/CommandExecutorServiceDefault.java | 429 ++++++++++++
.../changes/ChangedObjectsServiceInternal.java | 52 +-
.../services/command/CommandServiceDefault.java | 4 -
.../menubars/bootstrap3/MenuBarsServiceBS3.java | 34 +-
.../PersistenceSessionServiceInternalDefault.java | 8 +-
.../AbstractIsisSessionTemplate.java | 31 +-
.../system/internal/IsisLocaleInitializer.java | 4 +-
.../system/internal/IsisTimeZoneInitializer.java | 4 +-
.../persistence/PersistenceQueryFactory.java | 2 +-
.../system/persistence/PersistenceSession.java | 68 +-
.../persistence/PersistenceSessionFactory.java | 10 +-
.../PersistenceSessionFactoryMetamodelRefiner.java | 4 +
.../adaptermanager/OidAdapterHashMap.java | 6 +-
.../adaptermanager/PojoAdapterHashMap.java | 6 +-
.../system/session/IsisSessionFactoryBuilder.java | 6 +-
.../system/transaction/IsisTransaction.java | 39 +-
.../system/transaction/IsisTransactionManager.java | 2 +-
.../IsisComponentProviderUsingInstallers.java | 12 +-
.../isis/core/webapp/IsisWebAppBootstrapper.java | 4 +-
.../CreateSchemaObjectFromClassMetadata.java | 2 +-
.../commands/DataNucleusCreateObjectCommand.java | 2 +-
.../commands/DataNucleusDeleteObjectCommand.java | 2 +-
.../PersistenceQueryFindAllInstancesProcessor.java | 2 +-
...sistenceQueryFindUsingApplibQueryProcessor.java | 4 +-
.../datanucleus/persistence/queries/QueryUtil.java | 4 +-
.../objectstore/jdo/service/RegisterEntities.java | 3 +-
.../src/main/resources/META-INF/MANIFEST.MF | 6 -
core/schema/pom.xml | 9 +-
.../resources/org/apache/isis/schema/bindings.xml | 8 +-
.../org/apache/isis/schema/chg/chg-1.1.xsd | 2 +-
.../isis/schema/cmd/{cmd-1.3.xsd => cmd-1.4.xsd} | 45 +-
.../org/apache/isis/schema/common/common-1.1.xsd | 30 +-
.../isis/schema/ixn/{ixn-1.2.xsd => ixn-1.3.xsd} | 6 +-
core/security-shiro/pom.xml | 7 +-
core/security/pom.xml | 7 +-
core/specsupport/pom.xml | 5 +
.../core/specsupport/specs/CukeGlueAbstract2.java | 4 +-
.../specs/CukeGlueBootstrappingAbstract.java | 10 +
core/unittestsupport/pom.xml | 7 +-
core/viewer-restfulobjects-applib/pom.xml | 7 +-
core/viewer-restfulobjects-rendering/pom.xml | 8 +-
core/viewer-restfulobjects-server/pom.xml | 7 +-
.../ExceptionMapperForRuntimeException.java | 13 +-
.../server/mappers/entity/ExceptionDetail.java | 2 +-
core/viewer-wicket-applib/pom.xml | 6 +-
core/viewer-wicket-impl/pom.xml | 6 +-
.../wicket/viewer/IsisWicketApplication.java | 8 +-
.../integration/wicket/WebRequestCycleForIsis.java | 4 +-
.../ComponentFactoryRegistrarDefault.java | 33 +-
.../wicket/viewer/services/Object_clearHints.java | 5 +-
.../services/TranslationsResolverWicket.java | 2 +-
core/viewer-wicket-model/pom.xml | 5 +
.../viewer/wicket/model/models/ActionPrompt.java | 6 +
.../wicket/model/models/EntityCollectionModel.java | 20 +-
.../viewer/wicket/model/models/EntityModel.java | 68 +-
.../viewer/wicket/model/models/ScalarModel.java | 59 +-
.../model/models/ScalarModelWithMultiPending.java | 16 +-
.../model/models/ScalarModelWithPending.java | 20 +-
.../model/models/ToggledMementosProvider.java} | 18 +-
.../wicket/model/models/EntityModel_hintsTest.java | 2 +-
core/viewer-wicket-ui/pom.xml | 5 +
.../AdditionalLinksAsDropDownPanel.html | 1 +
.../entityactions/EntityActionLinkFactory.java | 8 +-
.../actionmenu/entityactions/LinkAndLabelUtil.java | 12 +-
.../actionmenu/serviceactions/CssMenuItem.java | 8 +-
.../serviceactions/ServiceActionLinkFactory.java | 7 +-
.../serviceactions/ServiceActionUtil.java | 12 +
.../actionprompt/ActionPromptModalWindow.java | 2 +
.../collection/AssociatedWithActionsHelper.java | 87 +++
.../ui/components/collection/CollectionPanel.java | 99 ++-
.../collection/bulk/BulkActionsHelper.java | 57 +-
.../collection/bulk/BulkActionsLinkFactory.java | 4 +-
.../collection/bulk/BulkActionsProvider.java | 6 +-
.../CollectionContentsAsAjaxTablePanel.java | 4 +-
.../ajaxtable/IsisAjaxFallbackDataTable.java | 5 -
.../columns/ObjectAdapterPropertyColumn.java | 14 +-
.../components/entity/fieldset/PropertyGroup.java | 31 +-
.../wicket/ui/components/layout/bs3/col/Col.java | 15 +-
.../ui/components/property/PropertyEditPanel.java | 7 +-
.../ui/components/scalars/ScalarPanelAbstract.java | 2 +-
.../components/scalars/ScalarPanelAbstract2.java | 37 +-
.../scalars/ScalarPanelSelect2Abstract.java | 2 +-
.../components/scalars/primitive/BooleanPanel.java | 2 +-
.../ui/components/scalars/uuid/UuidConverter.java | 60 ++
.../ui/components/scalars/uuid/UuidPanel.java | 59 ++
.../components/scalars/uuid/UuidPanelFactory.java} | 32 +-
.../ui/components/scalars/uuid/UuidTextField.java | 53 ++
.../StandaloneCollectionPanel.java | 42 +-
.../components/widgets/bootstrap/ModalDialog.java | 10 +
.../widgets/linkandlabel/ActionLinkFactory.java | 5 +-
.../linkandlabel/ActionLinkFactoryAbstract.java | 78 ++-
.../widgets/themepicker/ThemeChooser.java | 2 +-
.../viewer/wicket/ui/pages/bootstrap-overrides.css | 17 +
.../wicket/ui/panels/FormExecutorDefault.java | 2 +-
.../scalars/uuid/UuidConverterTest_roundtrip.java | 73 ++
core/webserver/pom.xml | 5 +
core/wrapper/pom.xml | 7 +-
example/application/helloworld/pom.xml | 2 +-
.../bdd/specglue/BootstrappingGlue.java | 16 +-
.../{RunBddSpecs.java => RunIntegBddSpecs.java} | 2 +-
.../modules/simple/dom/impl/SimpleObject.java | 3 +-
.../simple/dom/impl/SimpleObject.layout.xml | 6 +-
324 files changed, 6511 insertions(+), 2877 deletions(-)
diff --cc adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_publishing.adoc
index 0a17ecc,59e3205..20f146f
--- a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_publishing.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_publishing.adoc
@@@ -8,10 -8,10 +8,10 @@@
The `publishing()` attribute determines whether and how an action invocation is published via the registered
-implementation of a xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublishingService[`PublishingService`]) or
+implementation of a xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`]) or
xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`]. This attribute is also
supported for xref:../rgant/rgant.adoc#_rgant-DomainObject_publishing[domain objects], where it controls whether changed objects
- are published as events, and for xref:../rgant/rgant.adoc#_rgant_Property_publishing[`@Property#publishing()`], where it controls
+ are published as events, and for xref:../rgant/rgant.adoc#_rgant-Property_publishing[`@Property#publishing()`], where it controls
whether property edits are published as events.
A common use case is to notify external "downstream" systems of changes in the state of the Isis application.
diff --cc adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-DomainObject_publishing.adoc
index bfba388,11ed8ba..1f529e3
--- a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-DomainObject_publishing.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-DomainObject_publishing.adoc
@@@ -7,11 -7,10 +7,11 @@@
The `publishing()` attribute determines whether and how a modified object instance is published via the registered
-implementation of a xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublishingService[`PublishingService`]) or
-xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`]. This attribute is also supported
+implementation of
+xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`].
+This attribute is also supported
for xref:../rgant/rgant.adoc#_rgant-Action_publishing[actions], where it controls whether action invocations are published as
- events, and for xref:../rgant/rgant.adoc#_rgant_Property_publishing[`@Property#publishing()`], where it controls whether
+ events, and for xref:../rgant/rgant.adoc#_rgant-Property_publishing[`@Property#publishing()`], where it controls whether
property edits are published as events.
A common use case is to notify external "downstream" systems of changes in the state of the Isis application.
diff --cc adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Property_publishing.adoc
index 2be7751,6cbf9fa..3c56ad3
--- a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Property_publishing.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Property_publishing.adoc
@@@ -8,11 -8,10 +8,11 @@@
The `publishing()` attribute determines whether and how a property edit is published via the registered implementation
-of a xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublishingService[`PublishingService`]) or
-xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`]. This attribute is also supported
+of
+xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`].
+This attribute is also supported
for xref:../rgant/rgant.adoc#_rgant-DomainObject_publishing[domain objects], where it controls whether changed objects are
- published as events, and for xref:../rgant/rgant.adoc#_rgant_Property_publishing[`@Property#publishing()`], where it controls
+ published as events, and for xref:../rgant/rgant.adoc#_rgant-Property_publishing[`@Property#publishing()`], where it controls
whether property edits are published as events.
A common use case is to notify external "downstream" systems of changes in the state of the Isis application.
diff --cc adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_schema-common.adoc
index 35acf2b,1bda81c..b5c8175
--- a/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_schema-common.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_schema-common.adoc
@@@ -130,10 -158,18 +158,17 @@@ The common schema also defines two type
Used for the return value of action invocations, and for the new value in property edits.
-These type definitions are just building blocks, also used within the xref:../rgcms/rgcms.adoc#_rgcms_schema-aim[action iInvocation memento] schema.
-The first, `valueDto` is The second, `valueType`, enumerates the different types of vales, eg of a
-formal parameter to an action.
+These type definitions are just building blocks.
+The first, `valueDto` is The second, `valueType`, enumerates the different types of vales, eg of a formal parameter to an action.
+ [IMPORTANT]
+ ====
+ When used as a parameter, blob and clob arguments are _not_ serialized.
+ Instead these are persisted only as references.
+ This is primarily to save storage space if the resultant XML is persisted as a memento (eg `CommandDto`).
+ ====
+
[[__rgcms_schema-common_ancillary]]
== Ancillary types
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_CommandService.adoc
index b04eef8,ce1e550..6dfe056
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_CommandService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_CommandService.adoc
@@@ -14,16 -16,12 +16,16 @@@ One use case for this is for regressio
There are a number of related use cases:
* they enable profiling of the running application (which actions are invoked then most often, what is their response time)
-* if xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`] or
-xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublishingService[`PublishingService`] (latter deprecated) is configured, they provide better traceability as the `Command` is also correlated with any published events, again through the unique `transactionId` GUID
-* if xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_AuderService[`AuditerService`] or
-xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_AuditService[`AuditingService`] (latter deprecated) is configured, they provide better audit information, since the `Command` (the 'cause' of an action) can be correlated to the audit records (the "effect" of the action) through the `transactionId` GUID
++
++
+* if xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`] is configured, they provide
+better traceability as the `Command` is also correlated with any published events, again through the unique
+`transactionId` GUID
+* if xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_AuditerService[`AuditerService`](s) are configured, they provide better audit
+information, since the `Command` (the 'cause' of an action) can be correlated to the audit records (the "effect" of
+the action) through the `transactionId` GUID
- However, while persistent ``Command``s _can_ be used for these use cases, it is recommended instead to use the
- xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_InteractionContext[`InteractionContext`] service and persistent implementations of the
- ``Interaction`` object, eg as provided by the (non-ASF) link:http://platform.incode.org[Incode Platform^]'s publishmq module.
+ However, while persistent ``Command``s _can_ be used for these use cases, it is recommended instead to use the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_InteractionContext[`InteractionContext`] service and persistent implementations of the ``Interaction`` object, eg as provided by the (non-ASF) link:http://platform.incode.org[Incode Platform^]'s publishmq module.
@@@ -52,12 -53,15 +55,12 @@@ public interface CommandService
}
----
<1> Instantiate the appropriate instance of the `Command` (as defined by the
- xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service). Its members will be populated automatically by
- the framework.
- <2> Deprecated and *IS NOT CALLED* by the framework.
- The framework automatically populates the ``Command``'s `timestamp`, `user` and `transactionId` fields, so there is no need for the service implementation to initialize any of these.
- In particular, the ``Command`` will already have been initialized with the provided `transactionId` argument.
- <3> Set the hint that the `Command` should be persisted if possible (when completed, see below).
+ xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service).
+ Its members will be populated automatically by the framework.
-<2> Deprecated and *IS NOT CALLED* by the framework.
-The framework automatically populates the ``Command``'s `timestamp`, `user` and `transactionId` fields, so there is no need for the service implementation to initialize any of these.
-In particular, the ``Command`` will already have been initialized with the provided `transactionId` argument.
-<3> Set the hint that the `Command` should be persisted if possible (when completed, see below).
-<4> "Complete" the command, typically meaning that the command should be persisted it if its `Command#getPersistence()` flag and persistence hint (`Command#isPersistHint()`) indicate that it should be. +
++<2> Set the hint that the `Command` should be persisted if possible (when completed, see below).
++<3> "Complete" the command, typically meaning that the command should be persisted it if its `Command#getPersistence()` flag and persistence hint (`Command#isPersistHint()`) indicate that it should be. +
+ +
+ The framework will automatically have set the `completedAt` property of the `Command`.
@@@ -97,10 -100,10 +100,10 @@@ This is closely related to the xref:../
The implementations of `CommandService` and `BackgroundCommandService` are intended to go together, so that persistent parent `Command`s can be associated with their child background `Command`s.
-The services provided by this module combines very well with the xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_AuditingService[`AuditingService`].
-The `CommandService` captures the _cause_ of an interaction (an action was invoked, a property was edited), while the `AuditingService3` captures the _effect_ of that interaction in terms of changed state.
+The services provided by this module combines very well with the xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_AuditerService[`AuditerService`].
- The `CommandService` captures the _cause_ of an interaction (an action was invoked, a property was edited), while the `AuditerService` captures the _effect_ of that interaction in terms of changed state.
++The `CommandService` captures the __cause__ of an interaction (an action was invoked, a property was edited), while the `AuditerService` captures the __effect__ of that interaction in terms of changed state.
-You may also want to configure the xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublishingService[`PublishingService`].
+You may also want to configure the xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`].
All three of these services collaborate implicitly by way of the xref:../rgcms/rgcms.adoc#_rgcms_classes_mixins_HasTransactionId[`HasTransactionId`] interface.
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_MetamodelService.adoc
index 3b45d42,222e67e..361e468
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_MetamodelService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_MetamodelService.adoc
@@@ -6,9 -6,11 +6,10 @@@
- The `MetaModelService4` service (and its various supertypes) provides access to a number of aspects of Apache Isis' internal metamodel.
+ The `MetaModelService5` service (and its various supertypes) provides access to a number of aspects of Apache Isis' internal metamodel.
-
+ [[_rgsvc_metadata-api_MetamodelService_api]]
== API
diff --cc adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_programming-model_actions.adoc
index 8a391b2,b48ab06..693703e
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_programming-model_actions.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_programming-model_actions.adoc
@@@ -255,8 -255,8 +255,13 @@@ public Order updateDiscount
return this;
}
----
++<<<<<<< HEAD
+<1> Specifies the property precision using xref:../rgant/rgant.adoc#_rgant_Column_scale[`@Column#scale()`]
+<2> Specifies the corresponding parameter precision using xref:../rgant/rgant.adoc#_rgant-Digits[`@Digits#fraction()`].
++=======
+ <1> Specifies the property precision using xref:../rgant/rgant.adoc#_rgant-Column_scale[`@Column#scale()`]
+ <2> Specifies the corresponding parameter precision using xref:../rgant/rgant.adoc#_rgant-Digits_fraction[`@Digits#fraction()`].
++>>>>>>> maint-1.16.1
See also xref:../ugfun/ugfun.adoc#_ugfun_programming-model_properties-vs-parameters[properties vs parameters].
diff --cc adocs/documentation/src/main/asciidoc/guides/ugvw/_ugvw_layout_file-based.adoc
index 4f49ccf,3a30493..38956fc
--- a/adocs/documentation/src/main/asciidoc/guides/ugvw/_ugvw_layout_file-based.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugvw/_ugvw_layout_file-based.adoc
@@@ -32,6 -32,27 +32,17 @@@ These are JAXB-annotated classes with c
+ == Search Algorithm (Library Support)
+
+ For a given domain object `Xxx` the framework initially searches for a file (on the classpath) called `Xxx.layout.xml`.
+
+ If this can't be found, then the framework will search for a file named `Xxx.layout.fallback.xml`.
+ If present, this will be used instead.
+
+ This therefore allows libraries that provide a domain entities/view models (for example, the (non-ASF) link:http://platform.incode.org[Incode Platform] modules) to define the UI of these objects using a layout file, while still allowing the consuming application to override that layout if it so requires.
+
+
+
-[NOTE]
-====
-It is also possible to describe layouts using a `.layout.json` file.
-However, `.layout.json` support is deprecated; the ``.layout.xml`` file also enables much more sophisticated layouts than those afforded by ``.layout.json``.
-
-If you have an application with older `.layout.json` files, then it is possible to download initial `.layout.xml` files using the xref:../rgsvc/rgsvc.adoc#_rgsvc_metadata-api_LayoutService[`LayoutService`] (exposed as an action on the prototyping menu).
-
-The `.layout.json` file will be ignored once a `.layout.xml` file is present.
-====
-
== Grids vs Components
diff --cc core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
index 0183df7,d1178eb..118b83d
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
@@@ -25,7 -25,13 +25,12 @@@ import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+ import org.apache.isis.applib.conmap.ContentMappingServiceForCommandDto;
+ import org.apache.isis.applib.conmap.ContentMappingServiceForCommandsDto;
+ import org.apache.isis.applib.services.command.CommandDtoProcessor;
+ import org.apache.isis.applib.services.command.CommandWithDto;
+ import org.apache.isis.applib.services.command.spi.CommandService;
import org.apache.isis.applib.services.eventbus.ActionDomainEvent;
-import org.apache.isis.applib.services.publish.PublisherService;
/**
* Domain semantics for domain object collection.
@@@ -115,8 -121,11 +120,11 @@@ public @interface Action
* <p>
* Has no meaning if annotated on an action of a domain service.
* </p>
+ *
+ * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
*/
+ @Deprecated
- InvokeOn invokeOn() default InvokeOn.OBJECT_ONLY;
+ InvokeOn invokeOn() default InvokeOn.NOT_SPECIFIED;
// //////////////////////////////////////
@@@ -178,7 -208,46 +202,46 @@@
* By default there are no restrictions, with the action being available in all environments.
* </p>
*/
- RestrictTo restrictTo() default RestrictTo.NO_RESTRICTIONS;
+ RestrictTo restrictTo() default RestrictTo.NOT_SPECIFIED;
+ // //////////////////////////////////////
+
+
+ /**
+ * Associates this action with a property or collection, specifying its id.
+ *
+ * <p>
+ * This is an alternative to using {@link MemberOrder#name()}. To specify the order (equivalent to
+ * {@link MemberOrder#sequence()}}), use {@link #associateWithSequence()}.
+ * </p>
+ *
+ * <p>
+ * For example <code>@Action(associateWith="items", associateWithSequence="2.1")</code>
+ * </p>
+ *
+ * <p>
+ * If an action is associated with a collection, then any matching parameters will have
+ * their choices automatically inferred from the collection (if not otherwise specified)
+ * and any collection parameter defaults can be specified using checkboxes
+ * (in the Wicket UI, at least).
+ * </p>
+ */
+ String associateWith() default "";
+
+ /**
+ * Specifies the sequence/order in the UI for an action that's been associated with a property or collection.
+ *
+ * <p>
+ * This is an alternative to using {@link MemberOrder#sequence()}, but is ignored if
+ * {@link Action#associateWith()} isn't also specified.
+ * </p>
+ *
+ * <p>
+ * For example <code>@Action(associateWith="items", associateWithSequence="2.1")</code>
+ * </p>
+ */
+ String associateWithSequence() default "1";
+
+
}
diff --cc core/applib/src/main/java/org/apache/isis/applib/annotation/CommandExecuteIn.java
index 6c666c5,cd9311a..789ab07
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandExecuteIn.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/CommandExecuteIn.java
@@@ -38,8 -38,50 +38,30 @@@ public enum CommandExecuteIn
* persisted {@link org.apache.isis.applib.services.command.Command command} object as a placeholder to the
* result.
*/
- BACKGROUND;
+ BACKGROUND,
+ /**
+ * For commands that are replicated from a master onto a slave and are to be replayed (typically using the same
+ * mechanism as "regular" background commands, eg a background job).
+ *
+ * <p>
+ * For framework use, not intended to be used in application code.
+ * </p>
+ */
+ REPLAYABLE,
+ /**
+ * For commands that have been excluded and will not run.
+ * These are typically for a replayable command that has hit an exception (which normally would prevent any further
+ * replayable commands from being replayed) and which the administrator has decided to skip.
+ */
+ EXCLUDED
+ ;
+
+ public boolean isForeground() { return this == FOREGROUND; }
+ public boolean isBackground() { return this == BACKGROUND; }
+ public boolean isReplayable() { return this == REPLAYABLE; }
+ public boolean isExcluded() { return this == EXCLUDED; }
+
- @Deprecated
- public static CommandExecuteIn from(final Command.ExecuteIn executeIn) {
- if(executeIn == null) return null;
- if(executeIn == Command.ExecuteIn.FOREGROUND) return FOREGROUND;
- if(executeIn == Command.ExecuteIn.BACKGROUND) return BACKGROUND;
- if(executeIn == Command.ExecuteIn.REPLAYABLE) return REPLAYABLE;
- // shouldn't happen
- throw new IllegalArgumentException("Unrecognized : executeIn" + executeIn);
- }
-
- @Deprecated
- public static Command.ExecuteIn from(final CommandExecuteIn commandExecuteIn) {
- if(commandExecuteIn == null) return null;
- if(commandExecuteIn == FOREGROUND) return Command.ExecuteIn.FOREGROUND;
- if(commandExecuteIn == BACKGROUND) return Command.ExecuteIn.BACKGROUND;
- if(commandExecuteIn == REPLAYABLE) return Command.ExecuteIn.REPLAYABLE;
- // shouldn't happen
- throw new IllegalArgumentException("Unrecognized : executeIn" + commandExecuteIn);
- }
-
public static class Type {
private Type() {}
diff --cc core/applib/src/main/java/org/apache/isis/applib/annotation/InvokeOn.java
index 8e17153,be84512..72dfed6
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/InvokeOn.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/InvokeOn.java
@@@ -40,12 -49,29 +49,28 @@@ public enum InvokeOn
* <p>
* Corresponds to (the deprecated) <code>@Bulk(appliesTo=BULK_ONLY)</code> annotation.
* </p>
+ *
+ * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
*/
+ @Deprecated
- COLLECTION_ONLY;
+ COLLECTION_ONLY,
+ /**
+ * Ignore the value provided by this annotation (meaning that the framework will keep searching, in meta
+ * annotations or superclasses/interfaces).
++ *
++ * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
+ */
- NOT_SPECIFIED
++ @Deprecated
++ NOT_SPECIFIED;
+
+ @Deprecated
+ public static Bulk.AppliesTo from(final InvokeOn invokeOn) {
+ if(invokeOn == null) return null;
+ if(invokeOn == OBJECT_AND_COLLECTION) return Bulk.AppliesTo.BULK_AND_REGULAR;
+ if(invokeOn == COLLECTION_ONLY) return Bulk.AppliesTo.BULK_ONLY;
+ if(invokeOn == OBJECT_ONLY) return Bulk.AppliesTo.REGULAR_ONLY;
+ // shouldn't happen
+ throw new IllegalArgumentException("Unrecognized appliesTo: " + invokeOn);
+ }
- @Deprecated
- public static InvokeOn from(final Bulk.AppliesTo appliesTo) {
- if(appliesTo == null) return null;
- if(appliesTo == Bulk.AppliesTo.BULK_AND_REGULAR) return OBJECT_AND_COLLECTION;
- if(appliesTo == Bulk.AppliesTo.BULK_ONLY) return COLLECTION_ONLY;
- if(appliesTo == Bulk.AppliesTo.REGULAR_ONLY) return OBJECT_ONLY;
- // shouldn't happen
- throw new IllegalArgumentException("Unrecognized appliesTo: " + appliesTo);
- }
}
diff --cc core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
index 77632c9,ed91f9e..4ec8d78
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
@@@ -131,9 -136,25 +136,25 @@@ public @interface Property
* or {@link org.apache.isis.applib.services.publish.PublisherService} is registered with the framework.
* </p>
*/
- Publishing publishing() default Publishing.AS_CONFIGURED;
+ Publishing publishing() default Publishing.NOT_SPECIFIED;
+ /**
+ * The {@link CommandDtoProcessor} to process this command's DTO.
+ *
+ * <p>
+ * Specifying a processor requires that the implementation of {@link CommandService} provides a
+ * custom implementation of {@link org.apache.isis.applib.services.command.Command} that additional extends
+ * from {@link CommandWithDto}.
+ * </p>
+ *
+ * <p>
+ * Tprocessor itself is used by {@link ContentMappingServiceForCommandDto} and
+ * {@link ContentMappingServiceForCommandsDto} to dynamically transform the DTOs.
+ * </p>
+ */
+ Class<? extends CommandDtoProcessor> commandDtoProcessor() default CommandDtoProcessor.class;
+
diff --cc core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingServiceForCommandDto.java
index 0000000,c3b055e..a31dc59
mode 000000,100644..100644
--- a/core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingServiceForCommandDto.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingServiceForCommandDto.java
@@@ -1,0 -1,151 +1,152 @@@
+ /*
+ * 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.applib.conmap;
+
+ import java.sql.Timestamp;
+ import java.util.List;
+
+ import javax.inject.Inject;
+ import javax.ws.rs.core.MediaType;
+
+ import org.apache.isis.applib.annotation.DomainService;
+ import org.apache.isis.applib.annotation.NatureOfService;
+ import org.apache.isis.applib.annotation.Programmatic;
+ import org.apache.isis.applib.conmap.spi.CommandDtoProcessorService;
+ import org.apache.isis.applib.services.bookmark.Bookmark;
+ import org.apache.isis.applib.services.command.Command;
+ import org.apache.isis.applib.services.command.CommandDtoProcessor;
+ import org.apache.isis.applib.services.command.CommandWithDto;
-import org.apache.isis.applib.services.metamodel.MetaModelService5;
++import org.apache.isis.applib.services.conmap.ContentMappingService;
++import org.apache.isis.applib.services.metamodel.MetaModelService;
+ import org.apache.isis.schema.cmd.v1.CommandDto;
+ import org.apache.isis.schema.common.v1.PeriodDto;
+ import org.apache.isis.schema.utils.CommandDtoUtils;
+ import org.apache.isis.schema.utils.jaxbadapters.JavaSqlTimestampXmlGregorianCalendarAdapter;
+
+ @DomainService(
+ nature = NatureOfService.DOMAIN,
+ menuOrder = "" + Integer.MAX_VALUE
+ )
+ public class ContentMappingServiceForCommandDto implements ContentMappingService {
+
+ @Programmatic
+ public Object map(Object object, final List<MediaType> acceptableMediaTypes) {
+ final boolean supported = Util.isSupported(CommandDto.class, acceptableMediaTypes);
+ if(!supported) {
+ return null;
+ }
+
+ return asProcessedDto(object);
+ }
+
+ /**
+ * Not part of the {@link ContentMappingService} API.
+ */
+ @Programmatic
+ public CommandDto map(final CommandWithDto commandWithDto) {
+ return asProcessedDto(commandWithDto);
+ }
+
+ CommandDto asProcessedDto(final Object object) {
+ if (!(object instanceof CommandWithDto)) {
+ return null;
+ }
+ final CommandWithDto commandWithDto = (CommandWithDto) object;
+ return asProcessedDto(commandWithDto);
+ }
+
+ private CommandDto asProcessedDto(final CommandWithDto commandWithDto) {
+ if(commandWithDto == null) {
+ return null;
+ }
+ CommandDto commandDto = commandWithDto.asDto();
+
+ // global processors
+ for (final CommandDtoProcessorService commandDtoProcessorService : commandDtoProcessorServices) {
+ commandDto = commandDtoProcessorService.process(commandWithDto, commandDto);
+ if(commandDto == null) {
+ // any processor could return null, effectively breaking the chain.
+ return null;
+ }
+ }
+
+ // specific processors for this specific member (action or property)
+ final CommandDtoProcessor commandDtoProcessor =
+ metaModelService.commandDtoProcessorFor(commandDto.getMember().getLogicalMemberIdentifier());
+ if (commandDtoProcessor == null) {
+ return commandDto;
+ }
+ return commandDtoProcessor.process(commandWithDto, commandDto);
+ }
+
+
+ /**
+ * Uses the SPI infrastructure to copy over standard properties from {@link Command} to {@link CommandDto}.
+ */
+ @DomainService(
+ nature = NatureOfService.DOMAIN,
+ // specify quite a high priority since custom processors will probably want to run after this one
+ // (but can choose to run before if they wish)
+ menuOrder = "1000"
+ )
+ public static class CopyOverFromCommand implements CommandDtoProcessorService {
+
+ public CommandDto process(final Command command, CommandDto commandDto) {
+
+ // for some reason this isn't being persisted initially, so patch it in. TODO: should fix this
+ commandDto.setUser(command.getUser());
+
+ // the timestamp field was only introduced in v1.4 of cmd.xsd, so there's no guarantee
+ // it will have been populated. We therefore copy the value in from CommandWithDto entity.
+ if(commandDto.getTimestamp() == null) {
+ final Timestamp timestamp = command.getTimestamp();
+ commandDto.setTimestamp(JavaSqlTimestampXmlGregorianCalendarAdapter.print(timestamp));
+ }
+
+ CommandDtoUtils.setUserData(commandDto,
+ CommandWithDto.USERDATA_KEY_TARGET_CLASS, command.getTargetClass());
+ CommandDtoUtils.setUserData(commandDto,
+ CommandWithDto.USERDATA_KEY_TARGET_ACTION, command.getTargetAction());
+ CommandDtoUtils.setUserData(commandDto,
+ CommandWithDto.USERDATA_KEY_ARGUMENTS, command.getArguments());
+
+ final Bookmark result = command.getResult();
+ CommandDtoUtils.setUserData(commandDto,
+ CommandWithDto.USERDATA_KEY_RETURN_VALUE, result != null ? result.toString() : null);
+ // knowing whether there was an exception is on the master is used to determine whether to
+ // continue when replayed on the slave if an exception occurs there also
+ CommandDtoUtils.setUserData(commandDto,
+ CommandWithDto.USERDATA_KEY_EXCEPTION, command.getException());
+
+ PeriodDto timings = CommandDtoUtils.timingsFor(commandDto);
+ timings.setStartedAt(JavaSqlTimestampXmlGregorianCalendarAdapter.print(command.getStartedAt()));
+ timings.setCompletedAt(JavaSqlTimestampXmlGregorianCalendarAdapter.print(command.getCompletedAt()));
+
+ return commandDto;
+ }
+ }
+
+
+ @Inject
- MetaModelService5 metaModelService;
++ MetaModelService metaModelService;
+
+ @Inject
+ List<CommandDtoProcessorService> commandDtoProcessorServices;
+
+ }
diff --cc core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingServiceForCommandsDto.java
index 0000000,95ba22a..71238d8
mode 000000,100644..100644
--- a/core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingServiceForCommandsDto.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingServiceForCommandsDto.java
@@@ -1,0 -1,94 +1,91 @@@
+ /*
+ * 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.applib.conmap;
+
+ import java.util.List;
+
+ import javax.inject.Inject;
+ import javax.ws.rs.core.MediaType;
+
+ import org.apache.isis.applib.annotation.DomainService;
+ import org.apache.isis.applib.annotation.NatureOfService;
+ import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.metamodel.MetaModelService5;
++import org.apache.isis.applib.services.conmap.ContentMappingService;
+ import org.apache.isis.schema.cmd.v1.CommandDto;
+ import org.apache.isis.schema.cmd.v1.CommandsDto;
+
+ @DomainService(
+ nature = NatureOfService.DOMAIN,
+ menuOrder = "" + Integer.MAX_VALUE
+ )
+ public class ContentMappingServiceForCommandsDto implements ContentMappingService {
+
+ @Programmatic
+ public Object map(Object object, final List<MediaType> acceptableMediaTypes) {
+ final boolean supported = Util.isSupported(CommandsDto.class, acceptableMediaTypes);
+ if(!supported) {
+ return null;
+ }
+
+ return map(object);
+ }
+
+ /**
+ * Not part of the {@link ContentMappingService} API.
+ */
+ @Programmatic
+ public CommandsDto map(final Object object) {
+ if(object instanceof CommandsDto) {
+ return ((CommandsDto) object);
+ }
+
- CommandDto commandDto = asDto(object, metaModelService5);
++ CommandDto commandDto = asDto(object);
+ if(commandDto != null) {
+ final CommandsDto commandsDto = new CommandsDto();
+ commandsDto.getCommandDto().add(commandDto);
+ return commandsDto;
+ }
+
+ if (object instanceof List) {
+ final List list = (List) object;
+ final CommandsDto commandsDto = new CommandsDto();
+ for (final Object obj : list) {
- final CommandDto objAsCommandDto = asDto(obj, metaModelService5);
++ final CommandDto objAsCommandDto = asDto(obj);
+ if(objAsCommandDto != null) {
+ commandsDto.getCommandDto().add(objAsCommandDto);
+ } else {
+ // simply ignore.
+ // this is the means by which we can avoid replicating commands.
+ }
+ }
+ return commandsDto;
+ }
+
+ // else
+ return new CommandsDto();
+ }
+
- private CommandDto asDto(final Object object, MetaModelService5 metaModelService5) {
++ private CommandDto asDto(final Object object) {
+ return contentMappingServiceForCommandDto.asProcessedDto(object);
+ }
+
+ @Inject
- MetaModelService5 metaModelService5;
-
- @Inject
+ ContentMappingServiceForCommandDto contentMappingServiceForCommandDto;
+
+ }
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/actinvoc/ActionInvocationContext.java
index 0ba521d,86060cc..2f6cb58
--- a/core/applib/src/main/java/org/apache/isis/applib/services/actinvoc/ActionInvocationContext.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/actinvoc/ActionInvocationContext.java
@@@ -45,12 -50,12 +50,15 @@@ public class ActionInvocationContext
/**
* Intended only to support unit testing.
+ *
+ * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
*/
+ @Deprecated
public static ActionInvocationContext onObject(final Object domainObject) {
- return new ActionInvocationContext(InvokedOn.OBJECT, Collections.singletonList(domainObject));
+ ActionInvocationContext aic = new ActionInvocationContext();
+ aic.setInvokedOn(InvokedOn.OBJECT);
+ aic.setDomainObjects(Collections.singletonList(domainObject));
+ return aic;
}
/**
@@@ -62,12 -70,12 +73,15 @@@
/**
* Intended only to support unit testing.
+ *
+ * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
*/
+ @Deprecated
public static ActionInvocationContext onCollection(final List<Object> domainObjects) {
- return new ActionInvocationContext(InvokedOn.COLLECTION, domainObjects);
+ ActionInvocationContext aic = new ActionInvocationContext();
+ aic.setInvokedOn(InvokedOn.COLLECTION);
+ aic.setDomainObjects(domainObjects);
+ return aic;
}
// //////////////////////////////////////
@@@ -78,8 -86,32 +92,7 @@@
private int index;
- // //////////////////////////////////////
-
- /**
- * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
- */
- @Deprecated
- public ActionInvocationContext() {
- }
-
- /**
- * @deprecated - now a {@link javax.enterprise.context.RequestScoped} service
- */
- @Deprecated
- public ActionInvocationContext(final InvokedOn invokedOn, final Object... domainObjects) {
- this(invokedOn, Arrays.asList(domainObjects));
- }
-
- /**
- * @deprecated - now a {@link javax.enterprise.context.RequestScoped} service
- */
- @Deprecated
- public ActionInvocationContext(final InvokedOn invokedOn, final List<Object> domainObjects) {
- this.invokedOn = invokedOn;
- this.domainObjects = domainObjects;
- }
-
// //////////////////////////////////////
/**
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
index d42f8ad,0ae75e1..d3e1496
--- a/core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
@@@ -17,14 -17,11 +17,12 @@@
package org.apache.isis.applib.services.command;
import java.sql.Timestamp;
+import java.util.List;
- import javax.annotation.Nullable;
-
import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.annotation.Command.ExecuteIn;
-import org.apache.isis.applib.annotation.Command.Persistence;
+import org.apache.isis.applib.annotation.CommandExecuteIn;
+import org.apache.isis.applib.annotation.CommandPersistence;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.clock.Clock;
import org.apache.isis.applib.services.HasTransactionId;
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/conmap/ContentMappingService.java
index a4a0fd7,49b0eb5..8de4d66
--- a/core/applib/src/main/java/org/apache/isis/applib/services/conmap/ContentMappingService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/conmap/ContentMappingService.java
@@@ -16,9 -16,10 +16,10 @@@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.applib.conmap;
+package org.apache.isis.applib.services.conmap;
import java.util.List;
+ import java.util.Map;
import javax.ws.rs.core.MediaType;
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
index 589b602,3263ba7..b4213ee
--- a/core/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
@@@ -20,11 -20,8 +20,12 @@@ package org.apache.isis.applib.services
import java.util.List;
+import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.AppManifest2;
import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.bookmark.Bookmark;
++import org.apache.isis.applib.services.command.CommandDtoProcessor;
/**
* This service provides a formal API into Isis' metamodel.
@@@ -61,87 -58,5 +62,89 @@@ public interface MetaModelService
@Programmatic
List<DomainMember> export();
+ /**
+ * @deprecated - use {@link #sortOf(Class, MetaModelService.Mode)}
+ */
+ @Deprecated
+ @Programmatic
+ Sort sortOf(Class<?> domainType);
+
+ /**
+ * @deprecated - use {@link #sortOf(Bookmark, MetaModelService.Mode)}
+ */
+ @Deprecated
+ @Programmatic
+ Sort sortOf(Bookmark bookmark);
+
+ @Programmatic
+ Sort sortOf(Class<?> domainType, Mode mode);
+
+ @Programmatic
+ Sort sortOf(Bookmark bookmark, Mode mode);
+
+ enum Sort {
+ VIEW_MODEL,
+ JDO_ENTITY,
+ DOMAIN_SERVICE,
+ MIXIN,
+ VALUE,
+ COLLECTION,
+ UNKNOWN;
+
+ public boolean isDomainService() {
+ return this == DOMAIN_SERVICE;
+ }
+
+ public boolean isMixin() {
+ return this == MIXIN;
+ }
+
+ public boolean isViewModel() {
+ return this == VIEW_MODEL;
+ }
+
+ public boolean isValue() {
+ return this == VALUE;
+ }
+
+ public boolean isCollection() {
+ return this == COLLECTION;
+ }
+
+ public boolean isJdoEntity() {
+ return this == JDO_ENTITY;
+ }
+
+ public boolean isUnknown() {
+ return this == UNKNOWN;
+ }
+
+ }
+
+ enum Mode {
+ /**
+ * If the {@link #sortOf(Class, Mode) sort of} object type is unknown, then throw an exception.
+ */
+ STRICT,
+ /**
+ * If the {@link #sortOf(Class, Mode) sort of} object type is unknown, then return {@link Sort#UNKNOWN}.
+ */
+ RELAXED
+ }
+
+ /**
+ * @return as {@link #getAppManifest()}, downcasted (else null).
+ */
+ @Programmatic
+ AppManifest2 getAppManifest2();
+
+ /**
+ * @return the {@link AppManifest} used to bootstrap the application.
+ */
+ @Programmatic
+ AppManifest getAppManifest();
+
++ @Programmatic
++ CommandDtoProcessor commandDtoProcessorFor(String memberIdentifier);
}
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
index 8631686,42380a6..124dba5
--- a/core/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
@@@ -20,6 -20,6 +20,8 @@@
package org.apache.isis.applib.services.xactn;
import org.apache.isis.applib.annotation.Programmatic;
++import org.apache.isis.applib.services.command.Command;
++import org.apache.isis.applib.services.command.CommandContext;
public interface TransactionService {
@@@ -50,54 -50,4 +52,70 @@@
@Programmatic
Transaction currentTransaction();
+ /**
+ * Generally this is equivalent to using {@link #currentTransaction()} and {@link Transaction#getTransactionState()}.
+ * However, if there is no current transaction, then this will return {@link TransactionState#NONE}.
+ */
+ @Programmatic
+ TransactionState getTransactionState();
+
+
+ /**
+ * Intended only for use by fixture scripts and integration tests.
+ *
+ * <p>
+ * The behaviour depends on the current state of the transaction, and the specified policy.
+ * <ul>
+ * <li>
+ * If the current transaction is in that it is still in progress, then commits and starts a new one.
+ * </li>
+ * <li>
+ * If the current transaction is complete, in that it is already committed or was rolled back, then simply starts a new one.
+ * </li>
+ * <li>
+ * If the current transaction is marked for abort, then depends on the provided policy:
+ * <ul>
+ * <li>
+ * If set to {@link Policy#ALWAYS always}, then rolls back and starts a new transaction
+ * </li>
+ * <li>
+ * But if set to {@link Policy#UNLESS_MARKED_FOR_ABORT marked for abort}, then fails fast by throwing a runtime exception.
+ * </li>
+ * </ul>
+ * </li>
+ *
+ * </ul>
+ * If the current transaction has been marked for abort only, then depends on the provided rolls it back, and (again) starts a new one.
+ * </p>
+ *
+ * <p>
+ * This is a refinement of the {@link TransactionService#nextTransaction()}, introduced in
+ * order to improve the error handling of that method in the case of an already must-abort transaction, and
+ * also to allow the caller to have more control on how to continue.
+ * </p>
+ */
+ @Programmatic
+ void nextTransaction(Policy policy);
+
++
++ /**
++ * If the current transaction does not use the specified {@link Command} as its
++ * {@link CommandContext#getCommand() command context}, then commit and start a new one.
++ * @param command
++ */
++ void nextTransaction(Command command);
++
++ /**
++ * As per {@link #nextTransaction(Policy)} and {@link #nextTransaction(Command)}.
++ */
++ void nextTransaction(Policy policy, Command command);
++
++
+ public enum Policy {
+ UNLESS_MARKED_FOR_ABORT,
+ ALWAYS
+ }
+
++
++
}
diff --cc core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java
index 8fe38c6,6c3ea91..b85a869
--- 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
@@@ -33,8 -37,12 +37,13 @@@ import org.joda.time.LocalTime
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.util.Casts;
+ import org.apache.isis.applib.value.Blob;
+ import org.apache.isis.applib.value.Clob;
+ import org.apache.isis.schema.cmd.v1.MapDto;
import org.apache.isis.schema.cmd.v1.ParamDto;
+ import org.apache.isis.schema.common.v1.BlobDto;
+ import org.apache.isis.schema.common.v1.ClobDto;
import org.apache.isis.schema.common.v1.CollectionDto;
import org.apache.isis.schema.common.v1.EnumDto;
import org.apache.isis.schema.common.v1.OidDto;
@@@ -322,11 -348,18 +355,19 @@@ public final class CommonDtoUtils
case ENUM:
final EnumDto enumDto = valueDto.getEnum();
final String enumType = enumDto.getEnumType();
+ @SuppressWarnings("rawtypes")
final Class<? extends Enum> enumClass = loadClassElseThrow(enumType);
- return (T) Enum.valueOf(enumClass, enumDto.getEnumName());
+ return Enum.valueOf(Casts.uncheckedCast(enumClass), enumDto.getEnumName());
case REFERENCE:
- return (T) valueDto.getReference();
+ return valueDto.getReference();
+ case COLLECTION:
- return (T)valueDto.getCollection();
++ return valueDto.getCollection();
+ case BLOB:
+ final BlobDto blobDto = valueDto.getBlob();
- return (T)new Blob(blobDto.getName(), blobDto.getMimeType(), blobDto.getBytes());
++ return new Blob(blobDto.getName(), blobDto.getMimeType(), blobDto.getBytes());
+ case CLOB:
+ final ClobDto clobDto = valueDto.getClob();
- return (T)new Clob(clobDto.getName(), clobDto.getMimeType(), clobDto.getChars());
++ return new Clob(clobDto.getName(), clobDto.getMimeType(), clobDto.getChars());
case VOID:
return null;
default:
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
index d6af533,b58ff4a..6c21f1c
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
@@@ -20,11 -20,26 +20,14 @@@
package org.apache.isis.core.metamodel.facets.actions.action;
import java.lang.reflect.Method;
+import java.util.List;
+ import com.google.common.base.Strings;
+
import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.annotation.ActionInteraction;
-import org.apache.isis.applib.annotation.ActionSemantics;
-import org.apache.isis.applib.annotation.Bulk;
-import org.apache.isis.applib.annotation.Command;
-import org.apache.isis.applib.annotation.Disabled;
-import org.apache.isis.applib.annotation.Hidden;
-import org.apache.isis.applib.annotation.Idempotent;
-import org.apache.isis.applib.annotation.PostsActionInvokedEvent;
-import org.apache.isis.applib.annotation.Prototype;
-import org.apache.isis.applib.annotation.PublishedAction;
-import org.apache.isis.applib.annotation.QueryOnly;
-import org.apache.isis.applib.annotation.TypeOf;
import org.apache.isis.applib.services.HasTransactionId;
import org.apache.isis.applib.services.eventbus.ActionDomainEvent;
-import org.apache.isis.applib.services.eventbus.ActionInvokedEvent;
+ import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FacetUtil;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
@@@ -52,11 -82,31 +55,15 @@@ import org.apache.isis.core.metamodel.f
import org.apache.isis.core.metamodel.facets.actions.publish.PublishedActionFacet;
import org.apache.isis.core.metamodel.facets.actions.semantics.ActionSemanticsFacet;
import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet;
+ import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
+ import org.apache.isis.core.metamodel.facets.members.order.annotprop.MemberOrderFacetForActionAnnotation;
+ import org.apache.isis.core.metamodel.services.ServicesInjector;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.CollectionUtils;
+ import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForDeprecatedAnnotation;
import org.apache.isis.core.metamodel.util.EventUtil;
-public class ActionAnnotationFacetFactory extends FacetFactoryAbstract
- implements MetaModelValidatorRefiner {
-
- private final MetaModelValidatorForDeprecatedAnnotation actionSemanticsValidator = new MetaModelValidatorForDeprecatedAnnotation(ActionSemantics.class);
- private final MetaModelValidatorForDeprecatedAnnotation actionInteractionValidator = new MetaModelValidatorForDeprecatedAnnotation(ActionInteraction.class);
- private final MetaModelValidatorForDeprecatedAnnotation postsActionInvokedEventValidator = new MetaModelValidatorForDeprecatedAnnotation(PostsActionInvokedEvent.class);
- private final MetaModelValidatorForDeprecatedAnnotation bulkValidator = new MetaModelValidatorForDeprecatedAnnotation(Bulk.class);
- private final MetaModelValidatorForDeprecatedAnnotation commandValidator = new MetaModelValidatorForDeprecatedAnnotation(Command.class);
- private final MetaModelValidatorForDeprecatedAnnotation queryOnlyValidator = new MetaModelValidatorForDeprecatedAnnotation(QueryOnly.class);
- private final MetaModelValidatorForDeprecatedAnnotation idempotentValidator = new MetaModelValidatorForDeprecatedAnnotation(Idempotent.class);
- private final MetaModelValidatorForDeprecatedAnnotation publishedActionValidator = new MetaModelValidatorForDeprecatedAnnotation(PublishedAction.class);
- private final MetaModelValidatorForDeprecatedAnnotation typeOfValidator = new MetaModelValidatorForDeprecatedAnnotation(TypeOf.class);
- private final MetaModelValidatorForDeprecatedAnnotation hiddenValidator = new MetaModelValidatorForDeprecatedAnnotation(Hidden.class);
- private final MetaModelValidatorForDeprecatedAnnotation disabledValidator = new MetaModelValidatorForDeprecatedAnnotation(Disabled.class);
- private final MetaModelValidatorForDeprecatedAnnotation prototypeValidator = new MetaModelValidatorForDeprecatedAnnotation(Prototype.class);
+public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
@@@ -216,8 -367,18 +224,8 @@@
return;
}
- CommandFacet commandFacet;
-
- // check for deprecated @Command annotation first
- final Command annotation = Annotations.getAnnotation(method, Command.class);
- commandFacet = commandValidator.flagIfPresent(
- CommandFacetForCommandAnnotation.create(annotation, processMethodContext.getFacetHolder(),
- servicesInjector), processMethodContext);
-
- // else check for @Action(command=...)
- if(commandFacet == null) {
- commandFacet = CommandFacetForActionAnnotation.create(action, getConfiguration(), servicesInjector, holder);
- }
+ // check for @Action(command=...)
- CommandFacet commandFacet = CommandFacetForActionAnnotation.create(actions, getConfiguration(), holder);
++ CommandFacet commandFacet = CommandFacetForActionAnnotation.create(actions, getConfiguration(), servicesInjector, holder);
FacetUtil.addFacet(commandFacet);
}
@@@ -279,5 -458,66 +287,25 @@@
FacetUtil.addFacet(typeOfFacet);
}
+ void processAssociateWith(final ProcessMethodContext processMethodContext) {
+
+ final Method method = processMethodContext.getMethod();
+ final FacetedMethod holder = processMethodContext.getFacetHolder();
+
+ // check for @Action(associateWith=...)
+ MemberOrderFacet memberOrderFacet = null;
+
+ final Action action = Annotations.getAnnotation(method, Action.class);
+ if (action != null) {
+ final String associateWith = action.associateWith();
+ if(!Strings.isNullOrEmpty(associateWith)) {
+ final String associateWithSequence = action.associateWithSequence();
+ memberOrderFacet = new MemberOrderFacetForActionAnnotation(associateWith, associateWithSequence, holder);
+ }
+ }
+
+ FacetUtil.addFacet(memberOrderFacet);
+ }
+
- // ///////////////////////////////////////////////////////////////
-
- @Override
- public void refineMetaModelValidator(final MetaModelValidatorComposite metaModelValidator, final IsisConfiguration configuration) {
- metaModelValidator.add(actionSemanticsValidator);
- metaModelValidator.add(actionInteractionValidator);
- metaModelValidator.add(postsActionInvokedEventValidator);
- metaModelValidator.add(bulkValidator);
- metaModelValidator.add(commandValidator);
- metaModelValidator.add(queryOnlyValidator);
- metaModelValidator.add(idempotentValidator);
- metaModelValidator.add(publishedActionValidator);
- metaModelValidator.add(typeOfValidator);
- metaModelValidator.add(hiddenValidator);
- metaModelValidator.add(disabledValidator);
- metaModelValidator.add(prototypeValidator);
- }
-
- // ///////////////////////////////////////////////////////////////
-
-
- @Override
- public void setServicesInjector(final ServicesInjector servicesInjector) {
- super.setServicesInjector(servicesInjector);
- final IsisConfiguration configuration = getConfiguration();
-
- actionSemanticsValidator.setConfiguration(configuration);
- actionInteractionValidator.setConfiguration(configuration);
- postsActionInvokedEventValidator.setConfiguration(configuration);
- bulkValidator.setConfiguration(configuration);
- commandValidator.setConfiguration(configuration);
- queryOnlyValidator.setConfiguration(configuration);
- idempotentValidator.setConfiguration(configuration);
- publishedActionValidator.setConfiguration(configuration);
- typeOfValidator.setConfiguration(configuration);
- hiddenValidator.setConfiguration(configuration);
- disabledValidator.setConfiguration(configuration);
- prototypeValidator.setConfiguration(configuration);
- }
-
-
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetForActionAnnotation.java
index 499b411,6a9cff4..85577a8
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetForActionAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetForActionAnnotation.java
@@@ -33,44 -35,41 +35,53 @@@ import org.apache.isis.core.metamodel.s
public class CommandFacetForActionAnnotation extends CommandFacetAbstract {
public static CommandFacet create(
- final Action action,
+ final List<Action> actions,
final IsisConfiguration configuration,
+ final ServicesInjector servicesInjector,
final FacetHolder holder) {
- CommandReification commandReification =
- action != null
- ? action.command()
- : CommandReification.AS_CONFIGURED;
- CommandPersistence commandPersistence =
- action != null
- ? action.commandPersistence()
- : CommandPersistence.PERSISTED;
- final CommandExecuteIn commandExecuteIn =
- action != null
- ? action.commandExecuteIn()
- : CommandExecuteIn.FOREGROUND;
- final Class<? extends CommandDtoProcessor> processorClass =
- action != null
- ? action.commandDtoProcessor()
- : null;
- final CommandDtoProcessor processor = newProcessorElseNull(processorClass);
+ final CommandActionsConfiguration setting = CommandActionsConfiguration.parse(configuration);
- if(processor != null) {
- commandReification = CommandReification.ENABLED;
- commandPersistence = CommandPersistence.PERSISTED;
- }
- final Persistence persistence = CommandPersistence.from(commandPersistence);
- final ExecuteIn executeIn = CommandExecuteIn.from(commandExecuteIn);
+ return actions.stream()
+ .filter(action -> action.command() != CommandReification.NOT_SPECIFIED)
+ .findFirst()
+ .map(action -> {
+
- final CommandReification command = action.command();
- final CommandPersistence persistence = action.commandPersistence();
++ CommandReification command = action.command();
++ CommandPersistence persistence = action.commandPersistence();
+ final CommandExecuteIn executeIn = action.commandExecuteIn();
++ final Class<? extends CommandDtoProcessor> processorClass = action.commandDtoProcessor();
++ final CommandDtoProcessor processor = newProcessorElseNull(processorClass);
+
++ if(processor != null) {
++ command = CommandReification.ENABLED;
++ persistence = CommandPersistence.PERSISTED;
++ }
- switch (commandReification) {
- case AS_CONFIGURED:
- final CommandActionsConfiguration setting = CommandActionsConfiguration.parse(configuration);
- switch (setting) {
+ switch (command) {
+ case AS_CONFIGURED:
+ switch (setting) {
+ case NONE:
+ return null;
+ case IGNORE_SAFE:
+ if (hasSafeSemantics(holder)) {
+ return null;
+ }
+ // else fall through
+ default:
+ return (CommandFacet)new CommandFacetForActionAnnotationAsConfigured(
- persistence, executeIn, Enablement.ENABLED, holder);
++ persistence, executeIn, Enablement.ENABLED, holder, servicesInjector);
+ }
+ case DISABLED:
+ return null;
+ case ENABLED:
- return new CommandFacetForActionAnnotation(persistence, executeIn, Enablement.ENABLED, holder);
++ return new CommandFacetForActionAnnotation(
++ persistence, executeIn, Enablement.ENABLED, processor, holder, servicesInjector);
+ }
+ throw new IllegalStateException("command '" + command + "' not recognised");
+ })
+ .orElseGet(() -> {
+ switch (setting) {
case NONE:
return null;
case IGNORE_SAFE:
@@@ -79,29 -82,31 +90,30 @@@
}
// else fall through
default:
- return action != null
- ? new CommandFacetForActionAnnotationAsConfigured(persistence, executeIn, Enablement.ENABLED, holder,
- servicesInjector)
- : CommandFacetFromConfiguration.create(holder, servicesInjector);
- }
- case DISABLED:
- return null;
- case ENABLED:
- return new CommandFacetForActionAnnotation(
- persistence, executeIn, Enablement.ENABLED, processor,
- holder, servicesInjector);
- }
-
- return null;
+ return CommandFacetFromConfiguration.create(holder);
+ }
-
+ });
}
+ private static boolean hasSafeSemantics(final FacetHolder holder) {
+ final ActionSemanticsFacet actionSemanticsFacet = holder.getFacet(ActionSemanticsFacet.class);
+ if(actionSemanticsFacet == null) {
+ throw new IllegalStateException("Require ActionSemanticsFacet in order to process");
+ }
+ if(actionSemanticsFacet.value().isSafeInNature()) {
+ return true;
+ }
+ return false;
+ }
CommandFacetForActionAnnotation(
- final Persistence persistence,
- final ExecuteIn executeIn,
+ final CommandPersistence persistence,
+ final CommandExecuteIn executeIn,
final Enablement enablement,
- final FacetHolder holder) {
- super(persistence, executeIn, enablement, holder);
+ final CommandDtoProcessor processor,
+ final FacetHolder holder,
+ final ServicesInjector servicesInjector) {
+ super(persistence, executeIn, enablement, processor, holder, servicesInjector);
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetForActionAnnotationAsConfigured.java
index 07c3d86,8550b5a..8d19fae
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetForActionAnnotationAsConfigured.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetForActionAnnotationAsConfigured.java
@@@ -18,18 -18,21 +18,21 @@@
*/
package org.apache.isis.core.metamodel.facets.actions.action.command;
-import org.apache.isis.applib.annotation.Command.ExecuteIn;
-import org.apache.isis.applib.annotation.Command.Persistence;
+import org.apache.isis.applib.annotation.CommandExecuteIn;
+import org.apache.isis.applib.annotation.CommandPersistence;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+ import org.apache.isis.core.metamodel.services.ServicesInjector;
public class CommandFacetForActionAnnotationAsConfigured extends CommandFacetForActionAnnotation {
CommandFacetForActionAnnotationAsConfigured(
- final Persistence persistence,
- final ExecuteIn executeIn,
+ final CommandPersistence persistence,
+ final CommandExecuteIn executeIn,
final Enablement enablement,
- final FacetHolder holder) {
- super(persistence, executeIn, enablement, holder);
+ final FacetHolder holder,
+ final ServicesInjector servicesInjector) {
+ super(persistence, executeIn, enablement, null,
+ holder, servicesInjector);
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetFromConfiguration.java
index 4f91364,c1b7f71..387aed5
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetFromConfiguration.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/command/CommandFacetFromConfiguration.java
@@@ -27,15 -28,20 +28,19 @@@ import org.apache.isis.core.metamodel.s
public class CommandFacetFromConfiguration extends CommandFacetAbstract {
- public static CommandFacet create(final FacetHolder holder) {
- return new CommandFacetFromConfiguration(CommandPersistence.PERSISTED, CommandExecuteIn.FOREGROUND, holder);
+ public static CommandFacet create(
+ final FacetHolder holder,
+ final ServicesInjector servicesInjector) {
- return new CommandFacetFromConfiguration(Persistence.PERSISTED, ExecuteIn.FOREGROUND, holder,
++ return new CommandFacetFromConfiguration(CommandPersistence.PERSISTED, CommandExecuteIn.FOREGROUND, holder,
+ servicesInjector);
}
private CommandFacetFromConfiguration(
- final Persistence persistence,
- final ExecuteIn executeIn,
+ final CommandPersistence persistence,
+ final CommandExecuteIn executeIn,
- final FacetHolder holder) {
- super(persistence, executeIn, Enablement.ENABLED, holder);
+ final FacetHolder holder,
+ final ServicesInjector servicesInjector) {
- super(persistence, executeIn, Enablement.ENABLED, null,
- holder, servicesInjector);
++ super(persistence, executeIn, Enablement.ENABLED, null, holder, servicesInjector);
}
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacet.java
index 6dff421,b9f8fdd..d8561c6
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacet.java
@@@ -19,10 -19,10 +19,11 @@@
package org.apache.isis.core.metamodel.facets.actions.command;
-import org.apache.isis.applib.annotation.Command.ExecuteIn;
-import org.apache.isis.applib.annotation.Command.Persistence;
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.CommandExecuteIn;
+import org.apache.isis.applib.annotation.CommandPersistence;
import org.apache.isis.applib.services.command.Command;
+ import org.apache.isis.applib.services.command.CommandDtoProcessor;
import org.apache.isis.core.metamodel.facetapi.Facet;
/**
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacetAbstract.java
index 609ecc6,e08b4ca..ad63162
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacetAbstract.java
@@@ -19,8 -19,9 +19,9 @@@
package org.apache.isis.core.metamodel.facets.actions.command;
-import org.apache.isis.applib.annotation.Command.ExecuteIn;
-import org.apache.isis.applib.annotation.Command.Persistence;
+import org.apache.isis.applib.annotation.CommandExecuteIn;
+import org.apache.isis.applib.annotation.CommandPersistence;
+ import org.apache.isis.applib.services.command.CommandDtoProcessor;
import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facets.MarkerFacetAbstract;
@@@ -40,16 -42,20 +42,20 @@@ public abstract class CommandFacetAbstr
}
}
- private final Persistence persistence;
- private final ExecuteIn executeIn;
+ private final CommandPersistence persistence;
+ private final CommandExecuteIn executeIn;
private final Enablement enablement;
+ private final CommandDtoProcessor processor;
public CommandFacetAbstract(
- final Persistence persistence,
- final ExecuteIn executeIn,
+ final CommandPersistence persistence,
+ final CommandExecuteIn executeIn,
- final Enablement enablement,
- final FacetHolder holder) {
+ final Enablement enablement,
+ final CommandDtoProcessor processor,
+ final FacetHolder holder,
+ final ServicesInjector servicesInjector) {
super(type(), holder);
+ inject(processor, servicesInjector);
this.persistence = persistence;
this.executeIn = executeIn;
this.enablement = enablement;
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/MustSatisfySpecificationFacetAbstract.java
index c2f013e,235b2dc..4dd9533
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/MustSatisfySpecificationFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/MustSatisfySpecificationFacetAbstract.java
@@@ -21,8 -21,10 +21,10 @@@ package org.apache.isis.core.metamodel.
import java.util.List;
- import org.apache.isis.applib.services.wrapper.events.ValidityEvent;
+ import com.google.common.collect.Lists;
+
-import org.apache.isis.applib.events.ValidityEvent;
import org.apache.isis.applib.services.i18n.TranslationService;
++import org.apache.isis.applib.services.wrapper.events.ValidityEvent;
import org.apache.isis.applib.spec.Specification;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.facetapi.Facet;
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForParameterAnnotation.java
index 3e1e7e6,f94da8e..78bbdb1
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForParameterAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForParameterAnnotation.java
@@@ -38,21 -35,15 +38,19 @@@ public class MustSatisfySpecificationFa
final FacetHolder holder,
final ServicesInjector servicesInjector) {
- if (parameter == null) {
- return null;
- }
-
- final Class<?>[] values = parameter.mustSatisfy();
- final List<Specification> specifications = specificationsFor(values);
- return specifications.size() > 0 ? new MustSatisfySpecificationFacetForParameterAnnotation(specifications, holder, servicesInjector) : null;
+ List<Specification> specifications = parameters.stream()
+ .map(Parameter::mustSatisfy)
+ .flatMap(classes ->
+ Arrays.stream(classes)
+ .map(MustSatisfySpecificationFacetAbstract::newSpecificationElseNull)
+ .filter(Objects::nonNull)
+ )
- .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ return specifications.size() > 0
+ ? new MustSatisfySpecificationFacetForParameterAnnotation(specifications, holder, servicesInjector)
+ : null;
}
-
private MustSatisfySpecificationFacetForParameterAnnotation(
final List<Specification> specifications,
final FacetHolder holder,
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
index a405e95,7f919f7..6f82d19
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
@@@ -215,7 -283,8 +215,7 @@@ public class PropertyAnnotationFacetFac
}
// check for @Property(command=...)
- final CommandFacet commandFacet = CommandFacetForPropertyAnnotation.create(properties, getConfiguration(), holder);
- final CommandFacet commandFacet = CommandFacetForPropertyAnnotation.create(property, getConfiguration(), holder,
- servicesInjector);
++ final CommandFacet commandFacet = CommandFacetForPropertyAnnotation.create(properties, getConfiguration(), holder, servicesInjector);
FacetUtil.addFacet(commandFacet);
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/command/CommandFacetForPropertyAnnotation.java
index 28c5902,3eb1290..dee1ed2
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/command/CommandFacetForPropertyAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/command/CommandFacetForPropertyAnnotation.java
@@@ -33,53 -35,56 +35,63 @@@ import org.apache.isis.core.metamodel.s
public class CommandFacetForPropertyAnnotation extends CommandFacetAbstract {
public static CommandFacet create(
- final Property property,
+ final List<Property> properties,
final IsisConfiguration configuration,
- final FacetHolder holder) {
+ final FacetHolder holder,
+ final ServicesInjector servicesInjector) {
- CommandReification commandReification = property != null ? property.command() : CommandReification.AS_CONFIGURED;
- final CommandPersistence commandPersistence = property != null ? property.commandPersistence() : CommandPersistence.PERSISTED;
- final CommandExecuteIn commandExecuteIn = property != null? property.commandExecuteIn() : CommandExecuteIn.FOREGROUND;
- final Class<? extends CommandDtoProcessor> processorClass =
- property != null ? property.commandDtoProcessor() : null;
- final CommandDtoProcessor processor = newProcessorElseNull(processorClass);
-
- if(processor != null) {
- commandReification = CommandReification.ENABLED;
- }
- final Persistence persistence = CommandPersistence.from(commandPersistence);
- final ExecuteIn executeIn = CommandExecuteIn.from(commandExecuteIn);
+ final CommandPropertiesConfiguration setting = CommandPropertiesConfiguration.parse(configuration);
+ return properties.stream()
+ .filter(property -> property.command() != CommandReification.NOT_SPECIFIED)
+ .findFirst()
+ .map(property -> {
- final CommandReification command = property.command();
++ CommandReification command = property.command();
+ final CommandPersistence commandPersistence = property.commandPersistence();
+ final CommandExecuteIn commandExecuteIn = property.commandExecuteIn();
- switch (commandReification) {
- case AS_CONFIGURED:
- final CommandPropertiesConfiguration setting = CommandPropertiesConfiguration.parse(configuration);
- switch (setting) {
- case NONE:
- return null;
- default:
- return property != null
- ? new CommandFacetForPropertyAnnotationAsConfigured(persistence, executeIn, Enablement.ENABLED, holder,
- servicesInjector)
- : CommandFacetFromConfiguration.create(holder, servicesInjector);
- }
- case DISABLED:
- return null;
- case ENABLED:
- return new CommandFacetForPropertyAnnotation(persistence, executeIn, Enablement.ENABLED, holder,
- processor, servicesInjector);
- }
++ final Class<? extends CommandDtoProcessor> processorClass =
++ property != null ? property.commandDtoProcessor() : null;
++ final CommandDtoProcessor processor = newProcessorElseNull(processorClass);
+
- return null;
++ if(processor != null) {
++ command = CommandReification.ENABLED;
++ }
+ switch (command) {
+ case AS_CONFIGURED:
+ switch (setting) {
+ case NONE:
+ return null;
+ default:
+ return (CommandFacet)new CommandFacetForPropertyAnnotationAsConfigured(commandPersistence,
- commandExecuteIn, Enablement.ENABLED, holder);
++ commandExecuteIn, Enablement.ENABLED, holder, servicesInjector);
+ }
+ case DISABLED:
+ return null;
+ case ENABLED:
- return new CommandFacetForPropertyAnnotation(commandPersistence, commandExecuteIn, Enablement.ENABLED, holder);
++ return new CommandFacetForPropertyAnnotation(commandPersistence, commandExecuteIn, Enablement.ENABLED, holder, processor, servicesInjector);
+ }
+ throw new IllegalStateException("command '" + command + "' not recognised");
+ })
+ .orElseGet(() -> {
+ switch (setting) {
+ case NONE:
+ return null;
+ default:
+ return CommandFacetFromConfiguration.create(holder);
+ }
+ });
}
CommandFacetForPropertyAnnotation(
- final Persistence persistence,
- final ExecuteIn executeIn,
+ final CommandPersistence persistence,
+ final CommandExecuteIn executeIn,
final Enablement enablement,
- final FacetHolder holder) {
- super(persistence, executeIn, enablement, holder);
+ final FacetHolder holder,
+ final CommandDtoProcessor processor,
+ final ServicesInjector servicesInjector) {
+ super(persistence, executeIn, enablement, processor, holder, servicesInjector);
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/command/CommandFacetForPropertyAnnotationAsConfigured.java
index 582d8c2,ea71ae5..00816fb
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/command/CommandFacetForPropertyAnnotationAsConfigured.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/command/CommandFacetForPropertyAnnotationAsConfigured.java
@@@ -18,18 -18,19 +18,19 @@@
*/
package org.apache.isis.core.metamodel.facets.properties.property.command;
-import org.apache.isis.applib.annotation.Command.ExecuteIn;
-import org.apache.isis.applib.annotation.Command.Persistence;
+import org.apache.isis.applib.annotation.CommandExecuteIn;
+import org.apache.isis.applib.annotation.CommandPersistence;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+ import org.apache.isis.core.metamodel.services.ServicesInjector;
public class CommandFacetForPropertyAnnotationAsConfigured extends CommandFacetForPropertyAnnotation {
CommandFacetForPropertyAnnotationAsConfigured(
- final Persistence persistence,
- final ExecuteIn executeIn,
+ final CommandPersistence persistence,
+ final CommandExecuteIn executeIn,
final Enablement enablement,
- final FacetHolder holder) {
- super(persistence, executeIn, enablement, holder);
+ final FacetHolder holder, final ServicesInjector servicesInjector) {
+ super(persistence, executeIn, enablement, holder, null, servicesInjector);
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mustsatisfy/MustSatisfySpecificationFacetForPropertyAnnotation.java
index fa4be84,dcc56c9..5c93fbf
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mustsatisfy/MustSatisfySpecificationFacetForPropertyAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mustsatisfy/MustSatisfySpecificationFacetForPropertyAnnotation.java
@@@ -38,21 -35,15 +38,19 @@@ public class MustSatisfySpecificationFa
final FacetHolder holder,
final ServicesInjector servicesInjector) {
- if (property == null) {
- return null;
- }
-
- final Class<?>[] values = property.mustSatisfy();
- final List<Specification> specifications = specificationsFor(values);
- return specifications.size() > 0 ? new MustSatisfySpecificationFacetForPropertyAnnotation(specifications, holder, servicesInjector) : null;
+ List<Specification> specifications = properties.stream()
+ .map(Property::mustSatisfy)
+ .flatMap(classes ->
+ Arrays.stream(classes)
+ .map(MustSatisfySpecificationFacetAbstract::newSpecificationElseNull)
+ .filter(Objects::nonNull)
+ )
- .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ return specifications.size() > 0
+ ? new MustSatisfySpecificationFacetForPropertyAnnotation(specifications, holder, servicesInjector)
+ : null;
}
-
private MustSatisfySpecificationFacetForPropertyAnnotation(final List<Specification> specifications, final FacetHolder holder, final ServicesInjector servicesInjector) {
super(specifications, holder, servicesInjector);
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
index f9c1adc,342589f..9e5b34c
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
@@@ -34,10 -34,14 +34,14 @@@ import org.apache.isis.applib.annotatio
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.services.bookmark.Bookmark;
+ import org.apache.isis.applib.services.command.CommandDtoProcessor;
import org.apache.isis.applib.services.grid.GridService;
import org.apache.isis.applib.services.metamodel.DomainMember;
-import org.apache.isis.applib.services.metamodel.MetaModelService5;
+import org.apache.isis.applib.services.metamodel.MetaModelService;
+ import org.apache.isis.core.metamodel.facets.actions.command.CommandFacet;
import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
+ import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+ import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
import org.apache.isis.core.metamodel.services.appmanifest.AppManifestProvider;
import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternal.java
index 2a81809,09107b6..bfcc89c
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternal.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternal.java
@@@ -21,8 -21,9 +21,9 @@@ import java.util.List
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.BookmarkService2;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.xactn.Transaction;
+ import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.xactn.Transaction2;
import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternalNoop.java
index 87407e1,05454f8..086400b
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternalNoop.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternalNoop.java
@@@ -24,8 -24,9 +24,9 @@@ import org.apache.isis.applib.annotatio
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.BookmarkService2;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.xactn.Transaction;
+ import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.xactn.Transaction2;
import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/xactn/TransactionServiceDefault.java
index 96d92de,59946d5..0848d8b
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/xactn/TransactionServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/xactn/TransactionServiceDefault.java
@@@ -21,8 -21,9 +21,9 @@@ package org.apache.isis.core.metamodel.
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.services.xactn.Transaction;
+import org.apache.isis.applib.services.xactn.TransactionService;
+ import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.xactn.Transaction2;
-import org.apache.isis.applib.services.xactn.TransactionService3;
import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.metamodel.services.persistsession.PersistenceSessionServiceInternal;
@@@ -41,11 -42,21 +42,21 @@@ public class TransactionServiceDefault
@Override
public void nextTransaction() {
- nextTransaction(TransactionService.Policy.UNLESS_MARKED_FOR_ABORT);
+ nextTransaction((Command)null);
+ }
+
+ @Override
- public void nextTransaction(final Command command) {
- nextTransaction(TransactionService3.Policy.UNLESS_MARKED_FOR_ABORT, command);
++ public void nextTransaction(final Command commandIfAny) {
++ nextTransaction(TransactionService.Policy.UNLESS_MARKED_FOR_ABORT, commandIfAny);
}
@Override
- public void nextTransaction(TransactionService3.Policy policy) {
+ public void nextTransaction(TransactionService.Policy policy) {
+ nextTransaction(policy, null);
+ }
+
+ @Override
- public void nextTransaction(TransactionService3.Policy policy, final Command commandIfAny) {
++ public void nextTransaction(TransactionService.Policy policy, final Command commandIfAny) {
final TransactionState transactionState = getTransactionState();
switch (transactionState) {
case NONE:
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index dd405ea,4e753eb..7d4e842
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@@ -23,23 -23,27 +23,24 @@@ import java.util.Collections
import java.util.Comparator;
import java.util.List;
-import javax.annotation.Nullable;
-
import com.google.common.base.Function;
+ import org.apache.isis.applib.annotation.DomainObject;
-import org.apache.isis.applib.annotation.ObjectType;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.consent.Consent;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.consent.InteractionResult;
--import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
import org.apache.isis.core.metamodel.facets.all.help.HelpFacet;
import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
--import org.apache.isis.core.metamodel.facets.object.parented.ParentedCollectionFacet;
++import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
import org.apache.isis.core.metamodel.facets.object.icon.IconFacet;
import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet;
import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
++import org.apache.isis.core.metamodel.facets.object.parented.ParentedCollectionFacet;
import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
import org.apache.isis.core.metamodel.facets.object.plural.PluralFacet;
import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
@@@ -162,7 -187,7 +184,7 @@@ public interface ObjectSpecification ex
* Returns the title string for the specified object.
*
* <p>
-- * Corresponds to the {@link TitleFacet#value()) value} of
++ * Corresponds to the {@link TitleFacet#title(ObjectAdapter)} ) value} of
* {@link TitleFacet}; is not necessarily immutable.
*
* @deprecated use {@link #getTitle(ObjectAdapter, ObjectAdapter)}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
index c225cf8,bbdbeb4..0c421e4
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
@@@ -374,11 -385,151 +378,59 @@@ public interface ObjectAction extends O
private Predicates() {
}
- public static Predicate<ObjectAction> dynamicallyVisible(
- final ObjectAdapter target,
- final InteractionInitiatedBy interactionInitiatedBy,
- final Where where) {
- return org.apache.isis.applib.filter.Filters
- .asPredicate(Filters.dynamicallyVisible(target, interactionInitiatedBy, where));
- }
-
- public static Predicate<ObjectAction> withId(final String actionId) {
- return org.apache.isis.applib.filter.Filters.asPredicate(Filters.withId(actionId));
- }
-
- public static Predicate<ObjectAction> withNoValidationRules() {
- return org.apache.isis.applib.filter.Filters.asPredicate(Filters.withNoValidationRules());
- }
-
- public static Predicate<ObjectAction> ofType(final ActionType type) {
- return org.apache.isis.applib.filter.Filters.asPredicate(Filters.ofType(type));
- }
-
- public static Predicate<ObjectAction> bulk() {
- return org.apache.isis.applib.filter.Filters.asPredicate(Filters.bulk());
- }
-
- // UNUSED?
- public static Predicate<ObjectAction> notBulkOnly() {
- return org.apache.isis.applib.filter.Filters.asPredicate(Filters.notBulkOnly());
- }
-
- public static Predicate<ObjectAction> memberOrderOf(ObjectAssociation association) {
- return org.apache.isis.applib.filter.Filters.asPredicate(Filters.memberOrderOf(association));
- }
-
+ public static Predicate<ObjectAction> associatedWith(final String collectionName) {
+ return new AssociatedWith(collectionName);
+ }
+
+ public static Predicate<ObjectAction> associatedWithAndWithCollectionParameterFor(
+ final String collectionName,
+ final ObjectSpecification collectionTypeOfSpec) {
+
+ return com.google.common.base.Predicates.and(
+ new AssociatedWith(collectionName),
+ new HasParameterMatching(
+ new ObjectActionParameter.Predicates.CollectionParameter(collectionTypeOfSpec)
+ )
+ );
+ }
+
+ public static class AssociatedWith implements Predicate<ObjectAction> {
+ private final String memberNameAssociatedWith;
+ public AssociatedWith(final String memberNameAssociatedWith) {
+ this.memberNameAssociatedWith = memberNameAssociatedWith;
+ }
+
+ @Override
+ public boolean apply(final ObjectAction objectAction) {
+ final MemberOrderFacet memberOrderFacet = objectAction.getFacet(MemberOrderFacet.class);
+ if(memberOrderFacet == null) {
+ return false;
+ }
+ final String name = memberNameAssociatedWith;
+ final String memberOrderName = memberOrderFacet.untranslatedName();
+ return name != null && memberOrderName != null &&
+ Objects.equal(name.toLowerCase(), memberOrderName.toLowerCase());
+ }
+ }
+
+ public static class HasParameterMatching implements Predicate<ObjectAction> {
+ private final Predicate<ObjectActionParameter> parameterPredicate;
+ public HasParameterMatching(final Predicate<ObjectActionParameter> parameterPredicate) {
+ this.parameterPredicate = parameterPredicate;
+ }
+
+ @Override
+ public boolean apply(@Nullable final ObjectAction objectAction) {
+ return FluentIterable
+ .from(objectAction.getParameters())
+ .anyMatch(parameterPredicate);
+ }
+ }
- }
-
- //endregion
- //region > Filters
-
- public static final class Filters {
-
- private Filters() {
- }
-
- /**
- * @deprecated -use {@link com.google.common.base.Predicate equivalent}
- */
- @Deprecated
- public static Filter<ObjectAction> dynamicallyVisible(
- final ObjectAdapter target,
- final InteractionInitiatedBy interactionInitiatedBy,
- final Where where) {
- return new Filter<ObjectAction>() {
+ public static com.google.common.base.Predicate ofType(final ActionType type) {
+ return new Predicate<ObjectAction>() {
@Override
- public boolean accept(final ObjectAction objectAction) {
- final Consent visible = objectAction.isVisible(target, interactionInitiatedBy, where);
- return visible.isAllowed();
- }
- };
- }
-
- /**
- * @deprecated -use {@link com.google.common.base.Predicate equivalent}
- */
- @Deprecated
- public static Filter<ObjectAction> withId(final String actionId) {
- return new Filter<ObjectAction>() {
- @Override
- public boolean accept(ObjectAction objectAction) {
- return objectAction.getId().equals(actionId);
- }
- };
- }
-
- /**
- * @deprecated -use {@link com.google.common.base.Predicate equivalent}
- */
- @Deprecated
- public static Filter<ObjectAction> withNoValidationRules() {
- return new Filter<ObjectAction>() {
- @Override
- public boolean accept(final ObjectAction objectAction) {
- final List<Facet> validatingFacets = objectAction.getFacets(FacetFilters
- .isA(ValidatingInteractionAdvisor.class));
- return validatingFacets.isEmpty();
- }
- };
- }
-
- /**
- * @deprecated -use {@link com.google.common.base.Predicate equivalent}
- */
- @Deprecated
- public static Filter<ObjectAction> ofType(final ActionType type) {
- return new Filter<ObjectAction>() {
- @Override
- public boolean accept(ObjectAction oa) {
+ public boolean apply(ObjectAction oa) {
return oa.getType() == type;
}
};
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
index 6ababf3,df26433..c0e7043
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
@@@ -19,9 -19,12 +19,12 @@@
package org.apache.isis.core.metamodel.spec.feature;
+ import javax.annotation.Nullable;
+
import com.google.common.base.Function;
+ import com.google.common.base.Predicate;
-import org.apache.isis.applib.filter.Filter;
+import com.google.common.base.Predicate;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index 702ab74,ca81150..32004bc
--- 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
@@@ -96,17 -98,26 +99,22 @@@ public class SpecificationLoader implem
private final MetaModelValidator metaModelValidator;
private final SpecificationCacheDefault cache = new SpecificationCacheDefault();
- private final List<LayoutMetadataReader> layoutMetadataReaders;
+ private final PostProcessor postProcessor;
public SpecificationLoader(
+ final IsisConfiguration configuration,
final ProgrammingModel programmingModel,
final MetaModelValidator metaModelValidator,
- final List<LayoutMetadataReader> layoutMetadataReaders,
final ServicesInjector servicesInjector) {
+ this.configuration = configuration;
+
this.servicesInjector = servicesInjector;
this.programmingModel = programmingModel;
this.metaModelValidator = metaModelValidator;
this.facetProcessor = new FacetProcessor(programmingModel);
+ this.postProcessor = new PostProcessor(programmingModel, servicesInjector);
-
- this.layoutMetadataReaders = layoutMetadataReaders;
}
@Override
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
index 2b77b34,4446489..7b5871d
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
@@@ -185,9 -203,9 +185,9 @@@ public class FacetedMethodsBuilder
// ////////////////////////////////////////////////////////////////////////////
- public Properties introspectClass() {
+ public void introspectClass() {
if (LOG.isInfoEnabled()) {
- LOG.info("introspecting " + getClassName() + ": class-level details");
+ LOG.info("introspecting {}: class-level details", getClassName());
}
// process facets at object level
@@@ -238,9 -311,9 +238,9 @@@
return associationFacetMethods;
}
- private List<FacetedMethod> createAssociationFacetedMethods(Properties properties) {
+ private List<FacetedMethod> createAssociationFacetedMethods() {
if (LOG.isDebugEnabled()) {
- LOG.debug("introspecting " + getClassName() + ": properties and collections");
+ LOG.debug("introspecting {}: properties and collections", getClassName());
}
final Set<Method> associationCandidateMethods = getFacetProcessor().findAssociationCandidateAccessors(methods, new HashSet<Method>());
@@@ -277,15 -351,13 +277,15 @@@
findAndRemovePrefixedNonVoidMethods(MethodScope.OBJECT, GET_PREFIX, Object.class, 0, propertyAccessors);
findAndRemovePrefixedNonVoidMethods(MethodScope.OBJECT, IS_PREFIX, Boolean.class, 0, propertyAccessors);
- createPropertyFacetedMethodsFromAccessors(propertyAccessors, fields, properties);
+ createPropertyFacetedMethodsFromAccessors(propertyAccessors, fields);
}
- private void createCollectionFacetedMethodsFromAccessors(final List<Method> accessorMethods, final List<FacetedMethod> facetMethodsToAppendto, Properties properties) {
+ private void createCollectionFacetedMethodsFromAccessors(
+ final List<Method> accessorMethods,
+ final List<FacetedMethod> facetMethodsToAppendto) {
for (final Method accessorMethod : accessorMethods) {
if (LOG.isDebugEnabled()) {
- LOG.debug(" identified accessor method representing collection: " + accessorMethod);
+ LOG.debug(" identified accessor method representing collection: {}", accessorMethod);
}
// create property and add facets
@@@ -309,12 -381,10 +309,12 @@@
}
}
- private void createPropertyFacetedMethodsFromAccessors(final List<Method> accessorMethods, final List<FacetedMethod> facetedMethodsToAppendto, Properties properties) throws MetaModelException {
+ private void createPropertyFacetedMethodsFromAccessors(
+ final List<Method> accessorMethods,
+ final List<FacetedMethod> facetedMethodsToAppendto) throws MetaModelException {
for (final Method accessorMethod : accessorMethods) {
- LOG.debug(" identified accessor method representing property: " + accessorMethod);
+ LOG.debug(" identified accessor method representing property: {}", accessorMethod);
final Class<?> returnType = accessorMethod.getReturnType();
@@@ -362,12 -432,13 +362,12 @@@
* Perhaps it's important to skip helpers first. I doubt it, though.
*/
private List<FacetedMethod> findActionFacetedMethods(
- final MethodScope methodScope,
- final Properties metadataProperties) {
+ final MethodScope methodScope) {
if (LOG.isDebugEnabled()) {
- LOG.debug("introspecting " + getClassName() + ": actions");
+ LOG.debug("introspecting {}: actions", getClassName());
}
- final List<FacetedMethod> actionFacetedMethods1 = findActionFacetedMethods(methodScope, RecognisedHelpersStrategy.SKIP, metadataProperties);
- final List<FacetedMethod> actionFacetedMethods2 = findActionFacetedMethods(methodScope, RecognisedHelpersStrategy.DONT_SKIP, metadataProperties);
+ final List<FacetedMethod> actionFacetedMethods1 = findActionFacetedMethods(methodScope, RecognisedHelpersStrategy.SKIP);
+ final List<FacetedMethod> actionFacetedMethods2 = findActionFacetedMethods(methodScope, RecognisedHelpersStrategy.DONT_SKIP);
return ListExtensions.combineWith(actionFacetedMethods1, actionFacetedMethods2);
}
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index 720fdfd,65d2ff3..ddcbd68
--- 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
@@@ -173,11 -175,8 +173,6 @@@ public class ObjectSpecificationDefaul
}
--
- if(isNotIntrospected()) {
- facetedMethodsBuilder.introspectClassPostProcessing();
- }
-
-
if(isNotIntrospected()) {
updateFromFacetValues();
}
diff --cc core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorHelper.java
index 52835a8,ee0b8ce..4dc3dfe
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorHelper.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/JavaReflectorHelper.java
@@@ -57,7 -60,7 +57,7 @@@ public final class JavaReflectorHelpe
programmingModel.refineMetaModelValidator(metaModelValidator, configuration);
}
- return new SpecificationLoader(programmingModel, metaModelValidator, servicesInjector);
- return new SpecificationLoader(configuration, programmingModel, metaModelValidator, layoutMetadataReaders, servicesInjector);
++ return new SpecificationLoader(configuration, programmingModel, metaModelValidator, servicesInjector);
}
}
diff --cc core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderTestAbstract.java
index 47b2183,8e386f2..2360cbe
--- 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
@@@ -106,8 -108,9 +106,8 @@@ public abstract class SpecificationLoad
final SpecificationLoader specificationLoader =
new SpecificationLoader(
- new ProgrammingModelFacetsJava5(stubConfiguration),
+ stubConfiguration, new ProgrammingModelFacetsJava5(stubConfiguration),
- new MetaModelValidatorDefault(), Lists.<LayoutMetadataReader>newArrayList(
- new LayoutMetadataReaderFromJson()), stubServicesInjector);
+ new MetaModelValidatorDefault(), stubServicesInjector);
stubServicesInjector.addFallbackIfRequired(SpecificationLoader.class, specificationLoader);
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
index 751d85e,90c2bc4..0d5ec9d
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
@@@ -16,32 -16,16 +16,32 @@@
*/
package org.apache.isis.core.runtime.services.background;
- import java.sql.Timestamp;
- import java.util.Collections;
import java.util.List;
- import com.google.common.base.Function;
- import com.google.common.base.Throwables;
- import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.clock.ClockService;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.Command.Executor;
+import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.InteractionContext;
+import org.apache.isis.applib.services.jaxb.JaxbService;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.runtime.sessiontemplate.AbstractIsisSessionTemplate;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
-import org.apache.isis.applib.services.command.Command;
+ import org.apache.isis.applib.services.command.CommandExecutorService;
+ import org.apache.isis.applib.services.command.CommandWithDto;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
import org.apache.isis.core.runtime.system.transaction.TransactionalClosure;
@@@ -65,24 -37,40 +53,36 @@@
* This implementation uses the {@link #findBackgroundCommandsToExecute() hook method} so that it is
* independent of the location where the actions have actually been persisted to.
*/
- public abstract class BackgroundCommandExecution extends AbstractIsisSessionTemplate {
+ public abstract class BackgroundCommandExecution extends CommandExecutionAbstract {
+ private final static Logger LOG = LoggerFactory.getLogger(BackgroundCommandExecution.class);
+ /**
+ * Defaults to the historical defaults * for running background commands.
+ */
+ public BackgroundCommandExecution() {
+ this(CommandExecutorService.SudoPolicy.NO_SWITCH);
+ }
+
+ public BackgroundCommandExecution(final CommandExecutorService.SudoPolicy sudoPolicy) {
+ super(sudoPolicy);
+ }
+
+ // //////////////////////////////////////
-
protected void doExecute(Object context) {
final PersistenceSession persistenceSession = getPersistenceSession();
final IsisTransactionManager transactionManager = getTransactionManager(persistenceSession);
- final List<Command> backgroundCommands = Lists.newArrayList();
- transactionManager.executeWithinTransaction(new TransactionalClosure() {
- @Override
- public void execute() {
- backgroundCommands.addAll(findBackgroundCommandsToExecute());
- }
+ final List<Command> commands = Lists.newArrayList();
- transactionManager.executeWithinTransaction(new TransactionalClosure() {
- @Override
- public void execute() {
- commands.addAll(findBackgroundCommandsToExecute());
- }
++ transactionManager.executeWithinTransaction(() -> {
++ commands.addAll(findBackgroundCommandsToExecute());
});
- for (final Command backgroundCommand : backgroundCommands) {
- execute(transactionManager, backgroundCommand);
+ LOG.debug("Found {} to execute", commands.size());
+
+ for (final Command command : commands) {
+ execute(transactionManager, (CommandWithDto) command);
}
}
@@@ -91,210 -79,5 +91,4 @@@
*/
protected abstract List<? extends Command> findBackgroundCommandsToExecute();
- // //////////////////////////////////////
-
-
- private void execute(
- final IsisTransactionManager transactionManager,
- final Command backgroundCommand) {
-
- transactionManager.executeWithinTransaction(
- backgroundCommand,
- new TransactionalClosure() {
- @Override
- public void execute() {
-
- // setup for us by IsisTransactionManager; will have the transactionId of the backgroundCommand
- final Interaction backgroundInteraction = interactionContext.getInteraction();
-
- final String memento = backgroundCommand.getMemento();
-
- try {
- backgroundCommand.setExecutor(Executor.BACKGROUND);
-
- final CommandDto dto = jaxbService.fromXml(CommandDto.class, memento);
-
- final MemberDto memberDto = dto.getMember();
- final String memberId = memberDto.getMemberIdentifier();
-
- final OidsDto oidsDto = CommandDtoUtils.targetsFor(dto);
- final List<OidDto> targetOidDtos = oidsDto.getOid();
-
- final InteractionType interactionType = memberDto.getInteractionType();
- if(interactionType == InteractionType.ACTION_INVOCATION) {
-
- final ActionDto actionDto = (ActionDto) memberDto;
-
- for (OidDto targetOidDto : targetOidDtos) {
-
- final ObjectAdapter targetAdapter = adapterFor(targetOidDto);
- final ObjectAction objectAction = findObjectAction(targetAdapter, memberId);
-
- // we pass 'null' for the mixedInAdapter; if this action _is_ a mixin then
- // it will switch the targetAdapter to be the mixedInAdapter transparently
- final ObjectAdapter[] argAdapters = argAdaptersFor(actionDto);
- final ObjectAdapter resultAdapter = objectAction.execute(
- targetAdapter, null, argAdapters, InteractionInitiatedBy.FRAMEWORK);
-
- //
- // for the result adapter, we could alternatively have used...
- // (priorExecution populated by the push/pop within the interaction object)
- //
- // final Interaction.Execution priorExecution = backgroundInteraction.getPriorExecution();
- // Object unused = priorExecution.getReturned();
- //
-
- // REVIEW: this doesn't really make sense if >1 action
- // in any case, the capturing of the action interaction should be the
- // responsibility of auditing/profiling
- if(resultAdapter != null) {
- Bookmark resultBookmark = CommandUtil.bookmarkFor(resultAdapter);
- backgroundCommand.setResult(resultBookmark);
- }
- }
- } else {
-
- final PropertyDto propertyDto = (PropertyDto) memberDto;
-
- for (OidDto targetOidDto : targetOidDtos) {
-
- final Bookmark bookmark = Bookmark.from(targetOidDto);
- final Object targetObject = bookmarkService.lookup(bookmark);
-
- final ObjectAdapter targetAdapter = adapterFor(targetObject);
-
- final OneToOneAssociation property = findOneToOneAssociation(targetAdapter, memberId);
-
- final ObjectAdapter newValueAdapter = newValueAdapterFor(propertyDto);
-
- property.set(targetAdapter, newValueAdapter, InteractionInitiatedBy.FRAMEWORK);
- // there is no return value for property modifications.
- }
- }
-
- } catch (RuntimeException e) {
- // hmmm, this doesn't really make sense if >1 action
- //
- // in any case, the capturing of the result of the action invocation should be the
- // responsibility of the interaction...
- backgroundCommand.setException(Throwables.getStackTraceAsString(e));
-
- // lower down the stack the IsisTransactionManager will have set the transaction to abort
- // however, we don't want that to occur (because any changes made to the backgroundCommand itself
- // would also be rolled back, and it would keep getting picked up again by a scheduler for
- // processing); instead we clear the abort cause and ensure we can continue.
- transactionManager.getCurrentTransaction().clearAbortCauseAndContinue();
- }
-
- // it's possible that there is no priorExecution, specifically if there was an exception
- // invoking the action. We therefore need to guard that case.
- final Interaction.Execution<?,?> priorExecution = backgroundInteraction.getPriorExecution();
- final Timestamp completedAt =
- priorExecution != null
- ? priorExecution.getCompletedAt()
- : clockService.nowAsJavaSqlTimestamp(); // close enough...
- backgroundCommand.setCompletedAt(completedAt);
- }
-
- private ObjectAction findObjectAction(
- final ObjectAdapter targetAdapter,
- final String actionId) throws RuntimeException {
-
- final ObjectSpecification specification = targetAdapter.getSpecification();
-
- final ObjectAction objectAction = findActionElseNull(specification, actionId);
- if(objectAction == null) {
- throw new RuntimeException(String.format("Unknown action '%s'", actionId));
- }
- return objectAction;
- }
-
- private OneToOneAssociation findOneToOneAssociation(
- final ObjectAdapter targetAdapter,
- final String propertyId) throws RuntimeException {
-
-
- final ObjectSpecification specification = targetAdapter.getSpecification();
-
- final OneToOneAssociation property = findOneToOneAssociationElseNull(specification, propertyId);
- if(property == null) {
- throw new RuntimeException(String.format("Unknown property '%s'", propertyId));
- }
- return property;
- }
- });
- }
-
- protected ObjectAdapter newValueAdapterFor(final PropertyDto propertyDto) {
- final ValueWithTypeDto newValue = propertyDto.getNewValue();
- final Object arg = CommonDtoUtils.getValue(newValue);
- return adapterFor(arg);
- }
-
- private static ObjectAction findActionElseNull(
- final ObjectSpecification specification,
- final String actionId) {
- final List<ObjectAction> objectActions = specification.getObjectActions(Contributed.INCLUDED);
- for (final ObjectAction objectAction : objectActions) {
- if(objectAction.getIdentifier().toClassAndNameIdentityString().equals(actionId)) {
- return objectAction;
- }
- }
- return null;
- }
-
- private static OneToOneAssociation findOneToOneAssociationElseNull(
- final ObjectSpecification specification,
- final String propertyId) {
- final List<ObjectAssociation> associations = specification.getAssociations(Contributed.INCLUDED);
- for (final ObjectAssociation association : associations) {
- if( association.getIdentifier().toClassAndNameIdentityString().equals(propertyId) &&
- association instanceof OneToOneAssociation) {
- return (OneToOneAssociation) association;
- }
- }
- return null;
- }
-
- private ObjectAdapter[] argAdaptersFor(final ActionDto actionDto) {
- final List<ParamDto> params = paramDtosFrom(actionDto);
- final List<ObjectAdapter> args = Lists.newArrayList(
- Iterables.transform(params, new Function<ParamDto, ObjectAdapter>() {
- @Override
- public ObjectAdapter apply(final ParamDto paramDto) {
- final Object arg = CommonDtoUtils.getValue(paramDto);
- return adapterFor(arg);
- }
- })
- );
- return args.toArray(new ObjectAdapter[]{});
- }
-
- private static List<ParamDto> paramDtosFrom(final ActionDto actionDto) {
- final ParamsDto parameters = actionDto.getParameters();
- if (parameters != null) {
- final List<ParamDto> parameterList = parameters.getParameter();
- if (parameterList != null) {
- return parameterList;
- }
- }
- return Collections.emptyList();
- }
-
- // //////////////////////////////////////
-
-
- @javax.inject.Inject
- BookmarkService bookmarkService;
-
- @javax.inject.Inject
- JaxbService jaxbService;
-
- @javax.inject.Inject
- InteractionContext interactionContext;
-
- @javax.inject.Inject
- ClockService clockService;
-
--
}
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/CommandExecutorServiceDefault.java
index 0000000,cb29cf0..c27f847
mode 000000,100644..100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/CommandExecutorServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/CommandExecutorServiceDefault.java
@@@ -1,0 -1,430 +1,429 @@@
+ /**
+ * 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.core.runtime.services.background;
+
+ import java.sql.Timestamp;
+ import java.util.Collections;
+ import java.util.List;
+
+ import com.google.common.base.Function;
+ import com.google.common.base.Throwables;
+ import com.google.common.collect.Iterables;
+ import com.google.common.collect.Lists;
+
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ import org.apache.isis.applib.annotation.DomainService;
+ import org.apache.isis.applib.annotation.NatureOfService;
+ import org.apache.isis.applib.annotation.Programmatic;
+ import org.apache.isis.applib.services.bookmark.Bookmark;
+ import org.apache.isis.applib.services.bookmark.BookmarkService2;
+ import org.apache.isis.applib.services.clock.ClockService;
+ import org.apache.isis.applib.services.command.Command;
+ import org.apache.isis.applib.services.command.CommandContext;
+ import org.apache.isis.applib.services.command.CommandExecutorService;
+ import org.apache.isis.applib.services.command.CommandWithDto;
+ import org.apache.isis.applib.services.iactn.Interaction;
+ import org.apache.isis.applib.services.iactn.InteractionContext;
+ import org.apache.isis.applib.services.sudo.SudoService;
+ import org.apache.isis.applib.services.xactn.Transaction2;
-import org.apache.isis.applib.services.xactn.TransactionService3;
+ import org.apache.isis.applib.services.xactn.TransactionState;
+ import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+ import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+ import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+ import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
+ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+ import org.apache.isis.core.metamodel.spec.feature.Contributed;
+ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+ import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+ import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+ import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+ import org.apache.isis.core.runtime.system.context.IsisContext;
+ import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+ import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
+ import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
+ import org.apache.isis.schema.cmd.v1.ActionDto;
+ import org.apache.isis.schema.cmd.v1.CommandDto;
+ import org.apache.isis.schema.cmd.v1.MemberDto;
+ import org.apache.isis.schema.cmd.v1.ParamDto;
+ import org.apache.isis.schema.cmd.v1.ParamsDto;
+ import org.apache.isis.schema.cmd.v1.PropertyDto;
+ import org.apache.isis.schema.common.v1.CollectionDto;
+ import org.apache.isis.schema.common.v1.InteractionType;
+ import org.apache.isis.schema.common.v1.OidDto;
+ import org.apache.isis.schema.common.v1.OidsDto;
+ import org.apache.isis.schema.common.v1.ValueDto;
+ import org.apache.isis.schema.common.v1.ValueType;
+ import org.apache.isis.schema.common.v1.ValueWithTypeDto;
+ import org.apache.isis.schema.utils.CommandDtoUtils;
+ import org.apache.isis.schema.utils.CommonDtoUtils;
+
+ @DomainService(nature = NatureOfService.DOMAIN)
+ public class CommandExecutorServiceDefault implements CommandExecutorService {
+
+ private final static Logger LOG = LoggerFactory.getLogger(CommandExecutorServiceDefault.class);
+
+ @Programmatic
+ public void executeCommand(
+ final CommandExecutorService.SudoPolicy sudoPolicy,
+ final CommandWithDto commandWithDto) {
+
+ ensureTransactionInProgressWithContext(commandWithDto);
+
+ switch (sudoPolicy) {
+ case NO_SWITCH:
+ executeCommand(commandWithDto);
+ break;
+ case SWITCH:
+ final String user = commandWithDto.getUser();
+ sudoService.sudo(user, new Runnable() {
+ @Override
+ public void run() {
+ executeCommand(commandWithDto);
+ }
+ });
+ break;
+ default:
+ throw new IllegalStateException("Probable framework error, unrecognized sudoPolicy: " + sudoPolicy);
+ }
+
+ // double check that we've ended up in the same state
+ ensureTransactionInProgress();
+ }
+
+ private void ensureTransactionInProgressWithContext(final Command command) {
+
+ ensureTransactionInProgress();
+
+ // check the required command is used as the context.
+ // this will ensure that any audit entries also inherit from this existing command.
+ if(commandContext.getCommand() != command) {
+ transactionService.nextTransaction(command);
+ }
+ }
+
+ private void ensureTransactionInProgress() {
+ final Transaction2 currentTransaction = transactionService.currentTransaction();
+ if(currentTransaction == null) {
+ throw new IllegalStateException("No current transaction");
+ }
+ final TransactionState transactionState = currentTransaction.getTransactionState();
+ if(!transactionState.canCommit()) {
+ throw new IllegalStateException("Current transaction is not in a state to be committed, is: " + transactionState);
+ }
+ }
+
+ protected void executeCommand(final CommandWithDto commandWithDto) {
+
+ // setup for us by IsisTransactionManager; will have the transactionId of the backgroundCommand
+ final Interaction interaction = interactionContext.getInteraction();
+
+ org.apache.isis.applib.annotation.Command.ExecuteIn executeIn = commandWithDto.getExecuteIn();
+
+ LOG.info("Executing: {} {} {} {}", executeIn, commandWithDto.getMemberIdentifier(), commandWithDto.getTimestamp(), commandWithDto.getTransactionId());
+
+ RuntimeException exceptionIfAny = null;
+
+ try {
+ commandWithDto.setExecutor(Command.Executor.BACKGROUND);
+
+ // responsibility for setting the Command#startedAt is in the ActionInvocationFacet or
+ // PropertySetterFacet, but this is run if the domain object was found. If the domain object is
+ // thrown then we would have a command with only completedAt, which is inconsistent.
+ // Therefore instead we copy down from the backgroundInteraction (similar to how we populate the
+ // completedAt at the end)
+ final Interaction.Execution currentExecution = interaction.getCurrentExecution();
+
+ final Timestamp startedAt = currentExecution != null
+ ? currentExecution.getStartedAt()
+ : clockService.nowAsJavaSqlTimestamp();
+
+ commandWithDto.setStartedAt(startedAt);
+
+ final CommandDto dto = commandWithDto.asDto();
+
+ final MemberDto memberDto = dto.getMember();
+ final String memberId = memberDto.getMemberIdentifier();
+
+ final OidsDto oidsDto = CommandDtoUtils.targetsFor(dto);
+ final List<OidDto> targetOidDtos = oidsDto.getOid();
+
+ final InteractionType interactionType = memberDto.getInteractionType();
+ if(interactionType == InteractionType.ACTION_INVOCATION) {
+
+ final ActionDto actionDto = (ActionDto) memberDto;
+
+ for (OidDto targetOidDto : targetOidDtos) {
+
+ final ObjectAdapter targetAdapter = adapterFor(targetOidDto);
+ final ObjectAction objectAction = findObjectAction(targetAdapter, memberId);
+
+ // we pass 'null' for the mixedInAdapter; if this action _is_ a mixin then
+ // it will switch the targetAdapter to be the mixedInAdapter transparently
+ final ObjectAdapter[] argAdapters = argAdaptersFor(actionDto);
+ final ObjectAdapter resultAdapter = objectAction.execute(
+ targetAdapter, null, argAdapters, InteractionInitiatedBy.FRAMEWORK);
+
+ // flush any Isis PersistenceCommands pending
+ // (else might get transient objects for the return value)
+ transactionService.flushTransaction();
+
+ //
+ // for the result adapter, we could alternatively have used...
+ // (priorExecution populated by the push/pop within the interaction object)
+ //
+ // final Interaction.Execution priorExecution = backgroundInteraction.getPriorExecution();
+ // Object unused = priorExecution.getReturned();
+ //
+
+ // REVIEW: this doesn't really make sense if >1 action
+ if(resultAdapter != null) {
+ Bookmark resultBookmark = CommandUtil.bookmarkFor(resultAdapter);
+ commandWithDto.setResult(resultBookmark);
+ }
+ }
+ } else {
+
+ final PropertyDto propertyDto = (PropertyDto) memberDto;
+
+ for (OidDto targetOidDto : targetOidDtos) {
+
+ final Bookmark bookmark = Bookmark.from(targetOidDto);
+ final Object targetObject = bookmarkService.lookup(bookmark);
+
+ final ObjectAdapter targetAdapter = adapterFor(targetObject);
+
+ final OneToOneAssociation property = findOneToOneAssociation(targetAdapter, memberId);
+
+ final ObjectAdapter newValueAdapter = newValueAdapterFor(propertyDto);
+
+ property.set(targetAdapter, newValueAdapter, InteractionInitiatedBy.FRAMEWORK);
+
+ // there is no return value for property modifications.
+ }
+ }
+
+ } catch (RuntimeException ex) {
+
+ LOG.warn("Exception when executing : {} {}", executeIn, commandWithDto.getMemberIdentifier(), ex);
+
+ exceptionIfAny = ex;
+ }
+
+ // committing the xactn might also trigger an exception
+ try {
+ transactionService.nextTransaction(TransactionService3.Policy.ALWAYS);
+ } catch(RuntimeException ex) {
+
+ LOG.warn("Exception when committing : {} {}", executeIn, commandWithDto.getMemberIdentifier(), ex);
+
+ if(exceptionIfAny == null) {
+ exceptionIfAny = ex;
+ }
+
+ // this will set up a new transaction
+ transactionService.nextTransaction();
+ }
+
+ // it's possible that there is no priorExecution, specifically if there was an exception
+ // when performing the action invocation/property edit. We therefore need to guard that case.
+ final Interaction.Execution priorExecution = interaction.getPriorExecution();
+ if (commandWithDto.getStartedAt() == null) {
+ // if attempting to commit the xactn threw an error, we will (I think?) have lost this info, so need to
+ // capture
+ commandWithDto.setStartedAt(
+ priorExecution != null
+ ? priorExecution.getStartedAt()
+ : clockService.nowAsJavaSqlTimestamp());
+ }
+
+ final Timestamp completedAt =
+ priorExecution != null
+ ? priorExecution.getCompletedAt()
+ : clockService.nowAsJavaSqlTimestamp(); // close enough...
+ commandWithDto.setCompletedAt(completedAt);
+
+ if(exceptionIfAny != null) {
+ commandWithDto.setException(Throwables.getStackTraceAsString(exceptionIfAny));
+ }
+ }
+
+ // //////////////////////////////////////
+
+ private static ObjectAction findObjectAction(
+ final ObjectAdapter targetAdapter,
+ final String actionId) throws RuntimeException {
+
+ final ObjectSpecification specification = targetAdapter.getSpecification();
+
+ final ObjectAction objectAction = findActionElseNull(specification, actionId);
+ if(objectAction == null) {
+ throw new RuntimeException(String.format("Unknown action '%s'", actionId));
+ }
+ return objectAction;
+ }
+
+ private static OneToOneAssociation findOneToOneAssociation(
+ final ObjectAdapter targetAdapter,
+ final String propertyId) throws RuntimeException {
+
+ final ObjectSpecification specification = targetAdapter.getSpecification();
+
+ final OneToOneAssociation property = findOneToOneAssociationElseNull(specification, propertyId);
+ if(property == null) {
+ throw new RuntimeException(String.format("Unknown property '%s'", propertyId));
+ }
+ return property;
+ }
+
+ private ObjectAdapter newValueAdapterFor(final PropertyDto propertyDto) {
+ final ValueWithTypeDto newValue = propertyDto.getNewValue();
+ final Object arg = CommonDtoUtils.getValue(newValue);
+ return adapterFor(arg);
+ }
+
+ private static ObjectAction findActionElseNull(
+ final ObjectSpecification specification,
+ final String actionId) {
+ final List<ObjectAction> objectActions = specification.getObjectActions(Contributed.INCLUDED);
+ for (final ObjectAction objectAction : objectActions) {
+ if(objectAction.getIdentifier().toClassAndNameIdentityString().equals(actionId)) {
+ return objectAction;
+ }
+ }
+ return null;
+ }
+
+ private static OneToOneAssociation findOneToOneAssociationElseNull(
+ final ObjectSpecification specification,
+ final String propertyId) {
+ final List<ObjectAssociation> associations = specification.getAssociations(Contributed.INCLUDED);
+ for (final ObjectAssociation association : associations) {
+ if( association.getIdentifier().toClassAndNameIdentityString().equals(propertyId) &&
+ association instanceof OneToOneAssociation) {
+ return (OneToOneAssociation) association;
+ }
+ }
+ return null;
+ }
+
+ private ObjectAdapter[] argAdaptersFor(final ActionDto actionDto) {
+ final List<ParamDto> params = paramDtosFrom(actionDto);
+ final List<ObjectAdapter> args = Lists.newArrayList(
+ Iterables.transform(params, new Function<ParamDto, ObjectAdapter>() {
+ @Override
+ public ObjectAdapter apply(final ParamDto paramDto) {
+ final Object arg = CommonDtoUtils.getValue(paramDto);
+ return adapterFor(arg);
+ }
+ })
+ );
+ return args.toArray(new ObjectAdapter[]{});
+ }
+
+ private static List<ParamDto> paramDtosFrom(final ActionDto actionDto) {
+ final ParamsDto parameters = actionDto.getParameters();
+ if (parameters != null) {
+ final List<ParamDto> parameterList = parameters.getParameter();
+ if (parameterList != null) {
+ return parameterList;
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ private ObjectAdapter adapterFor(final Object targetObject) {
+ if(targetObject instanceof OidDto) {
+ final OidDto oidDto = (OidDto) targetObject;
+ return adapterFor(oidDto);
+ }
+ if(targetObject instanceof CollectionDto) {
+ final CollectionDto collectionDto = (CollectionDto) targetObject;
+ final List<ValueDto> valueDtoList = collectionDto.getValue();
+ final List<Object> pojoList = Lists.newArrayList();
+ for (final ValueDto valueDto : valueDtoList) {
+ ValueType valueType = collectionDto.getType();
+ final Object valueOrOidDto = CommonDtoUtils.getValue(valueDto, valueType);
+ // converting from adapter and back means we handle both
+ // collections of references and of values
+ final ObjectAdapter objectAdapter = adapterFor(valueOrOidDto);
+ Object pojo = objectAdapter != null ? objectAdapter.getObject() : null;
+ pojoList.add(pojo);
+ }
+ return adapterFor(pojoList);
+ }
+ if(targetObject instanceof Bookmark) {
+ final Bookmark bookmark = (Bookmark) targetObject;
+ return adapterFor(bookmark);
+ }
+ return getPersistenceSession().adapterFor(targetObject);
+ }
+
+ private ObjectAdapter adapterFor(final OidDto oidDto) {
+ final Bookmark bookmark = Bookmark.from(oidDto);
+ return adapterFor(bookmark);
+ }
+
+ private ObjectAdapter adapterFor(final Bookmark bookmark) {
+ final RootOid rootOid = RootOid.create(bookmark);
+ return adapterFor(rootOid);
+ }
+
+ private ObjectAdapter adapterFor(final RootOid rootOid) {
+ return getPersistenceSession().adapterFor(rootOid);
+ }
+
+ // //////////////////////////////////////
+
+ protected IsisSessionFactory getIsisSessionFactory() {
+ return IsisContext.getSessionFactory();
+ }
+
+ protected PersistenceSession getPersistenceSession() {
+ return getIsisSessionFactory().getCurrentSession().getPersistenceSession();
+ }
+
+ protected IsisTransactionManager getTransactionManager(PersistenceSession persistenceSession) {
+ return persistenceSession.getTransactionManager();
+ }
+
+ protected SpecificationLoader getSpecificationLoader() {
+ return getIsisSessionFactory().getSpecificationLoader();
+ }
+
+ // //////////////////////////////////////
+
+ @javax.inject.Inject
+ BookmarkService2 bookmarkService;
+
+ @javax.inject.Inject
+ InteractionContext interactionContext;
+
+ @javax.inject.Inject
+ SudoService sudoService;
+
+ @javax.inject.Inject
+ ClockService clockService;
+
+ @javax.inject.Inject
+ TransactionService3 transactionService;
+
+ @javax.inject.Inject
+ CommandContext commandContext;
+
+ }
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
index 91bf672,d2dfeed..5a8fc46
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
@@@ -25,8 -25,9 +25,9 @@@ import org.apache.isis.applib.annotatio
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.BookmarkService2;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.xactn.Transaction;
+ import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.xactn.Transaction2;
import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactoryMetamodelRefiner.java
index c294447,8ae7ac6..8f5352d
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactoryMetamodelRefiner.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactoryMetamodelRefiner.java
@@@ -22,6 -22,10 +22,8 @@@ import org.apache.isis.core.commons.con
import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
+ import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorToCheckModuleExtent;
+ import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorToCheckObjectSpecIdsUnique;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.auditable.AuditableAnnotationInJdoApplibFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.auditable.AuditableMarkerInterfaceInJdoApplibFacetFactory;
import org.apache.isis.objectstore.jdo.metamodel.facets.object.datastoreidentity.JdoDatastoreIdentityAnnotationFacetFactory;
import org.apache.isis.objectstore.jdo.metamodel.facets.object.discriminator.JdoDiscriminatorAnnotationFacetFactory;
import org.apache.isis.objectstore.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableAnnotationFacetFactory;
diff --cc core/security-shiro/pom.xml
index dfaecd6,0c86741..13535bb
--- a/core/security-shiro/pom.xml
+++ b/core/security-shiro/pom.xml
@@@ -23,12 -23,11 +23,11 @@@
<parent>
<groupId>org.apache.isis.core</groupId>
<artifactId>isis</artifactId>
- <version>1.16.1-SNAPSHOT</version>
+ <version>2.0.0-M1-SNAPSHOT</version>
</parent>
- <groupId>org.apache.isis.core</groupId>
<artifactId>isis-core-security-shiro</artifactId>
- <version>1.16.1-SNAPSHOT</version>
+ <version>2.0.0-M1-SNAPSHOT</version>
<name>Apache Isis Security Shiro</name>
diff --cc core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueAbstract2.java
index 01b95a3,528d463..e144b27
--- a/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueAbstract2.java
+++ b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueAbstract2.java
@@@ -22,7 -22,8 +22,9 @@@ import org.apache.isis.core.runtime.hea
* Base class for BDD spec glue.
*
* <p>
- * Note that there also needs to be at least one spec glue that inherits from{@link CukeGlueBootstrappingAbstract}.
+ * Note that there also needs to be at least one spec glue that performs the bootstrapping.
- * inherits from{@link CukeGlueBootstrappingAbstract}.
++ * This should inline the boilerplate that can be found in {@link CukeGlueBootstrappingAbstract} (it's not possible
++ * to inherit from that class, unfortunately).
* </p>
*/
public abstract class CukeGlueAbstract2 extends HeadlessAbstract {
diff --cc core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueBootstrappingAbstract.java
index 0ca1e90,e5e21e2..8a02153
--- a/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueBootstrappingAbstract.java
+++ b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueBootstrappingAbstract.java
@@@ -25,7 -25,17 +25,17 @@@ import cucumber.api.java.Before
/**
* For BDD spec using headless access, there needs to be (at least) one BDD spec glue that inherits from this adapter
* class, specifying the {@link Module} to use to bootstrap the system.
+ *
+ * <p>
- * <b>This class is deprecated</b>. it's not possible to subclass from this class, it'll result in an exception:
++ * <b>This class is deprecated</b>. It's not possible to subclass from this class, it'll result in an exception:
+ * <code>cucumber.runtime.CucumberException: You're not allowed to extend classes that define Step Definitions or
+ * hooks</code>.
+ * Instead, just inline the contents of this class.
+ * </p>
+ *
- * @deprecated - it's not possible to subclass from this class, Instead, just inline the contents of this class.
++ * @deprecated - it's not possible to subclass from this class. Instead, just inline the contents of this class.
*/
+ @Deprecated
public abstract class CukeGlueBootstrappingAbstract extends HeadlessWithBootstrappingAbstract {
protected CukeGlueBootstrappingAbstract(final Module module) {
diff --cc core/viewer-wicket-applib/pom.xml
index 914e2e0,5c1e359..a415304
--- a/core/viewer-wicket-applib/pom.xml
+++ b/core/viewer-wicket-applib/pom.xml
@@@ -24,10 -24,9 +24,9 @@@
<parent>
<groupId>org.apache.isis.core</groupId>
<artifactId>isis</artifactId>
- <version>1.16.1-SNAPSHOT</version>
+ <version>2.0.0-M1-SNAPSHOT</version>
</parent>
- <groupId>org.apache.isis.core</groupId>
<artifactId>isis-core-viewer-wicket-applib</artifactId>
<name>Apache Isis Wicket Viewer Applib</name>
diff --cc core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
index a350367,fc06ba5..613e2ca
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@@ -45,10 -48,16 +48,19 @@@ import org.apache.isis.viewer.wicket.ui
import org.apache.isis.viewer.wicket.ui.components.header.HeaderPanelFactory;
import org.apache.isis.viewer.wicket.ui.components.property.PropertyEditFormPanelFactory;
import org.apache.isis.viewer.wicket.ui.components.property.PropertyEditPanelFactory;
- import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.*;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisBlobPanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisClobPanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisColorPanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisDatePanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisDateTimePanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisMoneyPanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisPasswordPanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisPercentagePanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisTimePanelFactory;
+ import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisTimeStampPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.Jdk8LocalDatePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.Jdk8LocalDateTimePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.Jdk8OffsetDateTimePanelFactory;
import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlDatePanelFactory;
import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlTimePanelFactory;
import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlTimestampPanelFactory;
diff --cc core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/bulk/BulkActionsHelper.java
index 395c37a,39fd75a..e80e8f2
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/bulk/BulkActionsHelper.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/bulk/BulkActionsHelper.java
@@@ -21,11 -21,11 +21,11 @@@ package org.apache.isis.viewer.wicket.u
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
++import java.util.stream.Collectors;
- import com.google.common.base.Predicate;
- import com.google.common.collect.Iterables;
-import com.google.common.collect.FluentIterable;
++import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
-import org.apache.isis.applib.filter.Filters;
import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
import org.apache.isis.core.metamodel.spec.ActionType;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@@ -55,32 -54,28 +54,26 @@@ public class BulkActionsHelper implemen
return Collections.emptyList();
}
- final ObjectSpecification typeSpec = model.getTypeOfSpecification();
-
- List<ObjectAction> objectActions = typeSpec.getObjectActions(ActionType.USER, Contributed.INCLUDED,
- com.google.common.base.Predicates.<ObjectAction>alwaysTrue());
+ final ObjectSpecification objectSpec = getObjectSpecification(isisSessionFactory);
- final DeploymentCategory deploymentCategory = isisSessionFactory.getDeploymentCategory();
- if ( !deploymentCategory.isProduction()) {
- List<ObjectAction> prototypeActions = typeSpec.getObjectActions(ActionType.PROTOTYPE, Contributed.INCLUDED,
- com.google.common.base.Predicates.<ObjectAction>alwaysTrue());
- objectActions.addAll(prototypeActions);
- }
+ final List<ActionType> actionTypes = inferActionTypes(isisSessionFactory);
- List<ObjectAction> objectActions = objectSpec.getObjectActions(actionTypes, Contributed.INCLUDED, Filters.<ObjectAction>any());
++ List<ObjectAction> objectActions = objectSpec.getObjectActions(actionTypes, Contributed.INCLUDED, Predicates.<ObjectAction>alwaysTrue());
- List<ObjectAction> flattenedActions = objectActions;
-
- return Lists.newArrayList(Iterables.filter(flattenedActions, BULK));
- return FluentIterable.from(objectActions)
- .filter(ObjectAction.Predicates.bulk())
- .toList();
++ return objectActions.stream().filter(ObjectAction.Predicates.bulk()::apply).collect(Collectors.toList());
}
+ private ObjectSpecification getObjectSpecification(final IsisSessionFactory isisSessionFactory) {
+ return collectionModel.getTypeOfSpecification();
+ }
- @SuppressWarnings("deprecation")
- private static final Predicate<ObjectAction> BULK = ObjectAction.Predicates.bulk();
-
- /**
- * Protected so can be overridden in testing if required.
- */
- protected boolean isDebugMode() {
- return true;
+ private List<ActionType> inferActionTypes(final IsisSessionFactory isisSessionFactory) {
+ final List<ActionType> actionTypes = Lists.newArrayList();
+ actionTypes.add(ActionType.USER);
+ final DeploymentCategory deploymentCategory = isisSessionFactory.getDeploymentCategory();
+ if ( !deploymentCategory.isProduction()) {
+ actionTypes.add(ActionType.PROTOTYPE);
+ }
+ return actionTypes;
}
}
diff --cc example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObject.java
index 519ad7a,9c598d3..8da92ba
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObject.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObject.java
@@@ -63,9 -64,11 +64,9 @@@ public class SimpleObject implements Co
private String notes;
- @Action(semantics = SemanticsOf.IDEMPOTENT, command = CommandReification.ENABLED, publishing = Publishing.ENABLED)
+ @Action(semantics = SemanticsOf.IDEMPOTENT, command = CommandReification.ENABLED, publishing = Publishing.ENABLED, associateWith = "name")
public SimpleObject updateName(
- @Parameter(maxLength = 40)
- @ParameterLayout(named = "Name")
- final String name) {
+ @Name final String name) {
setName(name);
return this;
}
--
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.