You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/10/19 07:19:38 UTC

[causeway] branch spring6 updated (4d39697614 -> 4f545c1b80)

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a change to branch spring6
in repository https://gitbox.apache.org/repos/asf/causeway.git


    from 4d39697614 Merge pull request #1960 from apache/dependabot/maven/spring6/com.google.errorprone-error_prone_annotations-2.23.0
     add 083474e470 CAUSEWAY-3636: initial scaffolding
     add 8e43f85155 CAUSEWAY-3636: wip some more
     add 3914a5eb58 CAUSEWAY-3636: completes implementation
     add 158a58ef0f CAUSEWAY-3636: fixes unit test
     add 5c9fb42385 CAUSEWAY-3636: fixes integ test
     add 29489c5aa0 CAUSEWAY-3636: fixes compilation issue
     add 7871734036 CAUSEWAY-3636: fixes test
     add 7860965cb6 CAUSEWAY-3636: updates docs
     add c6ecbdabc7 Merge pull request #1958 from apache/CAUSEWAY-3636
     add 0d13f46017 CAUSEWAY-3636: refactors LayoutResourceLoader#tryLoadLayoutResource to return a Try
     add 38da5621f2 Bump com.google.errorprone:error_prone_annotations from 2.22.0 to 2.23.0
     add 02587740a7 Merge pull request #1959 from apache/dependabot/maven/master/com.google.errorprone-error_prone_annotations-2.23.0
     new 4f545c1b80 Merge remote-tracking branch 'origin/master' into spring6

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 antora/playbooks/site-extensions.yml               |   4 +
 antora/playbooks/site.ALL.yml                      |   3 +
 antora/playbooks/site.NEXT.yml                     |   3 +
 antora/playbooks/site.yml                          |   3 +
 bom/pom.xml                                        |  18 ++-
 .../core/config/CausewayConfiguration.java         |  18 ++-
 core/metamodel/src/main/java/module-info.java      |   1 +
 .../metamodel/CausewayModuleCoreMetamodel.java     |   3 +
 .../_testing/MetaModelContext_forTesting.java      |   4 +-
 .../services/grid/GridLoaderServiceDefault.java    |  66 +++++-----
 .../services/grid/spi/LayoutResource.java          |  13 ++
 .../services/grid/spi/LayoutResourceLoader.java    |  42 ++++++
 .../grid/spi/LayoutResourceLoaderDefault.java      |  47 +++++++
 .../GridLoaderServiceDefault_resourceNameTest.java |   7 +-
 .../{commandlog => layoutgithub}/adoc/antora.yml   |   0
 .../adoc/modules/layoutgithub}/nav.adoc            |   0
 .../adoc/modules/layoutgithub}/pages/about.adoc    |  33 ++---
 .../modules/layoutgithub/partials/module-nav.adoc  |   4 +
 .../{docgen/help => layoutgithub/loader}/pom.xml   |  28 +++-
 .../CausewayModuleExtLayoutGithubLoader.java       | 131 +++++++++++++++++++
 .../layoutgithub/loader/menu/LayoutLoaderMenu.java | 122 ++++++++++++++++++
 .../layoutgithub/loader/spi/GitHubItem.java        |   5 +-
 .../layoutgithub/loader/spi/GitHubResponse.java    |  12 +-
 .../loader/spi/LayoutResourceLoaderFromGithub.java | 142 +++++++++++++++++++++
 ...oaderFromGithub_tryLoadLayoutResource_Test.java |  77 +++++++++++
 .../extensions/layoutgithub/loader/spi/.gitignore  |   1 +
 extensions/core/{docgen => layoutgithub}/pom.xml   |   8 +-
 extensions/pom.xml                                 |   1 +
 ...CausewayExtLayoutGithubRoleAndPermissions.java} |  10 +-
 ...ewayExtSecmanRegularUserRoleAndPermissions.java |   5 +
 .../scripts/SeedUsersAndRolesFixtureScript.java    |   3 +
 31 files changed, 739 insertions(+), 75 deletions(-)
 create mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResource.java
 create mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoader.java
 create mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoaderDefault.java
 copy extensions/core/{commandlog => layoutgithub}/adoc/antora.yml (100%)
 copy {antora/components/userguide/modules/btb => extensions/core/layoutgithub/adoc/modules/layoutgithub}/nav.adoc (100%)
 copy extensions/core/{docgen/adoc/modules/docgen => layoutgithub/adoc/modules/layoutgithub}/pages/about.adoc (64%)
 create mode 100644 extensions/core/layoutgithub/adoc/modules/layoutgithub/partials/module-nav.adoc
 copy extensions/core/{docgen/help => layoutgithub/loader}/pom.xml (68%)
 create mode 100644 extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/CausewayModuleExtLayoutGithubLoader.java
 create mode 100644 extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/menu/LayoutLoaderMenu.java
 copy testing/unittestsupport/applib/src/test/java/org/apache/causeway/testing/unittestsupport/applib/dom/pojo/holders/ExampleBean.java => extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/spi/GitHubItem.java (88%)
 copy testing/unittestsupport/applib/src/test/java/org/apache/causeway/testing/unittestsupport/applib/dom/pojo/holders/ExampleBean.java => extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/spi/GitHubResponse.java (77%)
 create mode 100644 extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/spi/LayoutResourceLoaderFromGithub.java
 create mode 100644 extensions/core/layoutgithub/loader/src/test/java/org/apache/causeway/extensions/layoutgithub/loader/spi/LayoutResourceLoaderFromGithub_tryLoadLayoutResource_Test.java
 create mode 100644 extensions/core/layoutgithub/loader/src/test/resources/org/apache/causeway/extensions/layoutgithub/loader/spi/.gitignore
 copy extensions/core/{docgen => layoutgithub}/pom.xml (85%)
 copy extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/role/seed/{CausewayExtDocgenRoleAndPermissions.java => CausewayExtLayoutGithubRoleAndPermissions.java} (84%)


