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

davsclaus pushed a commit to branch dia3
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 45fec41203d0ac127fb8e46edbbe399b363044fa
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu May 7 18:24:49 2026 +0200

    CAMEL-23400: camel-diagram - prepare for being used in maven tooling and 
also as SPI in camel-core
---
 .../apache/camel/diagram/RouteDiagramHelper.java   | 20 ++----
 .../org/apache/camel/diagram/RouteDiagramTest.java |  4 +-
 .../main/java/org/apache/camel/CamelContext.java   |  5 ++
 .../src/main/java/org/apache/camel/NamedRoute.java | 12 ++++
 .../camel/impl/engine/AbstractCamelContext.java    | 13 ++--
 .../camel/impl/engine/SimpleCamelContext.java      |  7 ++
 .../impl/console/RouteStructureDevConsole.java     | 75 +++++++++-------------
 .../org/apache/camel/impl/DefaultCamelContext.java |  6 ++
 .../org/apache/camel/support/LoggerHelper.java     | 28 +++++++-
 9 files changed, 101 insertions(+), 69 deletions(-)

diff --git 
a/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramHelper.java
 
b/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramHelper.java
index eaff690ceb4b..5a3fe8b5028e 100644
--- 
a/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramHelper.java
+++ 
b/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramHelper.java
@@ -21,6 +21,8 @@ import java.util.List;
 
 import org.apache.camel.diagram.RouteDiagramLayoutEngine.NodeInfo;
 import org.apache.camel.diagram.RouteDiagramLayoutEngine.RouteInfo;
+import org.apache.camel.support.LoggerHelper;
+import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.json.JsonArray;
 import org.apache.camel.util.json.JsonObject;
 import org.apache.camel.util.json.Jsoner;
@@ -86,21 +88,9 @@ public final class RouteDiagramHelper {
         if (source == null || source.isBlank()) {
             return null;
         }
-        // strip URI scheme prefix (e.g. "file:", "classpath:") — only if the 
part
-        // before the first colon is all letters (a valid scheme). This avoids
-        // stripping line numbers from sources like "cheese.java:9".
-        int colon = source.indexOf(':');
-        if (colon > 0) {
-            String scheme = source.substring(0, colon);
-            if (scheme.chars().allMatch(Character::isLetter)) {
-                source = source.substring(colon + 1);
-            }
-        }
-        // return just the filename part
-        int slash = Math.max(source.lastIndexOf('/'), 
source.lastIndexOf('\\'));
-        if (slash >= 0 && slash < source.length() - 1) {
-            return source.substring(slash + 1);
-        }
+        source = LoggerHelper.sourceNameOnly(source);
+        source = LoggerHelper.stripScheme(source);
+        source = FileUtil.stripPath(source);
         return source;
     }
 }
diff --git 
a/components/camel-diagram/src/test/java/org/apache/camel/diagram/RouteDiagramTest.java
 
