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

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


The following commit(s) were added to refs/heads/main by this push:
     new b493ae7c7a8 CAUSEWAY-3964: inspect arbitrary type (new UI actions)
b493ae7c7a8 is described below

commit b493ae7c7a863e66a8b2b43e45fcf30d59800ad3
Author: andi-huber <[email protected]>
AuthorDate: Mon Feb 9 11:54:07 2026 +0100

    CAUSEWAY-3964: inspect arbitrary type (new UI actions)
---
 .../metamodel/CausewayModuleCoreMetamodel.java     |  4 ++
 .../inspect/model/MetamodelInspectMenu.java        | 80 ++++++++++++++++++++++
 .../inspect/model/MetamodelInspectView.java        | 18 ++++-
 3 files changed, 100 insertions(+), 2 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/CausewayModuleCoreMetamodel.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/CausewayModuleCoreMetamodel.java
index 51e2202f8fa..f0b1049c17e 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/CausewayModuleCoreMetamodel.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/CausewayModuleCoreMetamodel.java
@@ -49,6 +49,7 @@
 import org.apache.causeway.core.metamodel.context.MetaModelContextFactory;
 import 
org.apache.causeway.core.metamodel.facets.object.logicaltype.LogicalTypeMalformedValidator;
 import 
org.apache.causeway.core.metamodel.inspect.CausewayModuleCoreMetamodelMixins;
+import org.apache.causeway.core.metamodel.inspect.model.MetamodelInspectMenu;
 import org.apache.causeway.core.metamodel.inspect.model.MetamodelInspectView;
 import 
org.apache.causeway.core.metamodel.progmodel.ProgrammingModelInitFilterDefault;
 import 
org.apache.causeway.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
@@ -199,6 +200,9 @@
 
         // standalone validators
         LogicalTypeMalformedValidator.class,
+        
+        // menubar contributions
+        MetamodelInspectMenu.class
 })
 public class CausewayModuleCoreMetamodel {
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/inspect/model/MetamodelInspectMenu.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/inspect/model/MetamodelInspectMenu.java
new file mode 100644
index 00000000000..0bdd9e1199f
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/inspect/model/MetamodelInspectMenu.java
@@ -0,0 +1,80 @@
+/*
+ *  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.core.metamodel.inspect.model;
+
+import java.util.function.Supplier;
+
+import jakarta.inject.Named;
+
+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.PriorityPrecedence;
+import org.apache.causeway.applib.annotation.RestrictTo;
+import org.apache.causeway.commons.internal.context._Context;
+import org.apache.causeway.core.metamodel.CausewayModuleCoreMetamodel;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
+
+@Named(CausewayModuleCoreMetamodel.NAMESPACE + ".MetamodelInspectMenu")
+@DomainService
+@DomainServiceLayout(
+        named = "Prototyping",
+        menuBar = DomainServiceLayout.MenuBar.SECONDARY
+)
[email protected](PriorityPrecedence.MIDPOINT)
+public class MetamodelInspectMenu {
+
+    @Action(restrictTo = RestrictTo.PROTOTYPING)
+    @ActionLayout(named = "Inspect type", cssClassFa = "solid shapes")
+    public MetamodelInspectView inspect(String fullyQualifiedClassName) {
+       return inspect(fullyQualifiedClassName, ()->null);
+    }
+    @MemberSupport 
+    public String validate0Inspect(String fullyQualifiedClassName) {
+       return validateClassName(fullyQualifiedClassName);
+    }
+    
+    // -- UTIL
+    
+    static MetamodelInspectView inspect(String fullyQualifiedClassName, 
Supplier<MetamodelInspectView> fallback) {
+       try {
+               var classOfInterest = 
_Context.loadClass(fullyQualifiedClassName);
+               return MetaModelContext.instance()
+                       .map(MetaModelContext::getSpecificationLoader)
+                       
.map(specLoader->specLoader.loadSpecification(classOfInterest))
+                       .map(MetamodelInspectView::root)
+                       .orElseGet(fallback);
+       } catch (ClassNotFoundException e) {
+               // unexpected, as covered by validate
+               }
+       return null;
+    }
+     
+    static String validateClassName(String fullyQualifiedClassName) {
+       try {
+               _Context.loadClass(fullyQualifiedClassName);
+       } catch (ClassNotFoundException e) {
+                       return e.getMessage();
+               }
+       return null;
+    }
+     
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/inspect/model/MetamodelInspectView.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/inspect/model/MetamodelInspectView.java
index 0fe7d975c3f..09016ab5d2e 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/inspect/model/MetamodelInspectView.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/inspect/model/MetamodelInspectView.java
@@ -20,11 +20,14 @@
 
 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.ActionLayout.Position;
 import org.apache.causeway.applib.annotation.DomainObject;
 import org.apache.causeway.applib.annotation.Editing;
 import org.apache.causeway.applib.annotation.Introspection;
 import org.apache.causeway.applib.annotation.LabelPosition;
+import org.apache.causeway.applib.annotation.MemberSupport;
 import org.apache.causeway.applib.annotation.Nature;
 import org.apache.causeway.applib.annotation.ObjectSupport;
 import org.apache.causeway.applib.annotation.Property;
@@ -34,9 +37,10 @@
 import org.apache.causeway.applib.graph.tree.TreePath;
 import org.apache.causeway.applib.value.Markup;
 import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.core.metamodel.CausewayModuleCoreMetamodel;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 
-@Named(CausewayModuleApplib.NAMESPACE + ".MetamodelInspectView")
+@Named(CausewayModuleCoreMetamodel.NAMESPACE + ".MetamodelInspectView")
 @DomainObject(
     nature=Nature.VIEW_MODEL,
     editing = Editing.DISABLED,
@@ -88,6 +92,16 @@ public ObjectSupport.IconResource icon(final 
ObjectSupport.IconSize iconSize) {
     public Markup getDetails() {
         return activeNode().details();
     }
+
+    @Action 
+    @ActionLayout(position = Position.PANEL, fieldSetId = "tree", named = 
"Inspect other", cssClassFa = "solid shapes")
+    public MetamodelInspectView inspect(String fullyQualifiedClassName) {
+       return MetamodelInspectMenu.inspect(fullyQualifiedClassName, null);
+    }
+    @MemberSupport 
+    public String validate0Inspect(String fullyQualifiedClassName) {
+       return MetamodelInspectMenu.validateClassName(fullyQualifiedClassName);
+    }
     
     // -- IMPLEMENTATION DETAILS
 

Reply via email to