Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 0EA24200BCF for ; Mon, 5 Dec 2016 13:20:48 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 0D364160AF9; Mon, 5 Dec 2016 12:20:48 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id C0FA2160B17 for ; Mon, 5 Dec 2016 13:20:45 +0100 (CET) Received: (qmail 73517 invoked by uid 500); 5 Dec 2016 12:20:45 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 73412 invoked by uid 99); 5 Dec 2016 12:20:44 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Dec 2016 12:20:44 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C607DE00E5; Mon, 5 Dec 2016 12:20:44 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: davsclaus@apache.org To: commits@camel.apache.org Date: Mon, 05 Dec 2016 12:20:45 -0000 Message-Id: In-Reply-To: <6287a6dff559425f9f9f526087b36f5d@git.apache.org> References: <6287a6dff559425f9f9f526087b36f5d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/4] camel git commit: CAMEL-10559: route parser for java and xml to parse source code. Donated from fabric8 project. archived-at: Mon, 05 Dec 2016 12:20:48 -0000 http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/CamelJavaParserHelper.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/CamelJavaParserHelper.java b/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/CamelJavaParserHelper.java new file mode 100644 index 0000000..6df709a --- /dev/null +++ b/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/CamelJavaParserHelper.java @@ -0,0 +1,638 @@ +/** + * 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.Collections; +import java.util.List; + +import org.apache.camel.parser.ParserResult; +import org.apache.camel.parser.RouteBuilderParser; +import org.apache.camel.parser.roaster.AnonymousMethodSource; +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.ClassInstanceCreation; +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.ReturnStatement; +import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.SimpleName; +import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.SimpleType; +import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.SingleMemberAnnotation; +import org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.Statement; +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.VariableDeclaration; +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.AnnotationSource; +import org.jboss.forge.roaster.model.source.FieldSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.jboss.forge.roaster.model.source.MethodSource; +import org.jboss.forge.roaster.model.util.Strings; + +/** + * A Camel Java parser that only depends on the Roaster API. + *

+ * This implementation is lower level details. For a higher level parser see {@link RouteBuilderParser}. + */ +public final class CamelJavaParserHelper { + + private CamelJavaParserHelper() { + // utility class + } + + public static MethodSource findConfigureMethod(JavaClassSource clazz) { + MethodSource method = clazz.getMethod("configure"); + // must be public void configure() + if (method != null && method.isPublic() && method.getParameters().isEmpty() && method.getReturnType().isType("void")) { + return method; + } + + // maybe the route builder is from unit testing with camel-test as an anonymous inner class + // there is a bit of code to dig out this using the eclipse jdt api + method = findCreateRouteBuilderMethod(clazz); + if (method != null) { + return findConfigureMethodInCreateRouteBuilder(clazz, method); + } + + return null; + } + + public static List> findInlinedConfigureMethods(JavaClassSource clazz) { + List> answer = new ArrayList<>(); + + List> methods = clazz.getMethods(); + if (methods != null) { + for (MethodSource method : methods) { + if (method.isPublic() + && (method.getParameters() == null || method.getParameters().isEmpty()) + && (method.getReturnType() == null || method.getReturnType().isType("void"))) { + // maybe the method contains an inlined createRouteBuilder usually from an unit test method + MethodSource builder = findConfigureMethodInCreateRouteBuilder(clazz, method); + if (builder != null) { + answer.add(builder); + } + } + } + } + + return answer; + } + + private static MethodSource findCreateRouteBuilderMethod(JavaClassSource clazz) { + MethodSource method = clazz.getMethod("createRouteBuilder"); + if (method != null && (method.isPublic() || method.isProtected()) && method.getParameters().isEmpty()) { + return method; + } + return null; + } + + private static MethodSource findConfigureMethodInCreateRouteBuilder(JavaClassSource clazz, MethodSource method) { + // find configure inside the code + MethodDeclaration md = (MethodDeclaration) method.getInternal(); + Block block = md.getBody(); + if (block != null) { + List statements = block.statements(); + for (int i = 0; i < statements.size(); i++) { + Statement stmt = (Statement) statements.get(i); + Expression exp = null; + if (stmt instanceof ReturnStatement) { + ReturnStatement rs = (ReturnStatement) stmt; + exp = rs.getExpression(); + } else if (stmt instanceof ExpressionStatement) { + ExpressionStatement es = (ExpressionStatement) stmt; + exp = es.getExpression(); + if (exp instanceof MethodInvocation) { + MethodInvocation mi = (MethodInvocation) exp; + for (Object arg : mi.arguments()) { + if (arg instanceof ClassInstanceCreation) { + exp = (Expression) arg; + break; + } + } + } + } + if (exp != null && exp instanceof ClassInstanceCreation) { + ClassInstanceCreation cic = (ClassInstanceCreation) exp; + boolean isRouteBuilder = false; + if (cic.getType() instanceof SimpleType) { + SimpleType st = (SimpleType) cic.getType(); + isRouteBuilder = "RouteBuilder".equals(st.getName().toString()); + } + if (isRouteBuilder && cic.getAnonymousClassDeclaration() != null) { + List body = cic.getAnonymousClassDeclaration().bodyDeclarations(); + for (int j = 0; j < body.size(); j++) { + Object line = body.get(j); + if (line instanceof MethodDeclaration) { + MethodDeclaration amd = (MethodDeclaration) line; + if ("configure".equals(amd.getName().toString())) { + return new AnonymousMethodSource(clazz, amd); + } + } + } + } + } + } + } + + return null; + } + + public static List parseCamelConsumerUris(MethodSource method, boolean strings, boolean fields) { + return doParseCamelUris(method, true, false, strings, fields); + } + + public static List parseCamelProducerUris(MethodSource method, boolean strings, boolean fields) { + return doParseCamelUris(method, false, true, strings, fields); + } + + private static List doParseCamelUris(MethodSource method, boolean consumers, boolean producers, + boolean strings, boolean fields) { + + List answer = new ArrayList(); + + if (method != null) { + MethodDeclaration md = (MethodDeclaration) method.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(); + + List uris = new ArrayList(); + parseExpression(method.getOrigin(), block, exp, uris, consumers, producers, strings, fields); + if (!uris.isEmpty()) { + // reverse the order as we will grab them from last->first + Collections.reverse(uris); + answer.addAll(uris); + } + } + } + } + } + + return answer; + } + + private static void parseExpression(JavaClassSource clazz, Block block, Expression exp, List uris, + boolean consumers, boolean producers, boolean strings, boolean fields) { + if (exp == null) { + return; + } + if (exp instanceof MethodInvocation) { + MethodInvocation mi = (MethodInvocation) exp; + doParseCamelUris(clazz, block, mi, uris, consumers, producers, strings, fields); + // if the method was called on another method, then recursive + exp = mi.getExpression(); + parseExpression(clazz, block, exp, uris, consumers, producers, strings, fields); + } + } + + private static void doParseCamelUris(JavaClassSource clazz, Block block, MethodInvocation mi, List uris, + boolean consumers, boolean producers, boolean strings, boolean fields) { + String name = mi.getName().getIdentifier(); + + if (consumers) { + if ("from".equals(name)) { + List args = mi.arguments(); + if (args != null) { + for (Object arg : args) { + if (isValidArgument(name, arg)) { + extractEndpointUriFromArgument(name, clazz, block, uris, arg, strings, fields); + } + } + } + } + if ("fromF".equals(name)) { + List args = mi.arguments(); + // the first argument is where the uri is + if (args != null && args.size() >= 1) { + Object arg = args.get(0); + if (isValidArgument(name, arg)) { + extractEndpointUriFromArgument(name, clazz, block, uris, arg, strings, fields); + } + } + } + if ("pollEnrich".equals(name)) { + List args = mi.arguments(); + // the first argument is where the uri is + if (args != null && args.size() >= 1) { + Object arg = args.get(0); + if (isValidArgument(name, arg)) { + extractEndpointUriFromArgument(name, clazz, block, uris, arg, strings, fields); + } + } + } + } + + if (producers) { + if ("to".equals(name) || "toD".equals(name)) { + List args = mi.arguments(); + if (args != null) { + for (Object arg : args) { + // skip if the arg is a boolean, ExchangePattern or Iterateable, type + if (isValidArgument(name, arg)) { + extractEndpointUriFromArgument(name, clazz, block, uris, arg, strings, fields); + } + } + } + } + if ("toF".equals(name)) { + List args = mi.arguments(); + // the first argument is where the uri is + if (args != null && args.size() >= 1) { + Object arg = args.get(0); + if (isValidArgument(name, arg)) { + extractEndpointUriFromArgument(name, clazz, block, uris, arg, strings, fields); + } + } + } + if ("enrich".equals(name) || "wireTap".equals(name)) { + List args = mi.arguments(); + // the first argument is where the uri is + if (args != null && args.size() >= 1) { + Object arg = args.get(0); + if (isValidArgument(name, arg)) { + extractEndpointUriFromArgument(name, clazz, block, uris, arg, strings, fields); + } + } + } + } + } + + private static boolean isValidArgument(String node, Object arg) { + // skip boolean argument, as toD can accept a boolean value + if (arg instanceof BooleanLiteral) { + return false; + } + // skip ExchangePattern argument + if (arg instanceof QualifiedName) { + QualifiedName qn = (QualifiedName) arg; + String name = qn.getFullyQualifiedName(); + if (name.startsWith("ExchangePattern")) { + return false; + } + } + return true; + } + + private static void extractEndpointUriFromArgument(String node, JavaClassSource clazz, Block block, List uris, Object arg, boolean strings, boolean fields) { + if (strings) { + String uri = getLiteralValue(clazz, block, (Expression) arg); + if (!Strings.isBlank(uri)) { + int position = ((Expression) arg).getStartPosition(); + + // if the node is fromF or toF, then replace all %s with {{%s}} as we cannot parse that value + if ("fromF".equals(node) || "toF".equals(node)) { + uri = uri.replaceAll("\\%s", "\\{\\{\\%s\\}\\}"); + } + + uris.add(new ParserResult(node, position, uri)); + return; + } + } + if (fields && arg instanceof SimpleName) { + FieldSource field = getField(clazz, block, (SimpleName) arg); + if (field != null) { + // find the endpoint uri from the annotation + AnnotationSource annotation = field.getAnnotation("org.apache.camel.cdi.Uri"); + if (annotation == null) { + annotation = field.getAnnotation("org.apache.camel.EndpointInject"); + } + if (annotation != null) { + Expression exp = (Expression) annotation.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; + } + } + } + String uri = CamelJavaParserHelper.getLiteralValue(clazz, block, exp); + if (!Strings.isBlank(uri)) { + int position = ((SimpleName) arg).getStartPosition(); + uris.add(new ParserResult(node, position, uri)); + } + } else { + // the field may be initialized using variables, so we need to evaluate those expressions + Object fi = field.getInternal(); + if (fi instanceof VariableDeclaration) { + Expression exp = ((VariableDeclaration) fi).getInitializer(); + String uri = CamelJavaParserHelper.getLiteralValue(clazz, block, exp); + if (!Strings.isBlank(uri)) { + // we want the position of the field, and not in the route + int position = ((VariableDeclaration) fi).getStartPosition(); + uris.add(new ParserResult(node, position, uri)); + } + } + } + } + } + + // cannot parse it so add a failure + uris.add(new ParserResult(node, -1, arg.toString(), false)); + } + + public static List parseCamelSimpleExpressions(MethodSource method) { + List answer = new ArrayList(); + + MethodDeclaration md = (MethodDeclaration) method.getInternal(); + Block block = md.getBody(); + if (block != null) { + for (Object statement : block.statements()) { + // must be a method call expression + if (statement instanceof ExpressionStatement) { + ExpressionStatement es = (ExpressionStatement) statement; + Expression exp = es.getExpression(); + + List expressions = new ArrayList(); + parseExpression(null, method.getOrigin(), block, exp, expressions); + if (!expressions.isEmpty()) { + // reverse the order as we will grab them from last->first + Collections.reverse(expressions); + answer.addAll(expressions); + } + } + } + } + + return answer; + } + + private static void parseExpression(String node, JavaClassSource clazz, Block block, Expression exp, List expressions) { + if (exp == null) { + return; + } + if (exp instanceof MethodInvocation) { + MethodInvocation mi = (MethodInvocation) exp; + doParseCamelSimple(node, clazz, block, mi, expressions); + // if the method was called on another method, then recursive + exp = mi.getExpression(); + parseExpression(node, clazz, block, exp, expressions); + } + } + + private static void doParseCamelSimple(String node, JavaClassSource clazz, Block block, MethodInvocation mi, List expressions) { + String name = mi.getName().getIdentifier(); + + if ("simple".equals(name)) { + List args = mi.arguments(); + // the first argument is a string parameter for the simple expression + if (args != null && args.size() >= 1) { + // it is a String type + Object arg = args.get(0); + String simple = getLiteralValue(clazz, block, (Expression) arg); + if (!Strings.isBlank(simple)) { + int position = ((Expression) arg).getStartPosition(); + expressions.add(new ParserResult(node, position, simple)); + } + } + } + + // simple maybe be passed in as an argument + List args = mi.arguments(); + if (args != null) { + for (Object arg : args) { + if (arg instanceof MethodInvocation) { + MethodInvocation ami = (MethodInvocation) arg; + doParseCamelSimple(node, clazz, block, ami, expressions); + } + } + } + } + + @SuppressWarnings("unchecked") + private static FieldSource 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 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 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; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlHelper.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlHelper.java b/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlHelper.java new file mode 100644 index 0000000..53d4783 --- /dev/null +++ b/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/CamelXmlHelper.java @@ -0,0 +1,268 @@ +/** + * 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.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.jboss.forge.roaster.model.util.Strings; + +/** + * Various XML helper methods used for parsing XML routes. + */ +public final class CamelXmlHelper { + + private CamelXmlHelper() { + // utility class + } + + public static String getSafeAttribute(Node node, String key) { + if (node != null) { + Node attr = node.getAttributes().getNamedItem(key); + if (attr != null) { + return attr.getNodeValue(); + } + } + return null; + } + + public static List findAllEndpoints(Document dom) { + List nodes = new ArrayList<>(); + + NodeList list = dom.getElementsByTagName("endpoint"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + if ("endpoint".equals(child.getNodeName())) { + // it may not be a camel namespace, so skip those + String ns = child.getNamespaceURI(); + if (ns == null) { + NamedNodeMap attrs = child.getAttributes(); + if (attrs != null) { + Node node = attrs.getNamedItem("xmlns"); + if (node != null) { + ns = node.getNodeValue(); + } + } + } + // assume no namespace its for camel + if (ns == null || ns.contains("camel")) { + nodes.add(child); + } + } + } + + list = dom.getElementsByTagName("onException"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + findAllUrisRecursive(child, nodes); + } + list = dom.getElementsByTagName("onCompletion"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + findAllUrisRecursive(child, nodes); + } + list = dom.getElementsByTagName("intercept"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + findAllUrisRecursive(child, nodes); + } + list = dom.getElementsByTagName("interceptFrom"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + findAllUrisRecursive(child, nodes); + } + list = dom.getElementsByTagName("interceptSendToEndpoint"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + findAllUrisRecursive(child, nodes); + } + list = dom.getElementsByTagName("rest"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + if ("route".equals(child.getNodeName()) || "to".equals(child.getNodeName())) { + findAllUrisRecursive(child, nodes); + } + } + list = dom.getElementsByTagName("route"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + if ("route".equals(child.getNodeName())) { + findAllUrisRecursive(child, nodes); + } + } + + return nodes; + } + + private static void findAllUrisRecursive(Node node, List nodes) { + // okay its a route so grab all uri attributes we can find + String url = getSafeAttribute(node, "uri"); + if (url != null) { + nodes.add(node); + } + + NodeList children = node.getChildNodes(); + if (children != null) { + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + findAllUrisRecursive(child, nodes); + } + } + } + } + + public static List findAllSimpleExpressions(Document dom) { + List nodes = new ArrayList<>(); + + NodeList list = dom.getElementsByTagName("route"); + for (int i = 0; i < list.getLength(); i++) { + Node child = list.item(i); + if ("route".equals(child.getNodeName())) { + findAllSimpleExpressionsRecursive(child, nodes); + } + } + + return nodes; + } + + private static void findAllSimpleExpressionsRecursive(Node node, List nodes) { + // okay its a route so grab if its + if ("simple".equals(node.getNodeName())) { + nodes.add(node); + } + + NodeList children = node.getChildNodes(); + if (children != null) { + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + findAllSimpleExpressionsRecursive(child, nodes); + } + } + } + } + + public static Element getSelectedCamelElementNode(String key, InputStream resourceInputStream) throws Exception { + Document root = loadCamelXmlFileAsDom(resourceInputStream); + Element selectedElement = null; + if (root != null) { + Node selectedNode = findCamelNodeInDocument(root, key); + if (selectedNode instanceof Element) { + selectedElement = (Element) selectedNode; + } + } + return selectedElement; + } + + private static Document loadCamelXmlFileAsDom(InputStream resourceInputStream) throws Exception { + // must enforce the namespace to be http://camel.apache.org/schema/spring which is what the camel-core JAXB model uses + Document root = XmlLineNumberParser.parseXml(resourceInputStream, "camelContext,routes,rests", "http://camel.apache.org/schema/spring"); + return root; + } + + private static Node findCamelNodeInDocument(Document root, String key) { + Node selectedNode = null; + if (root != null && !Strings.isBlank(key)) { + String[] paths = key.split("/"); + NodeList camels = getCamelContextElements(root); + if (camels != null) { + Map rootNodeCounts = new HashMap<>(); + for (int i = 0, size = camels.getLength(); i < size; i++) { + Node node = camels.item(i); + boolean first = true; + for (String path : paths) { + if (first) { + first = false; + String actual = getIdOrIndex(node, rootNodeCounts); + if (!equal(actual, path)) { + node = null; + } + } else { + node = findCamelNodeForPath(node, path); + } + if (node == null) { + break; + } + } + if (node != null) { + return node; + } + } + } + } + return selectedNode; + } + + private static Node findCamelNodeForPath(Node node, String path) { + NodeList childNodes = node.getChildNodes(); + if (childNodes != null) { + Map nodeCounts = new HashMap<>(); + for (int i = 0, size = childNodes.getLength(); i < size; i++) { + Node child = childNodes.item(i); + if (child instanceof Element) { + String actual = getIdOrIndex(child, nodeCounts); + if (equal(actual, path)) { + return child; + } + } + } + } + return null; + } + + private static String getIdOrIndex(Node node, Map nodeCounts) { + String answer = null; + if (node instanceof Element) { + Element element = (Element) node; + String elementName = element.getTagName(); + if ("routes".equals(elementName)) { + elementName = "camelContext"; + } + Integer countObject = nodeCounts.get(elementName); + int count = countObject != null ? countObject.intValue() : 0; + nodeCounts.put(elementName, ++count); + answer = element.getAttribute("id"); + if (Strings.isBlank(answer)) { + answer = "_" + elementName + count; + } + } + return answer; + } + + private static NodeList getCamelContextElements(Document dom) { + NodeList camels = dom.getElementsByTagName("camelContext"); + if (camels == null || camels.getLength() == 0) { + camels = dom.getElementsByTagName("routes"); + } + return camels; + } + + private static boolean equal(Object a, Object b) { + return a == b ? true : a != null && b != null && a.equals(b); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/XmlLineNumberParser.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/XmlLineNumberParser.java b/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/XmlLineNumberParser.java new file mode 100644 index 0000000..b214b1e --- /dev/null +++ b/tooling/route-parser/src/main/java/org/apache/camel/parser/helper/XmlLineNumberParser.java @@ -0,0 +1,197 @@ +/** + * 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.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.util.Stack; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * An XML parser that uses SAX to include line and column number for each XML element in the parsed Document. + *

+ * The line number and column number can be obtained from a Node/Element using + *

+ *   String lineNumber = (String) node.getUserData(XmlLineNumberParser.LINE_NUMBER);
+ *   String lineNumberEnd = (String) node.getUserData(XmlLineNumberParser.LINE_NUMBER_END);
+ *   String columnNumber = (String) node.getUserData(XmlLineNumberParser.COLUMN_NUMBER);
+ *   String columnNumberEnd = (String) node.getUserData(XmlLineNumberParser.COLUMN_NUMBER_END);
+ * 
+ */ +public final class XmlLineNumberParser { + + public static final String LINE_NUMBER = "lineNumber"; + public static final String COLUMN_NUMBER = "colNumber"; + public static final String LINE_NUMBER_END = "lineNumberEnd"; + public static final String COLUMN_NUMBER_END = "colNumberEnd"; + + private XmlLineNumberParser() { + } + + /** + * Parses the XML. + * + * @param is the XML content as an input stream + * @return the DOM model + * @throws Exception is thrown if error parsing + */ + public static Document parseXml(final InputStream is) throws Exception { + return parseXml(is, null, null); + } + + /** + * Parses the XML. + * + * @param is the XML content as an input stream + * @param rootNames one or more root names that is used as baseline for beginning the parsing, for example camelContext to start parsing + * when Camel is discovered. Multiple names can be defined separated by comma + * @param forceNamespace an optional namespace to force assign to each node. This may be needed for JAXB unmarshalling from XML -> POJO. + * @return the DOM model + * @throws Exception is thrown if error parsing + */ + public static Document parseXml(final InputStream is, final String rootNames, final String forceNamespace) throws Exception { + final Document doc; + SAXParser parser; + final SAXParserFactory factory = SAXParserFactory.newInstance(); + parser = factory.newSAXParser(); + final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + // turn off validator and loading external dtd + dbf.setValidating(false); + dbf.setNamespaceAware(true); + dbf.setFeature("http://xml.org/sax/features/namespaces", false); + dbf.setFeature("http://xml.org/sax/features/validation", false); + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); + final DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + doc = docBuilder.newDocument(); + + final Stack elementStack = new Stack(); + final StringBuilder textBuffer = new StringBuilder(); + final DefaultHandler handler = new DefaultHandler() { + private Locator locator; + private boolean found; + + @Override + public void setDocumentLocator(final Locator locator) { + this.locator = locator; // Save the locator, so that it can be used later for line tracking when traversing nodes. + this.found = rootNames == null; + } + + private boolean isRootName(String qName) { + for (String root : rootNames.split(",")) { + if (qName.equals(root)) { + return true; + } + } + return false; + } + + @Override + public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException { + addTextIfNeeded(); + + if (rootNames != null && !found) { + if (isRootName(qName)) { + found = true; + } + } + + if (found) { + Element el; + if (forceNamespace != null) { + el = doc.createElementNS(forceNamespace, qName); + } else { + el = doc.createElement(qName); + } + + for (int i = 0; i < attributes.getLength(); i++) { + el.setAttribute(attributes.getQName(i), attributes.getValue(i)); + } + + el.setUserData(LINE_NUMBER, String.valueOf(this.locator.getLineNumber()), null); + el.setUserData(COLUMN_NUMBER, String.valueOf(this.locator.getColumnNumber()), null); + elementStack.push(el); + } + } + + @Override + public void endElement(final String uri, final String localName, final String qName) { + if (!found) { + return; + } + + addTextIfNeeded(); + + final Element closedEl = elementStack.isEmpty() ? null : elementStack.pop(); + if (closedEl != null) { + if (elementStack.isEmpty()) { + // Is this the root element? + doc.appendChild(closedEl); + } else { + final Element parentEl = elementStack.peek(); + parentEl.appendChild(closedEl); + } + + closedEl.setUserData(LINE_NUMBER_END, String.valueOf(this.locator.getLineNumber()), null); + closedEl.setUserData(COLUMN_NUMBER_END, String.valueOf(this.locator.getColumnNumber()), null); + } + } + + @Override + public void characters(final char ch[], final int start, final int length) throws SAXException { + textBuffer.append(ch, start, length); + } + + @Override + public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException { + // do not resolve external dtd + return new InputSource(new StringReader("")); + } + + // Outputs text accumulated under the current node + private void addTextIfNeeded() { + if (textBuffer.length() > 0) { + final Element el = elementStack.isEmpty() ? null : elementStack.peek(); + if (el != null) { + final Node textNode = doc.createTextNode(textBuffer.toString()); + el.appendChild(textNode); + textBuffer.delete(0, textBuffer.length()); + } + } + } + }; + parser.parse(is, handler); + + return doc; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelEndpointDetails.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelEndpointDetails.java b/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelEndpointDetails.java index 9b03710..3b112a4 100644 --- a/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelEndpointDetails.java +++ b/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelEndpointDetails.java @@ -16,6 +16,9 @@ */ package org.apache.camel.parser.model; +/** + * Details about a parsed and discovered Camel endpoint. + */ public class CamelEndpointDetails { private String fileName; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelSimpleDetails.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelSimpleDetails.java b/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelSimpleDetails.java deleted file mode 100644 index 058111d..0000000 --- a/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelSimpleDetails.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * 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; - -public class CamelSimpleDetails { - - private String fileName; - private String lineNumber; - private String lineNumberEnd; - private String className; - private String methodName; - private String simple; - private boolean predicate; - private boolean expression; - - 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 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 getSimple() { - return simple; - } - - public void setSimple(String simple) { - this.simple = simple; - } - - public boolean isPredicate() { - return predicate; - } - - public void setPredicate(boolean predicate) { - this.predicate = predicate; - } - - public boolean isExpression() { - return expression; - } - - public void setExpression(boolean expression) { - this.expression = expression; - } - - @Override - public String toString() { - return simple; - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelSimpleExpressionDetails.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelSimpleExpressionDetails.java b/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelSimpleExpressionDetails.java new file mode 100644 index 0000000..9d6db11 --- /dev/null +++ b/tooling/route-parser/src/main/java/org/apache/camel/parser/model/CamelSimpleExpressionDetails.java @@ -0,0 +1,101 @@ +/** + * 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; + +/** + * Details about a parsed and discovered Camel simple expression. + */ +public class CamelSimpleExpressionDetails { + + private String fileName; + private String lineNumber; + private String lineNumberEnd; + private String className; + private String methodName; + private String simple; + private boolean predicate; + private boolean expression; + + 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 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 getSimple() { + return simple; + } + + public void setSimple(String simple) { + this.simple = simple; + } + + public boolean isPredicate() { + return predicate; + } + + public void setPredicate(boolean predicate) { + this.predicate = predicate; + } + + public boolean isExpression() { + return expression; + } + + public void setExpression(boolean expression) { + this.expression = expression; + } + + @Override + public String toString() { + return simple; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/main/java/org/apache/camel/parser/roaster/AnonymousMethodSource.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/main/java/org/apache/camel/parser/roaster/AnonymousMethodSource.java b/tooling/route-parser/src/main/java/org/apache/camel/parser/roaster/AnonymousMethodSource.java new file mode 100644 index 0000000..234082a --- /dev/null +++ b/tooling/route-parser/src/main/java/org/apache/camel/parser/roaster/AnonymousMethodSource.java @@ -0,0 +1,426 @@ +/** + * 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.roaster; + +import java.lang.annotation.Annotation; +import java.util.List; + +import org.jboss.forge.roaster.model.JavaType; +import org.jboss.forge.roaster.model.Type; +import org.jboss.forge.roaster.model.TypeVariable; +import org.jboss.forge.roaster.model.Visibility; +import org.jboss.forge.roaster.model.source.AnnotationSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.jboss.forge.roaster.model.source.JavaDocSource; +import org.jboss.forge.roaster.model.source.MethodSource; +import org.jboss.forge.roaster.model.source.ParameterSource; +import org.jboss.forge.roaster.model.source.TypeVariableSource; + +/** + * In use when we have discovered a RouteBuilder being as anonymous inner class + */ +public class AnonymousMethodSource implements MethodSource { + + // this implementation should only implement the needed logic to support the parser + + private final JavaClassSource origin; + private final Object internal; + + public AnonymousMethodSource(JavaClassSource origin, Object internal) { + this.origin = origin; + this.internal = internal; + } + + @Override + public MethodSource setDefault(boolean b) { + return null; + } + + @Override + public MethodSource setSynchronized(boolean b) { + return null; + } + + @Override + public MethodSource setNative(boolean b) { + return null; + } + + @Override + public MethodSource setReturnType(Class aClass) { + return null; + } + + @Override + public MethodSource setReturnType(String s) { + return null; + } + + @Override + public MethodSource setReturnType(JavaType javaType) { + return null; + } + + @Override + public MethodSource setReturnTypeVoid() { + return null; + } + + @Override + public MethodSource setBody(String s) { + return null; + } + + @Override + public MethodSource setConstructor(boolean b) { + return null; + } + + @Override + public MethodSource setParameters(String s) { + return null; + } + + @Override + public MethodSource addThrows(String s) { + return null; + } + + @Override + public MethodSource addThrows(Class aClass) { + return null; + } + + @Override + public MethodSource removeThrows(String s) { + return null; + } + + @Override + public MethodSource removeThrows(Class aClass) { + return null; + } + + @Override + public boolean isSynchronized() { + return false; + } + + @Override + public boolean isNative() { + return false; + } + + @Override + public String getBody() { + return null; + } + + @Override + public boolean isConstructor() { + return false; + } + + @Override + public Type getReturnType() { + return null; + } + + @Override + public boolean isReturnTypeVoid() { + return false; + } + + @Override + public List> getParameters() { + return null; + } + + @Override + public String toSignature() { + return null; + } + + @Override + public List getThrownExceptions() { + return null; + } + + @Override + public boolean isDefault() { + return false; + } + + @Override + public ParameterSource addParameter(Class aClass, String s) { + return null; + } + + @Override + public ParameterSource addParameter(String s, String s1) { + return null; + } + + @Override + public ParameterSource addParameter(JavaType javaType, String s) { + return null; + } + + @Override + public void removeAllAnnotations() { + } + + @Override + public MethodSource removeParameter(ParameterSource parameterSource) { + return null; + } + + @Override + public MethodSource removeParameter(Class aClass, String s) { + return null; + } + + @Override + public MethodSource removeParameter(String s, String s1) { + return null; + } + + @Override + public MethodSource removeParameter(JavaType javaType, String s) { + return null; + } + + @Override + public MethodSource setAbstract(boolean b) { + return null; + } + + @Override + public List> getAnnotations() { + return null; + } + + @Override + public boolean hasAnnotation(Class aClass) { + return false; + } + + @Override + public boolean hasAnnotation(String s) { + return false; + } + + @Override + public AnnotationSource getAnnotation(Class aClass) { + return null; + } + + @Override + public AnnotationSource getAnnotation(String s) { + return null; + } + + @Override + public AnnotationSource addAnnotation() { + return null; + } + + @Override + public AnnotationSource addAnnotation(Class aClass) { + return null; + } + + @Override + public AnnotationSource addAnnotation(String s) { + return null; + } + + @Override + public MethodSource removeAnnotation(org.jboss.forge.roaster.model.Annotation annotation) { + return null; + } + + @Override + public List> getTypeVariables() { + return null; + } + + @Override + public TypeVariableSource getTypeVariable(String s) { + return null; + } + + @Override + public TypeVariableSource addTypeVariable() { + return null; + } + + @Override + public TypeVariableSource addTypeVariable(String s) { + return null; + } + + @Override + public MethodSource removeTypeVariable(String s) { + return null; + } + + @Override + public MethodSource removeTypeVariable(TypeVariable typeVariable) { + return null; + } + + @Override + public boolean hasJavaDoc() { + return false; + } + + @Override + public boolean isAbstract() { + return false; + } + + @Override + public MethodSource setFinal(boolean b) { + return null; + } + + @Override + public boolean isFinal() { + return false; + } + + @Override + public Object getInternal() { + return internal; + } + + @Override + public JavaDocSource> getJavaDoc() { + return null; + } + + @Override + public MethodSource removeJavaDoc() { + return null; + } + + @Override + public MethodSource setName(String s) { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public JavaClassSource getOrigin() { + return origin; + } + + @Override + public MethodSource setStatic(boolean b) { + return null; + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public MethodSource setPackagePrivate() { + return null; + } + + @Override + public MethodSource setPublic() { + return null; + } + + @Override + public MethodSource setPrivate() { + return null; + } + + @Override + public MethodSource setProtected() { + return null; + } + + @Override + public MethodSource setVisibility(Visibility visibility) { + return null; + } + + @Override + public boolean isPackagePrivate() { + return false; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public boolean isPrivate() { + return false; + } + + @Override + public boolean isProtected() { + return false; + } + + @Override + public Visibility getVisibility() { + return null; + } + + @Override + public int getColumnNumber() { + return 0; + } + + @Override + public int getStartPosition() { + return 0; + } + + @Override + public int getEndPosition() { + return 0; + } + + @Override + public int getLineNumber() { + return 0; + } + + @Override + public boolean hasTypeVariable(String arg0) { + return false; + } + + @Override + public MethodSource setReturnType(Type arg0) { + return null; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/main/java/org/apache/camel/parser/roaster/StatementFieldSource.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/main/java/org/apache/camel/parser/roaster/StatementFieldSource.java b/tooling/route-parser/src/main/java/org/apache/camel/parser/roaster/StatementFieldSource.java new file mode 100644 index 0000000..cbfcedc --- /dev/null +++ b/tooling/route-parser/src/main/java/org/apache/camel/parser/roaster/StatementFieldSource.java @@ -0,0 +1,278 @@ +/** + * 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.roaster; + +import java.util.List; + +import org.jboss.forge.roaster.model.Annotation; +import org.jboss.forge.roaster.model.JavaType; +import org.jboss.forge.roaster.model.Type; +import org.jboss.forge.roaster.model.Visibility; +import org.jboss.forge.roaster.model.impl.TypeImpl; +import org.jboss.forge.roaster.model.source.AnnotationSource; +import org.jboss.forge.roaster.model.source.FieldSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.jboss.forge.roaster.model.source.JavaDocSource; + +public class StatementFieldSource implements FieldSource { + + // this implementation should only implement the needed logic to support the parser + + private final JavaClassSource origin; + private final Object internal; + private final Type type; + + public StatementFieldSource(JavaClassSource origin, Object internal, Object typeInternal) { + this.origin = origin; + this.internal = internal; + this.type = new TypeImpl(origin, typeInternal); + } + + @Override + public FieldSource setType(Class clazz) { + return null; + } + + @Override + public FieldSource setType(String type) { + return null; + } + + @Override + public FieldSource setLiteralInitializer(String value) { + return null; + } + + @Override + public FieldSource setStringInitializer(String value) { + return null; + } + + @Override + public FieldSource setTransient(boolean value) { + return null; + } + + @Override + public FieldSource setVolatile(boolean value) { + return null; + } + + @Override + public FieldSource setType(JavaType entity) { + return null; + } + + @Override + public List getAnnotations() { + return null; + } + + @Override + public boolean hasAnnotation(String type) { + return false; + } + + @Override + public boolean hasAnnotation(Class type) { + return false; + } + + @Override + public AnnotationSource getAnnotation(String type) { + return null; + } + + @Override + public AnnotationSource addAnnotation() { + return null; + } + + @Override + public AnnotationSource addAnnotation(String className) { + return null; + } + + @Override + public void removeAllAnnotations() { + } + + @Override + public Object removeAnnotation(Annotation annotation) { + return null; + } + + @Override + public AnnotationSource addAnnotation(Class type) { + return null; + } + + @Override + public AnnotationSource getAnnotation(Class type) { + return null; + } + + @Override + public Type getType() { + return type; + } + + @Override + public String getStringInitializer() { + return null; + } + + @Override + public String getLiteralInitializer() { + return null; + } + + @Override + public boolean isTransient() { + return false; + } + + @Override + public boolean isVolatile() { + return false; + } + + @Override + public Object setFinal(boolean finl) { + return null; + } + + @Override + public boolean isFinal() { + return false; + } + + @Override + public Object getInternal() { + return internal; + } + + @Override + public JavaDocSource getJavaDoc() { + return null; + } + + @Override + public boolean hasJavaDoc() { + return false; + } + + @Override + public Object removeJavaDoc() { + return null; + } + + @Override + public Object setName(String name) { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public Object getOrigin() { + return origin; + } + + @Override + public Object setStatic(boolean value) { + return null; + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public Object setPackagePrivate() { + return null; + } + + @Override + public Object setPublic() { + return null; + } + + @Override + public Object setPrivate() { + return null; + } + + @Override + public Object setProtected() { + return null; + } + + @Override + public Object setVisibility(Visibility scope) { + return null; + } + + @Override + public boolean isPackagePrivate() { + return false; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public boolean isPrivate() { + return false; + } + + @Override + public boolean isProtected() { + return false; + } + + @Override + public Visibility getVisibility() { + return null; + } + + @Override + public int getColumnNumber() { + return 0; + } + + @Override + public int getStartPosition() { + return 0; + } + + @Override + public int getEndPosition() { + return 0; + } + + @Override + public int getLineNumber() { + return 0; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiConcatRouteBuilderConfigureTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiConcatRouteBuilderConfigureTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiConcatRouteBuilderConfigureTest.java index 0bd7fb1..326d599 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiConcatRouteBuilderConfigureTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiConcatRouteBuilderConfigureTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiRouteBuilderConfigureTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiRouteBuilderConfigureTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiRouteBuilderConfigureTest.java index 16e01da..6cb2492 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiRouteBuilderConfigureTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterCdiRouteBuilderConfigureTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterConcatFieldRouteBuilderConfigureTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterConcatFieldRouteBuilderConfigureTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterConcatFieldRouteBuilderConfigureTest.java index 9cd8f11..099ea7b 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterConcatFieldRouteBuilderConfigureTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterConcatFieldRouteBuilderConfigureTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterEndpointInjectTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterEndpointInjectTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterEndpointInjectTest.java index a239789..c432183 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterEndpointInjectTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterEndpointInjectTest.java @@ -20,7 +20,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.apache.camel.parser.RouteBuilderParser; import org.apache.camel.parser.model.CamelEndpointDetails; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterFieldRouteBuilderConfigureTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterFieldRouteBuilderConfigureTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterFieldRouteBuilderConfigureTest.java index 75c6781..53495e9 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterFieldRouteBuilderConfigureTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterFieldRouteBuilderConfigureTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMethodCallRouteBuilderConfigureTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMethodCallRouteBuilderConfigureTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMethodCallRouteBuilderConfigureTest.java index 24cec20..c7ca922 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMethodCallRouteBuilderConfigureTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMethodCallRouteBuilderConfigureTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyFieldMethodCallRouteBuilderConfigureTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyFieldMethodCallRouteBuilderConfigureTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyFieldMethodCallRouteBuilderConfigureTest.java index a715ca3..951a4cb 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyFieldMethodCallRouteBuilderConfigureTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyFieldMethodCallRouteBuilderConfigureTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyLocalAddRouteBuilderTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyLocalAddRouteBuilderTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyLocalAddRouteBuilderTest.java index 4c80879..89f9544 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyLocalAddRouteBuilderTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyLocalAddRouteBuilderTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyNettyTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyNettyTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyNettyTest.java index 99e288a..9dc1687 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyNettyTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterMyNettyTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineConstRouteBuilderConfigureTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineConstRouteBuilderConfigureTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineConstRouteBuilderConfigureTest.java index b6b8ca0..a4fc1fb 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineConstRouteBuilderConfigureTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineConstRouteBuilderConfigureTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; http://git-wip-us.apache.org/repos/asf/camel/blob/07563515/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineRouteBuilderConfigureTest.java ---------------------------------------------------------------------- diff --git a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineRouteBuilderConfigureTest.java b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineRouteBuilderConfigureTest.java index 6e40043..b7cb3d6 100644 --- a/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineRouteBuilderConfigureTest.java +++ b/tooling/route-parser/src/test/java/org/apache/camel/parser/java/RoasterNewLineRouteBuilderConfigureTest.java @@ -19,7 +19,7 @@ package org.apache.camel.parser.java; import java.io.File; import java.util.List; -import org.apache.camel.parser.CamelJavaParserHelper; +import org.apache.camel.parser.helper.CamelJavaParserHelper; import org.apache.camel.parser.ParserResult; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource;