Repository: camel
Updated Branches:
  refs/heads/parser2 16d66ddae -> aa1283552


Camel route coverage for XML


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/aed13265
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/aed13265
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/aed13265

Branch: refs/heads/parser2
Commit: aed132655e6cfc8318218482f515ce75d266c3ed
Parents: 16d66dd
Author: Claus Ibsen <[email protected]>
Authored: Mon Oct 9 15:09:19 2017 +0200
Committer: Claus Ibsen <[email protected]>
Committed: Mon Oct 9 15:09:19 2017 +0200

----------------------------------------------------------------------
 examples/camel-example-spring-boot-xml/pom.xml  | 151 +++++++++++++++++++
 .../camel-example-spring-boot-xml/readme.adoc   |  41 +++++
 .../src/main/java/sample/camel/SampleBean.java  |  38 +++++
 .../sample/camel/SampleCamelApplication.java    |  40 +++++
 .../src/main/resources/application.properties   |  46 ++++++
 .../src/main/resources/my-camel.xml             |  21 +++
 .../java/sample/camel/FooApplicationTest.java   |  52 +++++++
 .../camel/SampleCamelApplicationTest.java       |  49 ++++++
 examples/pom.xml                                |   1 +
 .../org/apache/camel/parser/XmlRouteParser.java |  55 +++++++
 .../parser/helper/CamelXmlTreeParserHelper.java |  71 +++++++++
 .../camel/parser/xml/XmlParseTreeTest.java      |  60 ++++++++
 .../org/apache/camel/parser/xml/mycamel.xml     |   2 +-
 .../apache/camel/maven/RouteCoverageMojo.java   |  32 ++--
 14 files changed, 637 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/camel-example-spring-boot-xml/pom.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-xml/pom.xml 