[causeway] 01/01: Merge remote-tracking branch 'origin/master' into spring6

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch spring6
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 4f545c1b803fb72119fb975c2d6b8d19985ee5e1
Merge: 4d39697614 02587740a7
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Oct 19 09:19:33 2023 +0200

    Merge remote-tracking branch 'origin/master' into spring6

 antora/playbooks/site-extensions.yml               |   4 +
 antora/playbooks/site.ALL.yml                      |   3 +
 antora/playbooks/site.NEXT.yml                     |   3 +
 antora/playbooks/site.yml                          |   3 +
 bom/pom.xml                                        |  18 ++-
 .../core/config/CausewayConfiguration.java         |  18 ++-
 core/metamodel/src/main/java/module-info.java      |   1 +
 .../metamodel/CausewayModuleCoreMetamodel.java     |   3 +
 .../_testing/MetaModelContext_forTesting.java      |   4 +-
 .../services/grid/GridLoaderServiceDefault.java    |  66 +++++-----
 .../services/grid/spi/LayoutResource.java          |  13 ++
 .../services/grid/spi/LayoutResourceLoader.java    |  42 ++++++
 .../grid/spi/LayoutResourceLoaderDefault.java      |  47 +++++++
 .../GridLoaderServiceDefault_resourceNameTest.java |   7 +-
 extensions/core/layoutgithub/adoc/antora.yml       |  19 +++
 .../adoc/modules/layoutgithub/nav.adoc             |   4 +
 .../adoc/modules/layoutgithub/pages/about.adoc     | 100 +++++++++++++++
 .../modules/layoutgithub/partials/module-nav.adoc  |   4 +
 extensions/core/layoutgithub/loader/pom.xml        |  72 +++++++++++
 .../CausewayModuleExtLayoutGithubLoader.java       | 131 +++++++++++++++++++
 .../layoutgithub/loader/menu/LayoutLoaderMenu.java | 122 ++++++++++++++++++
 .../layoutgithub/loader/spi/GitHubItem.java        |  27 ++++
 .../layoutgithub/loader/spi/GitHubResponse.java    |  32 +++++
 .../loader/spi/LayoutResourceLoaderFromGithub.java | 142 +++++++++++++++++++++
 ...oaderFromGithub_tryLoadLayoutResource_Test.java |  77 +++++++++++
 .../extensions/layoutgithub/loader/spi/.gitignore  |   1 +
 extensions/core/layoutgithub/pom.xml               |  45 +++++++
 extensions/pom.xml                                 |   1 +
 .../CausewayExtLayoutGithubRoleAndPermissions.java |  51 ++++++++
 ...ewayExtSecmanRegularUserRoleAndPermissions.java |   5 +
 .../scripts/SeedUsersAndRolesFixtureScript.java    |   3 +
 31 files changed, 1029 insertions(+), 39 deletions(-)

