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; - } - } }
