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

davsclaus pushed a commit to branch rest-dsl-parser
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/rest-dsl-parser by this push:
     new 926d86c  CAMEL-12824: camel-route-parser - Add parser for rest-dsl
926d86c is described below

commit 926d86c20e628c9f85fd7448452f76d1881dd7db
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sun Sep 23 11:55:17 2018 +0200

    CAMEL-12824: camel-route-parser - Add parser for rest-dsl
---
 .../org/apache/camel/parser/XmlRestDslParser.java  |  28 ++++-
 .../parser/helper/CamelXmlRestDslParserHelper.java | 136 +++++++++++++++++++++
 .../apache/camel/parser/xml/XmlRestDslTest.java    |  42 +++++++
 .../org/apache/camel/parser/xml/myrest.xml         |  13 ++
 4 files changed, 217 insertions(+), 2 deletions(-)

diff --git 
a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRestDslParser.java
 
b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRestDslParser.java
index db7a835..e28a295 100644
--- 
a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRestDslParser.java
+++ 
b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRestDslParser.java
@@ -25,6 +25,7 @@ import org.w3c.dom.Document;
 import org.apache.camel.parser.helper.CamelXmlRestDslParserHelper;
 import org.apache.camel.parser.helper.XmlLineNumberParser;
 import org.apache.camel.parser.model.RestConfigurationDetails;
+import org.apache.camel.parser.model.RestServiceDetails;
 
 /**
  * A Camel XML parser that parses Camel XML Rest DSL source code.
@@ -33,8 +34,6 @@ import org.apache.camel.parser.model.RestConfigurationDetails;
  */
 public final class XmlRestDslParser {
 
-    // TODO: xml rest services
-
     private XmlRestDslParser() {
     }
 
@@ -62,4 +61,29 @@ public final class XmlRestDslParser {
         return Collections.EMPTY_LIST;
     }
 
+    /**
+     * Parses the java source class and build a rest service model of the 
discovered rest services in the java source class.
+     *
+     * @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 rest services
+     */
+    public static List<RestServiceDetails> parseRestService(InputStream xml, 
String baseDir, String fullyQualifiedFileName) {
+
+        // 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) {
+            CamelXmlRestDslParserHelper parser = new 
CamelXmlRestDslParserHelper();
+            return parser.parseRestService(dom, baseDir, 
fullyQualifiedFileName);
+        }
+
+        return Collections.EMPTY_LIST;
+    }
+
 }
diff --git 
a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlRestDslParserHelper.java
 
b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlRestDslParserHelper.java
index 0e83c1f..bb04cab 100644
--- 
a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlRestDslParserHelper.java
+++ 
b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlRestDslParserHelper.java
@@ -24,6 +24,8 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
 import org.apache.camel.parser.model.RestConfigurationDetails;
