You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2018/09/20 09:41:10 UTC
[camel] 01/02: CAMEL-12824: camel-route-parser - Add parser for
rest-dsl
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 adcf45c5dea9c5ce25eb58debb3b67f29095d71b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Sep 20 11:09:55 2018 +0200
CAMEL-12824: camel-route-parser - Add parser for rest-dsl
---
.../org/apache/camel/parser/RestDslParser.java | 75 ++++
.../helper/CamelJavaRestDslParserHelper.java | 381 +++++++++++++++++++++
.../parser/model/RestConfigurationDetails.java | 328 ++++++++++++++++++
.../camel/parser/java/MyRestDslRouteBuilder.java | 31 ++
.../camel/parser/java/RoasterJavaRestDslTest.java | 55 +++
5 files changed, 870 insertions(+)
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
new file mode 100644
index 0000000..fb29182
--- /dev/null
+++ b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/RestDslParser.java
@@ -0,0 +1,75 @@
+/**
+ * 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.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.camel.parser.helper.CamelJavaParserHelper;
+import org.apache.camel.parser.helper.CamelJavaRestDslParserHelper;
+import org.apache.camel.parser.model.RestConfigurationDetails;
+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.
+ * <p/>
+ * This implementation is higher level details, and uses the lower level parser {@link CamelJavaRestDslParserHelper}.
+ */
+public final class RestDslParser {
+
+ private RestDslParser() {
+ }
+
+ /**
+ * Parses the java source class and build a rest configuration model of the discovered rest configurations in the java source class.
+ *
+ * @param clazz the java source class
+ * @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(JavaClassSource clazz, String baseDir, String fullyQualifiedFileName,
+ boolean includeInlinedRouteBuilders) {
+
+ List<MethodSource<JavaClassSource>> methods = new ArrayList<>();
+ MethodSource<JavaClassSource> method = CamelJavaParserHelper.findConfigureMethod(clazz);
+ if (method != null) {
+ methods.add(method);
+ }
+ if (includeInlinedRouteBuilders) {
+ List<MethodSource<JavaClassSource>> inlinedMethods = CamelJavaParserHelper.findInlinedConfigureMethods(clazz);
+ if (!inlinedMethods.isEmpty()) {
+ methods.addAll(inlinedMethods);
+ }
+ }
+
+ CamelJavaRestDslParserHelper parser = new CamelJavaRestDslParserHelper();
+ List<RestConfigurationDetails> list = new ArrayList<>();
+ for (MethodSource<JavaClassSource> configureMethod : methods) {
+ // there may be multiple route builder configure methods
+ List<RestConfigurationDetails> details = parser.parseRestConfiguration(clazz, baseDir, fullyQualifiedFileName, configureMethod);
+ list.addAll(details);
+ }
+ // we end up parsing bottom->up so reverse list
+ Collections.reverse(list);
+
+ return list;
+ }
+
+}
diff --git a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelJavaRestDslParserHelper.java b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelJavaRestDslParserHelper.java
new file mode 100644
index 0000000..38cc0c1
--- /dev/null
+++ b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/helper/CamelJavaRestDslParserHelper.java
@@ -0,0 +1,381 @@
+/**
+ * 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.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.parser.model.RestConfigurationDetails;
+import org.apache.camel.parser.roaster.StatementFieldSource;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.ASTNode;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.Block;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.BooleanLiteral;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.Expression;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.InfixExpression;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.MemberValuePair;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.MethodInvocation;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.NormalAnnotation;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.NumberLiteral;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.ParenthesizedExpression;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.QualifiedName;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.SimpleName;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.SingleMemberAnnotation;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.StringLiteral;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.Type;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+import org.jboss.forge.roaster.model.Annotation;
+import org.jboss.forge.roaster.model.source.FieldSource;
+import org.jboss.forge.roaster.model.source.JavaClassSource;
+import org.jboss.forge.roaster.model.source.MethodSource;
+
+/**
+ * A Camel Java Rest DSL parser that only depends on the Roaster API.
+ * <p/>
+ * This implement is used for parsing the Camel routes and build a tree structure of the Rest DSL services.
+ */
+public final class CamelJavaRestDslParserHelper {
+
+ public List<RestConfigurationDetails> parseRestConfiguration(JavaClassSource clazz, String baseDir, String fullyQualifiedFileName,
+ MethodSource<JavaClassSource> configureMethod) {
+
+ List<RestConfigurationDetails> answer = new ArrayList<>();
+
+ if (configureMethod != null) {
+ MethodDeclaration md = (MethodDeclaration) configureMethod.getInternal();
+ Block block = md.getBody();
+ if (block != null) {
+ for (Object statement : md.getBody().statements()) {
+ // must be a method call expression
+ if (statement instanceof ExpressionStatement) {
+ ExpressionStatement es = (ExpressionStatement) statement;
+ Expression exp = es.getExpression();
+ boolean valid = isRestConfiguration(exp);
+ if (valid) {
+ RestConfigurationDetails node = new RestConfigurationDetails();
+ answer.add(node);
+
+ // include source code details
+ int pos = exp.getStartPosition();
+ int line = findLineNumber(fullyQualifiedFileName, pos);
+ if (line > -1) {
+ node.setLineNumber("" + line);
+ }
+ node.setFileName(fullyQualifiedFileName);
+ node.setClassName(clazz.getQualifiedName());
+ node.setMethodName(configureMethod.getName());
+
+ parseExpression(node, fullyQualifiedFileName, clazz, configureMethod, block, exp);
+ }
+ }
+ }
+ }
+ }
+
+ return answer;
+ }
+
+ private boolean isRestConfiguration(Expression exp) {
+ String rootMethodName = null;
+
+ // find out if this is from a Camel route (eg from, route etc.)
+ Expression sub = exp;
+ while (sub instanceof MethodInvocation) {
+ sub = ((MethodInvocation) sub).getExpression();
+ if (sub instanceof MethodInvocation) {
+ Expression parent = ((MethodInvocation) sub).getExpression();
+ if (parent == null) {
+ break;
+ }
+ }
+ }
+ if (sub instanceof MethodInvocation) {
+ rootMethodName = ((MethodInvocation) sub).getName().getIdentifier();
+ } else if (sub instanceof SimpleName) {
+ rootMethodName = ((SimpleName) sub).getIdentifier();
+ }
+
+ // must be from rest configuration
+ return "restConfiguration".equals(rootMethodName);
+ }
+
+ private void parseExpression(RestConfigurationDetails node, String fullyQualifiedFileName,
+ JavaClassSource clazz, MethodSource<JavaClassSource> configureMethod, Block block,
+ Expression exp) {
+ if (exp == null) {
+ return;
+ }
+ if (exp instanceof MethodInvocation) {
+ MethodInvocation mi = (MethodInvocation) exp;
+ doParseRestConfiguration(node, fullyQualifiedFileName, clazz, configureMethod, block, mi);
+ // if the method was called on another method, then recursive
+ exp = mi.getExpression();
+ parseExpression(node, fullyQualifiedFileName, clazz, configureMethod, block, exp);
+ }
+ }
+
+ private void doParseRestConfiguration(RestConfigurationDetails node, String fullyQualifiedFileName,
+ JavaClassSource clazz, MethodSource<JavaClassSource> configureMethod, Block block,
+ MethodInvocation mi) {
+ String name = mi.getName().getIdentifier();
+ if ("port".equals(name)) {
+ node.setPort(extractValueFromFirstArgument(clazz, block, mi));
+ } else if ("contextPath".equals(name)) {
+ node.setContextPath(extractValueFromFirstArgument(clazz, block, mi));
+ }
+ }
+
+ private static String extractValueFromFirstArgument(JavaClassSource clazz, Block block, MethodInvocation mi) {
+ List args = mi.arguments();
+ if (args != null && args.size() > 0) {
+ Expression exp = (Expression) args.get(0);
+ return getLiteralValue(clazz, block, exp);
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static FieldSource<JavaClassSource> getField(JavaClassSource clazz, Block block, SimpleName ref) {
+ String fieldName = ref.getIdentifier();
+ if (fieldName != null) {
+ // find field in class
+ FieldSource field = clazz != null ? clazz.getField(fieldName) : null;
+ if (field == null) {
+ field = findFieldInBlock(clazz, block, fieldName);
+ }
+ return field;
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static FieldSource<JavaClassSource> findFieldInBlock(JavaClassSource clazz, Block block, String fieldName) {
+ for (Object statement : block.statements()) {
+ // try local statements first in the block
+ if (statement instanceof VariableDeclarationStatement) {
+ final Type type = ((VariableDeclarationStatement) statement).getType();
+ for (Object obj : ((VariableDeclarationStatement) statement).fragments()) {
+ if (obj instanceof VariableDeclarationFragment) {
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) obj;
+ SimpleName name = fragment.getName();
+ if (name != null && fieldName.equals(name.getIdentifier())) {
+ return new StatementFieldSource(clazz, fragment, type);
+ }
+ }
+ }
+ }
+
+ // okay the field may be burried inside an anonymous inner class as a field declaration
+ // outside the configure method, so lets go back to the parent and see what we can find
+ ASTNode node = block.getParent();
+ if (node instanceof MethodDeclaration) {
+ node = node.getParent();
+ }
+ if (node instanceof AnonymousClassDeclaration) {
+ List declarations = ((AnonymousClassDeclaration) node).bodyDeclarations();
+ for (Object dec : declarations) {
+ if (dec instanceof FieldDeclaration) {
+ FieldDeclaration fd = (FieldDeclaration) dec;
+ final Type type = fd.getType();
+ for (Object obj : fd.fragments()) {
+ if (obj instanceof VariableDeclarationFragment) {
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) obj;
+ SimpleName name = fragment.getName();
+ if (name != null && fieldName.equals(name.getIdentifier())) {
+ return new StatementFieldSource(clazz, fragment, type);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public static String getLiteralValue(JavaClassSource clazz, Block block, Expression expression) {
+ // unwrap parenthesis
+ if (expression instanceof ParenthesizedExpression) {
+ expression = ((ParenthesizedExpression) expression).getExpression();
+ }
+
+ if (expression instanceof StringLiteral) {
+ return ((StringLiteral) expression).getLiteralValue();
+ } else if (expression instanceof BooleanLiteral) {
+ return "" + ((BooleanLiteral) expression).booleanValue();
+ } else if (expression instanceof NumberLiteral) {
+ return ((NumberLiteral) expression).getToken();
+ }
+
+ // if it a method invocation then add a dummy value assuming the method invocation will return a valid response
+ if (expression instanceof MethodInvocation) {
+ String name = ((MethodInvocation) expression).getName().getIdentifier();
+ return "{{" + name + "}}";
+ }
+
+ // if its a qualified name (usually a constant field in another class)
+ // then add a dummy value as we cannot find the field value in other classes and maybe even outside the
+ // source code we have access to
+ if (expression instanceof QualifiedName) {
+ QualifiedName qn = (QualifiedName) expression;
+ String name = qn.getFullyQualifiedName();
+ return "{{" + name + "}}";
+ }
+
+ if (expression instanceof SimpleName) {
+ FieldSource<JavaClassSource> field = getField(clazz, block, (SimpleName) expression);
+ if (field != null) {
+ // is the field annotated with a Camel endpoint
+ if (field.getAnnotations() != null) {
+ for (Annotation ann : field.getAnnotations()) {
+ boolean valid = "org.apache.camel.EndpointInject".equals(ann.getQualifiedName()) || "org.apache.camel.cdi.Uri".equals(ann.getQualifiedName());
+ if (valid) {
+ Expression exp = (Expression) ann.getInternal();
+ if (exp instanceof SingleMemberAnnotation) {
+ exp = ((SingleMemberAnnotation) exp).getValue();
+ } else if (exp instanceof NormalAnnotation) {
+ List values = ((NormalAnnotation) exp).values();
+ for (Object value : values) {
+ MemberValuePair pair = (MemberValuePair) value;
+ if ("uri".equals(pair.getName().toString())) {
+ exp = pair.getValue();
+ break;
+ }
+ }
+ }
+ if (exp != null) {
+ return getLiteralValue(clazz, block, exp);
+ }
+ }
+ }
+ }
+ // is the field an org.apache.camel.Endpoint type?
+ if ("Endpoint".equals(field.getType().getSimpleName())) {
+ // then grab the uri from the first argument
+ VariableDeclarationFragment vdf = (VariableDeclarationFragment) field.getInternal();
+ expression = vdf.getInitializer();
+ if (expression instanceof MethodInvocation) {
+ MethodInvocation mi = (MethodInvocation) expression;
+ List args = mi.arguments();
+ if (args != null && args.size() > 0) {
+ // the first argument has the endpoint uri
+ expression = (Expression) args.get(0);
+ return getLiteralValue(clazz, block, expression);
+ }
+ }
+ } else {
+ // no annotations so try its initializer
+ VariableDeclarationFragment vdf = (VariableDeclarationFragment) field.getInternal();
+ expression = vdf.getInitializer();
+ if (expression == null) {
+ // its a field which has no initializer, then add a dummy value assuming the field will be initialized at runtime
+ return "{{" + field.getName() + "}}";
+ } else {
+ return getLiteralValue(clazz, block, expression);
+ }
+ }
+ } else {
+ // we could not find the field in this class/method, so its maybe from some other super class, so insert a dummy value
+ final String fieldName = ((SimpleName) expression).getIdentifier();
+ return "{{" + fieldName + "}}";
+ }
+ } else if (expression instanceof InfixExpression) {
+ String answer = null;
+ // is it a string that is concat together?
+ InfixExpression ie = (InfixExpression) expression;
+ if (InfixExpression.Operator.PLUS.equals(ie.getOperator())) {
+
+ String val1 = getLiteralValue(clazz, block, ie.getLeftOperand());
+ String val2 = getLiteralValue(clazz, block, ie.getRightOperand());
+
+ // if numeric then we plus the values, otherwise we string concat
+ boolean numeric = isNumericOperator(clazz, block, ie.getLeftOperand()) && isNumericOperator(clazz, block, ie.getRightOperand());
+ if (numeric) {
+ Long num1 = val1 != null ? Long.valueOf(val1) : 0;
+ Long num2 = val2 != null ? Long.valueOf(val2) : 0;
+ answer = "" + (num1 + num2);
+ } else {
+ answer = (val1 != null ? val1 : "") + (val2 != null ? val2 : "");
+ }
+
+ if (!answer.isEmpty()) {
+ // include extended when we concat on 2 or more lines
+ List extended = ie.extendedOperands();
+ if (extended != null) {
+ for (Object ext : extended) {
+ String val3 = getLiteralValue(clazz, block, (Expression) ext);
+ if (numeric) {
+ Long num3 = val3 != null ? Long.valueOf(val3) : 0;
+ Long num = Long.valueOf(answer);
+ answer = "" + (num + num3);
+ } else {
+ answer += val3 != null ? val3 : "";
+ }
+ }
+ }
+ }
+ }
+ return answer;
+ }
+
+ return null;
+ }
+
+ private static boolean isNumericOperator(JavaClassSource clazz, Block block, Expression expression) {
+ if (expression instanceof NumberLiteral) {
+ return true;
+ } else if (expression instanceof SimpleName) {
+ FieldSource field = getField(clazz, block, (SimpleName) expression);
+ if (field != null) {
+ return field.getType().isType("int") || field.getType().isType("long")
+ || field.getType().isType("Integer") || field.getType().isType("Long");
+ }
+ }
+ return false;
+ }
+
+ private static int findLineNumber(String fullyQualifiedFileName, int position) {
+ int lines = 0;
+
+ try {
+ int current = 0;
+ try (BufferedReader br = new BufferedReader(new FileReader(new File(fullyQualifiedFileName)))) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ lines++;
+ current += line.length() + 1; // add 1 for line feed
+ if (current >= position) {
+ return lines;
+ }
+ }
+ }
+ } catch (Exception e) {
+ // ignore
+ return -1;
+ }
+
+ return lines;
+ }
+
+}
diff --git a/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/model/RestConfigurationDetails.java b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/model/RestConfigurationDetails.java
new file mode 100644
index 0000000..c38cb65
--- /dev/null
+++ b/tooling/camel-route-parser/src/main/java/org/apache/camel/parser/model/RestConfigurationDetails.java
@@ -0,0 +1,328 @@
+/**
+ * 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.model;
+
+import java.util.Map;
+
+public class RestConfigurationDetails {
+
+ // source code details
+ private String fileName;
+ private String lineNumber;
+ private String lineNumberEnd;
+ private int linePosition;
+
+ // java source code details
+ private String className;
+ private String methodName;
+
+ // camel rest configuration details
+ private String component;
+ private String apiComponent;
+ private String producerComponent;
+ private String scheme;
+ private String host;
+ private String apiHost;
+ private String port;
+ private String producerApiDoc;
+ private String contextPath;
+ private String apiContextPath;
+ private String apiContextRouteId;
+ private String apiContextIdPattern;
+ private String apiContextListening;
+ private String apiVendorExtension;
+ private String hostNameResolver;
+ private String bindingMode;
+ private String skipBindingOnErrorCode;
+ private String clientRequestValidation;
+ private String enableCORS;
+ private String jsonDataFormat;
+ private String xmlDataFormat;
+ private Map<String, String> componentProperties;
+ private Map<String, String> endpointProperties;
+ private Map<String, String> consumerProperties;
+ private Map<String, String> dataFormatProperties;
+ private Map<String, String> apiProperties;
+ private Map<String, String> corsHeaders;
+
+ public RestConfigurationDetails() {
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getLineNumber() {
+ return lineNumber;
+ }
+
+ public void setLineNumber(String lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ public String getLineNumberEnd() {
+ return lineNumberEnd;
+ }
+
+ public void setLineNumberEnd(String lineNumberEnd) {
+ this.lineNumberEnd = lineNumberEnd;
+ }
+
+ public int getLinePosition() {
+ return linePosition;
+ }
+
+ public void setLinePosition(int linePosition) {
+ this.linePosition = linePosition;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+
+ public void setMethodName(String methodName) {
+ this.methodName = methodName;
+ }
+
+ public String getComponent() {
+ return component;
+ }
+
+ public void setComponent(String component) {
+ this.component = component;
+ }
+
+ public String getApiComponent() {
+ return apiComponent;
+ }
+
+ public void setApiComponent(String apiComponent) {
+ this.apiComponent = apiComponent;
+ }
+
+ public String getProducerComponent() {
+ return producerComponent;
+ }
+
+ public void setProducerComponent(String producerComponent) {
+ this.producerComponent = producerComponent;
+ }
+
+ public String getScheme() {
+ return scheme;
+ }
+
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public String getApiHost() {
+ return apiHost;
+ }
+
+ public void setApiHost(String apiHost) {
+ this.apiHost = apiHost;
+ }
+
+ public String getPort() {
+ return port;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ public String getProducerApiDoc() {
+ return producerApiDoc;
+ }
+
+ public void setProducerApiDoc(String producerApiDoc) {
+ this.producerApiDoc = producerApiDoc;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public void setContextPath(String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ public String getApiContextPath() {
+ return apiContextPath;
+ }
+
+ public void setApiContextPath(String apiContextPath) {
+ this.apiContextPath = apiContextPath;
+ }
+
+ public String getApiContextRouteId() {
+ return apiContextRouteId;
+ }
+
+ public void setApiContextRouteId(String apiContextRouteId) {
+ this.apiContextRouteId = apiContextRouteId;
+ }
+
+ public String getApiContextIdPattern() {
+ return apiContextIdPattern;
+ }
+
+ public void setApiContextIdPattern(String apiContextIdPattern) {
+ this.apiContextIdPattern = apiContextIdPattern;
+ }
+
+ public String getApiContextListening() {
+ return apiContextListening;
+ }
+
+ public void setApiContextListening(String apiContextListening) {
+ this.apiContextListening = apiContextListening;
+ }
+
+ public String getApiVendorExtension() {
+ return apiVendorExtension;
+ }
+
+ public void setApiVendorExtension(String apiVendorExtension) {
+ this.apiVendorExtension = apiVendorExtension;
+ }
+
+ public String getHostNameResolver() {
+ return hostNameResolver;
+ }
+
+ public void setHostNameResolver(String hostNameResolver) {
+ this.hostNameResolver = hostNameResolver;
+ }
+
+ public String getBindingMode() {
+ return bindingMode;
+ }
+
+ public void setBindingMode(String bindingMode) {
+ this.bindingMode = bindingMode;
+ }
+
+ public String getSkipBindingOnErrorCode() {
+ return skipBindingOnErrorCode;
+ }
+
+ public void setSkipBindingOnErrorCode(String skipBindingOnErrorCode) {
+ this.skipBindingOnErrorCode = skipBindingOnErrorCode;
+ }
+
+ public String getClientRequestValidation() {
+ return clientRequestValidation;
+ }
+
+ public void setClientRequestValidation(String clientRequestValidation) {
+ this.clientRequestValidation = clientRequestValidation;
+ }
+
+ public String getEnableCORS() {
+ return enableCORS;
+ }
+
+ public void setEnableCORS(String enableCORS) {
+ this.enableCORS = enableCORS;
+ }
+
+ public String getJsonDataFormat() {
+ return jsonDataFormat;
+ }
+
+ public void setJsonDataFormat(String jsonDataFormat) {
+ this.jsonDataFormat = jsonDataFormat;
+ }
+
+ public String getXmlDataFormat() {
+ return xmlDataFormat;
+ }
+
+ public void setXmlDataFormat(String xmlDataFormat) {
+ this.xmlDataFormat = xmlDataFormat;
+ }
+
+ public Map<String, String> getComponentProperties() {
+ return componentProperties;
+ }
+
+ public void setComponentProperties(Map<String, String> componentProperties) {
+ this.componentProperties = componentProperties;
+ }
+
+ public Map<String, String> getEndpointProperties() {
+ return endpointProperties;
+ }
+
+ public void setEndpointProperties(Map<String, String> endpointProperties) {
+ this.endpointProperties = endpointProperties;
+ }
+
+ public Map<String, String> getConsumerProperties() {
+ return consumerProperties;
+ }
+
+ public void setConsumerProperties(Map<String, String> consumerProperties) {
+ this.consumerProperties = consumerProperties;
+ }
+
+ public Map<String, String> getDataFormatProperties() {
+ return dataFormatProperties;
+ }
+
+ public void setDataFormatProperties(Map<String, String> dataFormatProperties) {
+ this.dataFormatProperties = dataFormatProperties;
+ }
+
+ public Map<String, String> getApiProperties() {
+ return apiProperties;
+ }
+
+ public void setApiProperties(Map<String, String> apiProperties) {
+ this.apiProperties = apiProperties;
+ }
+
+ public Map<String, String> getCorsHeaders() {
+ return corsHeaders;
+ }
+
+ public void setCorsHeaders(Map<String, String> corsHeaders) {
+ this.corsHeaders = corsHeaders;
+ }
+}
diff --git a/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/java/MyRestDslRouteBuilder.java b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/java/MyRestDslRouteBuilder.java
new file mode 100644
index 0000000..b73f77d
--- /dev/null
+++ b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/java/MyRestDslRouteBuilder.java
@@ -0,0 +1,31 @@
+/**
+ * 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.java;
+
+import org.apache.camel.builder.RouteBuilder;
+
+public class MyRestDslRouteBuilder extends RouteBuilder {
+
+ @Override
+ public void configure() throws Exception {
+ restConfiguration().contextPath("myapi").port(1234);
+
+ rest()
+ .get("/foo")
+ .to("log:foo");
+ }
+}
diff --git a/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/java/RoasterJavaRestDslTest.java b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/java/RoasterJavaRestDslTest.java
new file mode 100644
index 0000000..81a19a4
--- /dev/null
+++ b/tooling/camel-route-parser/src/test/java/org/apache/camel/parser/java/RoasterJavaRestDslTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.java;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.camel.parser.RestDslParser;
+import org.apache.camel.parser.model.RestConfigurationDetails;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.jboss.forge.roaster.Roaster;
+import org.jboss.forge.roaster.model.source.JavaClassSource;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RoasterJavaRestDslTest extends CamelTestSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RoasterJavaRestDslTest.class);
+
+ @Override
+ public boolean isDumpRouteCoverage() {
+ return false;
+ }
+
+ @Test
+ public void parseTree() throws Exception {
+ JavaClassSource clazz = (JavaClassSource) Roaster.parse(new File("src/test/java/org/apache/camel/parser/java/MyRestDslRouteBuilder.java"));
+
+ List<RestConfigurationDetails> list = RestDslParser.parseRestConfiguration(clazz, ".",
+ "src/test/java/org/apache/camel/parser/java/MyRestDslRouteBuilder.java", true);
+ assertEquals(1, list.size());
+ RestConfigurationDetails details = list.get(0);
+ assertEquals("src/test/java/org/apache/camel/parser/java/MyRestDslRouteBuilder.java", details.getFileName());
+ assertEquals("configure", details.getMethodName());
+ assertEquals("org.apache.camel.parser.java.MyRestDslRouteBuilder", details.getClassName());
+ assertEquals("1234", details.getPort());
+ assertEquals("myapi", details.getContextPath());
+ }
+
+}