b/components/camel-diagram/src/test/java/org/apache/camel/diagram/RouteDiagramTest.java
index a7ea8029bdd5..4f5e5cd86dca 100644
--- 
a/components/camel-diagram/src/test/java/org/apache/camel/diagram/RouteDiagramTest.java
+++ 
b/components/camel-diagram/src/test/java/org/apache/camel/diagram/RouteDiagramTest.java
@@ -818,12 +818,12 @@ class RouteDiagramTest {
 
     @Test
     void testExtractSourceNameWithLineNumber() {
-        assertEquals("cheese.java:9", 
RouteDiagramHelper.extractSourceName("cheese.java:9"));
+        assertEquals("cheese.java", 
RouteDiagramHelper.extractSourceName("cheese.java:9"));
     }
 
     @Test
     void testExtractSourceNameSchemeAndLineNumber() {
-        assertEquals("cheese.java:9", 
RouteDiagramHelper.extractSourceName("file:/path/to/cheese.java:9"));
+        assertEquals("cheese.java", 
RouteDiagramHelper.extractSourceName("file:/path/to/cheese.java:9"));
     }
 
     @Test
diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java 
b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
index 46700aa30751..7f8ebdc2ac0e 100644
--- a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
@@ -790,6 +790,11 @@ public interface CamelContext extends 
CamelContextLifecycle, RuntimeConfiguratio
      */
     List<RoutePolicyFactory> getRoutePolicyFactories();
 
+    /**
+     * Gets a light-weight API for the route model defunitions.
+     */
+    List<NamedRoute> getNamedRouteDefinitions();
+
     // Rest Methods
     //-----------------------------------------------------------------------
 
diff --git a/core/camel-api/src/main/java/org/apache/camel/NamedRoute.java 
b/core/camel-api/src/main/java/org/apache/camel/NamedRoute.java
index 047cd99be2db..017123bab68a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/NamedRoute.java
+++ b/core/camel-api/src/main/java/org/apache/camel/NamedRoute.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel;
 
+import org.apache.camel.spi.Resource;
+
 /**
  * Represents a node in the {@link org.apache.camel.model routes} which is 
identified as a route.
  */
@@ -26,6 +28,11 @@ public interface NamedRoute {
      */
     String getRouteId();
 
+    /**
+     * Gets the route description.
+     */
+    String getDescription();
+
     /**
      * Gets the node prefix id.
      */
@@ -51,4 +58,9 @@ public interface NamedRoute {
      */
     NamedNode getInput();
 
+    /**
+     * Gets the {@link Resource}.
+     */
+    Resource getResource();
+
 }
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 7a50b8fdd244..a66f12105837 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -3176,6 +3176,12 @@ public abstract class AbstractCamelContext extends 
BaseService
             LOG.debug("Skip starting routes as CamelContext has been 
configured with autoStartup=false");
         }
 
+        // dump routes when as we have model before creating the runtime 
models, which can help during troubleshooting
+        // when routes have problems starting
+        if (getDumpRoutes() != null && !"false".equals(getDumpRoutes())) {
+            doDumpRoutes();
+        }
+
         if (!getRouteController().isSupervising()) {
             // invoke this logic to warmup the routes and if possible also 
start the routes (using default route controller)
             StartupStep subStep
@@ -3187,13 +3193,6 @@ public abstract class AbstractCamelContext extends 
BaseService
             startupStepRecorder.endStep(subStep);
         }
 
-        // TODO: json,png should be later
-        // dump routes when as we have model before creating the runtime 
models, which can help during troubleshooting
-        // when routes have problems starting
-        if (getDumpRoutes() != null && !"false".equals(getDumpRoutes())) {
-            doDumpRoutes();
-        }
-
         // ensure extra dev consoles is loaded in case additional JARs has 
been dynamically added to the classpath
         if (devConsole) {
             StartupStep step = 
startupStepRecorder.beginStep(CamelContext.class, null, "Scan DevConsoles 
(phase 2)");
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index 23db758d00d6..7bf67d739dd5 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -16,12 +16,14 @@
  */
 package org.apache.camel.impl.engine;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ScheduledExecutorService;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
+import org.apache.camel.NamedRoute;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.RouteTemplateContext;
@@ -774,6 +776,11 @@ public class SimpleCamelContext extends 
AbstractCamelContext {
         throw new UnsupportedOperationException();
     }
 
+    @Override
+    public List<NamedRoute> getNamedRouteDefinitions() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public String getTestExcludeRoutes() {
         throw new UnsupportedOperationException();
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteStructureDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteStructureDevConsole.java
index 2e7188c4480f..38efd35994bb 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteStructureDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteStructureDevConsole.java
@@ -18,13 +18,10 @@ package org.apache.camel.impl.console;
 
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.function.Function;
 
 import org.apache.camel.Exchange;
-import org.apache.camel.Route;
-import org.apache.camel.api.management.ManagedCamelContext;
-import org.apache.camel.api.management.mbean.ManagedRouteMBean;
+import org.apache.camel.NamedRoute;
 import org.apache.camel.spi.ModelDumpLine;
 import org.apache.camel.spi.ModelToStructureDumper;
 import org.apache.camel.spi.annotations.DevConsole;
@@ -43,8 +40,6 @@ import static 
org.apache.camel.impl.console.ConsoleHelper.extractSourceLocationN
 @DevConsole(name = "route-structure", description = "Dump route structure")
 public class RouteStructureDevConsole extends AbstractDevConsole {
 
-    // TODO: no JMX but model only
-
     /**
      * Filters the routes matching by route id, route uri, and source location
      */
@@ -69,15 +64,16 @@ public class RouteStructureDevConsole extends 
AbstractDevConsole {
         final String brief = (String) options.getOrDefault(BRIEF, "false");
 
         final StringBuilder sb = new StringBuilder();
-        Function<ManagedRouteMBean, Object> task = mrb -> {
+        Function<NamedRoute, Object> task = def -> {
             try {
                 ModelToStructureDumper dumper = 
PluginHelper.getModelToStructureDumper(getCamelContext());
                 List<ModelDumpLine> lines
-                        = dumper.dumpStructure(getCamelContext(), 
mrb.getRouteId(), "true".equalsIgnoreCase(brief));
+                        = dumper.dumpStructure(getCamelContext(), 
def.getRouteId(), "true".equalsIgnoreCase(brief));
 
-                sb.append(String.format("    Id: %s", mrb.getRouteId()));
-                if (mrb.getSourceLocation() != null) {
-                    sb.append(String.format("%n    Source: %s", 
extractSourceLocationNoLineNumber(mrb.getSourceLocation())));
+                sb.append(String.format("    Id: %s", def.getRouteId()));
+                if (def.getResource() != null) {
+                    sb.append(String.format("%n    Source: %s",
+                            
extractSourceLocationNoLineNumber(def.getResource().getLocation())));
                 }
                 sb.append("\n\n");
                 for (ModelDumpLine line : lines) {
@@ -108,27 +104,27 @@ public class RouteStructureDevConsole extends 
AbstractDevConsole {
         final JsonObject root = new JsonObject();
         final JsonArray list = new JsonArray();
 
-        Function<ManagedRouteMBean, Object> task = mrb -> {
+        Function<NamedRoute, Object> task = def -> {
             JsonObject jo = new JsonObject();
             list.add(jo);
 
-            jo.put("routeId", mrb.getRouteId());
-            jo.put("from", mrb.getEndpointUri());
-            if (mrb.getSourceLocation() != null) {
-                jo.put("source", 
extractSourceLocationNoLineNumber(mrb.getSourceLocation()));
-                Integer line = 
extractSourceLocationLineNumber(mrb.getSourceLocation());
+            jo.put("routeId", def.getRouteId());
+            jo.put("from", def.getEndpointUrl());
+            if (def.getResource() != null) {
+                jo.put("source", 
extractSourceLocationNoLineNumber(def.getResource().getLocation()));
+                Integer line = 
extractSourceLocationLineNumber(def.getResource().getLocation());
                 if (line != null) {
                     jo.put("line", line);
                 }
             }
-            if (mrb.getDescription() != null) {
-                jo.put("description", mrb.getDescription());
+            if (def.getDescription() != null) {
+                jo.put("description", def.getDescription());
             }
 
             try {
                 ModelToStructureDumper dumper = 
PluginHelper.getModelToStructureDumper(getCamelContext());
                 List<ModelDumpLine> lines
-                        = dumper.dumpStructure(getCamelContext(), 
mrb.getRouteId(), "true".equalsIgnoreCase(brief));
+                        = dumper.dumpStructure(getCamelContext(), 
def.getRouteId(), "true".equalsIgnoreCase(brief));
                 JsonArray code = dumpAsJSon(lines);
                 jo.put("code", code);
             } catch (Exception e) {
@@ -141,45 +137,36 @@ public class RouteStructureDevConsole extends 
AbstractDevConsole {
         return root;
     }
 
-    protected void doCall(Map<String, Object> options, 
Function<ManagedRouteMBean, Object> task) {
+    protected void doCall(Map<String, Object> options, Function<NamedRoute, 
Object> task) {
         String path = (String) options.get(Exchange.HTTP_PATH);
         String subPath = path != null ? StringHelper.after(path, "/") : null;
         String filter = (String) options.get(FILTER);
         String limit = (String) options.get(LIMIT);
         final int max = limit == null ? Integer.MAX_VALUE : 
Integer.parseInt(limit);
 
-        ManagedCamelContext mcc = 
getCamelContext().getCamelContextExtension().getContextPlugin(ManagedCamelContext.class);
-        if (mcc != null) {
-            List<Route> routes = getCamelContext().getRoutes();
-            routes.sort((o1, o2) -> 
o1.getRouteId().compareToIgnoreCase(o2.getRouteId()));
-            routes.stream()
-                    .map(route -> mcc.getManagedRoute(route.getRouteId()))
-                    .filter(Objects::nonNull)
-                    .filter(r -> accept(r, filter))
-                    .filter(r -> accept(r, subPath))
-                    .sorted(RouteStructureDevConsole::sort)
-                    .limit(max)
-                    .forEach(task::apply);
-        }
+        var routes = getCamelContext().getNamedRouteDefinitions();
+        routes.sort((o1, o2) -> 
o1.getRouteId().compareToIgnoreCase(o2.getRouteId()));
+        routes.stream()
+                .filter(r -> accept(r, filter))
+                .filter(r -> accept(r, subPath))
+                .limit(max)
+                .forEach(task::apply);
     }
 
-    private static boolean accept(ManagedRouteMBean mrb, String filter) {
+    private static boolean accept(NamedRoute route, String filter) {
         if (filter == null || filter.isBlank()) {
             return true;
         }
 
-        String onlyName = LoggerHelper.sourceNameOnly(mrb.getSourceLocation());
-        return PatternHelper.matchPattern(mrb.getRouteId(), filter)
-                || PatternHelper.matchPattern(mrb.getEndpointUri(), filter)
-                || PatternHelper.matchPattern(mrb.getSourceLocationShort(), 
filter)
+        String uri = route.getInput().getLabel();
+        String loc = LoggerHelper.getLineNumberLoggerName(route);
+        String onlyName = LoggerHelper.sourceNameOnly(loc);
+        return PatternHelper.matchPattern(route.getRouteId(), filter)
+                || PatternHelper.matchPattern(uri, filter)
+                || PatternHelper.matchPattern(loc, filter)
                 || PatternHelper.matchPattern(onlyName, filter);
     }
 
-    private static int sort(ManagedRouteMBean o1, ManagedRouteMBean o2) {
-        // sort by id
-        return o1.getRouteId().compareTo(o2.getRouteId());
-    }
-
     private static JsonArray dumpAsJSon(List<ModelDumpLine> lines) {
         JsonArray code = new JsonArray();
         int counter = 0;
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 8477fd158e1e..c42c04fd7e15 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -30,6 +30,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
 import org.apache.camel.FailedToStartRouteException;
 import org.apache.camel.LoggingLevel;
+import org.apache.camel.NamedRoute;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
@@ -429,6 +430,11 @@ public class DefaultCamelContext extends 
SimpleCamelContext implements ModelCame
         }
     }
 
+    @Override
+    public List<NamedRoute> getNamedRouteDefinitions() {
+        return new ArrayList<>(model.getRouteDefinitions());
+    }
+
     @Override
     public List<RestDefinition> getRestDefinitions() {
         return model.getRestDefinitions();
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/LoggerHelper.java 
b/core/camel-support/src/main/java/org/apache/camel/support/LoggerHelper.java
index 1cf3e282a892..48e37c40e2e5 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/LoggerHelper.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/LoggerHelper.java
@@ -123,7 +123,24 @@ public final class LoggerHelper {
     }
 
     public static String sourceNameOnly(String location) {
-        return stripScheme(stripSourceLocationLineNumber(location));
+        int cnt = StringHelper.countChar(location, ':');
+        if (cnt <= 1) {
+            // include pseudo scheme due to extract methods rely on scheme 
included
+            location = "file:" + location;
+        }
+        Integer line = extractSourceLocationLineNumber(location);
+        if (line != null) {
+            // remove line number
+            location = extractSourceLocationNoLineNumber(location);
+            // strip scheme so its only the name
+            if (location.contains(":")) {
+                location = stripScheme(location);
+            }
+            return location;
+        } else {
+            // no line number so strip scheme
+            return stripScheme(location);
+        }
     }
 
     public static Integer extractSourceLocationLineNumber(String location) {
@@ -143,4 +160,13 @@ public final class LoggerHelper {
         return null;
     }
 
+    public static String extractSourceLocationNoLineNumber(String location) {
+        Integer line = extractSourceLocationLineNumber(location);
+        if (line != null) {
+            int pos = location.lastIndexOf(':');
+            return location.substring(0, pos);
+        }
+        return location;
+    }
+
 }

Reply via email to