This is an automated email from the ASF dual-hosted git repository. ahuber pushed a commit to branch 3971-layout.switching in repository https://gitbox.apache.org/repos/asf/causeway.git
commit c0971f6ac41f662e06391b5e7038de46d06f8d85 Author: andi-huber <[email protected]> AuthorDate: Wed Mar 4 13:03:41 2026 +0100 CAUSEWAY-3971: fixes ObjectMemberResolverForGrid to honor layout variants --- .../applib/layout/grid/bootstrap/BSUtil.java | 1 + .../core/metamodel/services/grid/GridLoader.java | 5 ++- .../services/grid/GridServiceDefault.java | 1 - .../services/grid/ObjectMemberResolverForGrid.java | 39 ++++++++++++++-------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/api/applib/src/main/java/org/apache/causeway/applib/layout/grid/bootstrap/BSUtil.java b/api/applib/src/main/java/org/apache/causeway/applib/layout/grid/bootstrap/BSUtil.java index 9f7782757b4..7d00b20e582 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/layout/grid/bootstrap/BSUtil.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/layout/grid/bootstrap/BSUtil.java @@ -104,6 +104,7 @@ void writeln(final String line) { w.writeln("bsGrid:"); w.inc(); w.writeln("class: %s".formatted(bsGrid.domainClass().getName())); + w.writeln("layoutKey: %s".formatted(bsGrid.layoutKey())); } @Override public void exit(final BSGrid bsGrid) { w.dec(); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/GridLoader.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/GridLoader.java index 5ba50aa9a24..ddb30f5932f 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/GridLoader.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/GridLoader.java @@ -41,7 +41,10 @@ record GridLoader( public Try<BSGrid> tryLoad(final LayoutKey layoutKey, final LayoutResource layoutResource) { return gridLoadingContext.gridMarshaller(layoutResource.format()) .orElseThrow() - .unmarshal(layoutKey.domainClass(), layoutResource.content(), layoutResource.format()); + .unmarshal(layoutKey.domainClass(), layoutResource.content(), layoutResource.format()) + .mapSuccessAsNullable(grid->grid!=null + ? grid.layoutKey(layoutKey) + : grid); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/GridServiceDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/GridServiceDefault.java index b667e9494e8..51318c26626 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/GridServiceDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/GridServiceDefault.java @@ -94,7 +94,6 @@ public void invalidate(final Class<?> domainClass) { public BSGrid load(final LayoutKey layoutKey) { var grid = cache.computeIfAbsent(layoutKey, this::tryLoadNoCache) .valueAsNonNullElseFail(); // at least we should have a fallback, otherwise there is some serious issue - grid.layoutKey(layoutKey); return grid; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/ObjectMemberResolverForGrid.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/ObjectMemberResolverForGrid.java index f9db6f0b458..a4b375e1367 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/ObjectMemberResolverForGrid.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/ObjectMemberResolverForGrid.java @@ -39,6 +39,7 @@ import org.apache.causeway.applib.layout.grid.bootstrap.BSRow; import org.apache.causeway.applib.layout.grid.bootstrap.BSTab; import org.apache.causeway.applib.layout.grid.bootstrap.BSTabGroup; +import org.apache.causeway.applib.layout.grid.bootstrap.BSUtil; import org.apache.causeway.applib.layout.grid.bootstrap.Size; import org.apache.causeway.applib.services.grid.GridService.LayoutKey; import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType; @@ -47,6 +48,7 @@ import org.apache.causeway.commons.internal.collections._Lists; import org.apache.causeway.commons.internal.collections._Sets; import org.apache.causeway.commons.internal.exceptions._Exceptions; +import org.apache.causeway.core.metamodel.facetapi.FacetRanking; import org.apache.causeway.core.metamodel.facets.actions.position.ActionPositionFacet; import org.apache.causeway.core.metamodel.facets.members.layout.group.GroupIdAndName; import org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacet; @@ -74,17 +76,24 @@ record ObjectMemberResolverForGrid( * Returns either a valid (left) or invalid (right) {@link BSGrid} */ public Either<BSGrid, BSGrid> resolve(final LayoutKey layoutKey, final BSGrid grid) { - final boolean valid = validateAndNormalize(grid, layoutKey.domainClass()); - if (valid) { - //TODO perhaps make available via context - new XmlLayoutRespectingFacetInstaller(context.specLoaderProvider().get()) - .installFacets(layoutKey, grid); - if(log.isDebugEnabled()) { - log.debug("Grid:\n\n{}\n\n", toXml(grid)); + try { + FacetRanking.setQualifier(layoutKey); + + final boolean valid = validateAndNormalize(grid, layoutKey.domainClass()); + if (valid) { + //TODO perhaps make available via context + new XmlLayoutRespectingFacetInstaller(context.specLoaderProvider().get()) + .installFacets(layoutKey, grid); + if(log.isDebugEnabled()) { + log.debug("Grid:\n\n{}\n\n", toXml(grid)); + } + return Either.left(grid); } - return Either.left(grid); + return Either.right(grid); + + } finally { + FacetRanking.removeQualifier(); } - return Either.right(grid); } // -- HELPER @@ -103,6 +112,8 @@ private boolean validateAndNormalize( final BSGrid bsGrid, final Class<?> domainClass) { + System.err.println("%s".formatted(BSUtil.toYaml(bsGrid))); + var gridModelIfValid = GridInitializationModel.createFrom(bsGrid); if(!gridModelIfValid.isPresent()) return false; // only present if valid @@ -150,7 +161,7 @@ private boolean validateAndNormalize( // along with any specified by existing metadata for (final OneToOneAssociation oneToOneAssociation : oneToOneAssociationById.values()) { - var layoutGroupFacet = oneToOneAssociation.getFacet(LayoutGroupFacet.class); + var layoutGroupFacet = oneToOneAssociation.lookupFacet(LayoutGroupFacet.class).orElse(null); if(layoutGroupFacet == null) { continue; } @@ -259,7 +270,7 @@ private boolean validateAndNormalize( for (final String actionId : sortedPossiblyMissingActionIds) { var objectAction = objectActionById.get(actionId); - var layoutGroupFacet = objectAction.getFacet(LayoutGroupFacet.class); + var layoutGroupFacet = objectAction.lookupFacet(LayoutGroupFacet.class).orElse(null); if(layoutGroupFacet == null) { continue; } @@ -275,10 +286,10 @@ private boolean validateAndNormalize( if(layoutGroupFacet.isExplicitBinding()) { var propertyLayoutDataList = gridModel.propertyLayoutDataById.get(layoutGroupName); if(_NullSafe.isEmpty(propertyLayoutDataList)) { - log.warn(String.format("Could not find propertyLayoutData for layoutGroupName of '%s'", layoutGroupName)); + log.warn(String.format("Could not find propertyLayoutData for layoutGroupName '%s'", layoutGroupName)); continue; } - var actionPositionFacet = objectAction.getFacet(ActionPositionFacet.class); + var actionPositionFacet = objectAction.lookupFacet(ActionPositionFacet.class).orElse(null); final ActionLayout.Position position = actionPositionFacet != null ? actionPositionFacet.position() : ActionLayout.Position.BELOW; @@ -320,7 +331,7 @@ private boolean validateAndNormalize( // 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 - var actionPositionFacet = objectAction.getFacet(ActionPositionFacet.class); + var actionPositionFacet = objectAction.lookupFacet(ActionPositionFacet.class).orElse(null); if(actionPositionFacet != null && actionPositionFacet.position() == ActionLayout.Position.PANEL) { actionLayoutData.setPosition(ActionLayout.Position.PANEL); } else {