diff --cc bom/pom.xml
index 38b501a684,f74f45d911..cf01a0dcda
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@@ -930,7 -934,23 +930,23 @@@ It is therefore a copy of org.apache:ap
  				<scope>compile</scope>
  			</dependency>
  
- 			<!-- org.apache.causeway.extensions (audittrail) -->
+             <!-- org.apache.causeway.extensions (layoutgithub) -->
+             <dependency>
+                 <groupId>org.apache.causeway.extensions</groupId>
+                 <artifactId>causeway-extensions-layoutgithub</artifactId>
 -                <version>2.0.0-SNAPSHOT</version>
++                <version>3.0.0-SNAPSHOT</version>
+                 <type>pom</type>
+                 <scope>compile</scope>
+             </dependency>
+             <dependency>
+                 <groupId>org.apache.causeway.extensions</groupId>
+                 <artifactId>causeway-extensions-layoutgithub-loader</artifactId>
 -                <version>2.0.0-SNAPSHOT</version>
++                <version>3.0.0-SNAPSHOT</version>
+                 <type>jar</type>
+                 <scope>compile</scope>
+             </dependency>
+ 
+             <!-- org.apache.causeway.extensions (audittrail) -->
  			<dependency>
  				<groupId>org.apache.causeway.extensions</groupId>
  				<artifactId>causeway-extensions-audittrail</artifactId>
diff --cc core/metamodel/src/main/java/module-info.java
index 3c4521f302,a58867dcdf..068fff71d4
--- a/core/metamodel/src/main/java/module-info.java
+++ b/core/metamodel/src/main/java/module-info.java
@@@ -141,15 -141,16 +141,16 @@@ open module org.apache.causeway.core.me
  
      exports org.apache.causeway.core.metamodel.valuetypes;
      exports org.apache.causeway.core.metamodel.facets.object.tabledec to org.apache.causeway.viewer.wicket.ui;
+     exports org.apache.causeway.core.metamodel.services.grid.spi;
  
      requires jakarta.activation;
 -    requires java.annotation;
 +    requires jakarta.annotation;
      requires java.desktop;
      requires java.sql;
 -    requires java.validation;
 +    requires jakarta.validation;
      requires java.xml;
 -    requires java.xml.bind;
 -    requires java.inject;
 +    requires jakarta.xml.bind;
 +    requires jakarta.inject;
      requires lombok;
      requires transitive org.apache.causeway.applib;
      requires transitive org.apache.causeway.commons;
diff --cc core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoaderDefault.java
index 0000000000,839db05dea..ef103a014d
mode 000000,100644..100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/spi/LayoutResourceLoaderDefault.java
@@@ -1,0 -1,47 +1,47 @@@
+ package org.apache.causeway.core.metamodel.services.grid.spi;
+ 
+ 
 -import javax.annotation.Priority;
 -import javax.inject.Named;
