This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 8b492b649894 CAMEL-22818: camel-core - AdviceWith should pin point to
same resource so route coverage can correlate (#20706)
8b492b649894 is described below
commit 8b492b649894ac146e7d7ebc7ad463c43594c69f
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jan 7 15:56:41 2026 +0100
CAMEL-22818: camel-core - AdviceWith should pin point to same resource so
route coverage can correlate (#20706)
---
.../camel-spring-parent/camel-spring-xml/pom.xml | 4 +
.../spring/DumpModelAsXmlPlaceholdersTest.java | 2 +-
.../SpringDumpRouteCoverageAdviceWithTest.java | 84 ++++++++++++++++
.../XmlIoDumpRouteCoverageAdviceWithTest.java | 109 +++++++++++++++++++++
.../SpringDumpRouteCoverageAdviceWithTest.xml | 36 +++++++
.../XmlIoDumpRouteCoverageAdviceWithTest.xml | 27 +++++
.../java/org/apache/camel/builder/AdviceWith.java | 8 ++
.../org/apache/camel/builder/AdviceWithTasks.java | 27 ++---
.../camel/issues/AdviceWithWeaveByIdTest.java | 56 +++++++++++
.../management/mbean/ManagedCamelContext.java | 2 +-
.../org/apache/camel/xml/LwModelToXMLDumper.java | 4 +-
11 files changed, 345 insertions(+), 14 deletions(-)
diff --git a/components/camel-spring-parent/camel-spring-xml/pom.xml
b/components/camel-spring-parent/camel-spring-xml/pom.xml
index b538df65a13d..d680e7e818fa 100644
--- a/components/camel-spring-parent/camel-spring-xml/pom.xml
+++ b/components/camel-spring-parent/camel-spring-xml/pom.xml
@@ -48,6 +48,10 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-xml-io</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-xml-jaxb</artifactId>
diff --git
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
index 8234b73068f5..94c1a60fa2f1 100644
---
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
+++
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
@@ -42,7 +42,7 @@ public class DumpModelAsXmlPlaceholdersTest extends
SpringTestSupport {
assertNotNull(xml);
log.info(xml);
- assertTrue(xml.contains("<route
xmlns=\"http://camel.apache.org/schema/spring\" id=\"Gouda\">"));
+ assertTrue(xml.contains("id=\"Gouda\">"));
assertTrue(xml.contains("\"direct:start-{{cheese.type}}\""));
assertTrue(xml.contains("\"direct:end-{{cheese.type}}\""));
}
diff --git
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.java
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.java
new file mode 100644
index 000000000000..887f45e527ee
--- /dev/null
+++
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.camel.spring.management;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.w3c.dom.Document;
+
+import org.apache.camel.builder.AdviceWith;
+import org.apache.camel.spring.SpringTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisabledOnOs(OS.AIX)
+public class SpringDumpRouteCoverageAdviceWithTest extends SpringTestSupport {
+
+ @Override
+ protected boolean useJmx() {
+ return true;
+ }
+
+ @Override
+ public boolean isUseAdviceWith() {
+ return true;
+ }
+
+ @Override
+ protected AbstractXmlApplicationContext createApplicationContext() {
+ return new ClassPathXmlApplicationContext(
+
"org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.xml");
+ }
+
+ protected MBeanServer getMBeanServer() {
+ return
context.getManagementStrategy().getManagementAgent().getMBeanServer();
+ }
+
+ @Test
+ public void testDumpRouteCoverage() throws Exception {
+ AdviceWith.adviceWith(context, "hello-process-pipeline", advice -> {
+
advice.weaveById("target-id").replace().to("mock:hello").id("target-id");
+ });
+
+ context.start();
+
+ // get the stats for the route
+ MBeanServer mbeanServer = getMBeanServer();
+ ObjectName on = getContextObjectName();
+
+ getMockEndpoint("mock:hello").expectedMessageCount(1);
+ template.sendBody("direct:hello-process", "Hello World");
+ assertMockEndpointsSatisfied();
+
+ String xml = (String) mbeanServer.invoke(on,
"dumpRoutesCoverageAsXml", null, null);
+ log.info(xml);
+
+ assertTrue(xml.contains("exchangesTotal=\"1\""));
+
+ // should be valid XML
+ Document doc = context.getTypeConverter().convertTo(Document.class,
xml);
+ assertNotNull(doc);
+ }
+
+}
diff --git
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.java
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.java
new file mode 100644
index 000000000000..839976cc3ec4
--- /dev/null
+++
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.camel.spring.management;
+
+import java.io.InputStream;
+
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.w3c.dom.Document;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWith;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.xml.LwModelHelper;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static
org.apache.camel.management.DefaultManagementAgent.DEFAULT_DOMAIN;
+import static
org.apache.camel.management.DefaultManagementObjectNameStrategy.KEY_CONTEXT;
+import static
org.apache.camel.management.DefaultManagementObjectNameStrategy.KEY_NAME;
+import static
org.apache.camel.management.DefaultManagementObjectNameStrategy.KEY_TYPE;
+import static
org.apache.camel.management.DefaultManagementObjectNameStrategy.TYPE_CONTEXT;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisabledOnOs(OS.AIX)
+public class XmlIoDumpRouteCoverageAdviceWithTest extends ContextTestSupport {
+
+ @Override
+ protected boolean useJmx() {
+ return true;
+ }
+
+ @Override
+ public boolean isUseAdviceWith() {
+ return true;
+ }
+
+ protected MBeanServer getMBeanServer() {
+ return
context.getManagementStrategy().getManagementAgent().getMBeanServer();
+ }
+
+ @Test
+ public void testDumpRouteCoverage() throws Exception {
+ InputStream is = this.getClass()
+
.getResourceAsStream("XmlIoDumpRouteCoverageAdviceWithTest.xml");
+ RoutesDefinition routes = LwModelHelper.loadRoutesDefinition(is);
+ context.addRouteDefinition(routes.getRoutes().get(0));
+ IOHelper.close(is);
+
+ AdviceWith.adviceWith(context, "hello-process-pipeline", advice -> {
+ advice.weaveById("target-id").replace().to("mock:hello");
+ });
+
+ context.start();
+
+ // get the stats for the route
+ MBeanServer mbeanServer = getMBeanServer();
+ ObjectName on = getContextObjectName();
+
+ getMockEndpoint("mock:hello").expectedMessageCount(1);
+ template.sendBody("direct:hello-process", "Hello World");
+ assertMockEndpointsSatisfied();
+
+ String xml = (String) mbeanServer.invoke(on,
"dumpRoutesCoverageAsXml", null, null);
+ log.info(xml);
+
+ // advice replaced <log> -> <to> which we should find in the XML dump
+ assertTrue(xml.contains("<to exchangesTotal=\"1\""));
+ assertTrue(xml.contains("uri=\"mock:hello\""));
+ assertTrue(xml.contains("sourceLineNumber=\"24\""));
+
+ // should be valid XML
+ Document doc = context.getTypeConverter().convertTo(Document.class,
xml);
+ assertNotNull(doc);
+ }
+
+ private ObjectName getContextObjectName() throws
MalformedObjectNameException {
+ return getCamelObjectName(TYPE_CONTEXT, context.getName());
+ }
+
+ private ObjectName getCamelObjectName(String type, String name) throws
MalformedObjectNameException {
+ String quote = "\"";
+ String on = DEFAULT_DOMAIN + ":"
+ + KEY_CONTEXT + "=" + context.getManagementName() + ","
+ + KEY_TYPE + "=" + type + ","
+ + KEY_NAME + "=" + quote + name + quote;
+ return ObjectName.getInstance(on);
+ }
+
+}
diff --git
a/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.xml
b/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.xml
new file mode 100644
index 000000000000..339b3b2ad7c5
--- /dev/null
+++
b/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.xml
@@ -0,0 +1,36 @@
+<?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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <camelContext xmlns="http://camel.apache.org/schema/spring">
+ <route id="hello-process-pipeline">
+ <from uri="direct:hello-process"/>
+ <log message="hello-process Start"/>
+ <log message="some message" id="target-id"/>
+ <log message="hello-process Done"/>
+ </route>
+ </camelContext>
+
+</beans>
diff --git
a/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.xml
b/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.xml
new file mode 100644
index 000000000000..d0aa2e3475f7
--- /dev/null
+++
b/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.xml
@@ -0,0 +1,27 @@
+<?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.
+
+-->
+<routes xmlns="http://camel.apache.org/schema/xml-io">
+ <route id="hello-process-pipeline">
+ <from uri="direct:hello-process"/>
+ <log message="hello-process Start"/>
+ <log message="some message" id="target-id"/>
+ <log message="hello-process Done"/>
+ </route>
+</routes>
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWith.java
b/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWith.java
index d21ae501fc8e..4dd8af70b4b1 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWith.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWith.java
@@ -202,6 +202,14 @@ public final class AdviceWith {
ExtendedCamelContext ecc = camelContext.getCamelContextExtension();
Model model =
camelContext.getCamelContextExtension().getContextPlugin(Model.class);
+ // before we can advice then the input route must be prepared
+ if (!definition.isPrepared()) {
+ RoutesDefinition routes = new RoutesDefinition();
+ routes.setCamelContext(camelContext);
+ routes.setResource(definition.getResource());
+ routes.prepareRoute(definition);
+ }
+
// inject this route into the advice route builder so it can access
this route
// and offer features to manipulate the route directly
if (builder instanceof AdviceWithRouteBuilder arb) {
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
b/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
index b7a00aa91094..5aaff2c3a22f 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
@@ -22,6 +22,7 @@ import java.util.Iterator;
import java.util.List;
import org.apache.camel.Endpoint;
+import org.apache.camel.LineNumberAware;
import org.apache.camel.model.AdviceWithDefinition;
import org.apache.camel.model.ChoiceDefinition;
import org.apache.camel.model.EndpointRequiredDefinition;
@@ -223,14 +224,14 @@ public final class AdviceWithTasks {
int index = outputs.indexOf(output);
if (index != -1) {
match = true;
+ ProcessorDefinition existing =
outputs.remove(index);
// flattern as replace uses a pipeline as
temporary holder
- ProcessorDefinition<?> flattern =
flatternOutput(replace);
- outputs.add(index + 1, flattern);
- Object old = outputs.remove(index);
+ ProcessorDefinition<?> flattern =
flatternOutput(replace, existing);
+ outputs.add(index, flattern);
// must set parent on the node we added in the
route
ProcessorDefinition<?> parent =
output.getParent() != null ? output.getParent() : route;
flattern.setParent(parent);
- LOG.info("AdviceWith ({}) : [{}] --> replace
[{}]", matchBy.getId(), old, flattern);
+ LOG.info("AdviceWith ({}) : [{}] --> replace
[{}]", matchBy.getId(), existing, flattern);
}
}
}
@@ -355,9 +356,9 @@ public final class AdviceWithTasks {
int index = outputs.indexOf(output);
if (index != -1) {
match = true;
+ ProcessorDefinition existing =
outputs.get(index);
// flattern as before uses a pipeline as
temporary holder
- ProcessorDefinition<?> flattern =
flatternOutput(before);
- Object existing = outputs.get(index);
+ ProcessorDefinition<?> flattern =
flatternOutput(before, existing);
outputs.add(index, flattern);
// must set parent on the node we added in the
route
ProcessorDefinition<?> parent =
output.getParent() != null ? output.getParent() : route;
@@ -425,9 +426,9 @@ public final class AdviceWithTasks {
int index = outputs.indexOf(output);
if (index != -1) {
match = true;
+ ProcessorDefinition existing =
outputs.get(index);
// flattern as after uses a pipeline as
temporary holder
- ProcessorDefinition<?> flattern =
flatternOutput(after);
- Object existing = outputs.get(index);
+ ProcessorDefinition<?> flattern =
flatternOutput(after, existing);
outputs.add(index + 1, flattern);
// must set parent on the node we added in the
route
ProcessorDefinition<?> parent =
output.getParent() != null ? output.getParent() : route;
@@ -635,17 +636,21 @@ public final class AdviceWithTasks {
};
}
- private static ProcessorDefinition<?>
flatternOutput(ProcessorDefinition<?> output) {
+ private static ProcessorDefinition<?>
flatternOutput(ProcessorDefinition<?> output, LineNumberAware source) {
if (output instanceof AdviceWithDefinition advice) {
+ // copy over location from source so the advised nodes also have
same location
+ advice.getOutputs().forEach(o ->
LineNumberAware.trySetLineNumberAware(o, source));
if (advice.getOutputs().size() == 1) {
- return advice.getOutputs().get(0);
+ output = advice.getOutputs().get(0);
} else {
// it should be a pipeline
PipelineDefinition pipe = new PipelineDefinition();
pipe.setOutputs(advice.getOutputs());
- return pipe;
+ output = pipe;
}
}
+ // copy over location from source so the advised nodes also have same
location
+ LineNumberAware.trySetLineNumberAware(output, source);
return output;
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithWeaveByIdTest.java
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithWeaveByIdTest.java
new file mode 100644
index 000000000000..6b4c822cccbd
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithWeaveByIdTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.camel.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWith;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+
+public class AdviceWithWeaveByIdTest extends ContextTestSupport {
+
+ @Test
+ public void testWeaveByType() throws Exception {
+ AdviceWith.adviceWith(context.getRouteDefinitions().get(0), context,
new AdviceWithRouteBuilder() {
+ @Override
+ public void configure() {
+ weaveById("target-id").replace().to("mock:baz");
+ }
+ });
+
+ getMockEndpoint("mock:baz").expectedMessageCount(1);
+
+ template.sendBody("direct:start", "World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:start")
+ .log("a")
+ .log("b").id("target-id")
+ .log("c");
+ }
+ };
+ }
+
+}
diff --git
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index 6b88d05205a0..cfd2bb3d7693 100644
---
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -894,7 +894,7 @@ public class ManagedCamelContext extends
ManagedPerformanceCounter implements Ti
getExchangesTotal(), getTotalProcessingTime()))
.append(">\n");
- String xml = dumpRoutesAsXml(false, true);
+ String xml = dumpRoutesAsXml(false, true, true);
if (xml != null) {
// use the coverage xml parser to dump the routes and enrich with
coverage stats
Document dom = RouteCoverageXmlParser.parseXml(context, new
ByteArrayInputStream(xml.getBytes()));
diff --git
a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
index f009c7803570..eb0edb17e547 100644
---
a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
+++
b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
@@ -104,10 +104,12 @@ public class LwModelToXMLDumper implements
ModelToXMLDumper {
}
// write location information
if (sourceLocation || context.isDebugging()) {
- String loc = (def instanceof RouteDefinition ?
((RouteDefinition) def).getInput() : def).getLocation();
int line = (def instanceof RouteDefinition ?
((RouteDefinition) def).getInput() : def).getLineNumber();
if (line != -1) {
writer.addAttribute("sourceLineNumber",
Integer.toString(line));
+ }
+ String loc = (def instanceof RouteDefinition ?
((RouteDefinition) def).getInput() : def).getLocation();
+ if (loc != null) {
writer.addAttribute("sourceLocation", loc);
}
}