+import org.apache.camel.parser.model.RestServiceDetails;
+import org.apache.camel.parser.model.RestVerbDetails;
 
 public final class CamelXmlRestDslParserHelper {
 
@@ -39,6 +41,18 @@ public final class CamelXmlRestDslParserHelper {
         return answer;
     }
 
+    public List<RestServiceDetails> parseRestService(Node xmlNode, String 
baseDir, String fullyQualifiedFileName) {
+
+        List<RestServiceDetails> answer = new ArrayList<>();
+
+        RestServiceDetails detail = new RestServiceDetails();
+        detail.setFileName(fullyQualifiedFileName);
+        walkXmlTree(xmlNode, detail);
+        answer.add(detail);
+
+        return answer;
+    }
+
     private void walkXmlTree(Node xmlNode, RestConfigurationDetails detail) {
         if ("restConfiguration".equals(xmlNode.getNodeName())) {
             String lineNumber = (String) 
xmlNode.getUserData(XmlLineNumberParser.LINE_NUMBER);
@@ -130,6 +144,128 @@ public final class CamelXmlRestDslParserHelper {
         }
     }
 
+    private void walkXmlTree(Node xmlNode, RestServiceDetails detail) {
+        if ("rest".equals(xmlNode.getNodeName())) {
+            String lineNumber = (String) 
xmlNode.getUserData(XmlLineNumberParser.LINE_NUMBER);
+            String lineNumberEnd = (String) 
xmlNode.getUserData(XmlLineNumberParser.LINE_NUMBER_END);
+            detail.setLineNumber(lineNumber);
+            detail.setLineNumberEnd(lineNumberEnd);
+            extractAttributes(xmlNode, detail);
+        }
+
+        if (isParentRest(xmlNode)) {
+            if ("delete".equals(xmlNode.getNodeName())) {
+                RestVerbDetails verb = new RestVerbDetails();
+                verb.setMethod("delete");
+                detail.addVerb(verb);
+                extractAttributes(xmlNode, verb);
+            } else if ("get".equals(xmlNode.getNodeName())) {
+                RestVerbDetails verb = new RestVerbDetails();
+                verb.setMethod("get");
+                detail.addVerb(verb);
+                extractAttributes(xmlNode, verb);
+            } else if ("head".equals(xmlNode.getNodeName())) {
+                RestVerbDetails verb = new RestVerbDetails();
+                verb.setMethod("head");
+                detail.addVerb(verb);
+                extractAttributes(xmlNode, verb);
+            } else if ("patch".equals(xmlNode.getNodeName())) {
+                RestVerbDetails verb = new RestVerbDetails();
+                verb.setMethod("patch");
+                detail.addVerb(verb);
+                extractAttributes(xmlNode, verb);
+            } else if ("post".equals(xmlNode.getNodeName())) {
+                RestVerbDetails verb = new RestVerbDetails();
+                verb.setMethod("post");
+                detail.addVerb(verb);
+                extractAttributes(xmlNode, verb);
+            } else if ("put".equals(xmlNode.getNodeName())) {
+                RestVerbDetails verb = new RestVerbDetails();
+                verb.setMethod("put");
+                detail.addVerb(verb);
+                extractAttributes(xmlNode, verb);
+            }
+
+            if ("description".equals(xmlNode.getNodeName())) {
+                String value = xmlNode.getTextContent();
+                RestVerbDetails verb = getLastVerb(detail);
+                if (verb != null) {
+                    verb.setDescription(value);
+                } else {
+                    detail.setDescription(value);
+                }
+            } else if ("to".equals(xmlNode.getNodeName())) {
+                NamedNodeMap map = xmlNode.getAttributes();
+                String uri = extractAttribute(map, "uri");
+                RestVerbDetails verb = getLastVerb(detail);
+                if (verb != null) {
+                    verb.setTo(uri);
+                }
+            } else if ("toD".equals(xmlNode.getNodeName())) {
+                NamedNodeMap map = xmlNode.getAttributes();
+                String uri = extractAttribute(map, "uri");
+                RestVerbDetails verb = getLastVerb(detail);
+                if (verb != null) {
+                    verb.setToD(uri);
+                }
+            }
+        }
+
+        // walk the rest of the children
+        NodeList children = xmlNode.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node child = children.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                walkXmlTree(child, detail);
+            }
+        }
+    }
+
+    private static void extractAttributes(Node xmlNode, RestServiceDetails 
detail) {
+        NamedNodeMap map = xmlNode.getAttributes();
+        detail.setConsumes(extractAttribute(map, "consumes"));
+        detail.setProduces(extractAttribute(map, "produces"));
+        detail.setApiDocs(extractAttribute(map, "apiDocs"));
+        detail.setBindingMode(extractAttribute(map, "bindingMode"));
+        detail.setClientRequestValidation(extractAttribute(map, 
"clientRequestValidation"));
+        detail.setEnableCORS(extractAttribute(map, "enableCORS"));
+        detail.setPath(extractAttribute(map, "path"));
+        detail.setSkipBindingOnErrorCode(extractAttribute(map, 
"skipBindingOnErrorCode"));
+        detail.setTag(extractAttribute(map, "tag"));
+    }
+
+    private static void extractAttributes(Node xmlNode, RestVerbDetails 
detail) {
+        NamedNodeMap map = xmlNode.getAttributes();
+        detail.setUri(extractAttribute(map, "uri"));
+        detail.setConsumes(extractAttribute(map, "consumes"));
+        detail.setProduces(extractAttribute(map, "produces"));
+        detail.setApiDocs(extractAttribute(map, "apiDocs"));
+        detail.setBindingMode(extractAttribute(map, "bindingMode"));
+        detail.setClientRequestValidation(extractAttribute(map, 
"clientRequestValidation"));
+        detail.setSkipBindingOnErrorCode(extractAttribute(map, 
"skipBindingOnErrorCode"));
+        detail.setType(extractAttribute(map, "type"));
+        detail.setOutType(extractAttribute(map, "outType"));
+    }
+
+    private static RestVerbDetails getLastVerb(RestServiceDetails detail) {
+        if (detail.getVerbs() == null) {
+            return null;
+        }
+        return detail.getVerbs().get(detail.getVerbs().size() - 1);
+    }
+
+    private static boolean isParentRest(Node node) {
+        if (node == null) {
+            return false;
+        }
+        String name = node.getNodeName();
+        if ("rest".equals(name)) {
+            return true;
+        } else {
+            return isParentRest(node.getParentNode());
+        }
+    }
+
     private static String extractAttribute(NamedNodeMap map, String name) {
         if (map != null) {
             Node attr = map.getNamedItem(name);
diff --git 
a/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlRestDslTest.java
 
b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlRestDslTest.java
index 6acc2c6..78e1156 100644
--- 
a/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlRestDslTest.java
+++ 
b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlRestDslTest.java
@@ -16,12 +16,17 @@
  */
 package org.apache.camel.parser.xml;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.util.List;
 
+import org.apache.camel.parser.RestDslParser;
 import org.apache.camel.parser.XmlRestDslParser;
 import org.apache.camel.parser.model.RestConfigurationDetails;
+import org.apache.camel.parser.model.RestServiceDetails;
+import org.jboss.forge.roaster.Roaster;
+import org.jboss.forge.roaster.model.source.JavaClassSource;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -66,4 +71,41 @@ public class XmlRestDslTest {
         assertEquals("value2", details.getCorsHeaders().get("key2"));
     }
 
+    @Test
+    public void parseRestService() throws Exception {
+        InputStream is = new 
FileInputStream("src/test/resources/org/apache/camel/parser/xml/myrest.xml");
+        String fqn = 
"src/test/resources/org/apache/camel/camel/parser/xml/myrest.xml";
+        String baseDir = "src/test/resources";
+        List<RestServiceDetails> list = XmlRestDslParser.parseRestService(is, 
baseDir, fqn);
+
+        assertEquals(1, list.size());
+        RestServiceDetails details = list.get(0);
+        
assertEquals("src/test/resources/org/apache/camel/camel/parser/xml/myrest.xml", 
details.getFileName());
+        assertNull(details.getMethodName());
+        assertNull(details.getClassName());
+
+        assertEquals("37", details.getLineNumber());
+        assertEquals("47", details.getLineNumberEnd());
+        
assertEquals("src/test/resources/org/apache/camel/camel/parser/xml/myrest.xml", 
details.getFileName());
+        assertNull(details.getMethodName());
+        assertNull(details.getClassName());
+
+        assertEquals("/foo", details.getPath());
+        assertEquals("my foo service", details.getDescription());
+        assertEquals("json", details.getProduces());
+        assertEquals("json", details.getProduces());
+        assertEquals(2, details.getVerbs().size());
+        assertEquals("get", details.getVerbs().get(0).getMethod());
+        assertEquals("{id}", details.getVerbs().get(0).getUri());
+        assertEquals("get by id", details.getVerbs().get(0).getDescription());
+        assertEquals("log:id", details.getVerbs().get(0).getTo());
+        assertEquals("false", details.getVerbs().get(0).getApiDocs());
+        assertEquals("post", details.getVerbs().get(1).getMethod());
+        assertEquals("post something", 
details.getVerbs().get(1).getDescription());
+        assertEquals("xml", details.getVerbs().get(1).getBindingMode());
+        assertEquals("log:post", details.getVerbs().get(1).getToD());
+        assertNull(details.getVerbs().get(1).getUri());
+    }
+
+
 }
diff --git 
a/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/myrest.xml
 
b/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/myrest.xml
index 370be9e..82f493a 100644
--- 
a/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/myrest.xml
+++ 
b/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/myrest.xml
@@ -33,6 +33,19 @@
       <corsHeaders key="key1" value="value1"/>
       <corsHeaders key="key2" value="value2"/>
     </restConfiguration>
+
+    <rest path="/foo" consumes="xml" produces="json">
+      <description>my foo service</description>
+      <get uri="{id}" apiDocs="false">
+        <description>get by id</description>
+        <to uri="log:id"/>
+      </get>
+      <post bindingMode="xml">
+        <description>post something</description>
+        <toD uri="log:post"/>
+      </post>
+    </rest>
+
   </camelContext>
 
 </beans>

Reply via email to