++import jakarta.annotation.Priority;
++import jakarta.inject.Named;
+ 
+ import org.springframework.beans.factory.annotation.Qualifier;
+ import org.springframework.stereotype.Service;
+ 
+ import org.apache.causeway.applib.annotation.PriorityPrecedence;
+ import org.apache.causeway.applib.value.NamedWithMimeType;
+ import org.apache.causeway.commons.functional.Try;
+ import org.apache.causeway.commons.io.DataSource;
+ import org.apache.causeway.core.metamodel.CausewayModuleCoreMetamodel;
+ import org.apache.causeway.core.metamodel.services.grid.GridLoaderServiceDefault;
+ 
+ import lombok.NonNull;
+ import lombok.RequiredArgsConstructor;
+ 
+ /**
+  * A simpler SPI for {@link GridLoaderServiceDefault}.
+  */
+ @Service
+ @Named(CausewayModuleCoreMetamodel.NAMESPACE + ".LayoutResourceLoaderDefault")
+ @Priority(PriorityPrecedence.MIDPOINT)
+ @Qualifier("Default")
+ @RequiredArgsConstructor //JUnit Support
+ //@Log4j2
+ public class LayoutResourceLoaderDefault implements LayoutResourceLoader {
+ 
+     @Override
+     public Try<LayoutResource> tryLoadLayoutResource(
+             final @NonNull Class<?> type,
+             final @NonNull String candidateResourceName) {
+ 
+         return DataSource.ofResource(type, candidateResourceName)
+             .tryReadAsStringUtf8()
+             .mapSuccess(fileContent->fileContent
+                 .map(layoutSource->
+                     new LayoutResource(
+                             candidateResourceName,
+                             NamedWithMimeType.CommonMimeType.valueOfFileName(candidateResourceName).orElseThrow(),
+                             layoutSource))
+                 .orElse(null));
+     }
+ 
+ }
diff --cc extensions/core/layoutgithub/loader/pom.xml
index 0000000000,56c9f75b48..77e9c4b2cb
mode 000000,100644..100644
--- a/extensions/core/layoutgithub/loader/pom.xml
+++ b/extensions/core/layoutgithub/loader/pom.xml
@@@ -1,0 -1,72 +1,72 @@@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!--
+   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.
+ -->
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+     <modelVersion>4.0.0</modelVersion>
+ 
+     <parent>
+         <groupId>org.apache.causeway.extensions</groupId>
+         <artifactId>causeway-extensions-layoutgithub</artifactId>
 -        <version>2.0.0-SNAPSHOT</version>
++        <version>3.0.0-SNAPSHOT</version>
+     </parent>
+ 
+ 
+     <artifactId>causeway-extensions-layoutgithub-loader</artifactId>
+     <name>Apache Causeway Ext - LayoutGitHub Loader</name>
+ 
+     <description>
+         Allows layout.xml files to be dynamically loaded from a github repo.
+     </description>
+ 
+     <properties>
+         <jar-plugin.automaticModuleName>org.apache.causeway.extensions.layoutgithub.loader</jar-plugin.automaticModuleName>
+         <git-plugin.propertiesDir>org/apache/causeway/extensions/layoutgithub/loader</git-plugin.propertiesDir>
+     </properties>
+ 
+     <dependencies>
+ 		<dependency>
+ 			<groupId>org.apache.causeway.core</groupId>
+ 			<artifactId>causeway-core-metamodel</artifactId>
+ 		</dependency>
+         <dependency>
+ 			<groupId>org.apache.causeway.valuetypes</groupId>
+ 			<artifactId>causeway-valuetypes-asciidoc-applib</artifactId>
+ 		</dependency>
+ 		<dependency>
+ 			<groupId>org.apache.causeway.valuetypes</groupId>
+ 			<artifactId>causeway-valuetypes-asciidoc-builder</artifactId>
+ 		</dependency>
+         <dependency>
+             <groupId>org.springframework</groupId>
+             <artifactId>spring-web</artifactId>
+         </dependency>
+ 
+         <dependency>
+             <groupId>org.junit.jupiter</groupId>
+             <artifactId>junit-jupiter</artifactId>
+             <scope>test</scope>
+         </dependency>
+         <dependency>
+             <groupId>org.assertj</groupId>
+             <artifactId>assertj-core</artifactId>
+             <scope>test</scope>
+         </dependency>
+     </dependencies>
+ 
+ </project>
diff --cc extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/menu/LayoutLoaderMenu.java
index 0000000000,940cb838c9..4f36bdd084
mode 000000,100644..100644
--- a/extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/menu/LayoutLoaderMenu.java
+++ b/extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/menu/LayoutLoaderMenu.java
@@@ -1,0 -1,122 +1,122 @@@
+ /*
+  *  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.causeway.extensions.layoutgithub.loader.menu;
+ 
 -import javax.inject.Inject;
 -import javax.inject.Named;
++import jakarta.inject.Inject;
++import jakarta.inject.Named;
+ 
+ import org.apache.causeway.applib.CausewayModuleApplib;
+ import org.apache.causeway.applib.annotation.Action;
+ import org.apache.causeway.applib.annotation.ActionLayout;
+ import org.apache.causeway.applib.annotation.DomainService;
+ import org.apache.causeway.applib.annotation.DomainServiceLayout;
+ import org.apache.causeway.applib.annotation.MemberSupport;
+ import org.apache.causeway.applib.annotation.NatureOfService;
+ import org.apache.causeway.applib.annotation.PriorityPrecedence;
+ import org.apache.causeway.applib.annotation.Publishing;
+ import org.apache.causeway.applib.annotation.SemanticsOf;
+ import org.apache.causeway.core.config.CausewayConfiguration;
+ import org.apache.causeway.extensions.layoutgithub.loader.CausewayModuleExtLayoutGithubLoader;
+ 
+ import lombok.Getter;
+ import lombok.RequiredArgsConstructor;
+ import lombok.val;
+ 
+ /**
+  * Provides actions to managed the dynamic loading of layouts from a github source code repository.
+  * <p>
+  *
+  * @since 2.x {@index}
+  */
+ @Named(CausewayModuleExtLayoutGithubLoader.NAMESPACE + ".LayoutLoaderMenu")
+ @DomainService(nature = NatureOfService.VIEW)
+ @DomainServiceLayout(
+         menuBar = DomainServiceLayout.MenuBar.TERTIARY
+ )
 -@javax.annotation.Priority(PriorityPrecedence.EARLY)
