use of org.jboss.forge.roaster.model.source.JavaClassSource in project camel by apache.
the class SpringBootAutoConfigurationMojo method createConnectorConfigurationSource.
private void createConnectorConfigurationSource(String packageName, ComponentModel model, String javaType, String connectorScheme, List<String> componentOptions) throws MojoFailureException {
final JavaClassSource javaClass = Roaster.create(JavaClassSource.class);
int pos = javaType.lastIndexOf(".");
String name = javaType.substring(pos + 1);
name = name.replace("Component", "ConnectorConfiguration");
javaClass.setPackage(packageName).setName(name);
String doc = "Generated by camel-connector-maven-plugin - do not edit this file!";
if (!Strings.isBlank(model.getDescription())) {
doc = model.getDescription() + "\n\n" + doc;
}
// replace Component with Connector
doc = doc.replaceAll("Component", "Connector");
doc = doc.replaceAll("component", "connector");
javaClass.getJavaDoc().setFullText(doc);
// compute the configuration prefix to use with spring boot configuration
String prefix = "";
if (!"false".equalsIgnoreCase(configurationPrefix)) {
// make sure prefix is in lower case
prefix = configurationPrefix.toLowerCase(Locale.US);
if (!prefix.endsWith(".")) {
prefix += ".";
}
}
prefix += connectorScheme.toLowerCase(Locale.US);
javaClass.addAnnotation("org.springframework.boot.context.properties.ConfigurationProperties").setStringValue("prefix", prefix);
for (ComponentOptionModel option : model.getComponentOptions()) {
// only include the options that has been explicit configured in the camel-connector.json file
boolean accepted = false;
if (componentOptions != null) {
accepted = componentOptions.stream().anyMatch(o -> o.equals(option.getName()));
}
if (accepted) {
String type = option.getJavaType();
PropertySource<JavaClassSource> prop = javaClass.addProperty(type, option.getName());
if ("true".equals(option.getDeprecated())) {
prop.getField().addAnnotation(Deprecated.class);
prop.getAccessor().addAnnotation(Deprecated.class);
prop.getMutator().addAnnotation(Deprecated.class);
// DeprecatedConfigurationProperty must be on getter when deprecated
prop.getAccessor().addAnnotation(DeprecatedConfigurationProperty.class);
}
if (!Strings.isBlank(option.getDescription())) {
prop.getField().getJavaDoc().setFullText(option.getDescription());
}
if (!Strings.isBlank(option.getDefaultValue())) {
if ("java.lang.String".equals(option.getJavaType())) {
prop.getField().setStringInitializer(option.getDefaultValue());
} else if ("long".equals(option.getJavaType()) || "java.lang.Long".equals(option.getJavaType())) {
// the value should be a Long number
String value = option.getDefaultValue() + "L";
prop.getField().setLiteralInitializer(value);
} else if ("integer".equals(option.getType()) || "boolean".equals(option.getType())) {
prop.getField().setLiteralInitializer(option.getDefaultValue());
} else if (!Strings.isBlank(option.getEnums())) {
String enumShortName = type.substring(type.lastIndexOf(".") + 1);
prop.getField().setLiteralInitializer(enumShortName + "." + option.getDefaultValue());
javaClass.addImport(model.getJavaType());
}
}
}
}
sortImports(javaClass);
String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java";
writeSourceIfChanged(javaClass, fileName);
}
use of org.jboss.forge.roaster.model.source.JavaClassSource in project camel by apache.
the class CamelJavaParserHelper method getLiteralValue.
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 + "}}";
}
// 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;
}
use of org.jboss.forge.roaster.model.source.JavaClassSource in project camel by apache.
the class RouteBuilderParser method parseRouteBuilderSimpleExpressions.
/**
* Parses the java source class to discover Camel simple expressions.
*
* @param clazz the java source class
* @param baseDir the base of the source code
* @param fullyQualifiedFileName the fully qualified source code file name
* @param simpleExpressions list to add discovered and parsed simple expressions
*/
public static void parseRouteBuilderSimpleExpressions(JavaClassSource clazz, String baseDir, String fullyQualifiedFileName, List<CamelSimpleExpressionDetails> simpleExpressions) {
MethodSource<JavaClassSource> method = CamelJavaParserHelper.findConfigureMethod(clazz);
if (method != null) {
List<ParserResult> expressions = CamelJavaParserHelper.parseCamelSimpleExpressions(method);
for (ParserResult result : expressions) {
if (result.isParsed()) {
String fileName = fullyQualifiedFileName;
if (fileName.startsWith(baseDir)) {
fileName = fileName.substring(baseDir.length() + 1);
}
CamelSimpleExpressionDetails detail = new CamelSimpleExpressionDetails();
detail.setFileName(fileName);
detail.setClassName(clazz.getQualifiedName());
detail.setMethodName("configure");
int line = findLineNumber(fullyQualifiedFileName, result.getPosition());
if (line > -1) {
detail.setLineNumber("" + line);
}
detail.setSimple(result.getElement());
boolean predicate = result.getPredicate() != null ? result.getPredicate() : false;
boolean expression = !predicate;
detail.setPredicate(predicate);
detail.setExpression(expression);
simpleExpressions.add(detail);
}
}
}
}
use of org.jboss.forge.roaster.model.source.JavaClassSource in project camel by apache.
the class RouteBuilderParser method parseRouteBuilderEndpoints.
/**
* Parses the java source class to discover Camel endpoints.
*
* @param clazz the java source class
* @param baseDir the base of the source code
* @param fullyQualifiedFileName the fully qualified source code file name
* @param endpoints list to add discovered and parsed endpoints
* @param unparsable list of unparsable nodes
* @param includeInlinedRouteBuilders whether to include inlined route builders in the parsing
*/
public static void parseRouteBuilderEndpoints(JavaClassSource clazz, String baseDir, String fullyQualifiedFileName, List<CamelEndpointDetails> endpoints, List<String> unparsable, boolean includeInlinedRouteBuilders) {
// look for fields which are not used in the route
for (FieldSource<JavaClassSource> field : clazz.getFields()) {
// is the field annotated with a Camel endpoint
String uri = null;
Expression exp = 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) {
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;
}
}
}
uri = CamelJavaParserHelper.getLiteralValue(clazz, null, exp);
}
}
// we only want to add fields which are not used in the route
if (!Strings.isBlank(uri) && findEndpointByUri(endpoints, uri) == null) {
// we only want the relative dir name from the
String fileName = fullyQualifiedFileName;
if (fileName.startsWith(baseDir)) {
fileName = fileName.substring(baseDir.length() + 1);
}
String id = field.getName();
CamelEndpointDetails detail = new CamelEndpointDetails();
detail.setFileName(fileName);
detail.setClassName(clazz.getQualifiedName());
detail.setEndpointInstance(id);
detail.setEndpointUri(uri);
detail.setEndpointComponentName(endpointComponentName(uri));
// favor the position of the expression which had the actual uri
Object internal = exp != null ? exp : field.getInternal();
// find position of field/expression
if (internal instanceof ASTNode) {
int pos = ((ASTNode) internal).getStartPosition();
int line = findLineNumber(fullyQualifiedFileName, pos);
if (line > -1) {
detail.setLineNumber("" + line);
}
}
// we do not know if this field is used as consumer or producer only, but we try
// to find out by scanning the route in the configure method below
endpoints.add(detail);
}
}
// find all the configure methods
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);
}
}
// determine this to ensure when we edit the endpoint we should only the options accordingly
for (MethodSource<JavaClassSource> configureMethod : methods) {
// consumers only
List<ParserResult> uris = CamelJavaParserHelper.parseCamelConsumerUris(configureMethod, true, true);
for (ParserResult result : uris) {
if (!result.isParsed()) {
if (unparsable != null) {
unparsable.add(result.getElement());
}
} else {
CamelEndpointDetails detail = findEndpointByUri(endpoints, result.getElement());
if (detail != null) {
// its a consumer only
detail.setConsumerOnly(true);
} else {
String fileName = fullyQualifiedFileName;
if (fileName.startsWith(baseDir)) {
fileName = fileName.substring(baseDir.length() + 1);
}
detail = new CamelEndpointDetails();
detail.setFileName(fileName);
detail.setClassName(clazz.getQualifiedName());
detail.setMethodName(configureMethod.getName());
detail.setEndpointInstance(null);
detail.setEndpointUri(result.getElement());
int line = findLineNumber(fullyQualifiedFileName, result.getPosition());
if (line > -1) {
detail.setLineNumber("" + line);
}
detail.setEndpointComponentName(endpointComponentName(result.getElement()));
detail.setConsumerOnly(true);
detail.setProducerOnly(false);
endpoints.add(detail);
}
}
}
// producer only
uris = CamelJavaParserHelper.parseCamelProducerUris(configureMethod, true, true);
for (ParserResult result : uris) {
if (!result.isParsed()) {
if (unparsable != null) {
unparsable.add(result.getElement());
}
} else {
CamelEndpointDetails detail = findEndpointByUri(endpoints, result.getElement());
if (detail != null) {
if (detail.isConsumerOnly()) {
// its both a consumer and producer
detail.setConsumerOnly(false);
detail.setProducerOnly(false);
} else {
// its a producer only
detail.setProducerOnly(true);
}
}
// the same endpoint uri may be used in multiple places in the same route
// so we should maybe add all of them
String fileName = fullyQualifiedFileName;
if (fileName.startsWith(baseDir)) {
fileName = fileName.substring(baseDir.length() + 1);
}
detail = new CamelEndpointDetails();
detail.setFileName(fileName);
detail.setClassName(clazz.getQualifiedName());
detail.setMethodName(configureMethod.getName());
detail.setEndpointInstance(null);
detail.setEndpointUri(result.getElement());
int line = findLineNumber(fullyQualifiedFileName, result.getPosition());
if (line > -1) {
detail.setLineNumber("" + line);
}
detail.setEndpointComponentName(endpointComponentName(result.getElement()));
detail.setConsumerOnly(false);
detail.setProducerOnly(true);
endpoints.add(detail);
}
}
}
}
use of org.jboss.forge.roaster.model.source.JavaClassSource in project camel by apache.
the class RoasterMyNettyTest method parse.
@Test
public void parse() throws Exception {
JavaClassSource clazz = (JavaClassSource) Roaster.parse(new File("src/test/java/org/apache/camel/parser/java/MyNettyTest.java"));
MethodSource<JavaClassSource> method = CamelJavaParserHelper.findConfigureMethod(clazz);
List<ParserResult> list = CamelJavaParserHelper.parseCamelConsumerUris(method, true, true);
for (ParserResult result : list) {
LOG.info("Consumer: " + result.getElement());
}
Assert.assertEquals("netty-http:http://0.0.0.0:{{port}}/foo", list.get(0).getElement());
Assert.assertEquals("netty-http:http://0.0.0.0:{{getNextPort}}/bar", list.get(1).getElement());
list = CamelJavaParserHelper.parseCamelProducerUris(method, true, true);
for (ParserResult result : list) {
LOG.info("Producer: " + result.getElement());
}
Assert.assertEquals("mock:input1", list.get(0).getElement());
Assert.assertEquals("netty-http:http://0.0.0.0:{{getNextPort}}/bar", list.get(1).getElement());
Assert.assertEquals("mock:input2", list.get(2).getElement());
}
Aggregations