This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 3973-backport.layout.switch
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/3973-backport.layout.switch by
this push:
new 1900ca6db45 CAUSEWAY-3973: [v2] support for layout variant export in
Object_downloadLayout
1900ca6db45 is described below
commit 1900ca6db458a4a39d1bd863c98d3e1f5c20665e
Author: andi-huber <[email protected]>
AuthorDate: Fri Mar 6 08:24:19 2026 +0100
CAUSEWAY-3973: [v2] support for layout variant export in
Object_downloadLayout
---
.../mixins/layout/Object_downloadLayout.java | 23 ++++++----
.../causeway/applib/services/grid/GridService.java | 9 ++--
.../applib/services/layout/LayoutService.java | 12 +++++-
.../services/layout/LayoutServiceDefault.java | 50 ++++++++++++++--------
.../metamodel/services/grid/GridLoadingTest.java | 6 +--
5 files changed, 66 insertions(+), 34 deletions(-)
diff --git
a/api/applib/src/main/java/org/apache/causeway/applib/mixins/layout/Object_downloadLayout.java
b/api/applib/src/main/java/org/apache/causeway/applib/mixins/layout/Object_downloadLayout.java
index 6350671c4e4..54378e843a0 100644
---
a/api/applib/src/main/java/org/apache/causeway/applib/mixins/layout/Object_downloadLayout.java
+++
b/api/applib/src/main/java/org/apache/causeway/applib/mixins/layout/Object_downloadLayout.java
@@ -37,7 +37,6 @@
import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType;
import lombok.RequiredArgsConstructor;
-import lombok.val;
/**
* Provides the ability to download the serialized layout (eg. XML) for any
domain
@@ -65,7 +64,9 @@ public class Object_downloadLayout {
public static class ActionDomainEvent
extends
org.apache.causeway.applib.CausewayModuleApplib.ActionDomainEvent<Object_downloadLayout>
{}
- private final Object holder;
+ @Inject LayoutService layoutService;
+
+ private final Object mixee;
@MemberSupport public Object act(
@ParameterLayout(
@@ -75,15 +76,19 @@ public static class ActionDomainEvent
final LayoutExportStyle style,
final CommonMimeType format) {
- val xmlString = layoutService.objectLayout(holder.getClass(), style,
format);
- return Clob.of(fileName, format, xmlString);
+ var layoutKey = layoutService.layoutKey(mixee).orElseThrow();
+ var xmlString = layoutService.objectLayout(layoutKey, style, format);
+ var infix= layoutKey.isVariant()
+ ? "-" + layoutKey.layoutIfAny()
+ : "";
+ return Clob.of(fileName + infix + ".layout", format, xmlString);
}
/**
* Defaults to the (simple) name of the domain object's class, with a
<code>.layout</code> suffix
*/
@MemberSupport public String default0Act() {
- return holder.getClass().getSimpleName() + ".layout";
+ return mixee.getClass().getSimpleName();
}
/**
* Default style is {@link LayoutExportStyle#MINIMAL}.
@@ -93,10 +98,10 @@ public static class ActionDomainEvent
}
@MemberSupport public CommonMimeType default2Act() {
- return layoutService.supportedObjectLayoutFormats().iterator().next();
}
+ return layoutService.supportedObjectLayoutFormats().iterator().next();
+ }
@MemberSupport public Set<CommonMimeType> choices2Act() {
- return layoutService.supportedObjectLayoutFormats(); }
-
- @Inject LayoutService layoutService;
+ return layoutService.supportedObjectLayoutFormats();
+ }
}
diff --git
a/api/applib/src/main/java/org/apache/causeway/applib/services/grid/GridService.java
b/api/applib/src/main/java/org/apache/causeway/applib/services/grid/GridService.java
index eac3e5b6d8c..836f132bf77 100644
---
a/api/applib/src/main/java/org/apache/causeway/applib/services/grid/GridService.java
+++
b/api/applib/src/main/java/org/apache/causeway/applib/services/grid/GridService.java
@@ -196,13 +196,16 @@ public LayoutKey(final Class<?> domainClass) {
GridMarshallerService<? extends Grid> marshaller();
default Grid toGridForExport(
- final Class<?> domainClass,
+ final LayoutKey layoutKey,
final LayoutExportStyle style) {
// don't use the grid from the facet, because it will be modified
subsequently.
- Grid grid = load(domainClass);
+ Grid grid = load(layoutKey.domainClass);
if(grid == null) {
- grid = defaultGridFor(domainClass);
+ grid = defaultGridFor(layoutKey.domainClass);
+ grid.layoutKey(new LayoutKey(layoutKey.domainClass, null));
+ } else {
+ grid.layoutKey(layoutKey);
}
grid = normalize(grid); // required so the grid's tns and
schema-locations get populated
if (style == LayoutExportStyle.COMPLETE) {
diff --git
a/api/applib/src/main/java/org/apache/causeway/applib/services/layout/LayoutService.java
b/api/applib/src/main/java/org/apache/causeway/applib/services/layout/LayoutService.java
index 2266a75f092..14f371e52d4 100644
---
a/api/applib/src/main/java/org/apache/causeway/applib/services/layout/LayoutService.java
+++
b/api/applib/src/main/java/org/apache/causeway/applib/services/layout/LayoutService.java
@@ -19,20 +19,28 @@
package org.apache.causeway.applib.services.layout;
import java.util.EnumSet;
+import java.util.Optional;
+import org.apache.causeway.applib.services.grid.GridService.LayoutKey;
import org.apache.causeway.applib.services.menu.MenuBarsService;
import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType;
+import org.springframework.lang.Nullable;
/**
* Provides the ability to obtain the serialized layout (eg. XML) for a single
domain object or
* for all domain objects, as well as the serialized layout for the
application's menu-bars.
*
- * @since 1.x - revised for 2.0 {@index}
+ * @since 1.x - revised for 2.0 and 4.0 {@index}
*/
public interface LayoutService {
// -- OBJECT LAYOUT
+ /**
+ * @since 4.0
+ */
+ Optional<LayoutKey> layoutKey(@Nullable Object domainObject);
+
/**
* Supported format(s) for {@link #objectLayout(Class, LayoutExportStyle,
CommonMimeType)}
* and {@link #toZip(LayoutExportStyle, CommonMimeType)}.
@@ -43,7 +51,7 @@ public interface LayoutService {
* Obtains the serialized form of the object layout (grid) for the
specified domain class.
* @throws UnsupportedOperationException when format is not supported
*/
- String objectLayout(Class<?> domainClass, LayoutExportStyle style,
CommonMimeType format);
+ String objectLayout(LayoutKey layoutKey, LayoutExportStyle style,
CommonMimeType format);
/**
* Obtains a zip file of the serialized layouts (grids) of all domain
entities and view models.
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/layout/LayoutServiceDefault.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/layout/LayoutServiceDefault.java
index 0e3af14b426..aa70c7d8eb5 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/layout/LayoutServiceDefault.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/layout/LayoutServiceDefault.java
@@ -20,18 +20,16 @@
import java.io.File;
import java.util.EnumSet;
+import java.util.Optional;
import javax.annotation.Priority;
import javax.inject.Inject;
import javax.inject.Named;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.lang.Nullable;
-import org.springframework.stereotype.Service;
-
import org.apache.causeway.applib.annotation.PriorityPrecedence;
import org.apache.causeway.applib.layout.grid.Grid;
import org.apache.causeway.applib.services.grid.GridService;
+import org.apache.causeway.applib.services.grid.GridService.LayoutKey;
import org.apache.causeway.applib.services.layout.LayoutExportStyle;
import org.apache.causeway.applib.services.layout.LayoutService;
import org.apache.causeway.applib.services.menu.MenuBarsService;
@@ -40,11 +38,16 @@
import org.apache.causeway.commons.internal.base._Casts;
import org.apache.causeway.commons.io.ZipUtils;
import org.apache.causeway.core.metamodel.CausewayModuleCoreMetamodel;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
+import org.apache.causeway.core.metamodel.facets.object.layout.LayoutFacet;
+import org.apache.causeway.core.metamodel.object.ManagedObjects;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
-import lombok.val;
import lombok.extern.log4j.Log4j2;
/**
@@ -60,7 +63,7 @@
@Log4j2
public class LayoutServiceDefault implements LayoutService {
- private final SpecificationLoader specificationLoader;
+ private final SpecificationLoader specLoader;
private final GridService gridService;
private final MenuBarsService menuBarsService;
@@ -75,20 +78,33 @@ public EnumSet<CommonMimeType>
supportedMenuBarsLayoutFormats() {
public String menuBarsLayout(
final MenuBarsService.Type type,
final CommonMimeType format) {
- val menuBars = menuBarsService.menuBars(type);
+ var menuBars = menuBarsService.menuBars(type);
return
menuBarsService.marshaller().marshal(_Casts.uncheckedCast(menuBars), format);
}
// -- OBJECT LAYOUT
+ @Override
+ public Optional<LayoutKey> layoutKey(final @Nullable Object domainObject) {
+ var mo = MetaModelContext.instanceElseFail()
+ .getObjectManager()
+ .adapt(domainObject);
+ if(ManagedObjects.isNullOrUnspecifiedOrEmpty(mo))
+ return Optional.empty();
+ var layoutPrefix = mo.objSpec().lookupFacet(LayoutFacet.class)
+ .map(layoutPrefixFacet->layoutPrefixFacet.layout(mo))
+ .orElse(null);
+ return Optional.of(new LayoutKey(domainObject.getClass(),
layoutPrefix));
+ }
+
@Override
public EnumSet<CommonMimeType> supportedObjectLayoutFormats() {
return gridService.marshaller().supportedFormats();
}
@Override
- public String objectLayout(final Class<?> domainClass, final
LayoutExportStyle style, final CommonMimeType format) {
- return tryGridToFormatted(domainClass, style, format)
+ public String objectLayout(final LayoutKey layoutKey, final
LayoutExportStyle style, final CommonMimeType format) {
+ return tryGridToFormatted(layoutKey, style, format)
.ifFailureFail()
.getValue()
.orElse(null);
@@ -96,18 +112,18 @@ public String objectLayout(final Class<?> domainClass,
final LayoutExportStyle s
@Override
public byte[] toZip(final LayoutExportStyle style, final CommonMimeType
format) {
- val domainObjectSpecs = specificationLoader.snapshotSpecifications()
+ var domainObjectSpecs = specLoader.snapshotSpecifications()
.filter(spec ->
!spec.isAbstract()
&& (spec.isEntity() || spec.isViewModel()));
- val zipBuilder = ZipUtils.zipEntryBuilder();
+ var zipBuilder = ZipUtils.zipEntryBuilder();
- for (val objectSpec : domainObjectSpecs) {
- val domainClass = objectSpec.getCorrespondingClass();
+ for (var objectSpec : domainObjectSpecs) {
+ var domainClass = objectSpec.getCorrespondingClass();
- tryGridToFormatted(domainClass, style, format)
- .accept(
+ tryGridToFormatted(new LayoutKey(domainClass), style, format)
+ .accept(
failure->
log.warn("failed to generate layout file for {}",
domainClass),
contentIfAny->{
@@ -122,11 +138,11 @@ public byte[] toZip(final LayoutExportStyle style, final
CommonMimeType format)
// -- HELPER
private Try<String> tryGridToFormatted(
- final Class<?> domainClass,
+ final LayoutKey layoutKey,
final LayoutExportStyle style,
final CommonMimeType format) {
return Try.call(()->
- gridToFormatted(gridService.toGridForExport(domainClass, style),
format));
+ gridToFormatted(gridService.toGridForExport(layoutKey, style),
format));
}
private String gridToFormatted(final @Nullable Grid grid, final
CommonMimeType format) {
diff --git
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/grid/GridLoadingTest.java
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/grid/GridLoadingTest.java
index 1795e230be6..4431ccdf97a 100644
---
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/grid/GridLoadingTest.java
+++
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/grid/GridLoadingTest.java
@@ -54,10 +54,10 @@ protected void afterSetUp() {
// test blueprint, for future work
void blueprint() {
- val domainClassAndLayout = new LayoutKey(Bar.class, null);
- gridLoaderService.loadLayoutResource(domainClassAndLayout,
EnumSet.of(CommonMimeType.XML));
+ val layoutKey = new LayoutKey(Bar.class, null);
+ gridLoaderService.loadLayoutResource(layoutKey,
EnumSet.of(CommonMimeType.XML));
- val xml = layoutService.objectLayout(Bar.class,
LayoutExportStyle.MINIMAL, CommonMimeType.XML);
+ val xml = layoutService.objectLayout(layoutKey,
LayoutExportStyle.MINIMAL, CommonMimeType.XML);
System.out.println(xml);
}