++@jakarta.annotation.Priority(PriorityPrecedence.EARLY)
+ @RequiredArgsConstructor(onConstructor_ = {@Inject})
+ public class LayoutLoaderMenu {
+ 
+     public static abstract class ActionDomainEvent<T> extends CausewayModuleApplib.ActionDomainEvent<T> {}
+ 
+     final CausewayConfiguration causewayConfiguration;
+ 
+     @Getter
+     private boolean enabled;
+ 
+ 
+     @Action(
+             commandPublishing = Publishing.DISABLED,
+             domainEvent = enableDynamicLayoutLoading.ActionDomainEvent.class,
+             executionPublishing = Publishing.DISABLED,
+             semantics = SemanticsOf.IDEMPOTENT
+     )
+     @ActionLayout(
+             cssClassFa = "fa-solid fa-toggle-on",
+             sequence = "100"
+     )
+     public class enableDynamicLayoutLoading {
+ 
+         public class ActionDomainEvent extends LayoutLoaderMenu.ActionDomainEvent<enableDynamicLayoutLoading> {}
+ 
+         @MemberSupport public void act() {
+             LayoutLoaderMenu.this.enabled = true;
+         }
+         @MemberSupport public boolean hideAct() {
+             return !isConfigured();
+         }
+         @MemberSupport public String disableAct() {
+             return LayoutLoaderMenu.this.enabled ? "Already enabled" : null;
+         }
+ 
+     }
+ 
+ 
+     @Action(
+             commandPublishing = Publishing.DISABLED,
+             domainEvent = enableDynamicLayoutLoading.ActionDomainEvent.class,
+             executionPublishing = Publishing.DISABLED,
+             semantics = SemanticsOf.IDEMPOTENT
+     )
+     @ActionLayout(
+             cssClassFa = "fa-solid fa-toggle-off",
+             sequence = "100"
+     )
+     public class disableDynamicLayoutLoading {
+ 
+         public class ActionDomainEvent extends LayoutLoaderMenu.ActionDomainEvent<enableDynamicLayoutLoading> {}
+ 
+         @MemberSupport public void act() {
+             LayoutLoaderMenu.this.enabled = false;
+         }
+         @MemberSupport public boolean hideAct() {
+             return !isConfigured();
+         }
+         @MemberSupport public String disableAct() {
+             return LayoutLoaderMenu.this.enabled ? null : "Already disabled";
+         }
+     }
+ 
+     boolean isConfigured() {
+         val layoutGithub = causewayConfiguration.getExtensions().getLayoutGithub();
+         return layoutGithub.getRepository() != null &&
+                layoutGithub.getApiKey() != null;
+     }
+ 
+ }
diff --cc extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/spi/LayoutResourceLoaderFromGithub.java
index 0000000000,cc6adbea1b..05a723ce01
mode 000000,100644..100644
--- a/extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/spi/LayoutResourceLoaderFromGithub.java
+++ b/extensions/core/layoutgithub/loader/src/main/java/org/apache/causeway/extensions/layoutgithub/loader/spi/LayoutResourceLoaderFromGithub.java
@@@ -1,0 -1,142 +1,142 @@@
+ /*
+  *  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.causeway.extensions.layoutgithub.loader.spi;
+ 
+ import java.util.HashMap;
+ 
 -import javax.annotation.Priority;
 -import javax.inject.Inject;
 -import javax.inject.Named;
++import jakarta.annotation.Priority;
++import jakarta.inject.Inject;
++import jakarta.inject.Named;
+ 
+ import org.springframework.beans.factory.annotation.Qualifier;
+ import org.springframework.core.ParameterizedTypeReference;
+ import org.springframework.http.HttpMethod;
+ import org.springframework.lang.Nullable;
+ import org.springframework.stereotype.Service;
+ import org.springframework.util.StringUtils;
+ import org.springframework.web.client.RestTemplate;
+ 
+ import org.apache.causeway.applib.annotation.PriorityPrecedence;
+ import org.apache.causeway.applib.services.queryresultscache.QueryResultsCache;
+ import org.apache.causeway.applib.value.NamedWithMimeType;
+ import org.apache.causeway.commons.functional.Try;
+ import org.apache.causeway.core.config.CausewayConfiguration;
+ import org.apache.causeway.core.metamodel.services.grid.spi.LayoutResource;
+ import org.apache.causeway.core.metamodel.services.grid.spi.LayoutResourceLoader;
+ import org.apache.causeway.extensions.layoutgithub.loader.CausewayModuleExtLayoutGithubLoader;
+ import org.apache.causeway.extensions.layoutgithub.loader.menu.LayoutLoaderMenu;
+ 
+ import lombok.NonNull;
+ import lombok.val;
+ 
+ @Service
+ @Named(CausewayModuleExtLayoutGithubLoader.NAMESPACE + ".LayoutResourceLoaderFromGithub")
+ @Priority(PriorityPrecedence.MIDPOINT - 100)
+ @Qualifier("Github")
+ //@Log4j2
+ public class LayoutResourceLoaderFromGithub implements LayoutResourceLoader {
+ 
+     final RestTemplate restTemplateForSearch;
+     final RestTemplate restTemplateForContent;
+     final CausewayConfiguration causewayConfiguration;
+     final LayoutLoaderMenu layoutLoaderMenu;
+     final QueryResultsCache queryResultsCache;
+ 
+     @Inject
+     public LayoutResourceLoaderFromGithub(
+             final @Qualifier("GithubSearch")  RestTemplate restTemplateForSearch,
+             final @Qualifier("GithubContent") RestTemplate restTemplateForContent,
+             final CausewayConfiguration causewayConfiguration,
+             final LayoutLoaderMenu layoutLoaderMenu,
+             final QueryResultsCache queryResultsCache) {
+         this.restTemplateForSearch = restTemplateForSearch;
+         this.restTemplateForContent = restTemplateForContent;
+         this.causewayConfiguration = causewayConfiguration;
+         this.layoutLoaderMenu = layoutLoaderMenu;
+         this.queryResultsCache = queryResultsCache;
+     }
+ 
+     @Override
+     public Try<LayoutResource> tryLoadLayoutResource(
+             final @NonNull Class<?> type,
+             final @NonNull String candidateResourceName) {
+         return layoutLoaderMenu.isEnabled()
+                 ? queryResultsCache.execute(() -> tryLoadLayoutResource(candidateResourceName),
+                         getClass(), "tryLoadLayoutResource", candidateResourceName)
+                 : Try.empty();
+     }
+ 
+     private Try<LayoutResource> tryLoadLayoutResource(final String candidateResourceName) {
+         var path = search(candidateResourceName);
+         return path.isFailure()
+             // preserve any issues that occurred when searching for the path
+             ? Try.failure(path.getFailure().get())
+             : content(candidateResourceName, path.getValue().orElse(null));
+     }
+ 
+     /**
+      * eg:
+      * <code>/search/code?q=SimpleObject.layout.xml+in:path+repo:apache/causeway-app-simpleapp</code>
+      */
+     private Try<String> search(final @NonNull String candidateResourceName) {
+ 
+         try {
+             val repo = causewayConfiguration.getExtensions().getLayoutGithub().getRepository();
+             val searchParams = new HashMap<String, String>();
+             searchParams.put("q", String.format("%s+in:path+repo:%s", candidateResourceName, repo));
+ 
+             val responseEntity = restTemplateForSearch
+                     .exchange("/search/code?q={q}", HttpMethod.GET, null,
+                             new ParameterizedTypeReference<GitHubResponse>() {}, searchParams);
+ 
+             GitHubResponse searchResponse = responseEntity.getBody();
+             if (searchResponse.getTotal_count() != 1) {
+                 return Try.empty();
+             }
+             return Try.success(searchResponse.getItems().get(0).getPath());
+         } catch (Exception ex) {
+             return Try.failure(ex);
+         }
+     }
+ 
+     /**
+      * eg:
+      * <code>/contents/module-simple/src/main/java/domainapp/modules/simple/dom/so/SimpleObject.layout.xml</code>
+      */
+     private Try<LayoutResource> content(
+             final @NonNull String candidateResourceName,
+             final @Nullable String path) {
+ 
+         if(path==null) return Try.empty();
+ 
+         try {
+             val contentResponse = restTemplateForContent.exchange("/contents/" + path, HttpMethod.GET, null, String.class);
+             val content = contentResponse.getBody();
+ 
+             return StringUtils.hasLength(content)
+                     ? Try.call(()->new LayoutResource(candidateResourceName, NamedWithMimeType.CommonMimeType.XML, content))
+                     : Try.empty();
+ 
+         } catch (Exception ex) {
+             return Try.failure(ex);
+         }
+     }
+ 
+ }
+ 
diff --cc extensions/core/layoutgithub/pom.xml
index 0000000000,f9f9279209..ff18c017d3
mode 000000,100644..100644
--- a/extensions/core/layoutgithub/pom.xml
+++ b/extensions/core/layoutgithub/pom.xml
@@@ -1,0 -1,45 +1,45 @@@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!--
+   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.
+ -->
+ <project xmlns="http://maven.apache.org/POM/4.0.0"
+ 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ 	<modelVersion>4.0.0</modelVersion>
+ 
+     <parent>
+         <groupId>org.apache.causeway.extensions</groupId>
+         <artifactId>causeway-extensions</artifactId>
 -        <version>2.0.0-SNAPSHOT</version>
