in camel-upgrade-recipes/src/main/java/org/apache/camel/upgrade/camel40/java/CamelAPIsRecipe.java [79:373]
public TreeVisitor<?, ExecutionContext> getVisitor() {
return RecipesUtil.newVisitor(new AbstractCamelJavaVisitor() {
//Cache for all methodInvocations CamelContext adapt(java.lang.Class).
private Map<UUID, Tree> adaptCache = new HashMap<>();
@Override
protected J.Import doVisitImport(J.Import _import, ExecutionContext context) {
J.Import im = super.doVisitImport(_import, context);
//Removed Discard and DiscardOldest from org.apache.camel.util.concurrent.ThreadPoolRejectedPolicy.
if (im.isStatic() && im.getTypeName().equals("org.apache.camel.util.concurrent.ThreadPoolRejectedPolicy")
&& im.getQualid() != null
&& ("Discard".equals(im.getQualid().getSimpleName())
|| "DiscardOldest".equals(im.getQualid().getSimpleName()))) {
Comment comment = RecipesUtil.createMultinlineComment(String.format(
"'ThreadPoolRejectedPolicy.%s' has been removed, consider using 'ThreadPoolRejectedPolicy.Abort'.",
im.getQualid().getSimpleName()));
im = im.withComments(Collections.singletonList(comment));
}
//Removed org.apache.camel.builder.SimpleBuilder.
// Was mostly used internally in Camel with the Java DSL in some situations.
else if ("org.apache.camel.builder.SimpleBuilder".equals(im.getTypeName())) {
Comment comment = RecipesUtil.createMultinlineComment(String.format(
"'%s' has been removed, (class was used internally).", SimpleBeanInfo.class.getCanonicalName()));
im = im.withComments(Collections.singletonList(comment));
}
//Move the following class from org.apache.camel.api.management.mbean.BacklogTracerEventMessage in camel-management-api JAR to org.apache.camel.spi.BacklogTracerEventMessage in camel-api JAR.
//
// BacklogTracerEventMessage moved from `org.apache.camel.api.management.mbean.BacklogTracerEventMessage`
// to `org.apache.camel.spi.BacklogTracerEventMessage`
doAfterVisit(
new ChangeType(
"org.apache.camel.api.management.mbean.BacklogTracerEventMessage",
"org.apache.camel.spi.BacklogTracerEventMessage", true).getVisitor());
return im;
}
@Override
protected J.ClassDeclaration doVisitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext context) {
J.ClassDeclaration cd = super.doVisitClassDeclaration(classDecl, context);
//Removed org.apache.camel.spi.OnCamelContextStart. Use org.apache.camel.spi.OnCamelContextStarting instead.
if (cd.getImplements() != null && cd.getImplements().stream()
.anyMatch(f -> TypeUtils.isOfClassType(f.getType(), "org.apache.camel.spi.OnCamelContextStart"))) {
doAfterVisit(new ImplementInterface<ExecutionContext>(cd, "org.apache.camel.spi.OnCamelContextStarting"));
doAfterVisit(new RemoveImplements("org.apache.camel.spi.OnCamelContextStart", null).getVisitor());
} //Removed org.apache.camel.spi.OnCamelContextStop. Use org.apache.camel.spi.OnCamelContextStopping instead.
else if (cd.getImplements() != null && cd.getImplements().stream()
.anyMatch(f -> TypeUtils.isOfClassType(f.getType(), "org.apache.camel.spi.OnCamelContextStop"))) {
doAfterVisit(new ImplementInterface<ExecutionContext>(cd, "org.apache.camel.spi.OnCamelContextStopping"));
doAfterVisit(new RemoveImplements("org.apache.camel.spi.OnCamelContextStop", null).getVisitor());
}
return cd;
}
@Override
protected J.FieldAccess doVisitFieldAccess(J.FieldAccess fieldAccess, ExecutionContext context) {
J.FieldAccess fa = super.doVisitFieldAccess(fieldAccess, context);
//The org.apache.camel.ExchangePattern has removed InOptionalOut.
if ("InOptionalOut".equals(fieldAccess.getSimpleName()) && fa.getType() != null
&& fa.getType().isAssignableFrom(Pattern.compile("org.apache.camel.ExchangePattern"))) {
return fa.withName(new J.Identifier(
UUID.randomUUID(), fa.getPrefix(), Markers.EMPTY, Collections.emptyList(),
"/* " + fa.getSimpleName() + " has been removed */", fa.getType(), null));
}
else if (("Discard".equals(fa.getSimpleName()) || "DiscardOldest".equals(fa.getSimpleName()))
&& fa.getType() != null && fa.getType().isAssignableFrom(
Pattern.compile("org.apache.camel.util.concurrent.ThreadPoolRejectedPolicy"))) {
Comment comment = RecipesUtil.createMultinlineComment(String.format(
"'ThreadPoolRejectedPolicy.%s' has been removed, consider using 'ThreadPoolRejectedPolicy.Abort'.",
fa.getSimpleName()));
fa = fa.withComments(Collections.singletonList(comment));
}
return fa;
}
@Override
protected J.MethodDeclaration doVisitMethodDeclaration(J.MethodDeclaration method, ExecutionContext context) {
J.MethodDeclaration md = super.doVisitMethodDeclaration(method, context);
//Method 'configure' was removed from `org.apache.camel.main.MainListener`, consider using 'beforeConfigure' or 'afterConfigure'.
if ("configure".equals(md.getSimpleName())
&& JavaType.Primitive.Void.equals(md.getReturnTypeExpression().getType())
&& md.getMethodType().getDeclaringType()
.isAssignableFrom(Pattern.compile("org.apache.camel.main.MainListener"))
&& !md.getParameters().isEmpty()
&& md.getParameters().size() == 1
&& md.getParameters().get(0) instanceof J.VariableDeclarations
&& ((J.VariableDeclarations) md.getParameters().get(0)).getType()
.isAssignableFrom(Pattern.compile("org.apache.camel.CamelContext"))) {
Comment comment = RecipesUtil.createMultinlineComment(String.format(
" Method '%s' was removed from `%s`, consider using 'beforeConfigure' or 'afterConfigure'. ",
md.getSimpleName(), "org.apache.camel.main.MainListener"));
md = md.withComments(Collections.singletonList(comment));
}
return md;
}
@Override
protected J.Annotation doVisitAnnotation(J.Annotation annotation, ExecutionContext context) {
J.Annotation a = super.doVisitAnnotation(annotation, context);
//Removed @FallbackConverter as you should use @Converter(fallback = true) instead.
if (a.getType().toString().equals("org.apache.camel.FallbackConverter")) {
maybeAddImport("org.apache.camel.Converter", null, false);
maybeRemoveImport("org.apache.camel.FallbackConverter");
return RecipesUtil.createAnnotation(annotation, "Converter", null, "fallback = true");
}
//Removed uri attribute on @EndpointInject, @Produce, and @Consume as you should use value (default) instead.
//For example @Produce(uri = "kafka:cheese") should be changed to @Produce("kafka:cheese")
else if (a.getType().toString().equals("org.apache.camel.EndpointInject")) {
Optional<String> originalValue = RecipesUtil.getValueOfArgs(a.getArguments(), "uri");
if (originalValue.isPresent()) {
return RecipesUtil.createAnnotation(annotation, "EndpointInject", s -> s.startsWith("uri="),
originalValue.get());
}
}
//Removed uri attribute on @EndpointInject, @Produce, and @Consume as you should use value (default) instead.
//For example @Produce(uri = "kafka:cheese") should be changed to @Produce("kafka:cheese")
else if (a.getType().toString().equals("org.apache.camel.Produce")) {
Optional<String> originalValue = RecipesUtil.getValueOfArgs(a.getArguments(), "uri");
if (originalValue.isPresent()) {
return RecipesUtil.createAnnotation(annotation, "Produce", s -> s.startsWith("uri="),
originalValue.get());
}
}
//Removed uri attribute on @EndpointInject, @Produce, and @Consume as you should use value (default) instead.
//For example @Produce(uri = "kafka:cheese") should be changed to @Produce("kafka:cheese")
else if (a.getType().toString().equals("org.apache.camel.Consume")) {
Optional<String> originalValue = RecipesUtil.getValueOfArgs(a.getArguments(), "uri");
if (originalValue.isPresent()) {
return RecipesUtil.createAnnotation(annotation, "Consume", s -> s.startsWith("uri="),
originalValue.get());
}
}
// Removed label on @UriEndpoint as you should use category instead.
else if (a.getType().toString().equals("org.apache.camel.spi.UriEndpoint")) {
Optional<String> originalValue = RecipesUtil.getValueOfArgs(a.getArguments(), "label");
if (originalValue.isPresent()) {
maybeAddImport("org.apache.camel.Category", null, false);
String newValue;
try {
newValue = RecipesUtil.Category.valueOf(originalValue.get().toUpperCase().replaceAll("\"", ""))
.getValue();
} catch (IllegalArgumentException e) {
newValue = originalValue.get() + "/*unknown_value*/";
}
return RecipesUtil.createAnnotation(annotation, "UriEndpoint", s -> s.startsWith("label="),
"category = {Category." + newValue + "}");
}
}
return a;
}
@Override
protected J.MethodInvocation doVisitMethodInvocation(J.MethodInvocation method, ExecutionContext context) {
J.MethodInvocation mi = super.doVisitMethodInvocation(method, context);
//if adapt method invocation is used as a select for another method invocation, it is replaced
if (mi.getSelect() != null && adaptCache.containsKey(mi.getSelect().getId())) {
getCursor().putMessage("adapt_cast", mi.getSelect().getId());
} else
// context.getExtension(ExtendedCamelContext.class).getComponentNameResolver() -> PluginHelper.getComponentNameResolver(context)
if (getMethodMatcher(MATCHER_CONTEXT_GET_ENDPOINT_MAP).matches(mi, false)) {
mi = mi.withName(new J.Identifier(
UUID.randomUUID(), mi.getPrefix(), Markers.EMPTY, Collections.emptyList(),
"/* " + mi.getSimpleName() + " has been removed, consider getEndpointRegistry() instead */",
mi.getType(), null));
}
// ProducerTemplate.asyncCallback() has been replaced by 'asyncSend(') or 'asyncRequest()'
else if (getMethodMatcher(M_PRODUCER_TEMPLATE_ASYNC_CALLBACK).matches(mi, false)) {
Comment comment = RecipesUtil.createMultinlineComment(String.format(
" Method '%s()' has been replaced by 'asyncSend()' or 'asyncRequest()'.", mi.getSimpleName()));
mi = mi.withComments(Collections.singletonList(comment));
}
//context.adapt(ModelCamelContext.class) -> ((ModelCamelContext) context)
else if (getMethodMatcher(M_CONTEXT_ADAPT).matches(mi, false)) {
if (mi.getType().isAssignableFrom(Pattern.compile("org.apache.camel.model.ModelCamelContext"))) {
J.Identifier type
= RecipesUtil.createIdentifier(mi.getPrefix(), "ModelCamelContext", "java.lang.Object");
J.ControlParentheses<?> cp
= RecipesUtil.createParentheses(RecipesUtil.createTypeCast(type, mi.getSelect()));
//put the type cast into cache in case it is replaced lately
mi = mi.withComments(
Collections.singletonList(RecipesUtil.createMultinlineComment("Method 'adapt' was removed.")));
adaptCache.put(method.getId(), cp);
} else if (mi.getType().isAssignableFrom(Pattern.compile("org.apache.camel.ExtendedCamelContext"))) {
mi = mi.withName(mi.getName().withSimpleName("getCamelContextExtension"))
.withArguments(Collections.emptyList());
maybeRemoveImport("org.apache.camel.ExtendedCamelContext");
}
}
//exchange.adapt(ExtendedExchange.class) -> exchange.getExchangeExtension()
else if (getMethodMatcher(M_EXCHANGE_ADAPT).matches(mi, false)
&& mi.getType().isAssignableFrom(Pattern.compile("org.apache.camel.ExtendedExchange"))) {
mi = mi.withName(mi.getName().withSimpleName("getExchangeExtension"))
.withArguments(Collections.emptyList());
maybeRemoveImport("org.apache.camel.ExtendedExchange");
}
//newExchange.getProperty(ExchangePropertyKey.FAILURE_HANDLED) -> newExchange.getExchangeExtension().isFailureHandled()
else if (getMethodMatcher(M_EXCHANGE_GET_PROPERTY).matches(mi, false)
&& mi.getArguments().get(0).toString().endsWith("FAILURE_HANDLED")) {
mi = mi.withName(mi.getName().withSimpleName("getExchangeExtension().isFailureHandled"))
.withArguments(Collections.emptyList());
maybeRemoveImport("org.apache.camel.ExchangePropertyKey");
}
//exchange.removeProperty(ExchangePropertyKey.FAILURE_HANDLED); -> exchange.getExchangeExtension().setFailureHandled(false);
else if (getMethodMatcher(M_EXCHANGE_REMOVE_PROPERTY).matches(mi, false)
&& mi.getArguments().get(0).toString().endsWith("FAILURE_HANDLED")) {
mi = mi.withName(mi.getName().withSimpleName("getExchangeExtension().setFailureHandled")).withArguments(
Collections.singletonList(RecipesUtil.createIdentifier(Space.EMPTY, "false", "java.lang.Boolean")));
maybeRemoveImport("org.apache.camel.ExchangePropertyKey");
}
//exchange.setProperty(ExchangePropertyKey.FAILURE_HANDLED, failureHandled); -> exchange.getExchangeExtension().setFailureHandled(failureHandled);
else if (getMethodMatcher(M_EXCHANGE_SET_PROPERTY).matches(mi, false)
&& mi.getArguments().get(0).toString().endsWith("FAILURE_HANDLED")) {
mi = mi.withName(mi.getName()
.withSimpleName("getExchangeExtension().setFailureHandled"))
.withArguments(Collections.singletonList(mi.getArguments().get(1).withPrefix(Space.EMPTY)));
maybeRemoveImport("org.apache.camel.ExchangePropertyKey");
}
//'org.apache.camel.catalogCamelCatalog.archetypeCatalogAsXml()` has been removed
else if (getMethodMatcher(M_CATALOG_ARCHETYPE_AS_XML).matches(mi, false)) {
mi = mi.withComments(Collections.singletonList(
RecipesUtil.createMultinlineComment(" Method '" + mi.getSimpleName() + "' has been removed. ")));
}
//context().setDumpRoutes(true); -> context().setDumpRoutes("xml");(or "yaml")
else if (getMethodMatcher(M_CONTEXT_SET_DUMP_ROUTES).matches(mi, false)) {
mi = mi.withComments(Collections.singletonList(RecipesUtil.createMultinlineComment(
" Method '" + mi.getSimpleName() + "' accepts String parameter ('xml' or 'yaml' or 'false'). ")));
}
//Boolean isDumpRoutes(); -> getDumpRoutes(); with returned type String
else if (getMethodMatcher(M_CONTEXT_IS_DUMP_ROUTES).matches(mi, false)) {
mi = mi.withName(mi.getName().withSimpleName("getDumpRoutes"))
.withComments(Collections.singletonList(RecipesUtil.createMultinlineComment(
" Method 'getDumpRoutes' returns String value ('xml' or 'yaml' or 'false'). ")));
}
// (CamelRuntimeCatalog) context.getExtension(RuntimeCamelCatalog.class) -> context.getCamelContextExtension().getContextPlugin(RuntimeCamelCatalog.class);
else if (getMethodMatcher(MATCHER_CONTEXT_GET_EXT).matches(mi, false)) {
mi = mi.withName(mi.getName().withSimpleName("getCamelContextExtension().getContextPlugin"))
.withMethodType(mi.getMethodType());
//remove type cast before expression
if (getCursor().getParent().getValue() instanceof J.TypeCast
&& ((J.TypeCast) getCursor().getParent().getValue()).getType().equals(mi.getType())) {
getCursor().getParent().putMessage("remove_type_cast", mi);
}
}
return mi;
}
@Override
public @Nullable J postVisit(J tree, ExecutionContext context) {
J j = super.postVisit(tree, context);
UUID adaptCast = getCursor().getMessage("adapt_cast");
if (adaptCast != null) {
J.MethodInvocation mi = (J.MethodInvocation) j;
J.ControlParentheses<?> cp = (J.ControlParentheses<?>) adaptCache.get(adaptCast);
J.MethodInvocation m = mi.withSelect(cp);
return m;
}
J removeTypeCast = getCursor().getMessage("remove_type_cast");
if (removeTypeCast != null) {
return removeTypeCast;
}
return j;
}
});
}