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
commit 90344acf562adc798fe4065f230cc59739144586 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Sep 20 16:04:41 2018 +0200 CAMEL-12824: camel-route-parser - Add parser for rest-dsl --- .../org/apache/camel/parser/RestDslParser.java | 3 +- .../org/apache/camel/parser/XmlRestDslParser.java | 63 +++++++++++++++ .../parser/helper/CamelXmlRestDslParserHelper.java | 93 ++++++++++++++++++++++ .../apache/camel/parser/xml/XmlRestDslTest.java | 63 +++++++++++++++ .../org/apache/camel/parser/xml/myrest.xml | 33 ++++++++ 5 files changed, 253 insertions(+), 2 deletions(-) diff --git a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/RestDslParser.java b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/RestDslParser.java index e8dd599..e73bbe9 100644 --- a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/RestDslParser.java +++ b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/RestDslParser.java @@ -27,14 +27,13 @@ import org.jboss.forge.roaster.model.source.JavaClassSource; import org.jboss.forge.roaster.model.source.MethodSource; /** - * A Camel Rest DSL parser that parses Camel Java Rest DSL. + * A Camel parser that parses Camel Java Rest DSL source code. * <p/> * This implementation is higher level details, and uses the lower level parser {@link CamelJavaRestDslParserHelper}. */ public final class RestDslParser { // TODO: add support for rest services (eg rest().get() ...) - // TODO: add XML rest-dsl parser also private RestDslParser() { } 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 new file mode 100644 index 0000000..372c9e1 --- /dev/null +++ b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/XmlRestDslParser.java @@ -0,0 +1,63 @@ +/** + * 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; + +import java.io.InputStream; +import java.util.Collections; +import java.util.List; + +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; + +/** + * A Camel XML parser that parses Camel XML Rest DSL source code. + * <p/> + * This implementation is higher level details, and uses the lower level parser {@link CamelXmlRestDslParserHelper}. + */ +public final class XmlRestDslParser { + + private XmlRestDslParser() { + } + + /** + * Parses the XML file and build a rest configuration model of the discovered rest configurations 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 rest configurations (often there is only one) + */ + public static List<RestConfigurationDetails> parseRestConfiguration(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.parseRestConfiguration(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 new file mode 100644 index 0000000..17c667b --- /dev/null +++ b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlRestDslParserHelper.java @@ -0,0 +1,93 @@ +/** + * 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.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.apache.camel.parser.model.RestConfigurationDetails; + +public final class CamelXmlRestDslParserHelper { + + public List<RestConfigurationDetails> parseRestConfiguration(Node xmlNode, String baseDir, String fullyQualifiedFileName) { + + List<RestConfigurationDetails> answer = new ArrayList<>(); + + RestConfigurationDetails detail = new RestConfigurationDetails(); + 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); + String lineNumberEnd = (String) xmlNode.getUserData(XmlLineNumberParser.LINE_NUMBER_END); + detail.setLineNumber(lineNumber); + detail.setLineNumberEnd(lineNumberEnd); + + NamedNodeMap map = xmlNode.getAttributes(); + detail.setComponent(extractAttribute(map, "component")); + detail.setApiComponent(extractAttribute(map, "apiComponent")); + detail.setProducerComponent(extractAttribute(map, "producerComponent")); + detail.setScheme(extractAttribute(map, "scheme")); + detail.setHost(extractAttribute(map, "host")); + detail.setApiHost(extractAttribute(map, "apiHost")); + detail.setPort(extractAttribute(map, "port")); + detail.setProducerApiDoc(extractAttribute(map, "producerApiDoc")); + detail.setContextPath(extractAttribute(map, "contextPath")); + detail.setApiContextPath(extractAttribute(map, "apiContextPath")); + detail.setApiContextRouteId(extractAttribute(map, "apiContextRouteId")); + detail.setApiContextIdPattern(extractAttribute(map, "apiContextIdPattern")); + detail.setApiContextListening(extractAttribute(map, "apiContextListening")); + detail.setApiVendorExtension(extractAttribute(map, "apiVendorExtension")); + detail.setHostNameResolver(extractAttribute(map, "hostNameResolver")); + detail.setBindingMode(extractAttribute(map, "bindingMode")); + detail.setSkipBindingOnErrorCode(extractAttribute(map, "skipBindingOnErrorCode")); + detail.setClientRequestValidation(extractAttribute(map, "clientRequestValidation")); + detail.setEnableCORS(extractAttribute(map, "enableCORS")); + detail.setJsonDataFormat(extractAttribute(map, "jsonDataFormat")); + detail.setXmlDataFormat(extractAttribute(map, "xmlDataFormat")); + } + + // 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 String extractAttribute(NamedNodeMap map, String name) { + if (map != null) { + Node attr = map.getNamedItem(name); + if (attr != null) { + return attr.getTextContent(); + } + } + return null; + } + +} 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 new file mode 100644 index 0000000..856c1e2 --- /dev/null +++ b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/xml/XmlRestDslTest.java @@ -0,0 +1,63 @@ +/** + * 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.XmlRestDslParser; +import org.apache.camel.parser.model.RestConfigurationDetails; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.assertEquals; + +public class XmlRestDslTest { + + 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/myrest.xml"); + String fqn = "src/test/resources/org/apache/camel/camel/parser/xml/myrest.xml"; + String baseDir = "src/test/resources"; + List<RestConfigurationDetails> list = XmlRestDslParser.parseRestConfiguration(is, baseDir, fqn); + + assertEquals(1, list.size()); + RestConfigurationDetails details = list.get(0); + assertEquals("src/test/resources/org/apache/camel/camel/parser/xml/myrest.xml", details.getFileName()); + assertEquals(null, details.getMethodName()); + assertEquals(null, details.getClassName()); + + assertEquals("29", details.getLineNumber()); + assertEquals("30", details.getLineNumberEnd()); + assertEquals("1234", details.getPort()); + assertEquals("myapi", details.getContextPath()); + assertEquals("jetty", details.getComponent()); + assertEquals("json", details.getBindingMode()); + assertEquals("swagger", details.getApiComponent()); + assertEquals("myapi/swagger", details.getApiContextPath()); + assertEquals("localhost", details.getApiHost()); + assertEquals("true", details.getSkipBindingOnErrorCode()); + assertEquals("https", details.getScheme()); + assertEquals("allLocalIp", details.getHostNameResolver()); + + } + +} 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 new file mode 100644 index 0000000..ef54669 --- /dev/null +++ b/tooling/camel-route-parser/src/test/resources/org/apache/camel/parser/xml/myrest.xml @@ -0,0 +1,33 @@ +<?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"> + <restConfiguration component="jetty" port="1234" bindingMode="json" apiComponent="swagger" scheme="https" + contextPath="myapi" apiContextPath="myapi/swagger" hostNameResolver="allLocalIp" apiHost="localhost" + skipBindingOnErrorCode="true"> + </restConfiguration> + </camelContext> + +</beans>