++        <version>3.0.0-SNAPSHOT</version>
+         <relativePath>../../pom.xml</relativePath>
+     </parent>
+ 
+     <artifactId>causeway-extensions-layoutgithub</artifactId>
+     <name>Apache Causeway Ext - LayoutGitHub</name>
+ 
+     <description>
+         Allows layouts to be dynamically loaded from a github repo.
+     </description>
+ 
+ 	<packaging>pom</packaging>
+ 
+ 	<modules>
+ 		<module>loader</module>
+ 	</modules>
+ 
+ </project>
diff --cc extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/seed/scripts/SeedUsersAndRolesFixtureScript.java
index fb49f91e88,cf2909b02b..1df97550c1
--- a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/seed/scripts/SeedUsersAndRolesFixtureScript.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/seed/scripts/SeedUsersAndRolesFixtureScript.java
@@@ -21,8 -21,10 +21,10 @@@ package org.apache.causeway.extensions.
  import java.io.File;
  import java.util.function.Supplier;
  
 -import javax.inject.Inject;
 +import jakarta.inject.Inject;
  
+ import org.apache.causeway.extensions.secman.applib.role.seed.CausewayExtLayoutGithubRoleAndPermissions;
+ 
  import org.springframework.lang.Nullable;
  
  import org.apache.causeway.applib.services.appfeat.ApplicationFeatureId;