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
The following commit(s) were added to refs/heads/master by this push:
new f29865af1d ISIS-3106: fixes handling of @ActionLayout(position)
f29865af1d is described below
commit f29865af1d4f6c0c28d6e558b0eb1ea2044eefc8
Author: Dan Haywood <[email protected]>
AuthorDate: Tue Aug 2 09:48:01 2022 +0100
ISIS-3106: fixes handling of @ActionLayout(position)
also adds descriptions for all of the mixins
---
.../mixins/layout/Object_downloadLayoutXml.java | 1 +
.../metamodel/Object_downloadMetamodelXml.java | 1 +
.../mixins/metamodel/Object_logicalTypeName.java | 5 +-
.../mixins/metamodel/Object_objectIdentifier.java | 1 +
.../mixins/metamodel/Object_rebuildMetamodel.java | 1 +
.../applib/mixins/rest/Object_openRestApi.java | 1 +
.../metamodel/inspect/Object_inspectMetamodel.java | 1 +
.../grid/bootstrap/GridSystemServiceBootstrap.java | 10 +-
...ntegTest.java => Layout_Counter_IntegTest.java} | 5 +-
.../integtest/Layout_SimpleObject_IntegTest.java | 190 +++++++++++++++++++++
.../model/Counter_updateNameUsingMixin.java | 37 ----
.../layouts/integtest/model/SimpleObject.java | 139 +++++++++++++++
.../integtest/model/SimpleObject.layout.xml | 47 +++++
.../layouts/integtest/model/types/Name.java | 20 +++
.../layouts/integtest/model/types/Notes.java | 25 +++
.../commons/applib/mixins/Object_impersonate.java | 1 +
.../applib/mixins/Object_impersonateWithRoles.java | 1 +
17 files changed, 443 insertions(+), 43 deletions(-)
diff --git
a/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_downloadLayoutXml.java
b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_downloadLayoutXml.java
index eb7a515092..ca812a3fba 100644
---
a/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_downloadLayoutXml.java
+++
b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_downloadLayoutXml.java
@@ -52,6 +52,7 @@ import lombok.val;
)
@ActionLayout(
cssClassFa = "fa-download",
+ describedAs = "Downloads the Xxx.layout.xml layout file
effective/inferred for this object",
fieldSetId = LayoutConstants.FieldSetId.METADATA,
position = ActionLayout.Position.PANEL_DROPDOWN,
sequence = "700.1"
diff --git
a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_downloadMetamodelXml.java
b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_downloadMetamodelXml.java
index 00d04b7ff4..d182e3f907 100644
---
a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_downloadMetamodelXml.java
+++
b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_downloadMetamodelXml.java
@@ -58,6 +58,7 @@ import lombok.val;
)
@ActionLayout(
cssClassFa = "fa-download",
+ describedAs = "Downloads a representation of the framework's internal
metamodel for this object's domain class",
fieldSetId = LayoutConstants.FieldSetId.METADATA,
position = ActionLayout.Position.PANEL_DROPDOWN,
sequence = "700.2"
diff --git
a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_logicalTypeName.java
b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_logicalTypeName.java
index 2440a8a677..5309b28819 100644
---
a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_logicalTypeName.java
+++
b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_logicalTypeName.java
@@ -36,10 +36,10 @@ import lombok.val;
/**
* Contributes a property exposing the logical object type of the domain
- * object, typically as specified by {@link DomainObject#logicalTypeName()}.
+ * object, typically as specified by {@link javax.inject.Named}.
*
* <p>
- * The object type is also accessible from the
+ * The logical type name is also accessible from the
* {@link org.apache.isis.applib.services.bookmark.Bookmark} of the
* object.
* </p>
@@ -53,6 +53,7 @@ import lombok.val;
*/
@Property
@PropertyLayout(
+ describedAs = "The logical name of this domain class (as used in
persistence, URLs etc). Intended to be stable/unchanging across time",
hidden = Where.ALL_TABLES,
fieldSetId = LayoutConstants.FieldSetId.METADATA,
sequence = "400.1"
diff --git
a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
index 6eb2e9ef7d..2e3435404a 100644
---
a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
+++
b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
@@ -52,6 +52,7 @@ import lombok.val;
*/
@Property
@PropertyLayout(
+ describedAs = "The identifier of this object instance, unique within
its domain class. Combined with the 'logical type name', is a unique
identifier across all domain classes.",
hidden = Where.ALL_TABLES,
fieldSetId = LayoutConstants.FieldSetId.METADATA,
sequence = "400.2"
diff --git
a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_rebuildMetamodel.java
b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_rebuildMetamodel.java
index 37f9b667ea..4de02e5b7f 100644
---
a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_rebuildMetamodel.java
+++
b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_rebuildMetamodel.java
@@ -47,6 +47,7 @@ import lombok.RequiredArgsConstructor;
)
@ActionLayout(
cssClassFa = "fa-sync",
+ describedAs = "Rebuilds the framework's internal metamodel of this
object's domain class",
fieldSetId = LayoutConstants.FieldSetId.METADATA,
position = ActionLayout.Position.PANEL,
sequence = "800.1"
diff --git
a/api/applib/src/main/java/org/apache/isis/applib/mixins/rest/Object_openRestApi.java
b/api/applib/src/main/java/org/apache/isis/applib/mixins/rest/Object_openRestApi.java
index 2889d4aae0..d1b982436b 100644
---
a/api/applib/src/main/java/org/apache/isis/applib/mixins/rest/Object_openRestApi.java
+++
b/api/applib/src/main/java/org/apache/isis/applib/mixins/rest/Object_openRestApi.java
@@ -50,6 +50,7 @@ import lombok.val;
)
@ActionLayout(
cssClassFa = "fa-external-link-alt",
+ describedAs = "Opens up a view of this object as represented in the
(Restful Objects) REST API",
fieldSetId = LayoutConstants.FieldSetId.METADATA,
position = ActionLayout.Position.PANEL_DROPDOWN,
sequence = "750.1"
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/inspect/Object_inspectMetamodel.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/inspect/Object_inspectMetamodel.java
index a4ef6ad266..76fdef7eac 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/inspect/Object_inspectMetamodel.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/inspect/Object_inspectMetamodel.java
@@ -52,6 +52,7 @@ import lombok.val;
)
@ActionLayout(
cssClassFa = "fa-sitemap",
+ describedAs = "Open up a view of the metamodel of this object's domain
class",
fieldSetId = LayoutConstants.FieldSetId.METADATA,
position = ActionLayout.Position.PANEL_DROPDOWN,
sequence = "700.2.1"
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap/GridSystemServiceBootstrap.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap/GridSystemServiceBootstrap.java
index 0540fef817..2c47c082e4 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap/GridSystemServiceBootstrap.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap/GridSystemServiceBootstrap.java
@@ -436,7 +436,15 @@ extends GridSystemServiceAbstract<BSGrid> {
final ActionLayoutData actionLayoutData = new
ActionLayoutData(actionId);
-
actionLayoutData.setPosition(ActionLayout.Position.PANEL_DROPDOWN);
+ // since the action is to be associated with a fieldSet, the
only available positions are PANEL and PANEL_DROPDOWN.
+ // if the action already has a preference for PANEL, then
preserve it, otherwise default to PANEL_DROPDOWN
+ val actionPositionFacet =
objectAction.getFacet(ActionPositionFacet.class);
+ if(actionPositionFacet != null &&
actionPositionFacet.position() == ActionLayout.Position.PANEL) {
+ actionLayoutData.setPosition(ActionLayout.Position.PANEL);
+ } else {
+
actionLayoutData.setPosition(ActionLayout.Position.PANEL_DROPDOWN);
+ }
+
final FieldSet fieldSet =
gridModel.getFieldSet(layoutGroupName);
addActionTo(fieldSet, actionLayoutData);
}
diff --git
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_IntegTest.java
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_Counter_IntegTest.java
similarity index 99%
rename from
regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_IntegTest.java
rename to
regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_Counter_IntegTest.java
index cca8034282..3b19e82c33 100644
---
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_IntegTest.java
+++
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_Counter_IntegTest.java
@@ -24,7 +24,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -80,10 +79,10 @@ import
org.apache.isis.viewer.wicket.applib.IsisModuleViewerWicketApplibMixins;
import lombok.val;
@SpringBootTest(
- classes = Layout_IntegTest.AppManifest.class
+ classes = Layout_Counter_IntegTest.AppManifest.class
)
@ActiveProfiles("test")
-public class Layout_IntegTest extends IsisIntegrationTestAbstract {
+public class Layout_Counter_IntegTest extends IsisIntegrationTestAbstract {
@SpringBootConfiguration
@EnableAutoConfiguration
diff --git
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_SimpleObject_IntegTest.java
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_SimpleObject_IntegTest.java
new file mode 100644
index 0000000000..6a4c377f82
--- /dev/null
+++
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/Layout_SimpleObject_IntegTest.java
@@ -0,0 +1,190 @@
+/*
+ * 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.regressiontests.layouts.integtest;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.context.annotation.PropertySources;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.TransactionException;
+import org.springframework.transaction.TransactionStatus;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.isis.applib.IsisModuleApplibMixins;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.layout.LayoutConstants;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.iactnlayer.InteractionService;
+import org.apache.isis.applib.services.metamodel.Config;
+import org.apache.isis.applib.services.metamodel.MetaModelService;
+import org.apache.isis.core.config.beans.IsisBeanTypeRegistry;
+import org.apache.isis.core.config.presets.IsisPresets;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import
org.apache.isis.core.metamodel.facets.actions.position.ActionPositionFacet;
+import
org.apache.isis.core.metamodel.facets.members.layout.group.LayoutGroupFacet;
+import
org.apache.isis.core.metamodel.facets.members.layout.order.LayoutOrderFacet;
+import org.apache.isis.core.metamodel.spec.feature.MixedIn;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.runtimeservices.IsisModuleCoreRuntimeServices;
+import org.apache.isis.regressiontests.layouts.integtest.model.Counter;
+import
org.apache.isis.regressiontests.layouts.integtest.model.LayoutTestDomainModel;
+import org.apache.isis.regressiontests.layouts.integtest.model.SimpleObject;
+import org.apache.isis.schema.metamodel.v2.Action;
+import org.apache.isis.schema.metamodel.v2.DomainClassDto;
+import org.apache.isis.schema.metamodel.v2.FacetAttr;
+import org.apache.isis.schema.metamodel.v2.MetamodelDto;
+import org.apache.isis.security.bypass.IsisModuleSecurityBypass;
+import
org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
+import org.apache.isis.viewer.wicket.applib.IsisModuleViewerWicketApplibMixins;
+
+import lombok.val;
+
+@SpringBootTest(
+ classes = Layout_SimpleObject_IntegTest.AppManifest.class
+)
+@ActiveProfiles("test")
+public class Layout_SimpleObject_IntegTest extends IsisIntegrationTestAbstract
{
+
+ @SpringBootConfiguration
+ @EnableAutoConfiguration
+ @Import({
+ IsisModuleApplibMixins.class,
+ IsisModuleViewerWicketApplibMixins.class,
+ IsisModuleCoreRuntimeServices.class,
+ IsisModuleSecurityBypass.class,
+ })
+ @PropertySources({
+ @PropertySource(IsisPresets.UseLog4j2Test)
+ })
+ @ComponentScan(basePackageClasses = {AppManifest.class,
LayoutTestDomainModel.class})
+ public static class AppManifest {
+
+
+ }
+
+ @BeforeAll
+ static void beforeAll() {
+ IsisPresets.forcePrototyping();
+ }
+
+
+ @Test
+ void openRestApi() {
+
+ // given
+ val action = lookupAction("openRestApi");
+
+ // when, then
+ List<Facet> facets =
action.getFacetHolder().streamFacets().collect(Collectors.toList());
+
+ val actionPositionFacet = action.getFacet(ActionPositionFacet.class);
+ assertThat(actionPositionFacet)
+ .satisfies(f ->
assertThat(f).extracting(ActionPositionFacet::getPrecedence).isEqualTo(Facet.Precedence.DEFAULT))
+ .satisfies(f ->
assertThat(f).extracting(ActionPositionFacet::position).isEqualTo(ActionLayout.Position.PANEL_DROPDOWN));
+
+ val layoutOrderFacet = action.getFacet(LayoutOrderFacet.class);
+ assertThat(layoutOrderFacet)
+ .satisfies(f ->
assertThat(f).extracting(LayoutOrderFacet::getPrecedence).isEqualTo(Facet.Precedence.DEFAULT))
+ .satisfies(f ->
assertThat(f).extracting(LayoutOrderFacet::getSequence).isEqualTo("750.1"))
+ ;
+
+ val layoutGroupFacet = action.getFacet(LayoutGroupFacet.class);
+ assertThat(layoutGroupFacet)
+ .satisfies(f ->
assertThat(f).extracting(LayoutGroupFacet::getGroupId).isEqualTo(LayoutConstants.FieldSetId.METADATA))
+ ;
+ }
+
+ @Test
+ void clearHints() {
+
+ // given
+ val action = lookupAction("clearHints");
+
+ // when, then
+ List<Facet> facets =
action.getFacetHolder().streamFacets().collect(Collectors.toList());
+
+ val actionPositionFacet = action.getFacet(ActionPositionFacet.class);
+ assertThat(actionPositionFacet)
+ .satisfies(f ->
assertThat(f).extracting(ActionPositionFacet::getPrecedence).isEqualTo(Facet.Precedence.DEFAULT))
+ .satisfies(f ->
assertThat(f).extracting(ActionPositionFacet::position).isEqualTo(ActionLayout.Position.PANEL));
+
+ val layoutOrderFacet = action.getFacet(LayoutOrderFacet.class);
+ assertThat(layoutOrderFacet)
+ .satisfies(f ->
assertThat(f).extracting(LayoutOrderFacet::getPrecedence).isEqualTo(Facet.Precedence.DEFAULT))
+ .satisfies(f ->
assertThat(f).extracting(LayoutOrderFacet::getSequence).isEqualTo("400.1"))
+ ;
+
+ val layoutGroupFacet = action.getFacet(LayoutGroupFacet.class);
+ assertThat(layoutGroupFacet)
+ .satisfies(f ->
assertThat(f).extracting(LayoutGroupFacet::getGroupId).isEqualTo(LayoutConstants.FieldSetId.METADATA))
+ ;
+ }
+
+ private ObjectAction lookupAction(String id) {
+ val objectSpecification =
specificationLoader.loadSpecification(SimpleObject.class);
+ List<ObjectAction> objectActions =
objectSpecification.streamAnyActions(MixedIn.INCLUDED).collect(Collectors.toList());
+ return objectSpecification.streamAnyActions(MixedIn.INCLUDED).filter(x
-> x.getId().equals(id)).findFirst().orElseThrow();
+ }
+
+
+ private void extracted(Class<?> cls) {
+ LogicalType logicalType =
metaModelService.lookupLogicalTypeByClass(cls).orElseThrow();
+ MetamodelDto metamodelDto = metaModelService.exportMetaModel(new
Config().withNamespacePrefix("layouts.test."));
+ Map<String, DomainClassDto> metaModelDtoById =
metamodelDto.getDomainClassDto().stream().collect(Collectors.toMap(DomainClassDto::getId,
Function.identity()));
+ DomainClassDto domainClassDto =
metaModelDtoById.get(cls.getCanonicalName());
+ Map<String, Action> actionById =
domainClassDto.getActions().getAct().stream().collect(Collectors.toMap(Action::getId,
Function.identity()));
+ List<org.apache.isis.schema.metamodel.v2.Facet> facets =
actionById.get("updateNameUsingDeclaredAction").getFacets().getFacet();
+ Map<String, org.apache.isis.schema.metamodel.v2.Facet> facetById =
facets.stream().collect(Collectors.toMap(org.apache.isis.schema.metamodel.v2.Facet::getId,
Function.identity()));
+ Map<String, String> facetAttrByName =
facetById.get(LayoutGroupFacet.class.getCanonicalName()).getAttr().stream().collect(Collectors.toMap(FacetAttr::getName,
FacetAttr::getValue));
+ facetAttrByName.get("Name");
+ }
+
+
+ @Inject InteractionService interactionService;
+ @Inject MetaModelService metaModelService;
+ @Inject SpecificationLoader specificationLoader;
+ @Inject BookmarkService bookmarkService;
+
+ @Inject IsisBeanTypeRegistry isisBeanTypeRegistry;
+
+}
diff --git
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/Counter_updateNameUsingMixin.java
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/Counter_updateNameUsingMixin.java
deleted file mode 100644
index e3cee6dd93..0000000000
---
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/Counter_updateNameUsingMixin.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.regressiontests.layouts.integtest.model;
-
-import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.services.wrapper.Mixin;
-
-import lombok.RequiredArgsConstructor;
-
-@Action()
-@RequiredArgsConstructor
-public class Counter_updateNameUsingMixin implements Mixin<Counter> {
-
- private final Counter counter;
-
- public Counter act(String name) {
- return counter.doUpdateName(name);
- }
-}
diff --git
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/SimpleObject.java
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/SimpleObject.java
new file mode 100644
index 0000000000..50f0c32c3c
--- /dev/null
+++
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/SimpleObject.java
@@ -0,0 +1,139 @@
+package org.apache.isis.regressiontests.layouts.integtest.model;
+
+import java.util.Comparator;
+
+import javax.inject.Inject;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.DomainObjectLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Publishing;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.applib.jaxb.PersistentEntityAdapter;
+import org.apache.isis.applib.services.message.MessageService;
+import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.applib.services.title.TitleService;
+import org.apache.isis.regressiontests.layouts.integtest.model.types.Name;
+import org.apache.isis.regressiontests.layouts.integtest.model.types.Notes;
+//import org.apache.isis.persistence.jpa.applib.integration.IsisEntityListener;
+
+import static org.apache.isis.applib.annotation.SemanticsOf.IDEMPOTENT;
+import static
org.apache.isis.applib.annotation.SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.val;
+
+
[email protected]
[email protected](
+ schema="simple",
+ uniqueConstraints = {
+ @javax.persistence.UniqueConstraint(name = "SimpleObject__name__UNQ",
columnNames = {"NAME"})
+ }
+)
[email protected]({
+ @javax.persistence.NamedQuery(
+ name = SimpleObject.NAMED_QUERY__FIND_BY_NAME_LIKE,
+ query = "SELECT so " +
+ "FROM SimpleObject so " +
+ "WHERE so.name LIKE :name"
+ )
+})
+//@javax.persistence.EntityListeners(IsisEntityListener.class)
+@DomainObject(logicalTypeName = "simple.SimpleObject", entityChangePublishing
= Publishing.ENABLED)
+@DomainObjectLayout()
+@NoArgsConstructor(access = AccessLevel.PUBLIC)
+@XmlJavaTypeAdapter(PersistentEntityAdapter.class)
+@ToString(onlyExplicitlyIncluded = true)
+public class SimpleObject implements Comparable<SimpleObject> {
+
+ static final String NAMED_QUERY__FIND_BY_NAME_LIKE =
"SimpleObject.findByNameLike";
+
+ @javax.persistence.Id
+ @javax.persistence.GeneratedValue(strategy =
javax.persistence.GenerationType.AUTO)
+ @javax.persistence.Column(name = "id", nullable = false)
+ private Long id;
+
+ @javax.persistence.Version
+ @javax.persistence.Column(name = "version", nullable = false)
+ @PropertyLayout(fieldSetId = "metadata", sequence = "999")
+ @Getter @Setter
+ private long version;
+
+ public static SimpleObject withName(String name) {
+ val simpleObject = new SimpleObject();
+ simpleObject.setName(name);
+ return simpleObject;
+ }
+
+ @Inject @javax.persistence.Transient RepositoryService repositoryService;
+ @Inject @javax.persistence.Transient TitleService titleService;
+ @Inject @javax.persistence.Transient MessageService messageService;
+
+
+
+ @Title
+ @Name
+ @javax.persistence.Column(length = Name.MAX_LEN, nullable = false)
+ @Getter @Setter @ToString.Include
+ @PropertyLayout(fieldSetId = "name", sequence = "1")
+ private String name;
+
+ @Notes
+ @javax.persistence.Column(length = Notes.MAX_LEN, nullable = true)
+ @Getter @Setter
+ @Property(commandPublishing = Publishing.ENABLED, executionPublishing =
Publishing.ENABLED)
+ @PropertyLayout(fieldSetId = "name", sequence = "2")
+ private String notes;
+
+
+ @Action(semantics = IDEMPOTENT, commandPublishing = Publishing.ENABLED,
executionPublishing = Publishing.ENABLED)
+ @ActionLayout(associateWith = "name", promptStyle = PromptStyle.INLINE)
+ public SimpleObject updateName(
+ @Name final String name) {
+ setName(name);
+ return this;
+ }
+ public String default0UpdateName() {
+ return getName();
+ }
+ public String validate0UpdateName(String newName) {
+ for (char prohibitedCharacter : "&%$!".toCharArray()) {
+ if( newName.contains(""+prohibitedCharacter)) {
+ return "Character '" + prohibitedCharacter + "' is not
allowed.";
+ }
+ }
+ return null;
+ }
+
+
+ @Action(semantics = NON_IDEMPOTENT_ARE_YOU_SURE)
+ @ActionLayout(
+ position = ActionLayout.Position.PANEL,
+ describedAs = "Deletes this object from the persistent datastore")
+ public void delete() {
+ final String title = titleService.titleOf(this);
+ messageService.informUser(String.format("'%s' deleted", title));
+ repositoryService.removeAndFlush(this);
+ }
+
+
+
+ private final static Comparator<SimpleObject> comparator =
+ Comparator.comparing(SimpleObject::getName);
+
+ @Override
+ public int compareTo(final SimpleObject other) {
+ return comparator.compare(this, other);
+ }
+
+}
diff --git
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/SimpleObject.layout.xml
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/SimpleObject.layout.xml
new file mode 100644
index 0000000000..deaca8e6f1
--- /dev/null
+++
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/SimpleObject.layout.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<bs3:grid xsi:schemaLocation="http://isis.apache.org/applib/layout/component
http://isis.apache.org/applib/layout/component/component.xsd
http://isis.apache.org/applib/layout/grid/bootstrap3
http://isis.apache.org/applib/layout/grid/bootstrap3/bootstrap3.xsd"
xmlns:c="http://isis.apache.org/applib/layout/component"
xmlns:bs3="http://isis.apache.org/applib/layout/grid/bootstrap3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <bs3:row>
+ <bs3:col span="12" unreferencedActions="true">
+ <c:domainObject bookmarking="AS_ROOT"/>
+ </bs3:col>
+ </bs3:row>
+ <bs3:row>
+ <bs3:col span="6">
+ <bs3:row>
+ <bs3:col span="12">
+ <bs3:tabGroup>
+ <bs3:tab name="Identity">
+ <bs3:row>
+ <bs3:col span="12">
+ <c:fieldSet name="Identity" id="identity"/>
+ </bs3:col>
+ </bs3:row>
+ </bs3:tab>
+ <bs3:tab name="Other">
+ <bs3:row>
+ <bs3:col span="12">
+ <c:fieldSet name="Other" id="other"
unreferencedProperties="true"/>
+ </bs3:col>
+ </bs3:row>
+ </bs3:tab>
+ <bs3:tab name="Metadata">
+ <bs3:row>
+ <bs3:col span="12">
+ <c:fieldSet name="Metadata" id="metadata"/>
+ </bs3:col>
+ </bs3:row>
+ </bs3:tab>
+ </bs3:tabGroup>
+ </bs3:col>
+ <bs3:col span="12">
+ <c:fieldSet name="Details" id="details"/>
+ </bs3:col>
+ </bs3:row>
+ </bs3:col>
+ <bs3:col span="6">
+ <bs3:tabGroup unreferencedCollections="true">
+ </bs3:tabGroup>
+ </bs3:col>
+ </bs3:row>
+</bs3:grid>
diff --git
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/types/Name.java
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/types/Name.java
new file mode 100644
index 0000000000..6895026986
--- /dev/null
+++
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/types/Name.java
@@ -0,0 +1,20 @@
+package org.apache.isis.regressiontests.layouts.integtest.model.types;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.isis.applib.annotation.Parameter;
+import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.annotation.Property;
+
+@Property(maxLength = Name.MAX_LEN)
+@Parameter(maxLength = Name.MAX_LEN)
+@ParameterLayout(named = "Name")
+@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER,
ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Name {
+
+ int MAX_LEN = 40;
+}
diff --git
a/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/types/Notes.java
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/types/Notes.java
new file mode 100644
index 0000000000..8b9b62bff5
--- /dev/null
+++
b/regressiontests/stable-layouts/src/main/java/org/apache/isis/regressiontests/layouts/integtest/model/types/Notes.java
@@ -0,0 +1,25 @@
+package org.apache.isis.regressiontests.layouts.integtest.model.types;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Parameter;
+import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Where;
+
+@Property(editing = Editing.ENABLED, maxLength = Notes.MAX_LEN)
+@PropertyLayout(named = "Notes", multiLine = 10, hidden = Where.ALL_TABLES)
+@Parameter(maxLength = Notes.MAX_LEN)
+@ParameterLayout(named = "Notes", multiLine = 10)
+@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER,
ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Notes {
+
+ int MAX_LEN = 4000;
+
+}
diff --git
a/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/applib/mixins/Object_impersonate.java
b/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/applib/mixins/Object_impersonate.java
index b541258374..ed666fabe8 100644
---
a/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/applib/mixins/Object_impersonate.java
+++
b/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/applib/mixins/Object_impersonate.java
@@ -49,6 +49,7 @@ import lombok.RequiredArgsConstructor;
)
@ActionLayout(
cssClassFa = "fa-mask",
+ describedAs = "Switch to another user account (for prototype/testing
only)",
fieldSetId = LayoutConstants.FieldSetId.METADATA,
position = ActionLayout.Position.PANEL_DROPDOWN,
redirectPolicy = Redirect.EVEN_IF_SAME,
diff --git
a/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/applib/mixins/Object_impersonateWithRoles.java
b/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/applib/mixins/Object_impersonateWithRoles.java
index 3b72bed935..b988a568bb 100644
---
a/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/applib/mixins/Object_impersonateWithRoles.java
+++
b/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/applib/mixins/Object_impersonateWithRoles.java
@@ -52,6 +52,7 @@ import lombok.val;
)
@ActionLayout(
cssClassFa = "fa-mask",
+ describedAs = "Switch to another user account with specified roles
(for prototype/testing only)",
fieldSetId = LayoutConstants.FieldSetId.METADATA,
position = ActionLayout.Position.PANEL_DROPDOWN,
redirectPolicy = Redirect.EVEN_IF_SAME,