b/examples/camel-example-spring-boot-xml/pom.xml
new file mode 100644
index 0000000..3501809
--- /dev/null
+++ b/examples/camel-example-spring-boot-xml/pom.xml
@@ -0,0 +1,151 @@
+<?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.camel.example</groupId>
+    <artifactId>examples</artifactId>
+    <version>2.20.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>camel-example-spring-boot-xml</artifactId>
+  <name>Camel :: Example :: Spring Boot XML</name>
+  <description>An example showing how to work with Camel routes in XML files 
and Spring Boot</description>
+
+  <properties>
+    <category>Beginner</category>
+
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <spring.boot-version>${spring-boot-version}</spring.boot-version>
+  </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <!-- Spring Boot BOM -->
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-dependencies</artifactId>
+        <version>${spring.boot-version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <!-- Camel BOM -->
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-spring-boot-dependencies</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <dependencies>
+
+    <!-- Spring Boot -->
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-undertow</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-actuator</artifactId>
+    </dependency>
+
+    <!-- Camel -->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-spring-boot-starter</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-stream-starter</artifactId>
+    </dependency>
+
+    <!-- test -->
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-test-spring</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+        <version>${spring-boot-version}</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>repackage</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-maven-plugin</artifactId>
+        <version>${project.version}</version>
+        <!-- allows to fail if not all routes are fully covered during testing 
-->
+<!--
+        <configuration>
+          <failOnError>true</failOnError>
+        </configuration>
+-->
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>jdk9-build</id>
+      <activation>
+        <jdk>9</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <argLine>--add-modules java.xml.bind --add-opens 
java.base/java.lang=ALL-UNNAMED</argLine>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/camel-example-spring-boot-xml/readme.adoc
----------------------------------------------------------------------
diff --git a/examples/camel-example-spring-boot-xml/readme.adoc 
b/examples/camel-example-spring-boot-xml/readme.adoc
new file mode 100644
index 0000000..72475b2
--- /dev/null
+++ b/examples/camel-example-spring-boot-xml/readme.adoc
@@ -0,0 +1,41 @@
+# Camel Example Spring Boot
+
+This example shows how to work with a simple Apache Camel application using 
Spring Boot.
+
+The example generates messages using timer trigger, writes them to standard 
output.
+
+## Camel routes
+
+The Camel route is located in the `SampleCamelRouter` class. In this class the 
route
+starts from a timer, that triggers every 2nd second and calls a Spring Bean 
`SampleBean`
+which returns a message, that is routed to a stream endpoint which writes to 
standard output.
+
+## Using Camel components
+
+Apache Camel provides 200+ components which you can use to integrate and route 
messages between many systems
+and data formats. To use any of these Camel components, add the component as a 
dependency to your project.
+
+## How to run
+
+You can run this example using
+
+    mvn spring-boot:run
+
+## To get info about the routes
+
+To show a summary of all the routes
+
+----
+curl -XGET -s http://localhost:8080/camel/routes
+----
+
+To show detailed information for a specific route
+
+----
+curl -XGET -s http://localhost:8080/camel/routes/{id}/info
+----
+
+
+## More information
+
+You can find more information about Apache Camel at the website: 
http://camel.apache.org/

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/camel-example-spring-boot-xml/src/main/java/sample/camel/SampleBean.java
----------------------------------------------------------------------
diff --git 
a/examples/camel-example-spring-boot-xml/src/main/java/sample/camel/SampleBean.java
 
b/examples/camel-example-spring-boot-xml/src/main/java/sample/camel/SampleBean.java
new file mode 100644
index 0000000..b60ef69
--- /dev/null
+++ 
b/examples/camel-example-spring-boot-xml/src/main/java/sample/camel/SampleBean.java
@@ -0,0 +1,38 @@
+/**
+ * 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 sample.camel;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * A bean that returns a message when you call the {@link #saySomething()} 
method.
+ * <p/>
+ * Uses <tt>@Component("myBean")</tt> to register this bean with the name 
<tt>myBean</tt>
+ * that we use in the Camel route to lookup this bean.
+ */
+@Component("myBean")
+public class SampleBean {
+
+    @Value("${greeting}")
+    private String say;
+
+    public String saySomething() {
+        return say;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/camel-example-spring-boot-xml/src/main/java/sample/camel/SampleCamelApplication.java
----------------------------------------------------------------------
diff --git 
a/examples/camel-example-spring-boot-xml/src/main/java/sample/camel/SampleCamelApplication.java
 
b/examples/camel-example-spring-boot-xml/src/main/java/sample/camel/SampleCamelApplication.java
new file mode 100644
index 0000000..a678dae
--- /dev/null
+++ 
b/examples/camel-example-spring-boot-xml/src/main/java/sample/camel/SampleCamelApplication.java
@@ -0,0 +1,40 @@
+/**
+ * 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 sample.camel;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ImportResource;
+
+//CHECKSTYLE:OFF
+/**
+ * A sample Spring Boot application that starts the Camel routes.
+ */
+@SpringBootApplication
+// load the spring xml file from classpath
+@ImportResource("classpath:my-camel.xml")
+public class SampleCamelApplication {
+
+    /**
+     * A main method to start this application.
+     */
+    public static void main(String[] args) {
+        SpringApplication.run(SampleCamelApplication.class, args);
+    }
+
+}
+//CHECKSTYLE:ON

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/camel-example-spring-boot-xml/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git 
a/examples/camel-example-spring-boot-xml/src/main/resources/application.properties
 
b/examples/camel-example-spring-boot-xml/src/main/resources/application.properties
new file mode 100644
index 0000000..75a10de
--- /dev/null
+++ 
b/examples/camel-example-spring-boot-xml/src/main/resources/application.properties
@@ -0,0 +1,46 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# the name of Camel
+camel.springboot.name = SampleCamel
+
+# to automatic shutdown the JVM after a period of time
+#camel.springboot.duration-max-seconds=60
+#camel.springboot.duration-max-messages=100
+
+# add for example: &repeatCount=5 to the timer endpoint to make Camel idle
+#camel.springboot.duration-max-idle-seconds=15
+
+# properties used in the Camel route and beans
+# --------------------------------------------
+
+# what to say
+greeting = Hello World
+
+# how often to trigger the timer
+timer.period = 2000
+
+# all access to actuator endpoints without security
+management.security.enabled = false
+# turn on actuator health check
+endpoints.health.enabled = true
+
+# to configure logging levels
+#logging.level.org.springframework = INFO
+#logging.level.org.apache.camel.spring.boot = INFO
+#logging.level.org.apache.camel.impl = DEBUG
+#logging.level.sample.camel = DEBUG

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/camel-example-spring-boot-xml/src/main/resources/my-camel.xml
----------------------------------------------------------------------
diff --git 
a/examples/camel-example-spring-boot-xml/src/main/resources/my-camel.xml 
b/examples/camel-example-spring-boot-xml/src/main/resources/my-camel.xml
new file mode 100644
index 0000000..4f5d773
--- /dev/null
+++ b/examples/camel-example-spring-boot-xml/src/main/resources/my-camel.xml
@@ -0,0 +1,21 @@
+<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 id="SampleCamel" xmlns="http://camel.apache.org/schema/spring";>
+    <route id="hello">
+      <from uri="timer:hello?period={{timer.period}}"/>
+      <transform>
+        <method ref="myBean" method="saySomething"/>
+      </transform>
+      <filter>
+        <simple>${body} contains 'foo'</simple>
+        <to uri="log:foo"/>
+      </filter>
+      <to uri="stream:out"/>
+    </route>
+  </camelContext>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/camel-example-spring-boot-xml/src/test/java/sample/camel/FooApplicationTest.java
----------------------------------------------------------------------
diff --git 
a/examples/camel-example-spring-boot-xml/src/test/java/sample/camel/FooApplicationTest.java
 
b/examples/camel-example-spring-boot-xml/src/test/java/sample/camel/FooApplicationTest.java
new file mode 100644
index 0000000..45f2076
--- /dev/null
+++ 
b/examples/camel-example-spring-boot-xml/src/test/java/sample/camel/FooApplicationTest.java
@@ -0,0 +1,52 @@
+/**
+ * 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 sample.camel;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.NotifyBuilder;
+import org.apache.camel.test.spring.CamelSpringBootRunner;
+import org.apache.camel.test.spring.EnableRouteCoverage;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import static org.junit.Assert.assertTrue;
+
+@RunWith(CamelSpringBootRunner.class)
+@SpringBootTest(classes = SampleCamelApplication.class,
+    properties = "greeting = Hello foo")
+@EnableRouteCoverage
+//@Ignore // enable me to run this test as well so we can cover testing the 
route completely
+public class FooApplicationTest {
+
+    @Autowired
+    private CamelContext camelContext;
+
+    @Test
+    public void shouldSayFoo() throws Exception {
+        // we expect that one or more messages is automatic done by the Camel
+        // route as it uses a timer to trigger
+        NotifyBuilder notify = new 
NotifyBuilder(camelContext).whenDone(1).create();
+
+        assertTrue(notify.matches(10, TimeUnit.SECONDS));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/camel-example-spring-boot-xml/src/test/java/sample/camel/SampleCamelApplicationTest.java
----------------------------------------------------------------------
diff --git 
a/examples/camel-example-spring-boot-xml/src/test/java/sample/camel/SampleCamelApplicationTest.java
 
b/examples/camel-example-spring-boot-xml/src/test/java/sample/camel/SampleCamelApplicationTest.java
new file mode 100644
index 0000000..f4c2fc5
--- /dev/null
+++ 
b/examples/camel-example-spring-boot-xml/src/test/java/sample/camel/SampleCamelApplicationTest.java
@@ -0,0 +1,49 @@
+/**
+ * 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 sample.camel;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.NotifyBuilder;
+import org.apache.camel.test.spring.CamelSpringBootRunner;
+import org.apache.camel.test.spring.EnableRouteCoverage;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import static org.junit.Assert.assertTrue;
+
+@RunWith(CamelSpringBootRunner.class)
+@SpringBootTest(classes = SampleCamelApplication.class)
+@EnableRouteCoverage
+public class SampleCamelApplicationTest {
+
+    @Autowired
+    private CamelContext camelContext;
+
+    @Test
+    public void shouldProduceMessages() throws Exception {
+        // we expect that one or more messages is automatic done by the Camel
+        // route as it uses a timer to trigger
+        NotifyBuilder notify = new 
NotifyBuilder(camelContext).whenDone(1).create();
+
+        assertTrue(notify.matches(10, TimeUnit.SECONDS));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/examples/pom.xml
----------------------------------------------------------------------
diff --git a/examples/pom.xml b/examples/pom.xml
index 6a67f6c..39ebcf1 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -108,6 +108,7 @@
     <module>camel-example-spring-boot-rest-swagger</module>
     <module>camel-example-spring-boot-servicecall</module>
     <module>camel-example-spring-boot-supervising-route-controller</module>
+    <module>camel-example-spring-boot-xml</module>
     <module>camel-example-spring-cloud-servicecall</module>
     <module>camel-example-spring-javaconfig</module>
     <module>camel-example-spring-jms</module>

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRouteParser.java
----------------------------------------------------------------------
diff --git 
a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRouteParser.java
 
b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRouteParser.java
index 364cf9a..d6696b4 100644
--- 
a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRouteParser.java
+++ 
b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRouteParser.java
@@ -17,8 +17,12 @@
 package org.apache.camel.parser;
 
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.camel.parser.helper.CamelXmlTreeParserHelper;
+import org.apache.camel.parser.model.CamelNodeDetails;
+import org.apache.camel.parser.model.CamelNodeDetailsFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 
@@ -44,6 +48,57 @@ public final class XmlRouteParser {
     }
 
     /**
+     * Parses the XML file and build a route model (tree) of the discovered 
routes in the XML source file.
+     *
+     * @param xml                     the xml file as input stream
+     * @param baseDir                 the base of the source code
+     * @param fullyQualifiedFileName  the fully qualified source code file name
+     * @return a list of route model (tree) of each discovered route
+     */
+    public static List<CamelNodeDetails> parseXmlRouteTree(InputStream xml, 
String baseDir, String fullyQualifiedFileName) {
+        List<CamelNodeDetails> answer = new ArrayList<>();
+
+        // try parse it as dom
+        Document dom = null;
+        try {
+            dom = XmlLineNumberParser.parseXml(xml);
+        } catch (Exception e) {
+            // ignore as the xml file may not be valid at this point
+        }
+        if (dom != null) {
+
+            // find any from which is the start of the route
+            CamelNodeDetailsFactory nodeFactory = 
CamelNodeDetailsFactory.newInstance();
+
+            List<Node> routes = CamelXmlHelper.findAllRoutes(dom);
+            for (Node route : routes) {
+                // parse each route and build
+                String routeId = getSafeAttribute(route, "id");
+                String lineNumber = (String) 
route.getUserData(XmlLineNumberParser.LINE_NUMBER);
+                String lineNumberEnd = (String) 
route.getUserData(XmlLineNumberParser.LINE_NUMBER_END);
+
+                // we only want the relative dir name from the resource 
directory, eg META-INF/spring/foo.xml
+                String fileName = fullyQualifiedFileName;
+                if (fileName.startsWith(baseDir)) {
+                    fileName = fileName.substring(baseDir.length() + 1);
+                }
+
+                CamelNodeDetails node = nodeFactory.newNode(null, "route");
+                node.setRouteId(routeId);
+                node.setFileName(fileName);
+                node.setLineNumber(lineNumber);
+                node.setLineNumberEnd(lineNumberEnd);
+
+                // parse the route and gather all its EIPs
+                List<CamelNodeDetails> tree = 
CamelXmlTreeParserHelper.parseCamelRouteTree(route, routeId, node, baseDir, 
fullyQualifiedFileName);
+                answer.addAll(tree);
+            }
+        }
+
+        return answer;
+    }
+
+    /**
      * Parses the XML source to discover Camel endpoints.
      *
      * @param xml                     the xml file as input stream

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlTreeParserHelper.java
----------------------------------------------------------------------
diff --git 
a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlTreeParserHelper.java
 
b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlTreeParserHelper.java
new file mode 100644
index 0000000..a9a75d9
--- /dev/null
+++ 
b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlTreeParserHelper.java
@@ -0,0 +1,71 @@
+/**
+ * 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.parser.helper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.camel.parser.model.CamelNodeDetails;
+import org.apache.camel.parser.model.CamelNodeDetailsFactory;
+
+public final class CamelXmlTreeParserHelper {
+
+    private CamelXmlTreeParserHelper() {
+    }
+
+    public static List<CamelNodeDetails> parseCamelRouteTree(Node route, 
String routeId, CamelNodeDetails parent,
+                                                             String baseDir, 
String fullyQualifiedFileName) {
+
+        CamelNodeDetailsFactory nodeFactory = 
CamelNodeDetailsFactory.newInstance();
+        List<CamelNodeDetails> answer = new ArrayList<>();
+
+        walkXmlTree(nodeFactory, route, parent);
+        answer.add(parent);
+        return answer;
+    }
+
+    private static void walkXmlTree(CamelNodeDetailsFactory nodeFactory, Node 
node, CamelNodeDetails parent) {
+        CamelNodeDetails newNode = null;
+
+        String name = node.getNodeName();
+        // skip route as we just keep from
+        if (!"route".equals(name)) {
+            String lineNumber = (String) 
node.getUserData(XmlLineNumberParser.LINE_NUMBER);
+            String lineNumberEnd = (String) 
node.getUserData(XmlLineNumberParser.LINE_NUMBER_END);
+            newNode = nodeFactory.newNode(parent, name);
+            newNode.setRouteId(parent.getRouteId());
+            newNode.setFileName(parent.getFileName());
+            newNode.setLineNumber(lineNumber);
+            newNode.setLineNumberEnd(lineNumberEnd);
+
+            parent.addOutput(newNode);
+        }
+
+        NodeList children = node.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node child = children.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                walkXmlTree(nodeFactory, child, newNode != null ? newNode : 
parent);
+            }
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlParseTreeTest.java
----------------------------------------------------------------------
diff --git 
a/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlParseTreeTest.java
 
b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlParseTreeTest.java
new file mode 100644
index 0000000..d65f287
--- /dev/null
+++ 
b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlParseTreeTest.java
@@ -0,0 +1,60 @@
+/**
+ * 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.parser.xml;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.camel.parser.XmlRouteParser;
+import org.apache.camel.parser.model.CamelNodeDetails;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class XmlParseTreeTest {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(XmlParseTreeTest.class);
+
+    @Test
+    public void testXmlTree() throws Exception {
+        InputStream is = new 
FileInputStream("src/test/resources/org/apache/camel/parser/xml/mycamel.xml");
+        String fqn = 
"src/test/resources/org/apache/camel/camel/parser/xml/mycamel.xml";
+        String baseDir = "src/test/resources";
+        List<CamelNodeDetails> list = XmlRouteParser.parseXmlRouteTree(is, 
baseDir, fqn);
+
+        assertEquals(1, list.size());
+        CamelNodeDetails details = list.get(0);
+        assertEquals("org/apache/camel/camel/parser/xml/mycamel.xml", 
details.getFileName());
+        assertEquals("myRoute", details.getRouteId());
+        assertEquals(null, details.getMethodName());
+        assertEquals(null, details.getClassName());
+
+        String tree = details.dump(0);
+        LOG.info("\n" + tree);
+
+        assertTrue(tree.contains("29\troute"));
+        assertTrue(tree.contains("32\t  from"));
+        assertTrue(tree.contains("35\t  transform"));
+        assertTrue(tree.contains("36\t    simple"));
+        assertTrue(tree.contains("39\t  to"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/mycamel.xml
----------------------------------------------------------------------
diff --git 
a/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/mycamel.xml
 
b/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/mycamel.xml
index 6293639..683d78f 100644
--- 
a/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/mycamel.xml
+++ 
b/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/mycamel.xml
@@ -26,7 +26,7 @@
   <!-- START SNIPPET: e1 -->
   <!-- camelContext is the Camel runtime, where we can host Camel routes -->
   <camelContext xmlns="http://camel.apache.org/schema/spring";>
-    <route>
+    <route id="myRoute">
       <!-- read input from the console using the stream component -->
       <from
           uri="stream:in?promptMessage=Enter something: "/>

http://git-wip-us.apache.org/repos/asf/camel/blob/aed13265/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java
----------------------------------------------------------------------
diff --git 
a/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java
 
b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java
index 21b28bf..6bd22ff 100644
--- 
a/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java
+++ 
b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/RouteCoverageMojo.java
@@ -18,6 +18,8 @@ package org.apache.camel.maven;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -27,14 +29,12 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
-import org.apache.camel.maven.helper.RouteCoverageHelper;
 import org.apache.camel.maven.helper.EndpointHelper;
+import org.apache.camel.maven.helper.RouteCoverageHelper;
 import org.apache.camel.maven.model.RouteCoverageNode;
 import org.apache.camel.parser.RouteBuilderParser;
-import org.apache.camel.parser.model.CamelEndpointDetails;
+import org.apache.camel.parser.XmlRouteParser;
 import org.apache.camel.parser.model.CamelNodeDetails;
-import org.apache.camel.parser.model.CamelRouteDetails;
-import org.apache.camel.parser.model.CamelSimpleExpressionDetails;
 import org.apache.camel.util.KeyValueHolder;
 import org.apache.maven.model.Resource;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -98,9 +98,6 @@ public class RouteCoverageMojo extends AbstractExecMojo {
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
 
-        List<CamelEndpointDetails> endpoints = new ArrayList<>();
-        List<CamelSimpleExpressionDetails> simpleExpressions = new 
ArrayList<>();
-        List<CamelRouteDetails> routeIds = new ArrayList<>();
         Set<File> javaFiles = new LinkedHashSet<File>();
         Set<File> xmlFiles = new LinkedHashSet<File>();
 
@@ -135,7 +132,6 @@ public class RouteCoverageMojo extends AbstractExecMojo {
         for (File file : javaFiles) {
             if (matchFile(file)) {
                 try {
-
                     // parse the java source code and find Camel RouteBuilder 
classes
                     String fqn = file.getPath();
                     String baseDir = ".";
@@ -154,7 +150,13 @@ public class RouteCoverageMojo extends AbstractExecMojo {
         for (File file : xmlFiles) {
             if (matchFile(file)) {
                 try {
-                    // TODO: implement me
+                    // parse the xml files code and find Camel routes
+                    String fqn = file.getPath();
+                    String baseDir = ".";
+                    InputStream is = new FileInputStream(file);
+                    List<CamelNodeDetails> result = 
XmlRouteParser.parseXmlRouteTree(is, baseDir, fqn);
+                    routeTrees.addAll(result);
+                    is.close();
                 } catch (Exception e) {
                     getLog().warn("Error parsing xml file " + file + " code 
due " + e.getMessage(), e);
                 }
@@ -402,16 +404,4 @@ public class RouteCoverageMojo extends AbstractExecMojo {
         return name;
     }
 
-    private static String asPackageName(String name) {
-        return name.replace(File.separator, ".");
-    }
-
-    private static String asSimpleClassName(String className) {
-        int dot = className.lastIndexOf('.');
-        if (dot > 0) {
-            return className.substring(dot + 1);
-        } else {
-            return className;
-        }
-    }
 }

Reply via email to