From 203bebceaa8d3dab86538eb39d3aa706bfa7fcf3 Mon Sep 17 00:00:00 2001 From: Nicolas Filotto Date: Mon, 9 Oct 2023 14:11:46 +0200 Subject: [PATCH 01/18] Ref #930: camel-debugger - Allow to find the source file by file name (#931) ## Motivation When using the Camel Quarkus, the Camel Debugger doesn't work because he cannot retrieve the source file corresponding to the breakpoints known by Camel. ## Modifications * Add the file name as a potential location known by Camel * Avoid calling `compile` in the case of Quarkus as it could prevent the automatic addition of the Camel Debugger from working properly * Set the environment variable `CAMEL_MAIN_DEBUGGING` required by Camel Quarkus to enable the camel-debug extension --- .../idea/runner/debugger/CamelDebuggerPatcher.java | 8 ++++++-- .../idea/runner/debugger/CamelDebuggerSession.java | 6 ++++-- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerPatcher.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerPatcher.java index cf77cc5b..4bbbd222 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerPatcher.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerPatcher.java @@ -644,6 +644,7 @@ private static void addCamelDebuggerProperties(ParametersList parametersList) { */ private static void addCamelDebuggerEnvironmentVariable(JavaParameters parameters) { parameters.getEnv().put("CAMEL_DEBUGGER_SUSPEND", "true"); + parameters.getEnv().put("CAMEL_MAIN_DEBUGGING", "true"); } /** @@ -711,7 +712,10 @@ void configureCamelDebugger(JavaParameters parameters) { @Override void addRequiredParameters(JavaParameters parameters) { - super.addRequiredMavenGoals(parameters); + // Avoid to compile as it can prevent the automatic addition of the Camel Debugger from working properly + // Indeed otherwise, the addition of the Camel Debugger to a custom pom file is simply ignored + parameters.getProgramParametersList().addAt(0, "clean"); + parameters.getProgramParametersList().addAt(1, runtime.getPluginGoal()); } @Override @@ -845,7 +849,7 @@ void autoAddCamelDebugger(Project project, JavaParameters parameters, String ver /** * The corresponding Camel Runtime. */ - private final CamelRuntime runtime; + protected final CamelRuntime runtime; /** * Constructs a {@code ExecutionMode} with the given Camel Runtime. diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java index 7e478649..fe785cc9 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java @@ -878,6 +878,7 @@ private String getBreakpointId(@NotNull PsiElement breakpointTag) { if (basePath != null && url.startsWith(basePath)) { sourceLocations.add(String.format("file:%s", url.substring(basePath.length() + 1))); // file:file.xml } + sourceLocations.add(virtualFile.getName()); // file.xml } else { //Then it must be a Jar sourceLocations = List.of(String.format("classpath:%s", url.substring(url.lastIndexOf("!") + 2))); } @@ -897,8 +898,9 @@ private String getBreakpointId(@NotNull PsiElement breakpointTag) { } else { relativePath = virtualFile.getName(); } - sourceLocations.add(relativePath); // file.xml - sourceLocations.add(String.format("file:%s", relativePath)); // file:file.xml + sourceLocations.add(relativePath); // file.java + sourceLocations.add(String.format("file:%s", relativePath)); // file:file.java + sourceLocations.add(virtualFile.getName()); // file.java } break; default: // noop diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index c6e0a10a..6d1201fa 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -11,6 +11,7 @@ +
  • Camel-Debugger: Improve the support of Camel Quarkus
  • Bug fixes
  • ]]> From 9caf73933f1ddd9f5c3c72f6fdd6e9931eb72266 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Tue, 10 Oct 2023 12:03:16 +0200 Subject: [PATCH 02/18] Bump for next version --- build.gradle | 2 +- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 9f9dbd0f..08cd14bd 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ allprojects { } group = 'com.github.camel-tooling' - version = '1.1.1' + version = '1.1.2' } subprojects { diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 6d1201fa..6021eba1 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -1,7 +1,7 @@ org.apache.camel Apache Camel - 1.1.1 + 1.1.2 Apache Camel -
  • Camel-Debugger: Improve the support of Camel Quarkus
  • Bug fixes
  • ]]> From f0ea5acfeb952bfb9edbbb63ea97cc3e2e124342 Mon Sep 17 00:00:00 2001 From: Nicolas Filotto Date: Wed, 11 Oct 2023 10:52:04 +0200 Subject: [PATCH 03/18] Ref #927: Improve the support of third party repositories (#933) ## Motivation Some operations such as the automatic download of the Camel Debugger don't consider third-party maven repositories. Moreover, third-party maven repositories are only detected in maven projects, it should be improved to support Gradle projects too. ## Modifications: * Delegates the extraction of third-party maven repositories to `MavenArtifactRetrieverContext` to make sure that all operations take them into account * Provides a way to retrieve the list of maven repositories from Gradle project * Retrieves the list of maven repositories from Maven project using the Maven model instead of using the DOM API * Removes all DOM-related classes as they are no longer used * Moves all Gradle-related classes into a `gradle` package * Moves all Maven-related classes into a `maven` package --- .../idea/gradle/GradleFileWriter.java | 289 ++++++++++++++++++ .../cameltooling/idea/gradle/GradleUtil.java | 102 +++++++ .../CamelMavenVersionManager.java | 19 +- .../MavenArtifactRetrieverContext.java | 13 +- .../cameltooling/idea/maven/MavenUtil.java | 84 +++++ .../runner/debugger/CamelDebuggerPatcher.java | 194 ++---------- .../idea/service/CamelCatalogService.java | 11 +- .../idea/service/CamelJBangService.java | 1 + .../idea/service/CamelService.java | 59 +--- .../idea/service/XmlErrorHandler.java | 46 --- .../cameltooling/idea/service/XmlUtils.java | 75 ----- .../src/main/resources/META-INF/plugin.xml | 1 + ...atalogProviderWithKarafArtifactTestIT.java | 3 +- ...alogProviderWithQuarkusArtifactTestIT.java | 3 +- ...gProviderWithSpringBootArtifactTestIT.java | 3 +- ...gProviderWithoutRuntimeArtifactTestIT.java | 3 +- .../idea/service/XmlUtilsTest.java | 78 ----- 17 files changed, 525 insertions(+), 459 deletions(-) create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/gradle/GradleFileWriter.java create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/gradle/GradleUtil.java rename camel-idea-plugin/src/main/java/com/github/cameltooling/idea/{service => maven}/CamelMavenVersionManager.java (90%) rename camel-idea-plugin/src/main/java/com/github/cameltooling/idea/{service => maven}/MavenArtifactRetrieverContext.java (91%) create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/MavenUtil.java delete mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/XmlErrorHandler.java delete mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/XmlUtils.java delete mode 100644 camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/XmlUtilsTest.java diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/gradle/GradleFileWriter.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/gradle/GradleFileWriter.java new file mode 100644 index 00000000..e002e5cf --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/gradle/GradleFileWriter.java @@ -0,0 +1,289 @@ +/* + * 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 com.github.cameltooling.idea.gradle; + +import java.io.IOException; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import com.intellij.openapi.vfs.VirtualFile; +import org.apache.maven.model.Dependency; + +/** + * The supported writers of gradle files. + */ +public enum GradleFileWriter { + /** + * The writer dedicated to gradle files written in Kotlin. + */ + KOTLIN { + @Override + public String getInitScriptFileName() { + return "init.gradle.kts"; + } + + @Override + String getListRepositoriesContent() { + return """ + allprojects { + tasks.register("cameltoolingShowRepos") { + repositories + .map{it as MavenArtifactRepository} + .forEach{ println("${it.name}=${it.url}")} + } + } + """; + } + @Override + public void writeDependency(Writer writer, Dependency dependency) throws IOException { + writer.write( + String.format( + """ + project.dependencies.add("runtimeOnly", "%s:%s:%s") + """, + dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() + ) + ); + } + + @Override + public void writeDependencies(Writer writer, List dependencies, String projectName) throws IOException { + writer.write( + String.format( + """ + project("%s") { + plugins.withType() { + dependencies { + """, + projectName + ) + ); + for (Dependency dependency : dependencies) { + writer.write( + String.format( + """ + add("runtimeOnly", "%s:%s:%s") + """, + dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() + ) + ); + } + writer.write( + """ + } + } + } + """ + ); + } + + @Override + public void writeBuildFileLocation(Writer writer, Path buildFile) throws IOException { + writer.write( + String.format( + """ + rootProject.buildFileName = "%s" + """, + buildFile.getFileName() + ) + ); + } + + @Override + public String getBuildScriptFileName() { + return "build.gradle.kts"; + } + + @Override + public String getSettingsScriptFileName() { + return "settings.gradle.kts"; + } + }, + /** + * The writer dedicated to gradle files written in Groovy. + */ + GROOVY { + @Override + public String getInitScriptFileName() { + return "init.gradle"; + } + + @Override + String getListRepositoriesContent() { + return """ + allprojects { + tasks.register('cameltoolingShowRepos') { + repositories + .collect{it as MavenArtifactRepository} + .forEach{ println("${it.name}=${it.url}")} + } + } + """; + } + @Override + public void writeDependency(Writer writer, Dependency dependency) throws IOException { + writer.write( + String.format( + """ + project.dependencies.add('runtimeOnly', '%s:%s:%s') + """, + dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() + ) + ); + } + + @Override + public void writeDependencies(Writer writer, List dependencies, String projectName) throws IOException { + writer.write( + String.format( + """ + project('%s') { + plugins.withType(JavaPlugin.class) { + dependencies { + """, + projectName + ) + ); + for (Dependency dependency : dependencies) { + writer.write( + String.format( + """ + runtimeOnly '%s:%s:%s' + """, + dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() + ) + ); + } + writer.write( + """ + } + } + } + """ + ); + } + + @Override + public void writeBuildFileLocation(Writer writer, Path buildFile) throws IOException { + writer.write( + String.format( + """ + rootProject.buildFileName = '%s' + """, + buildFile.getFileName() + ) + ); + } + + @Override + public String getBuildScriptFileName() { + return "build.gradle"; + } + + @Override + public String getSettingsScriptFileName() { + return "settings.gradle"; + } + }; + + + /** + * Writes the given dependency to the given writer. + * + * @param writer the target writer + * @param dependency the dependency to write + * @throws IOException if the dependency could not be written + */ + public abstract void writeDependency(Writer writer, Dependency dependency) throws IOException; + + /** + * Writes the given dependencies of a specific project to the given writer. + * + * @param writer the target writer + * @param dependencies the dependencies to write + * @param projectName the target project name + * @throws IOException if the dependencies could not be written + */ + public abstract void writeDependencies(Writer writer, List dependencies, String projectName) throws IOException; + + /** + * Writes the location of the new build file. + * + * @param writer the target writer + * @param buildFile the new build file to configure. + * @throws IOException if the location of the build file could not be written + */ + public abstract void writeBuildFileLocation(Writer writer, Path buildFile) throws IOException; + + /** + * @return the name of the build script file + */ + public abstract String getBuildScriptFileName(); + + /** + * @return the name of the settings script file + */ + public abstract String getSettingsScriptFileName(); + + /** + * @return the name of the initialization script file + */ + public abstract String getInitScriptFileName(); + + /** + * @return the code allowing to list the repositories of a Gradle project + */ + abstract String getListRepositoriesContent(); + + /** + * Writes the code allowing to list the repositories of a Gradle project. + * + * @param writer the target writer + * @throws IOException if the code could not be written + */ + void writeListRepositoriesContent(Writer writer) throws IOException { + writer.write(getListRepositoriesContent()); + } + + /** + * @param vf the virtual file to check + * @return the writer corresponding to the given virtual file, or {@code null} if none could be found + */ + public static GradleFileWriter from(VirtualFile vf) { + for (GradleFileWriter writer : values()) { + if (vf.findChild(writer.getBuildScriptFileName()) != null || vf.findChild(writer.getSettingsScriptFileName()) != null) { + return writer; + } + } + return null; + } + + /** + * @param parent the parent directory to check + * @return the writer corresponding to the given parent directory, or {@code null} if none could be found + */ + public static GradleFileWriter from(Path parent) { + for (GradleFileWriter writer : values()) { + if (Files.exists(parent.resolve(writer.getBuildScriptFileName())) || Files.exists(parent.resolve(writer.getSettingsScriptFileName()))) { + return writer; + } + } + return null; + } +} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/gradle/GradleUtil.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/gradle/GradleUtil.java new file mode 100644 index 00000000..f98300cd --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/gradle/GradleUtil.java @@ -0,0 +1,102 @@ +/* + * 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 com.github.cameltooling.idea.gradle; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.VirtualFile; +import org.gradle.tooling.GradleConnector; +import org.gradle.tooling.ProjectConnection; + +/** + * {@code GradleUtil} is a utility class for Gradle related tasks. + */ +public final class GradleUtil { + private static final Logger LOG = Logger.getInstance(GradleUtil.class); + private GradleUtil() { + } + + /** + * Scans for third party maven repositories in the Gradle scripts files of the project. + * + * @param vf the root directory of the project + * @return a map with repo id and url for each found repository. The map may be empty if no third party repository + */ + public static Map extractRepositoriesFomGradleProject(VirtualFile vf) { + File initFile = createListRepositoriesInitScript(vf); + if (initFile == null) { + return Map.of(); + } + Map answer = new LinkedHashMap<>(); + try (ProjectConnection connection = GradleConnector.newConnector() + .forProjectDirectory(new File(vf.getCanonicalPath())) + .connect(); + ByteArrayOutputStream stdOut = new ByteArrayOutputStream()) { + connection.newBuild().withArguments("--init-script", initFile.getPath(), "-q", "cameltoolingShowRepos") + .setStandardOutput(stdOut) + .setStandardError(stdOut) + .run(); + String[] lines = stdOut.toString().split("\n"); + for (String line : lines) { + String[] parts = line.split("="); + if (parts.length == 2) { + LOG.info("Found third party Maven repository id: " + parts[0] + " url:" + parts[1]); + answer.put(parts[0], parts[1]); + } + } + } catch (Exception e) { + LOG.warn("Error parsing Gradle project", e); + } + return answer; + } + + /** + * Creates a temporary init script file to list the repositories of the Gradle project. + * + * @param vf the root directory of the project + * @return the created init script file or {@code null} if the file could not be created, or it is not + * Gradle project + */ + private static File createListRepositoriesInitScript(VirtualFile vf) { + GradleFileWriter writer = GradleFileWriter.from(vf); + if (writer == null) { + return null; + } + + File initFile = Paths.get( + System.getProperty("java.io.tmpdir"), String.format("cameltooling.%s", writer.getInitScriptFileName()) + ).toFile(); + if (Files.exists(initFile.toPath()) && initFile.delete()) { + LOG.debug("Deleted old init file: " + initFile); + } + try (FileWriter fileWriter = new FileWriter(initFile, false)) { + writer.writeListRepositoriesContent(fileWriter); + } catch (IOException e) { + LOG.warn("Error parsing Gradle project", e); + return null; + } + return initFile; + } +} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelMavenVersionManager.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/CamelMavenVersionManager.java similarity index 90% rename from camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelMavenVersionManager.java rename to camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/CamelMavenVersionManager.java index cf21a4bf..50882e02 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelMavenVersionManager.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/CamelMavenVersionManager.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.cameltooling.idea.service; +package com.github.cameltooling.idea.maven; import java.io.IOException; import java.io.InputStream; @@ -22,30 +22,25 @@ import java.util.Enumeration; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import org.apache.camel.catalog.VersionManager; /** - * A copy of {@link org.apache.camel.catalog.maven.MavenVersionManager} as IDEA cannot use this class at runtime, + * A copy of {@code org.apache.camel.catalog.maven.MavenVersionManager} as IDEA cannot use this class at runtime, * so we use a simpler copy here. */ -class CamelMavenVersionManager implements VersionManager { +public class CamelMavenVersionManager implements VersionManager { /** * The logger. */ private static final Logger LOG = Logger.getInstance(CamelMavenVersionManager.class); - private final MavenArtifactRetrieverContext context = new MavenArtifactRetrieverContext(); + private final MavenArtifactRetrieverContext context; private String version; private String runtimeProviderVersion; - /** - * To add a 3rd party Maven repository. - * - * @param name the repository name - * @param url the repository url - */ - void addMavenRepository(String name, String url) { - context.addMavenRepository(name, url); + public CamelMavenVersionManager(Project project) { + this.context = new MavenArtifactRetrieverContext(project); } @Override diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/MavenArtifactRetrieverContext.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/MavenArtifactRetrieverContext.java similarity index 91% rename from camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/MavenArtifactRetrieverContext.java rename to camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/MavenArtifactRetrieverContext.java index e415c4a9..3de2d226 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/MavenArtifactRetrieverContext.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/MavenArtifactRetrieverContext.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.github.cameltooling.idea.service; +package com.github.cameltooling.idea.maven; import java.io.Closeable; import java.io.IOException; @@ -28,19 +28,21 @@ import java.util.Map; import com.github.cameltooling.idea.util.ArtifactCoordinates; +import com.intellij.openapi.project.Project; import org.apache.camel.tooling.maven.MavenArtifact; import org.apache.camel.tooling.maven.MavenDownloader; import org.apache.camel.tooling.maven.MavenDownloaderImpl; import org.apache.camel.tooling.maven.MavenGav; import org.apache.camel.tooling.maven.MavenResolutionException; +import static com.github.cameltooling.idea.maven.MavenUtil.scanThirdPartyMavenRepositories; + /** * {@code MavenArtifactRetrieverContext} is meant to be used to download artifacts from maven repositories. * All the downloaded artifacts and their dependencies are automatically added to the underlying * {@code URLClassLoader} to be able to have access to the local path of the artifacts. */ public class MavenArtifactRetrieverContext implements Closeable { - private final MavenDownloader downloader; private final Map repositories = new LinkedHashMap<>(); private final MavenClassLoader classLoader = new MavenClassLoader(); @@ -51,13 +53,18 @@ public MavenArtifactRetrieverContext() { ((MavenDownloaderImpl) downloader).build(); } + public MavenArtifactRetrieverContext(Project project) { + this(); + scanThirdPartyMavenRepositories(project).forEach(this::addMavenRepository); + } + /** * To add a 3rd party Maven repository. * * @param name the repository name * @param url the repository url */ - public void addMavenRepository(String name, String url) { + private void addMavenRepository(String name, String url) { repositories.put(name, url); } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/MavenUtil.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/MavenUtil.java new file mode 100644 index 00000000..5486d761 --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/maven/MavenUtil.java @@ -0,0 +1,84 @@ +/* + * 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 com.github.cameltooling.idea.maven; + +import java.io.InputStream; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.github.cameltooling.idea.gradle.GradleUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectUtil; +import com.intellij.openapi.vfs.VirtualFile; +import org.apache.maven.model.Model; +import org.apache.maven.model.Repository; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.jetbrains.annotations.NotNull; + +/** + * {@code MavenUtil} is a utility class for Maven related tasks. + */ +public final class MavenUtil { + private static final Logger LOG = Logger.getInstance(MavenUtil.class); + + private MavenUtil() { + } + + /** + * Scans for third party maven repositories in the root pom.xml file of the project. + * + * @return a map with repo id and url for each found repository. The map may be empty if no third party repository + * is defined in the pom.xml file + */ + static @NotNull Map scanThirdPartyMavenRepositories(Project project) { + VirtualFile vf = ProjectUtil.guessProjectDir(project); + if (vf != null) { + VirtualFile pom = vf.findFileByRelativePath("pom.xml"); + if (pom == null) { + return GradleUtil.extractRepositoriesFomGradleProject(vf); + } + return extractFomPomFile(pom); + } + + return Map.of(); + } + + /** + * Scans for third party maven repositories in the root pom.xml file of the project. + * + * @param vf the root directory of the project + * @return a map with repo id and url for each found repository. The map may be empty if no third party repository + */ + private static Map extractFomPomFile(VirtualFile vf) { + Map answer = new LinkedHashMap<>(); + try (InputStream is = vf.getInputStream()) { + final Model model = new MavenXpp3Reader().read(is); + for (Repository repository : model.getRepositories()) { + String id = repository.getId(); + String url = repository.getUrl(); + if (id != null && url != null) { + LOG.info("Found third party Maven repository id: " + id + " url:" + url); + answer.put(id, url); + } + } + } catch (Exception e) { + LOG.warn("Error parsing Maven pon.xml file", e); + } + return answer; + } +} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerPatcher.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerPatcher.java index 4bbbd222..14cbb603 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerPatcher.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerPatcher.java @@ -20,7 +20,6 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.io.Writer; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; @@ -36,6 +35,7 @@ import java.util.StringJoiner; import java.util.function.Function; +import com.github.cameltooling.idea.gradle.GradleFileWriter; import com.github.cameltooling.idea.runner.CamelQuarkusRunConfigurationType; import com.github.cameltooling.idea.runner.CamelRunConfiguration; import com.github.cameltooling.idea.runner.CamelSpringBootRunConfigurationType; @@ -44,7 +44,7 @@ import com.github.cameltooling.idea.service.CamelProjectPreferenceService; import com.github.cameltooling.idea.service.CamelRuntime; import com.github.cameltooling.idea.service.CamelService; -import com.github.cameltooling.idea.service.MavenArtifactRetrieverContext; +import com.github.cameltooling.idea.maven.MavenArtifactRetrieverContext; import com.github.cameltooling.idea.util.ArtifactCoordinates; import com.intellij.execution.Executor; import com.intellij.execution.JavaRunConfigurationBase; @@ -264,7 +264,7 @@ private static void patchJavaParametersOnDebug(Project project, ExecutionMode mo notify(project, MessageType.INFO, "Camel Debugger has been added automatically with success."); LOG.debug("The camel-debug has been added with success"); } catch (Exception e) { - LOG.error("Could not add the Camel Debugger automatically", e); + LOG.warn("Could not add the Camel Debugger automatically", e); notify(project, MessageType.ERROR, "Camel Debugger could not be added automatically."); } } else { @@ -407,22 +407,20 @@ private static List generateBuildFilesWithCamelDebugger(ExecutionMode mode final ParametersList parametersList = parameters.getProgramParametersList(); List listParameters = parametersList.getParameters(); final int indexBuildFile = Math.max(listParameters.indexOf("-b"), listParameters.indexOf("--build-file")); - final GradleBuildWriter writer; + final GradleFileWriter writer; final String targetBuildFileName; if (indexBuildFile == -1) { - if (Files.exists(parent.resolve("build.gradle.kts")) || Files.exists(parent.resolve("settings.gradle.kts"))) { - targetBuildFileName = "build.gradle.kts"; - writer = GradleBuildWriter.KOTLIN; - } else { - targetBuildFileName = "build.gradle"; - writer = GradleBuildWriter.GROOVY; + writer = GradleFileWriter.from(parent); + if (writer == null) { + return List.of(); } + targetBuildFileName = writer.getBuildScriptFileName(); } else { targetBuildFileName = parametersList.get(indexBuildFile + 1); if (targetBuildFileName.endsWith(".kts")) { - writer = GradleBuildWriter.KOTLIN; + writer = GradleFileWriter.KOTLIN; } else { - writer = GradleBuildWriter.GROOVY; + writer = GradleFileWriter.GROOVY; } } @@ -445,12 +443,12 @@ private static List generateBuildFilesWithCamelDebugger(ExecutionMode mode if (parameter.split(":").length >= expectedLength) { added = true; String projectName = parameter.substring(0, parameter.lastIndexOf(':')); - writer.write(fileWriter, dependencies, projectName); + writer.writeDependencies(fileWriter, dependencies, projectName); } } if (!added) { for (Dependency dependency : dependencies) { - writer.write(fileWriter, dependency); + writer.writeDependency(fileWriter, dependency); } } } @@ -464,17 +462,13 @@ private static List generateBuildFilesWithCamelDebugger(ExecutionMode mode final int indexSettingsFile = Math.max(listParameters.indexOf("-c"), listParameters.indexOf("--settings-file")); final String targetSettingsFileName; if (indexSettingsFile == -1) { - if (writer == GradleBuildWriter.KOTLIN) { - targetSettingsFileName = "settings.gradle.kts"; - } else { - targetSettingsFileName = "settings.gradle"; - } + targetSettingsFileName = writer.getSettingsScriptFileName(); } else { targetSettingsFileName = parametersList.get(indexSettingsFile + 1); } Path settingsFile = createGeneratedFile(parent, targetSettingsFileName); try (FileWriter fileWriter = new FileWriter(settingsFile.toFile(), true)) { - writer.write(fileWriter, buildFile); + writer.writeBuildFileLocation(fileWriter, buildFile); } if (indexSettingsFile == -1) { parametersList.add("-c"); @@ -587,7 +581,7 @@ private static void autoDownloadCamelDebugger(Project project, JavaParameters pa ); } } - for (URL url : downloadCamelDebugger(runtime, versionRuntime)) { + for (URL url : downloadCamelDebugger(project, runtime, versionRuntime)) { try { parameters.getClassPath().add(new File(url.toURI())); } catch (URISyntaxException e) { @@ -599,6 +593,7 @@ private static void autoDownloadCamelDebugger(Project project, JavaParameters pa /** * Downloads the Camel Debugger and its dependencies corresponding to the given runtime. * + * @param project the project for which the Camel Debugger needs to be downloaded. * @param runtime the target runtime for which the Camel Debugger is downloaded. * @param version the version of the Camel Debugger to download. * @return the list of {@link URL} corresponding to the location of the Camel Debugger and its dependencies that have @@ -606,8 +601,8 @@ private static void autoDownloadCamelDebugger(Project project, JavaParameters pa * @throws IOException if an error occurs while downloading the Camel Debugger and its dependencies. */ @NotNull - private static List downloadCamelDebugger(@NotNull CamelRuntime runtime, @NotNull String version) throws IOException { - try (MavenArtifactRetrieverContext context = new MavenArtifactRetrieverContext()) { + private static List downloadCamelDebugger(Project project, @NotNull CamelRuntime runtime, @NotNull String version) throws IOException { + try (MavenArtifactRetrieverContext context = new MavenArtifactRetrieverContext(project)) { ArtifactCoordinates debugArtifact = runtime.getDebugArtifact(); if (LOG.isDebugEnabled()) { LOG.debug(String.format("Trying to download %s %s with all its dependencies", debugArtifact, version)); @@ -1003,157 +998,4 @@ private void addRequiredMavenGoals(JavaParameters parameters) { parameters.getProgramParametersList().addAt(2, runtime.getPluginGoal()); } } - - /** - * The supported writer of gradle build file. - */ - private enum GradleBuildWriter { - - /** - * The writer dedicated to gradle build file written in Groovy. - */ - GROOVY { - @Override - void write(Writer writer, Dependency dependency) throws IOException { - writer.write( - String.format( - """ - project.dependencies.add('runtimeOnly', '%s:%s:%s') - """, - dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() - ) - ); - } - - @Override - void write(Writer writer, List dependencies, String projectName) throws IOException { - writer.write( - String.format( - """ - project('%s') { - plugins.withType(JavaPlugin.class) { - dependencies { - """, - projectName - ) - ); - for (Dependency dependency : dependencies) { - writer.write( - String.format( - """ - runtimeOnly '%s:%s:%s' - """, - dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() - ) - ); - } - writer.write( - """ - } - } - } - """ - ); - } - - @Override - void write(Writer writer, Path buildFile) throws IOException { - writer.write( - String.format( - """ - rootProject.buildFileName = '%s' - """, - buildFile.getFileName() - ) - ); - } - }, - /** - * The writer dedicated to gradle build file written in Kotlin. - */ - KOTLIN { - @Override - void write(Writer writer, Dependency dependency) throws IOException { - writer.write( - String.format( - """ - project.dependencies.add("runtimeOnly", "%s:%s:%s") - """, - dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() - ) - ); - } - - @Override - void write(Writer writer, List dependencies, String projectName) throws IOException { - writer.write( - String.format( - """ - project("%s") { - plugins.withType() { - dependencies { - """, - projectName - ) - ); - for (Dependency dependency : dependencies) { - writer.write( - String.format( - """ - add("runtimeOnly", "%s:%s:%s") - """, - dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() - ) - ); - } - writer.write( - """ - } - } - } - """ - ); - } - - @Override - void write(Writer writer, Path buildFile) throws IOException { - writer.write( - String.format( - """ - rootProject.buildFileName = "%s" - """, - buildFile.getFileName() - ) - ); - } - }; - - /** - * Writes the given dependency to the given writer. - * - * @param writer the target writer - * @param dependency the dependency to write - * @throws IOException if the dependency could not be written - */ - abstract void write(Writer writer, Dependency dependency) throws IOException; - - /** - * Writes the given dependencies of a specific project to the given writer. - * - * @param writer the target writer - * @param dependencies the dependencies to write - * @param projectName the target project name - * @throws IOException if the dependencies could not be written - */ - abstract void write(Writer writer, List dependencies, String projectName) throws IOException; - - /** - * Writes the location of the new build file. - * - * @param writer the target writer - * @param buildFile the new build file to configure. - * @throws IOException if the location of the build file could not be written - */ - abstract void write(Writer writer, Path buildFile) throws IOException; - } } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelCatalogService.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelCatalogService.java index f0d80445..9d559440 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelCatalogService.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelCatalogService.java @@ -16,9 +16,8 @@ */ package com.github.cameltooling.idea.service; -import java.util.Map; - import com.github.cameltooling.idea.catalog.CamelCatalogProvider; +import com.github.cameltooling.idea.maven.CamelMavenVersionManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.project.Project; import org.apache.camel.catalog.CamelCatalog; @@ -100,16 +99,12 @@ private void updateRuntimeProvider(CamelCatalog catalog) { * Loads a specific Camel version into the Catalog to use. * * @param version the version to load - * @param repos any third party maven repositories */ - boolean loadVersion(@NotNull String version, @NotNull Map repos) { + boolean loadVersion(@NotNull String version) { // we should load a new version of the catalog, and therefore must discard the old version dispose(); // use maven to be able to load the version dynamic - CamelMavenVersionManager maven = new CamelMavenVersionManager(); - - // add support for the maven repos - repos.forEach(maven::addMavenRepository); + CamelMavenVersionManager maven = new CamelMavenVersionManager(project); get().setVersionManager(maven); boolean loaded = get().getVersionManager().loadVersion(version); diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelJBangService.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelJBangService.java index 24f5026d..478471d8 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelJBangService.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelJBangService.java @@ -30,6 +30,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.github.cameltooling.idea.maven.MavenArtifactRetrieverContext; import com.github.cameltooling.idea.util.ArtifactCoordinates; import com.intellij.execution.ExecutionException; import com.intellij.execution.process.KillableColoredProcessHandler; diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelService.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelService.java index 7060838e..6fff95e6 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelService.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/CamelService.java @@ -16,8 +16,6 @@ */ package com.github.cameltooling.idea.service; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -25,19 +23,13 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -import javax.swing.*; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; +import javax.swing.Icon; import com.github.cameltooling.idea.catalog.CamelCatalogProvider; import com.github.cameltooling.idea.util.ArtifactCoordinates; @@ -53,19 +45,15 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.messages.Topic; import org.apache.camel.catalog.CamelCatalog; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.github.cameltooling.idea.service.XmlUtils.getChildNodeByTagName; -import static com.github.cameltooling.idea.service.XmlUtils.loadDocument; import static org.apache.camel.catalog.impl.CatalogHelper.loadText; /** @@ -533,8 +521,7 @@ private boolean notifyNewCamelCatalogVersionLoaded(boolean notifyLoaded) { private boolean downloadNewCamelCatalogVersion(@NotNull CamelCatalogProvider provider, @NotNull String version) { // find out the third party maven repositories final CamelCatalogService catalogService = getCamelCatalogService(); - boolean loaded = catalogService.loadVersion(version, scanThirdPartyMavenRepositories()) - && provider.loadRuntimeProviderVersion(project); + boolean loaded = catalogService.loadVersion(version) && provider.loadRuntimeProviderVersion(project); if (!loaded) { // always notify if download was not possible camelVersionNotification = CAMEL_NOTIFICATION_GROUP.createNotification( @@ -604,48 +591,6 @@ private void notifyForMissingJsonSchemas(List missingJSonSchemas) { } } - /** - * Scans for third party maven repositories in the root pom.xml file of the project. - * - * @return a map with repo id and url for each found repository. The map may be empty if no third party repository - * is defined in the pom.xml file - */ - private @NotNull Map scanThirdPartyMavenRepositories() { - Map answer = new LinkedHashMap<>(); - - VirtualFile vf = ProjectUtil.guessProjectDir(project); - if (vf != null) { - vf = vf.findFileByRelativePath("pom.xml"); - } - if (vf != null) { - try (InputStream is = vf.getInputStream()) { - Document dom = loadDocument(is, false); - NodeList list = dom.getElementsByTagName("repositories"); - if (list != null && list.getLength() == 1) { - Node repos = list.item(0); - if (repos instanceof Element) { - Element element = (Element) repos; - list = element.getElementsByTagName("repository"); - for (int i = 0; i < list.getLength(); i++) { - Node node = list.item(i); - // grab id and url - Node id = getChildNodeByTagName(node, "id"); - Node url = getChildNodeByTagName(node, "url"); - if (id != null && url != null) { - LOG.info("Found third party Maven repository id: " + id.getTextContent() + " url:" + url.getTextContent()); - answer.put(id.getTextContent(), url.getTextContent()); - } - } - } - } - } catch (Exception e) { - LOG.warn("Error parsing Maven pon.xml file", e); - } - } - - return answer; - } - /** * Adds any discovered third party Camel components from the dependency. * diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/XmlErrorHandler.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/XmlErrorHandler.java deleted file mode 100644 index 3bfd3121..00000000 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/XmlErrorHandler.java +++ /dev/null @@ -1,46 +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 com.github.cameltooling.idea.service; - -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -class XmlErrorHandler implements ErrorHandler { - - XmlErrorHandler() { - } - - @Override - public void warning(SAXParseException exception) throws SAXException { - throw new SAXException(saxMsg(exception)); - } - - @Override - public void error(SAXParseException exception) throws SAXException { - throw new SAXException(saxMsg(exception)); - } - - @Override - public void fatalError(SAXParseException exception) throws SAXException { - throw new SAXException(saxMsg(exception)); - } - - private String saxMsg(SAXParseException e) { - return "Line: " + e.getLineNumber() + ", Column: " + e.getColumnNumber() + ", Error: " + e.getMessage(); - } -} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/XmlUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/XmlUtils.java deleted file mode 100644 index 7c05811b..00000000 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/XmlUtils.java +++ /dev/null @@ -1,75 +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 com.github.cameltooling.idea.service; - -import java.io.InputStream; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.jetbrains.annotations.NotNull; - -/** - * XML and DOM utilities. - */ -final class XmlUtils { - - private XmlUtils() { - } - - /** - * Loads the input stream into a DOM - * - * @param is the input stream - * @param validating whether to validate or not - * @return the DOM - */ - static @NotNull Document loadDocument(@NotNull InputStream is, boolean validating) throws Exception { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = dbf.newDocumentBuilder(); - if (validating) { - documentBuilder.setErrorHandler(new XmlErrorHandler()); - } - dbf.setValidating(validating); - return documentBuilder.parse(is); - } - - /** - * Gets a child node by the given name. - * - * @param node the node - * @param name the name of the child node to find and return - * @return the child node, or null if none found - */ - static Node getChildNodeByTagName(Node node, String name) { - NodeList children = node.getChildNodes(); - if (children != null && children.getLength() > 0) { - for (int i = 0; i < children.getLength(); i++) { - Node child = children.item(i); - if (child instanceof Element) { - Element element = (Element) child; - if (name.equals(element.getTagName())) { - return element; - } - } - } - } - return null; - } -} diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 6021eba1..57e507fd 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -11,6 +11,7 @@ +
  • Improve the support of third party repositories
  • Bug fixes
  • ]]> diff --git a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithKarafArtifactTestIT.java b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithKarafArtifactTestIT.java index 9aaf132b..23661842 100644 --- a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithKarafArtifactTestIT.java +++ b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithKarafArtifactTestIT.java @@ -18,6 +18,7 @@ import com.github.cameltooling.idea.CamelLightCodeInsightFixtureTestCaseIT; import com.github.cameltooling.idea.catalog.CamelCatalogProvider; +import com.github.cameltooling.idea.maven.CamelMavenVersionManager; import org.apache.camel.catalog.CamelCatalog; import org.apache.camel.catalog.DefaultCamelCatalog; import org.jetbrains.annotations.Nullable; @@ -52,7 +53,7 @@ public void testGetCatalog() { * Ensure that the runtime provider can be loaded. */ public void testRuntimeProvider() { - getProject().getService(CamelCatalogService.class).get().setVersionManager(new CamelMavenVersionManager()); + getProject().getService(CamelCatalogService.class).get().setVersionManager(new CamelMavenVersionManager(getProject())); assertTrue(provider.loadRuntimeProviderVersion(getProject())); } } diff --git a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithQuarkusArtifactTestIT.java b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithQuarkusArtifactTestIT.java index 69ddc6b7..71e32e30 100644 --- a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithQuarkusArtifactTestIT.java +++ b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithQuarkusArtifactTestIT.java @@ -18,6 +18,7 @@ import com.github.cameltooling.idea.CamelLightCodeInsightFixtureTestCaseIT; import com.github.cameltooling.idea.catalog.CamelCatalogProvider; +import com.github.cameltooling.idea.maven.CamelMavenVersionManager; import org.apache.camel.catalog.CamelCatalog; import org.apache.camel.catalog.DefaultCamelCatalog; import org.jetbrains.annotations.Nullable; @@ -52,7 +53,7 @@ public void testGetCatalog() { * Ensure that the runtime provider can be loaded. */ public void testRuntimeProvider() { - getProject().getService(CamelCatalogService.class).get().setVersionManager(new CamelMavenVersionManager()); + getProject().getService(CamelCatalogService.class).get().setVersionManager(new CamelMavenVersionManager(getProject())); assertTrue(provider.loadRuntimeProviderVersion(getProject())); } } diff --git a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithSpringBootArtifactTestIT.java b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithSpringBootArtifactTestIT.java index c0e229d4..9556ee04 100644 --- a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithSpringBootArtifactTestIT.java +++ b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithSpringBootArtifactTestIT.java @@ -18,6 +18,7 @@ import com.github.cameltooling.idea.CamelLightCodeInsightFixtureTestCaseIT; import com.github.cameltooling.idea.catalog.CamelCatalogProvider; +import com.github.cameltooling.idea.maven.CamelMavenVersionManager; import org.apache.camel.catalog.CamelCatalog; import org.apache.camel.catalog.DefaultCamelCatalog; import org.jetbrains.annotations.Nullable; @@ -52,7 +53,7 @@ public void testGetCatalog() { * Ensure that the runtime provider can be loaded. */ public void testRuntimeProvider() { - getProject().getService(CamelCatalogService.class).get().setVersionManager(new CamelMavenVersionManager()); + getProject().getService(CamelCatalogService.class).get().setVersionManager(new CamelMavenVersionManager(getProject())); assertTrue(provider.loadRuntimeProviderVersion(getProject())); } } diff --git a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithoutRuntimeArtifactTestIT.java b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithoutRuntimeArtifactTestIT.java index 183ed7a7..9ea7bb88 100644 --- a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithoutRuntimeArtifactTestIT.java +++ b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/CamelCatalogProviderWithoutRuntimeArtifactTestIT.java @@ -18,6 +18,7 @@ import com.github.cameltooling.idea.CamelLightCodeInsightFixtureTestCaseIT; import com.github.cameltooling.idea.catalog.CamelCatalogProvider; +import com.github.cameltooling.idea.maven.CamelMavenVersionManager; import com.github.cameltooling.idea.util.ArtifactCoordinates; import com.intellij.testFramework.ServiceContainerUtil; import org.apache.camel.catalog.CamelCatalog; @@ -76,7 +77,7 @@ public void testSpringBootRuntimeProvider() { } private void testRuntimeProvider(CamelCatalogProvider provider) { - getProject().getService(CamelCatalogService.class).get().setVersionManager(new CamelMavenVersionManager()); + getProject().getService(CamelCatalogService.class).get().setVersionManager(new CamelMavenVersionManager(getProject())); assertTrue(provider.loadRuntimeProviderVersion(getProject())); } } diff --git a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/XmlUtilsTest.java b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/XmlUtilsTest.java deleted file mode 100644 index 5a009b90..00000000 --- a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/service/XmlUtilsTest.java +++ /dev/null @@ -1,78 +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 com.github.cameltooling.idea.service; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -public class XmlUtilsTest { - - private Document document; - - public XmlUtilsTest() throws Exception { - document = XmlUtils.loadDocument(readTestXmlFile(), true); - } - - @Test - public void loadDocument() { - assertEquals("problems", document.getDocumentElement().getTagName()); - } - - @Test - public void getChildNodeByTagName() { - NodeList problem = document.getElementsByTagName("problem"); - Node item = problem.item(0); - Node description = XmlUtils.getChildNodeByTagName(item, "description"); - assertEquals("fileExist is not applicable in consumer only mode", description.getTextContent()); - - } - - @Test - public void returnNullWhenRootDoesNotContainChildren() throws Exception { - Document document = XmlUtils.loadDocument(readTestXmlFileWithoutChildren(), true); - Element root = document.getDocumentElement(); - Node nothing = XmlUtils.getChildNodeByTagName(document, "description"); - assertNull(nothing); - } - - private FileInputStream readTestXmlFile() { - FileInputStream fileInputStream = null; - try { - fileInputStream = new FileInputStream("src/test/resources/testData/inspectionxml/expected.xml"); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return fileInputStream; - } - - private FileInputStream readTestXmlFileWithoutChildren() { - FileInputStream fileInputStream = null; - try { - fileInputStream = new FileInputStream("src/test/resources/testData/inspectionxml/expected-xml-without-children.xml"); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return fileInputStream; - } -} From a8e00ce95ce640aadba58c8a088fd588ebeb9acb Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Thu, 12 Oct 2023 19:39:01 +0200 Subject: [PATCH 04/18] Upgrade to Camel 4.1.0 (#935) --- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 3 ++- gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 57e507fd..7bf7fb03 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -11,7 +11,8 @@ -
  • Improve the support of third party repositories
  • +
  • Upgraded to Camel 4.1.0
  • +
  • Improve the support of third party Maven repositories
  • Bug fixes
  • ]]> diff --git a/gradle.properties b/gradle.properties index d849e09e..1c582d4c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ -camelVersion = 4.0.1 +camelVersion = 4.1.0 camelQuarkusVersion = 3.4.0 camelKameletVersion = 4.0.1 -camelKarafVersion = 3.21.0 +camelKarafVersion = 3.21.1 ideaVersion=2023.2.2 mavenResolverVersion=1.9.14 From 529f084efce17be21ee5eb721f72c74c6f26d81c Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Thu, 12 Oct 2023 19:48:48 +0200 Subject: [PATCH 05/18] Bump for next version --- build.gradle | 2 +- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 08cd14bd..ded4663d 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ allprojects { } group = 'com.github.camel-tooling' - version = '1.1.2' + version = '1.1.3' } subprojects { diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 7bf7fb03..749c920f 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -1,7 +1,7 @@ org.apache.camel Apache Camel - 1.1.2 + 1.1.3 Apache Camel -
  • Upgraded to Camel 4.1.0
  • -
  • Improve the support of third party Maven repositories
  • Bug fixes
  • ]]> From 0e1cdaaf3a066d9344fe9d2bdf7a301970449c23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 13:47:09 +0200 Subject: [PATCH 06/18] Bump com.fasterxml.jackson.dataformat:jackson-dataformat-yaml (#938) Bumps [com.fasterxml.jackson.dataformat:jackson-dataformat-yaml](https://github.com/FasterXML/jackson-dataformats-text) from 2.15.2 to 2.15.3. - [Commits](https://github.com/FasterXML/jackson-dataformats-text/compare/jackson-dataformats-text-2.15.2...jackson-dataformats-text-2.15.3) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- camel-idea-plugin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camel-idea-plugin/build.gradle b/camel-idea-plugin/build.gradle index a0d513f1..ead0ba1e 100644 --- a/camel-idea-plugin/build.gradle +++ b/camel-idea-plugin/build.gradle @@ -67,7 +67,7 @@ dependencies { implementation "org.apache.maven.resolver:maven-resolver-api:${mavenResolverVersion}" implementation "org.apache.maven.resolver:maven-resolver-impl:${mavenResolverVersion}" implementation "io.github.classgraph:classgraph:4.8.162" - implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2" + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.3" implementation "io.fabric8:kubernetes-model-apiextensions:6.9.0" testImplementation "org.apache.camel:camel-core:${camelVersion}" From 6c0520d715e929d7804425bb7cd655a374598787 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 13:47:20 +0200 Subject: [PATCH 07/18] Bump org.springframework:spring-context from 6.0.12 to 6.0.13 (#937) Bumps [org.springframework:spring-context](https://github.com/spring-projects/spring-framework) from 6.0.12 to 6.0.13. - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.0.12...v6.0.13) --- updated-dependencies: - dependency-name: org.springframework:spring-context dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- camel-idea-plugin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camel-idea-plugin/build.gradle b/camel-idea-plugin/build.gradle index ead0ba1e..192330e4 100644 --- a/camel-idea-plugin/build.gradle +++ b/camel-idea-plugin/build.gradle @@ -76,7 +76,7 @@ dependencies { testImplementation 'org.jboss.shrinkwrap:shrinkwrap-depchain:1.2.6' testImplementation 'org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-depchain:3.2.1' testImplementation 'org.hamcrest:hamcrest-all:1.3' - testImplementation 'org.springframework:spring-context:6.0.12' + testImplementation 'org.springframework:spring-context:6.0.13' testImplementation "org.apache.camel:camel-jsonpath:${camelVersion}" } From 629704e5759b0bbf93791c71775499f37643cd65 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Fri, 13 Oct 2023 14:21:35 +0200 Subject: [PATCH 08/18] #936 - Upgrade to IDEA 2023.2.3 (#939) --- .github/workflows/ci-build.yaml | 2 +- build-all.sh | 2 +- gradle.properties | 2 +- readme.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 2054401f..ef59bda1 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -40,7 +40,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - version: [2022.3.3, 2023.1.3, 2023.2.2] + version: [2022.3.3, 2023.1.3, 2023.2.3] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 diff --git a/build-all.sh b/build-all.sh index d4b88aed..385ccc4c 100755 --- a/build-all.sh +++ b/build-all.sh @@ -1,5 +1,5 @@ #!/bin/bash -for v in "2022.3.3" "2023.1.3" "2023.2.2"; do +for v in "2022.3.3" "2023.1.3" "2023.2.3"; do ./build.sh $v done diff --git a/gradle.properties b/gradle.properties index 1c582d4c..aff16fb9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,5 +2,5 @@ camelVersion = 4.1.0 camelQuarkusVersion = 3.4.0 camelKameletVersion = 4.0.1 camelKarafVersion = 3.21.1 -ideaVersion=2023.2.2 +ideaVersion=2023.2.3 mavenResolverVersion=1.9.14 diff --git a/readme.md b/readme.md index 4fca6aaf..644bd448 100644 --- a/readme.md +++ b/readme.md @@ -98,7 +98,7 @@ Importing the project into IntelliJ as plug-in only require you choose ìmport f #### Running the plug-in with a previous versions of IDEA -The plugin is tested with `IDEA 2023.2.2` or newer, but if you want to try with an older version you can follow this guide +The plugin is tested with `IDEA 2023.2.3` or newer, but if you want to try with an older version you can follow this guide > - Follow the guide [build from source](#buildingfromsource) > - Change the attribute `` in `camel-idea-plugin/src/main/resources/META-INF/plugin.xml` to match the version. please see [document](http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html) for build number description From ce0d487de1884233277177c06fe0b3dc0d52e840 Mon Sep 17 00:00:00 2001 From: Nicolas Filotto Date: Fri, 13 Oct 2023 15:07:20 +0200 Subject: [PATCH 09/18] Ref #932: Add completion for Kamelet names and options in binding files (#940) ## Motivation The binding uses kamelets for the source/sink/steps and we should have code assistance in IDEA plugin, to list the options from the kamelet, and also help to auto-complete Kamelet names (from the Kamelets catalog). ## Modifications: * Add new completion providers to provide the Kamelet names, option names, and option values * Adapt the existing code that provides the name of Kamelets to make it reusable in a different context --- .../CamelYamlFileReferenceContributor.java | 217 ++++++++++++++++++ .../CamelSmartCompletionEndpointOptions.java | 150 +++++++++--- .../extension/CamelKameletCompletion.java | 90 ++++++++ .../extension/CamelKameletNameCompletion.java | 60 +++++ .../CamelKameletOptionCompletion.java | 43 ++++ .../CamelKameletOptionNameCompletion.java | 159 +++++++++++++ .../CamelKameletOptionValueCompletion.java | 110 +++++++++ .../idea/service/KameletService.java | 10 + .../idea/util/YamlPatternConditions.java | 42 ++++ .../src/main/resources/META-INF/plugin.xml | 1 + .../CamelKameletNameCompletionIT.java | 106 +++++++++ .../CamelKameletOptionNameCompletionIT.java | 112 +++++++++ .../CamelKameletOptionValueCompletionIT.java | 102 ++++++++ .../kamelet/name/binding-no-kamelet.yaml | 10 + .../kamelet/name/binding-no-name.yaml | 10 + .../completion/kamelet/name/binding-sink.yaml | 10 + .../kamelet/name/binding-source.yaml | 10 + .../kamelet/name/binding-steps.yaml | 10 + .../kamelet/name/binding-unknown.yaml | 10 + .../completion/kamelet/name/binding.yaml | 10 + .../kamelet/name/bindingResult.yaml | 10 + .../optionname/binding-no-kamelet.yaml | 12 + .../kamelet/optionname/binding-no-name.yaml | 12 + .../kamelet/optionname/binding-sink.yaml | 12 + .../kamelet/optionname/binding-source.yaml | 12 + .../kamelet/optionname/binding-steps.yaml | 12 + .../kamelet/optionname/binding-unknown.yaml | 12 + .../kamelet/optionname/binding.yaml | 12 + .../kamelet/optionname/bindingResult.yaml | 12 + .../optionvalue/binding-no-kamelet.yaml | 12 + .../kamelet/optionvalue/binding-no-name.yaml | 12 + .../kamelet/optionvalue/binding-sink.yaml | 12 + .../kamelet/optionvalue/binding-source.yaml | 12 + .../kamelet/optionvalue/binding-steps.yaml | 12 + .../kamelet/optionvalue/binding-unknown.yaml | 12 + .../kamelet/optionvalue/binding.yaml | 12 + .../kamelet/optionvalue/bindingResult.yaml | 12 + img/54-kamelet-binding-completion.gif | Bin 0 -> 272758 bytes readme.md | 1 + 39 files changed, 1444 insertions(+), 31 deletions(-) create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletCompletion.java create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletNameCompletion.java create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionCompletion.java create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionNameCompletion.java create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionValueCompletion.java create mode 100644 camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletNameCompletionIT.java create mode 100644 camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletOptionNameCompletionIT.java create mode 100644 camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletOptionValueCompletionIT.java create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-no-kamelet.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-no-name.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-sink.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-source.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-steps.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-unknown.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/bindingResult.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-no-kamelet.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-no-name.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-sink.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-source.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-steps.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-unknown.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/bindingResult.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-no-kamelet.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-no-name.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-sink.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-source.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-steps.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-unknown.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding.yaml create mode 100644 camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/bindingResult.yaml create mode 100644 img/54-kamelet-binding-completion.gif diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/contributor/CamelYamlFileReferenceContributor.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/contributor/CamelYamlFileReferenceContributor.java index dbc35e55..ed077081 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/contributor/CamelYamlFileReferenceContributor.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/contributor/CamelYamlFileReferenceContributor.java @@ -18,6 +18,9 @@ import com.github.cameltooling.idea.completion.extension.CamelEndpointNameCompletionExtension; import com.github.cameltooling.idea.completion.extension.CamelEndpointSmartCompletionExtension; +import com.github.cameltooling.idea.completion.extension.CamelKameletNameCompletion; +import com.github.cameltooling.idea.completion.extension.CamelKameletOptionNameCompletion; +import com.github.cameltooling.idea.completion.extension.CamelKameletOptionValueCompletion; import com.github.cameltooling.idea.completion.header.CamelHeaderEndpointSource; import com.github.cameltooling.idea.completion.header.CamelYamlHeaderNameCompletion; import com.github.cameltooling.idea.completion.header.CamelYamlHeaderValueCompletion; @@ -26,13 +29,21 @@ import com.github.cameltooling.idea.util.YamlPatternConditions; import com.intellij.codeInsight.completion.CompletionInitializationContext; import com.intellij.codeInsight.completion.CompletionType; +import com.intellij.patterns.PatternCondition; import com.intellij.patterns.PlatformPatterns; +import com.intellij.patterns.PsiElementPattern; import com.intellij.patterns.StandardPatterns; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.TokenType; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; import org.jetbrains.yaml.YAMLElementTypes; import org.jetbrains.yaml.YAMLTokenTypes; import org.jetbrains.yaml.psi.YAMLKeyValue; +import org.jetbrains.yaml.psi.YAMLMapping; +import org.jetbrains.yaml.psi.YAMLSequence; +import org.jetbrains.yaml.psi.YAMLSequenceItem; import static com.intellij.patterns.PlatformPatterns.psiElement; @@ -41,6 +52,40 @@ */ public class CamelYamlFileReferenceContributor extends CamelContributor { + private static final PatternCondition WITH_FIRST_CHILD_IS_PROPERTIES = YamlPatternConditions.withFirstChild( + psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText("properties") + ); + private static final PsiElementPattern.Capture IS_KIND_KAMELET = psiElement(YAMLMapping.class) + .withChild( + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText("ref") + ) + ) + .withChild( + psiElement(YAMLMapping.class) + + .withChild( + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withPair("kind", "Kamelet") + ) + ) + .withChild( + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText("name") + ) + ) + ) + ) + ); + public CamelYamlFileReferenceContributor() { addCompletionExtension(new CamelEndpointNameCompletionExtension()); addCompletionExtension(new CamelEndpointSmartCompletionExtension(false)); @@ -212,5 +257,177 @@ public CamelYamlFileReferenceContributor() { ), new CamelYamlPropertyValueCompletion() ); + // Detect the name of a Kamelet in a Kamelet binding + addCamelKameletNameCompletion("source", true); + addCamelKameletNameCompletion("steps", false); + addCamelKameletNameCompletion("sink", false); + addCamelKameletOptionNameCompletion(); + addCamelKameletOptionValueCompletion(); + } + + private void addCamelKameletNameCompletion(String ancestorKeyName, boolean onlyConsumer) { + extend(CompletionType.BASIC, + psiElement(YAMLTokenTypes.TEXT) + .withSuperParent( + 2, + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText("name") + ) + ) + .withParent( + psiElement(YAMLMapping.class) + .withChild( + PlatformPatterns.psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withPair("kind", "Kamelet") + ) + ) + ) + ) + .withSuperParent( + 4, + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText("ref") + ) + ) + ) + .withSuperParent( + 6, + StandardPatterns.or( + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText(ancestorKeyName) + ) + ), + psiElement(YAMLSequenceItem.class) + .withSuperParent( + 2, + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText(ancestorKeyName) + ) + ) + ) + ) + + ), + new CamelKameletNameCompletion(onlyConsumer) + ); + } + + private void addCamelKameletOptionNameCompletion() { + extend(CompletionType.BASIC, + psiElement() + .with( + YamlPatternConditions.or( + psiElement(YAMLTokenTypes.TEXT) + .withSuperParent( + 2, + PlatformPatterns.psiElement(YAMLKeyValue.class) + .with( + WITH_FIRST_CHILD_IS_PROPERTIES + ) + ), + psiElement(YAMLTokenTypes.INDENT) + .afterSibling( + PlatformPatterns.psiElement(YAMLKeyValue.class) + .with( + WITH_FIRST_CHILD_IS_PROPERTIES + ) + ), + psiElement(YAMLTokenTypes.TEXT) + .withSuperParent( + 3, + PlatformPatterns.psiElement(YAMLKeyValue.class) + .with( + WITH_FIRST_CHILD_IS_PROPERTIES + ) + ) + ) + ) + .withAncestor( + 5, + StandardPatterns.or( + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .with(YamlPatternConditions.withText("source", "sink")) + ) + ) + .withChild(IS_KIND_KAMELET), + psiElement(YAMLSequenceItem.class) + .withSuperParent( + 2, + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText("steps") + ) + ) + ) + .withChild(IS_KIND_KAMELET) + ) + ), + new CamelKameletOptionNameCompletion() + ); + } + + + private void addCamelKameletOptionValueCompletion() { + extend(CompletionType.BASIC, + psiElement() + .withParent( + psiElement().with( + YamlPatternConditions.withElementType( + YAMLElementTypes.SCALAR_PLAIN_VALUE, YAMLElementTypes.SCALAR_QUOTED_STRING + ) + ) + ) + .withAncestor( + 4, + PlatformPatterns.psiElement(YAMLKeyValue.class) + .with( + WITH_FIRST_CHILD_IS_PROPERTIES + ) + ) + .withAncestor( + 6, + StandardPatterns.or( + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .with(YamlPatternConditions.withText("source", "sink")) + ) + ) + .withChild(IS_KIND_KAMELET), + psiElement(YAMLSequenceItem.class) + .withSuperParent( + 2, + psiElement(YAMLKeyValue.class) + .with( + YamlPatternConditions.withFirstChild( + PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY) + .withText("steps") + ) + ) + ) + .withChild(IS_KIND_KAMELET) + ) + ), + new CamelKameletOptionValueCompletion() + ); } } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/endpoint/CamelSmartCompletionEndpointOptions.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/endpoint/CamelSmartCompletionEndpointOptions.java index 1b3cd736..bf34dd61 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/endpoint/CamelSmartCompletionEndpointOptions.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/endpoint/CamelSmartCompletionEndpointOptions.java @@ -60,10 +60,97 @@ public static List addSmartCompletionSuggestionsQueryParameters(f final boolean xmlMode, final PsiElement element, final Editor editor) { + return addSmartCompletionSuggestionsQueryParameters( + new SmartCompletionSuggestionsQueryParametersContext.Default(query, xmlMode, element), + component, existing, element, editor + ); + } + + /** + * Context for the smart completion suggestions query parameters + */ + public interface SmartCompletionSuggestionsQueryParametersContext { + String getQueryAtPosition(); + String getConcatQuery(); + String getSuffix(); + boolean isXmlMode(); + boolean isLookupAsURI(); + boolean isConsumerOnly(); + boolean isProducerOnly(); + char getLookupSuffixChar(); + String getLookupSuffix(); + + /** + * Default implementation of the {@link SmartCompletionSuggestionsQueryParametersContext} + */ + class Default implements SmartCompletionSuggestionsQueryParametersContext { + private final String queryAtPosition; + private final String concatQuery; + private final String suffix; + private final boolean xmlMode; + private final boolean consumerOnly; + private final boolean producerOnly; + + public Default(final String[] query, boolean xmlMode, final PsiElement element) { + this.queryAtPosition = query[2]; + this.concatQuery = query[0]; + this.suffix = query[1]; + this.xmlMode = xmlMode; + final CamelIdeaUtils camelIdeaUtils = CamelIdeaUtils.getService(); + this.consumerOnly = camelIdeaUtils.isConsumerEndpoint(element); + this.producerOnly = camelIdeaUtils.isProducerEndpoint(element); + } + + public String getQueryAtPosition() { + return queryAtPosition; + } + + public String getConcatQuery() { + return concatQuery; + } + + public String getSuffix() { + return suffix; + } + + public boolean isXmlMode() { + return xmlMode; + } + + public boolean isLookupAsURI() { + return true; + } + + @Override + public boolean isConsumerOnly() { + return consumerOnly; + } + + @Override + public boolean isProducerOnly() { + return producerOnly; + } + + public char getLookupSuffixChar() { + return '='; + } + + public String getLookupSuffix() { + return "="; + } + } + } + + @NotNull + public static List addSmartCompletionSuggestionsQueryParameters(final SmartCompletionSuggestionsQueryParametersContext context, + final ComponentModel component, + final Map existing, + final PsiElement element, + final Editor editor) { final List answer = new ArrayList<>(); - String queryAtPosition = query[2]; - if (xmlMode) { + String queryAtPosition = context.getQueryAtPosition(); + if (context.isXmlMode()) { queryAtPosition = queryAtPosition.replace("&", "&"); } @@ -79,16 +166,12 @@ public static List addSmartCompletionSuggestionsQueryParameters(f if ("parameter".equals(option.getKind())) { final String name = option.getName(); - final CamelIdeaUtils camelIdeaUtils = CamelIdeaUtils.getService(); - // if we are consumer only, then any option that has producer in the label should be skipped (as its only for producer) - final boolean consumerOnly = camelIdeaUtils.isConsumerEndpoint(element); - if (consumerOnly && option.getLabel() != null && option.getLabel().contains("producer")) { + if (context.isConsumerOnly() && option.getLabel() != null && option.getLabel().contains("producer")) { continue; } // if we are producer only, then any option that has consumer in the label should be skipped (as its only for consumer) - final boolean producerOnly = camelIdeaUtils.isProducerEndpoint(element); - if (producerOnly && option.getLabel() != null && option.getLabel().contains("consumer")) { + if (context.isProducerOnly() && option.getLabel() != null && option.getLabel().contains("consumer")) { continue; } @@ -101,24 +184,27 @@ public static List addSmartCompletionSuggestionsQueryParameters(f // the lookup should prepare for the new option String lookup; - final String concatQuery = query[0]; - if (!concatQuery.contains("?")) { - // none existing options so we need to start with a ? mark - lookup = queryAtPosition + "?" + key; - } else { - if (!queryAtPosition.endsWith("&") && !queryAtPosition.endsWith("?")) { - lookup = queryAtPosition + "&" + key; + if (context.isLookupAsURI()) { + final String concatQuery = context.getConcatQuery(); + if (!concatQuery.contains("?")) { + // none existing options so we need to start with a ? mark + lookup = queryAtPosition + "?" + key; } else { - // there is already either an ending ? or & - lookup = queryAtPosition + key; + if (!queryAtPosition.endsWith("&") && !queryAtPosition.endsWith("?")) { + lookup = queryAtPosition + "&" + key; + } else { + // there is already either an ending ? or & + lookup = queryAtPosition + key; + } } - } - if (xmlMode) { - lookup = lookup.replace("&", "&"); + if (context.isXmlMode()) { + lookup = lookup.replace("&", "&"); + } + } else { + lookup = queryAtPosition + key; } LookupElementBuilder builder = LookupElementBuilder.create(new OptionSuggestion(option, lookup)); - final String suffix = query[1]; - builder = addInsertHandler(editor, builder, suffix); + builder = addInsertHandler(editor, builder, context.getLookupSuffixChar(), context.getLookupSuffix(), context.getSuffix()); // only show the option in the UI builder = builder.withPresentableText(name); // we don't want to highlight the advanced options which should be more seldom in use @@ -184,7 +270,7 @@ public static List addSmartCompletionSuggestionsContextPath(Strin return answer; } - private static List addSmartCompletionContextPathSuggestions(final String val, + public static List addSmartCompletionContextPathSuggestions(final String val, final ComponentModel component, final Map existing, final Predicate componentPredicate, @@ -287,10 +373,11 @@ private static String removeUnknownEnum(String val, final PsiElement element) { } /** - * We need special logic to determine when it should insert "=" at the end of the options + * We need special logic to determine when it should insert lookup suffix char at the end of the options */ @NotNull private static LookupElementBuilder addInsertHandler(final Editor editor, final LookupElementBuilder builder, + final char lookupSuffixChar, final String lookupSuffix, final String suffix) { return builder.withInsertHandler((context, item) -> { // enforce using replace select char as we want to replace any existing option @@ -300,12 +387,13 @@ private static LookupElementBuilder addInsertHandler(final Editor editor, final //if it's a property file the PsiElement does not start and end with an quot endSelectOffBy = 1; } - final char text = context - .getDocument() - .getCharsSequence() - .charAt(context.getSelectionEndOffset() - endSelectOffBy); - if (text != '=') { - EditorModificationUtil.insertStringAtCaret(editor, "="); + CharSequence content = context + .getDocument() + .getCharsSequence(); + int index = context.getSelectionEndOffset() - endSelectOffBy; + final char text = index < content.length() ? content.charAt(index) : ' '; + if (text != lookupSuffixChar) { + EditorModificationUtil.insertStringAtCaret(editor, lookupSuffix); } } else if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) { // we still want to keep the suffix because they are other options @@ -315,7 +403,7 @@ private static LookupElementBuilder addInsertHandler(final Editor editor, final // strip out first part of suffix until next option value = value.substring(pos); } - EditorModificationUtil.insertStringAtCaret(editor, "=" + value); + EditorModificationUtil.insertStringAtCaret(editor, lookupSuffix + value); // and move cursor back again final int offset = -1 * value.length(); EditorModificationUtil.moveCaretRelatively(editor, offset); diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletCompletion.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletCompletion.java new file mode 100644 index 00000000..c9733dbd --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletCompletion.java @@ -0,0 +1,90 @@ +/* + * 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 com.github.cameltooling.idea.completion.extension; + +import java.util.List; + +import com.github.cameltooling.idea.service.CamelCatalogService; +import com.github.cameltooling.idea.service.CamelService; +import com.github.cameltooling.idea.util.IdeaUtils; +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.completion.CompletionUtilCore; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import org.apache.camel.catalog.CamelCatalog; +import org.apache.camel.tooling.model.ComponentModel; +import org.jetbrains.annotations.NotNull; + +/** + * {@code CamelKameletCompletion} is a base class for all Camel Kamelet completion providers. + */ +abstract class CamelKameletCompletion extends CompletionProvider { + + protected final CamelEndpointSmartCompletionExtension.Mode mode = CamelEndpointSmartCompletionExtension.Mode.KAMELET; + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) { + Project project = parameters.getOriginalFile().getProject(); + if (project.getService(CamelService.class).isCamelProject()) { + final CamelCatalog camelCatalog = project.getService(CamelCatalogService.class).get(); + final IdeaUtils ideaUtils = IdeaUtils.getService(); + PsiElement element = parameters.getPosition(); + String val = ideaUtils.extractTextFromElement(element, true, true, true); + if (val == null || val.isEmpty()) { + return; + } + val = val.replace(CompletionUtilCore.DUMMY_IDENTIFIER, "") + .replace(CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED, ""); + final ComponentModel componentModel = mode.componentModel( + project, camelCatalog, "kamelet", getURIPrefix(element) + val, isConsumerOnly(project, element) + ); + if (componentModel == null) { + return; + } + final List answer = suggestions(componentModel, project, element, parameters.getEditor(), val); + // are there any results then add them + if (!answer.isEmpty()) { + result.withPrefixMatcher(val).addAllElements(answer); + result.stopHere(); + } + } + } + + /** + * @return the URI prefix to use when loading the component model. + */ + @NotNull + protected abstract String getURIPrefix(PsiElement element); + + /** + * @param project the project to check. + * @param element the element corresponding to the position of the completion. + * @return {@code true} if the component is consumer only, {@code false} otherwise. + */ + protected abstract boolean isConsumerOnly(Project project, PsiElement element); + + /** + * @return the list of suggestions for the given input value. + */ + protected abstract List suggestions(@NotNull ComponentModel componentModel, @NotNull Project project, + @NotNull PsiElement element, @NotNull Editor editor, String val); +} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletNameCompletion.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletNameCompletion.java new file mode 100644 index 00000000..a038d298 --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletNameCompletion.java @@ -0,0 +1,60 @@ +/* + * 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 com.github.cameltooling.idea.completion.extension; + +import java.util.List; +import java.util.Map; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import org.apache.camel.tooling.model.ComponentModel; +import org.jetbrains.annotations.NotNull; + +import static com.github.cameltooling.idea.completion.endpoint.CamelSmartCompletionEndpointOptions.addSmartCompletionContextPathSuggestions; + +/** + * {@code CamelKameletNameCompletion} is responsible for completing the name of a Camel Kamelet. + */ +public class CamelKameletNameCompletion extends CamelKameletCompletion { + + private final boolean consumerOnly; + + public CamelKameletNameCompletion(boolean consumerOnly) { + this.consumerOnly = consumerOnly; + } + + @Override + protected @NotNull String getURIPrefix(PsiElement element) { + return "kamelet:"; + } + + @Override + protected boolean isConsumerOnly(Project project, PsiElement element) { + return consumerOnly; + } + + @Override + protected List suggestions(@NotNull ComponentModel componentModel, @NotNull Project project, + @NotNull PsiElement element, @NotNull Editor editor, String val) { + return addSmartCompletionContextPathSuggestions( + "", componentModel, Map.of(), mode.getContextPathComponentPredicate(), + mode.getContextPathOptionPredicate(), mode.getIconProvider(project) + ); + } +} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionCompletion.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionCompletion.java new file mode 100644 index 00000000..1c5ddba3 --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionCompletion.java @@ -0,0 +1,43 @@ +/* + * 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 com.github.cameltooling.idea.completion.extension; + +import com.github.cameltooling.idea.service.KameletService; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; + +/** + * {@code CamelKameletOptionCompletion} is a base class for all Camel Kamelet option completion providers. + */ +abstract class CamelKameletOptionCompletion extends CamelKameletCompletion { + + @Override + protected boolean isConsumerOnly(Project project, PsiElement element) { + String name = getKameletName(element); + return name != null && project.getService(KameletService.class).isConsumer(name); + } + + /** + * Extracts the name of the Camel Kamelet from the given element. + * + * @param element the element + * @return the name of the Camel Kamelet or {@code null} if the element is not part of the configuration of Camel + * Kamelet + */ + protected abstract @Nullable String getKameletName(PsiElement element); +} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionNameCompletion.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionNameCompletion.java new file mode 100644 index 00000000..77fbd2e4 --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionNameCompletion.java @@ -0,0 +1,159 @@ +/* + * 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 com.github.cameltooling.idea.completion.extension; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.github.cameltooling.idea.completion.endpoint.CamelSmartCompletionEndpointOptions; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import org.apache.camel.tooling.model.ComponentModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.yaml.psi.YAMLKeyValue; +import org.jetbrains.yaml.psi.YAMLMapping; +import org.jetbrains.yaml.psi.YAMLValue; + +import static com.github.cameltooling.idea.completion.endpoint.CamelSmartCompletionEndpointOptions.addSmartCompletionSuggestionsQueryParameters; + +/** + * {@code CamelKameletOptionNameCompletion} is responsible for completing the name of a Camel Kamelet option. + */ +public class CamelKameletOptionNameCompletion extends CamelKameletOptionCompletion { + + @Override + protected List suggestions(@NotNull ComponentModel componentModel, @NotNull Project project, + @NotNull PsiElement element, @NotNull Editor editor, String val) { + boolean consumerOnly = isConsumerOnly(project, element); + return addSmartCompletionSuggestionsQueryParameters( + new Context(val, consumerOnly), componentModel, existing(element), element, editor + ); + } + + /** + * @return a map of already configured options if any, an empty map otherwise + */ + private Map existing(PsiElement element) { + YAMLKeyValue keyValue = PsiTreeUtil.getParentOfType(element, YAMLKeyValue.class); + if (keyValue == null || !keyValue.getKeyText().equals("properties")) { + return Map.of(); + } + PsiElement lastChild = keyValue.getLastChild(); + if (lastChild instanceof YAMLMapping mapping) { + return mapping.getKeyValues().stream().collect(Collectors.toMap( + YAMLKeyValue::getKeyText, YAMLKeyValue::getValueText + )); + } + return Map.of(); + } + + protected @Nullable String getKameletName(PsiElement element) { + YAMLKeyValue keyValue = PsiTreeUtil.getParentOfType(element, YAMLKeyValue.class); + if (keyValue == null || !keyValue.getKeyText().equals("properties")) { + return null; + } + YAMLMapping mapping = PsiTreeUtil.getParentOfType(keyValue, YAMLMapping.class); + if (mapping == null) { + return null; + } + YAMLKeyValue ref = mapping.getKeyValueByKey("ref"); + if (ref == null) { + return null; + } + YAMLValue value = ref.getValue(); + if (value instanceof YAMLMapping map) { + return Optional.ofNullable(map.getKeyValueByKey("name")) + .map(YAMLKeyValue::getValueText) + .orElse(null); + } + return null; + } + + @Override + protected @NotNull String getURIPrefix(PsiElement element) { + String name = getKameletName(element); + if (name == null) { + return "kamelet:"; + } + return "kamelet:" + name + "?"; + } + + /** + * {@code Context} is a context for the smart completion of Camel Kamelet option names. + */ + private static class Context implements CamelSmartCompletionEndpointOptions.SmartCompletionSuggestionsQueryParametersContext { + + private final String val; + private final boolean consumerOnly; + + Context(String val, boolean consumerOnly) { + this.val = val; + this.consumerOnly = consumerOnly; + } + + @Override + public String getQueryAtPosition() { + return val; + } + + @Override + public String getConcatQuery() { + return null; + } + + @Override + public String getSuffix() { + return val; + } + + @Override + public boolean isXmlMode() { + return false; + } + + @Override + public boolean isLookupAsURI() { + return false; + } + + @Override + public boolean isConsumerOnly() { + return consumerOnly; + } + + @Override + public boolean isProducerOnly() { + return !consumerOnly; + } + + @Override + public char getLookupSuffixChar() { + return ':'; + } + + @Override + public String getLookupSuffix() { + return ": "; + } + } +} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionValueCompletion.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionValueCompletion.java new file mode 100644 index 00000000..702a579a --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/completion/extension/CamelKameletOptionValueCompletion.java @@ -0,0 +1,110 @@ +/* + * 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 com.github.cameltooling.idea.completion.extension; + +import java.util.List; +import java.util.Optional; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import org.apache.camel.tooling.model.ComponentModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.yaml.psi.YAMLKeyValue; +import org.jetbrains.yaml.psi.YAMLMapping; +import org.jetbrains.yaml.psi.YAMLValue; + +import static com.github.cameltooling.idea.completion.endpoint.CamelSmartCompletionEndpointValue.addSmartCompletionForEndpointValue; + +/** + * {@code CamelKameletOptionValueCompletion} is responsible for completing the value of a Camel Kamelet option. + */ +public class CamelKameletOptionValueCompletion extends CamelKameletOptionCompletion { + @Override + protected @NotNull String getURIPrefix(PsiElement element) { + String answer = "kamelet:"; + String name = getKameletName(element); + if (name == null) { + return answer; + } + answer += name + "?"; + String optionName = getOptionName(element); + if (optionName == null) { + return answer; + } + answer += optionName + "="; + return answer; + } + + protected @Nullable String getKameletName(PsiElement element) { + YAMLKeyValue keyValue = PsiTreeUtil.getParentOfType(element, YAMLKeyValue.class); + if (keyValue == null) { + return null; + } else if (!keyValue.getKeyText().equals("properties")) { + keyValue = PsiTreeUtil.getParentOfType(keyValue, YAMLKeyValue.class); + if (keyValue == null || !keyValue.getKeyText().equals("properties")) { + return null; + } + } + + YAMLMapping mapping = PsiTreeUtil.getParentOfType(keyValue, YAMLMapping.class); + if (mapping == null) { + return null; + } + YAMLKeyValue ref = mapping.getKeyValueByKey("ref"); + if (ref == null) { + return null; + } + YAMLValue value = ref.getValue(); + if (value instanceof YAMLMapping map) { + return Optional.ofNullable(map.getKeyValueByKey("name")) + .map(YAMLKeyValue::getValueText) + .orElse(null); + } + return null; + } + + /** + * @return the name of the option or {@code null} if the element is not part of the configuration of Camel + */ + private String getOptionName(PsiElement element) { + YAMLKeyValue keyValue = PsiTreeUtil.getParentOfType(element, YAMLKeyValue.class); + if (keyValue == null) { + return null; + } + return keyValue.getKeyText(); + } + + @Override + protected List suggestions(@NotNull ComponentModel componentModel, @NotNull Project project, + @NotNull PsiElement element, @NotNull Editor editor, String val) { + String name = getOptionName(element); + if (name == null) { + return List.of(); + } + ComponentModel.EndpointOptionModel endpointOption = componentModel.getEndpointOptions().stream().filter( + o -> name.equals(o.getName())) + .findFirst().orElse(null); + if (endpointOption == null) { + return List.of(); + } + return addSmartCompletionForEndpointValue(editor, val, "", endpointOption, element, false); + } +} diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/KameletService.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/KameletService.java index 8a598789..bc499f28 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/KameletService.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/KameletService.java @@ -132,6 +132,16 @@ public void after(@NotNull List events) { ); } + /** + * Check if the given name corresponds to a Kamelet that can be used in a consumer endpoint. + * @param name the name of the Kamelet to check. + * @return {@code true} if the Kamelet can be used in a consumer endpoint, {@code false} otherwise. + */ + public boolean isConsumer(@NotNull String name) { + Kamelet kamelet = getKamelets().get(name); + return kamelet != null && KAMELET_SOURCE_TYPE.equals(kamelet.getType()); + } + /** * Gives the name of the Kamelets that can be used in a consumer endpoint. * diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/YamlPatternConditions.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/YamlPatternConditions.java index 03ac22b6..6fa800f4 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/YamlPatternConditions.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/YamlPatternConditions.java @@ -25,6 +25,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; +import org.jetbrains.yaml.psi.YAMLKeyValue; /** * A utility call to define special pattern conditions used to build element pattern for Yaml content. @@ -69,6 +70,15 @@ public static PatternCondition withFirstChild(@NotNull return new FirstChildPatternCondition<>(pattern); } + /** + * @param key the key to validate the key value pair. + * @param value the value to validate the key value pair. + * @return a {@code PatternCondition} that accepts {@code YAMLKeyValue}s which match with the given key value pair. + */ + public static PatternCondition withPair(@NotNull String key, @NotNull String value) { + return new PairPatternCondition<>(key, value); + } + /** * @param pattern the pattern to validate against the last child. * @return a {@code PatternCondition} that accepts elements whose last child matches with the given pattern. @@ -112,6 +122,38 @@ public boolean accepts(@NotNull T t, ProcessingContext context) { } } + /** + * {@code PairPatternCondition} is a {@link PatternCondition} allowing to identify {@code YAMLKeyValue}s which + * match with the specific key value pair. + */ + private static class PairPatternCondition extends PatternCondition { + + /** + * The key to validate the key value pair. + */ + private final String key; + /** + * The value to validate the key value pair. + */ + private final String value; + + /** + * Construct a {@code PairPatternCondition} with the given key value pair. + * @param key the key to validate the key value pair. + * @param value the value to validate the key value pair. + */ + PairPatternCondition(@NotNull String key, @NotNull String value) { + super("withPair"); + this.key = key; + this.value = value; + } + + @Override + public boolean accepts(@NotNull T t, ProcessingContext context) { + return key.equals(t.getKeyText()) && value.equals(t.getValueText()); + } + } + /** * {@code LastChildPatternCondition} is a {@link PatternCondition} allowing to identify elements whose * last child matches with a specific pattern. diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 749c920f..f962e67b 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -11,6 +11,7 @@ +
  • Add code completion for Kamelet names and options in Kamelet binding files
  • Bug fixes
  • ]]> diff --git a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletNameCompletionIT.java b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletNameCompletionIT.java new file mode 100644 index 00000000..6e70b5b0 --- /dev/null +++ b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletNameCompletionIT.java @@ -0,0 +1,106 @@ +/* + * 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 com.github.cameltooling.idea.completion; + +import java.util.Arrays; +import java.util.List; + +import com.github.cameltooling.idea.CamelLightCodeInsightFixtureTestCaseIT; + +/** + * Testing basic completion with Kamelet name in a Camel Kamelet binding. + */ +public class CamelKameletNameCompletionIT extends CamelLightCodeInsightFixtureTestCaseIT { + + @Override + protected String getTestDataPath() { + return "src/test/resources/testData/completion/kamelet/name"; + } + + public void testBindingNoKamelet() { + myFixture.configureByFiles("binding-no-kamelet.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingNoName() { + myFixture.configureByFiles("binding-no-name.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingUnknown() { + myFixture.configureByFiles("binding-unknown.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingBySource() { + myFixture.configureByFiles("binding-source.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.containsAll(Arrays.asList("timer-source", "aws-s3-source"))); + assertFalse(strings.containsAll(Arrays.asList("log-sink", "avro-deserialize-action"))); + myFixture.type("ti"); + strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("timer-source")); + assertFalse(strings.containsAll(Arrays.asList("log-sink", "avro-deserialize-action", "aws-s3-source"))); + } + + public void testBindingBySink() { + myFixture.configureByFiles("binding-sink.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.containsAll(Arrays.asList("log-sink", "avro-deserialize-action"))); + assertFalse(strings.containsAll(Arrays.asList("timer-source", "aws-s3-source"))); + myFixture.type("av"); + strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("avro-deserialize-action")); + assertFalse(strings.containsAll(Arrays.asList("log-sink", "timer-source", "aws-s3-source"))); + } + + public void testBindingBySteps() { + myFixture.configureByFiles("binding-steps.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.containsAll(Arrays.asList("log-sink", "avro-deserialize-action"))); + assertFalse(strings.containsAll(Arrays.asList("timer-source", "aws-s3-source"))); + myFixture.type("av"); + strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("avro-deserialize-action")); + assertFalse(strings.containsAll(Arrays.asList("log-sink", "timer-source", "aws-s3-source"))); + } + + public void testBinding() { + myFixture.configureByFiles("binding.yaml"); + myFixture.completeBasic(); + myFixture.type('\n'); + myFixture.checkResultByFile("bindingResult.yaml"); + } +} diff --git a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletOptionNameCompletionIT.java b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletOptionNameCompletionIT.java new file mode 100644 index 00000000..5138640b --- /dev/null +++ b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletOptionNameCompletionIT.java @@ -0,0 +1,112 @@ +/* + * 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 com.github.cameltooling.idea.completion; + +import java.util.Arrays; +import java.util.List; + +import com.github.cameltooling.idea.CamelLightCodeInsightFixtureTestCaseIT; +import com.github.cameltooling.idea.service.CamelProjectPreferenceService; + +/** + * Testing basic completion with Kamelet option name in a Camel Kamelet binding. + */ +public class CamelKameletOptionNameCompletionIT extends CamelLightCodeInsightFixtureTestCaseIT { + + protected void tearDown() throws Exception { + try { + CamelProjectPreferenceService.getService(getProject()).setOnlyShowKameletOptions(true); + } finally { + super.tearDown(); + } + } + + @Override + protected String getTestDataPath() { + return "src/test/resources/testData/completion/kamelet/optionname"; + } + + public void testBindingNoKamelet() { + myFixture.configureByFiles("binding-no-kamelet.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingNoName() { + myFixture.configureByFiles("binding-no-name.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingUnknown() { + myFixture.configureByFiles("binding-unknown.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingBySource() { + myFixture.configureByFiles("binding-source.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.containsAll(Arrays.asList("period", "message"))); + myFixture.type("pe"); + strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("period")); + assertFalse(strings.contains("message")); + } + + public void testBindingBySink() { + myFixture.configureByFiles("binding-sink.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.containsAll(Arrays.asList("loggerName", "level"))); + myFixture.type("lo"); + strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("loggerName")); + assertFalse(strings.contains("level")); + } + + public void testBindingBySteps() { + myFixture.configureByFiles("binding-steps.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.containsAll(Arrays.asList("field", "headerOutput"))); + myFixture.type("f"); + strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("field")); + assertFalse(strings.contains("headerOutput")); + } + + public void testBinding() { + myFixture.configureByFiles("binding.yaml"); + myFixture.completeBasic(); + myFixture.type('\n'); + myFixture.checkResultByFile("bindingResult.yaml", true); + } +} diff --git a/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletOptionValueCompletionIT.java b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletOptionValueCompletionIT.java new file mode 100644 index 00000000..6e4101e3 --- /dev/null +++ b/camel-idea-plugin/src/test/java/com/github/cameltooling/idea/completion/CamelKameletOptionValueCompletionIT.java @@ -0,0 +1,102 @@ +/* + * 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 com.github.cameltooling.idea.completion; + +import java.util.Arrays; +import java.util.List; + +import com.github.cameltooling.idea.CamelLightCodeInsightFixtureTestCaseIT; +import com.github.cameltooling.idea.service.CamelProjectPreferenceService; + +/** + * Testing basic completion with Kamelet option value in a Camel Kamelet binding. + */ +public class CamelKameletOptionValueCompletionIT extends CamelLightCodeInsightFixtureTestCaseIT { + + protected void tearDown() throws Exception { + try { + CamelProjectPreferenceService.getService(getProject()).setOnlyShowKameletOptions(true); + } finally { + super.tearDown(); + } + } + + @Override + protected String getTestDataPath() { + return "src/test/resources/testData/completion/kamelet/optionvalue"; + } + + public void testBindingNoKamelet() { + myFixture.configureByFiles("binding-no-kamelet.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingNoName() { + myFixture.configureByFiles("binding-no-name.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingUnknown() { + myFixture.configureByFiles("binding-unknown.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.isEmpty()); + } + + public void testBindingBySource() { + myFixture.configureByFiles("binding-source.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("text/plain")); + } + + public void testBindingBySink() { + myFixture.configureByFiles("binding-sink.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("INFO")); + } + + public void testBindingBySteps() { + myFixture.configureByFiles("binding-steps.yaml"); + myFixture.completeBasic(); + List strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.containsAll(Arrays.asList("true", "false"))); + myFixture.type("f"); + strings = myFixture.getLookupElementStrings(); + assertNotNull(strings); + assertTrue(strings.contains("false")); + assertFalse(strings.contains("true")); + } + + public void testBinding() { + myFixture.configureByFiles("binding.yaml"); + myFixture.completeBasic(); + myFixture.type('\n'); + myFixture.checkResultByFile("bindingResult.yaml"); + } +} diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-no-kamelet.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-no-kamelet.yaml new file mode 100644 index 00000000..b6aeff75 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-no-kamelet.yaml @@ -0,0 +1,10 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Foo + apiVersion: camel.apache.org/v1 + name: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-no-name.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-no-name.yaml new file mode 100644 index 00000000..36a50441 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-no-name.yaml @@ -0,0 +1,10 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + foo: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-sink.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-sink.yaml new file mode 100644 index 00000000..46304909 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-sink.yaml @@ -0,0 +1,10 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-source.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-source.yaml new file mode 100644 index 00000000..26a31cf4 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-source.yaml @@ -0,0 +1,10 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-steps.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-steps.yaml new file mode 100644 index 00000000..57dda848 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-steps.yaml @@ -0,0 +1,10 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + steps: + - ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-unknown.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-unknown.yaml new file mode 100644 index 00000000..16adf608 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding-unknown.yaml @@ -0,0 +1,10 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + foo: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding.yaml new file mode 100644 index 00000000..7d67cc92 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/binding.yaml @@ -0,0 +1,10 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: ti diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/bindingResult.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/bindingResult.yaml new file mode 100644 index 00000000..da1bef84 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/name/bindingResult.yaml @@ -0,0 +1,10 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-no-kamelet.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-no-kamelet.yaml new file mode 100644 index 00000000..44d70c97 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-no-kamelet.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Foo + apiVersion: camel.apache.org/v1 + name: log-sink + properties: + diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-no-name.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-no-name.yaml new file mode 100644 index 00000000..d4d2480a --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-no-name.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + foo: log-sink + properties: + diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-sink.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-sink.yaml new file mode 100644 index 00000000..73e32e94 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-sink.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: log-sink + properties: + diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-source.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-source.yaml new file mode 100644 index 00000000..18699b84 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-source.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-steps.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-steps.yaml new file mode 100644 index 00000000..ebd6b417 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-steps.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + steps: + - ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: extract-field-action + properties: + diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-unknown.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-unknown.yaml new file mode 100644 index 00000000..2c85aa8e --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding-unknown.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + foo: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: log-sink + properties: + diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding.yaml new file mode 100644 index 00000000..d7ae93e0 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/binding.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + pe diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/bindingResult.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/bindingResult.yaml new file mode 100644 index 00000000..ef3d95ff --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionname/bindingResult.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + period: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-no-kamelet.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-no-kamelet.yaml new file mode 100644 index 00000000..ade3b41b --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-no-kamelet.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Foo + apiVersion: camel.apache.org/v1 + name: log-sink + properties: + level: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-no-name.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-no-name.yaml new file mode 100644 index 00000000..55b58cfb --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-no-name.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + foo: log-sink + properties: + level: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-sink.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-sink.yaml new file mode 100644 index 00000000..d5ba1035 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-sink.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + sink: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: log-sink + properties: + level: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-source.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-source.yaml new file mode 100644 index 00000000..8748bdd7 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-source.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + contentType: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-steps.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-steps.yaml new file mode 100644 index 00000000..d25fee53 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-steps.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + steps: + - ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: extract-field-action + properties: + headerOutput: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-unknown.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-unknown.yaml new file mode 100644 index 00000000..682ed2b7 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding-unknown.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + foo: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: log-sink + properties: + level: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding.yaml new file mode 100644 index 00000000..8748bdd7 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/binding.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + contentType: diff --git a/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/bindingResult.yaml b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/bindingResult.yaml new file mode 100644 index 00000000..42f60fd2 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/completion/kamelet/optionvalue/bindingResult.yaml @@ -0,0 +1,12 @@ +apiVersion: camel.apache.org/v1 +kind: Pipe +metadata: + name: my-bind +spec: + source: + ref: + kind: Kamelet + apiVersion: camel.apache.org/v1 + name: timer-source + properties: + contentType: text/plain diff --git a/img/54-kamelet-binding-completion.gif b/img/54-kamelet-binding-completion.gif new file mode 100644 index 0000000000000000000000000000000000000000..52921a5c404b854e2e14c901a2c6ae42501d6871 GIT binary patch literal 272758 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

    ~hgZCw-&Lzy8&8)y)Jw!_r@eJ@$o8 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 Sc;7v^t&+iO!?s=p1OPiE5=gcH literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index 644bd448..be67b2ed 100644 --- a/readme.md +++ b/readme.md @@ -12,6 +12,7 @@ The plugin includes: - Code completion for Camel message headers (available `setHeader` and `header`) in Java, XML and YAML files (`ctrl + space`) with corresponding Quick documentation (`ctrl + j`) - Code completion for Camel property placeholders (cursor after `{{`) - Code completion for Camel options' key and value in properties and YAML files (`ctrl + space`) with corresponding Quick documentation (`ctrl + j`) +- Code completion for Kamelet name and options' key and value in Kamelet binding files (`ctrl + space`) with corresponding Quick documentation (`ctrl + j`) - Real time validation for Camel endpoints in Java, XML, YAML (underline errors in red) - Real time validation for Camel simple language in Java, XML, YAML (underline errors in red) - Endpoint options filtered to only include applicable options when used as consumer vs producer only mode From 210c9d19b244fbd7beb502d18f513c47ec4075f7 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sat, 14 Oct 2023 10:33:05 +0200 Subject: [PATCH 10/18] Update changelog --- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index f962e67b..12e15782 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -11,8 +11,9 @@ +

  • Upgraded to IDEA 2023.2.3
  • Add code completion for Kamelet names and options in Kamelet binding files
  • -
  • Bug fixes
  • +
  • Dependeny upgrades
  • ]]>
    From 16d4bf4664ce949d14223d10edc7da922d5ad67a Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sat, 14 Oct 2023 10:46:02 +0200 Subject: [PATCH 11/18] Bump for next version --- build.gradle | 2 +- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index ded4663d..faf445de 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ allprojects { } group = 'com.github.camel-tooling' - version = '1.1.3' + version = '1.1.4' } subprojects { diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 12e15782..fcd3f795 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -1,7 +1,7 @@ org.apache.camel Apache Camel - 1.1.3 + 1.1.4 Apache Camel -
  • Upgraded to IDEA 2023.2.3
  • -
  • Add code completion for Kamelet names and options in Kamelet binding files
  • -
  • Dependeny upgrades
  • +
  • Bug fixes
  • ]]>
    From 95429be8f026e194436c5ffe6ccfba56678d7e93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 17:11:41 +0200 Subject: [PATCH 12/18] Bump io.github.classgraph:classgraph from 4.8.162 to 4.8.163 (#944) Bumps [io.github.classgraph:classgraph](https://github.com/classgraph/classgraph) from 4.8.162 to 4.8.163. - [Release notes](https://github.com/classgraph/classgraph/releases) - [Commits](https://github.com/classgraph/classgraph/compare/classgraph-4.8.162...classgraph-4.8.163) --- updated-dependencies: - dependency-name: io.github.classgraph:classgraph dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- camel-idea-plugin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camel-idea-plugin/build.gradle b/camel-idea-plugin/build.gradle index 192330e4..ce81ab7e 100644 --- a/camel-idea-plugin/build.gradle +++ b/camel-idea-plugin/build.gradle @@ -66,7 +66,7 @@ dependencies { // Needed to avoid conflicts with the version of the maven resolver used by IntelliJ implementation "org.apache.maven.resolver:maven-resolver-api:${mavenResolverVersion}" implementation "org.apache.maven.resolver:maven-resolver-impl:${mavenResolverVersion}" - implementation "io.github.classgraph:classgraph:4.8.162" + implementation "io.github.classgraph:classgraph:4.8.163" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.3" implementation "io.fabric8:kubernetes-model-apiextensions:6.9.0" From 0c09a743c5f9ff48429dd96da4546e777bacb93e Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Sun, 22 Oct 2023 09:23:16 -0300 Subject: [PATCH 13/18] Add plugin icon on marketplace (fixes #943) (#946) Co-authored-by: Adriano Machado --- .../src/main/resources/META-INF/plugin.xml | 5 +- .../main/resources/META-INF/pluginIcon.svg | 46 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 camel-idea-plugin/src/main/resources/META-INF/pluginIcon.svg diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index fcd3f795..af51e5d7 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -5,13 +5,14 @@ Apache Camel
  • Bug fixes
  • +
  • New marketplace icon
  • ]]>
    @@ -36,7 +37,7 @@ org.intellij.intelliLang - + diff --git a/camel-idea-plugin/src/main/resources/META-INF/pluginIcon.svg b/camel-idea-plugin/src/main/resources/META-INF/pluginIcon.svg new file mode 100644 index 00000000..5909e08d --- /dev/null +++ b/camel-idea-plugin/src/main/resources/META-INF/pluginIcon.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 10115551bac3b38565ee7990870a56f3b05d8d47 Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Sun, 22 Oct 2023 09:24:57 -0300 Subject: [PATCH 14/18] Fix named beans detection and route builder class hierarchy. (#947) Co-authored-by: Adriano Machado --- .../inspection/AbstractCamelInspection.java | 27 +++-- .../ui/CamelDebuggerEvaluationDialog.java | 4 +- .../extension/camel/JavaCamelIdeaUtils.java | 54 ++++++---- .../idea/util/CamelIdeaUtils.java | 8 +- .../cameltooling/idea/util/IdeaUtils.java | 101 ++++++++++-------- .../idea/util/JavaClassUtils.java | 56 +++++----- .../src/main/resources/META-INF/plugin.xml | 2 - 7 files changed, 134 insertions(+), 118 deletions(-) diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/inspection/AbstractCamelInspection.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/inspection/AbstractCamelInspection.java index 0a785693..4d4d1bd0 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/inspection/AbstractCamelInspection.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/inspection/AbstractCamelInspection.java @@ -49,10 +49,10 @@ public abstract class AbstractCamelInspection extends LocalInspectionTool { private boolean forceEnabled; - public AbstractCamelInspection() { + protected AbstractCamelInspection() { } - public AbstractCamelInspection(boolean forceEnabled) { + protected AbstractCamelInspection(boolean forceEnabled) { this.forceEnabled = forceEnabled; } @@ -119,7 +119,7 @@ private void validateSimple(@NotNull PsiElement element, final @NotNull Problems CamelService camelService = element.getProject().getService(CamelService.class); IElementType type = element.getNode().getElementType(); - LOG.trace("Element " + element + " of type: " + type + " to inspect simple: " + text); + LOG.trace("Element %s of type: %s to inspect simple: %s".formatted(element, type, text)); try { // need to use the classloader that can load classes from the camel-core @@ -146,8 +146,8 @@ private void validateSimple(@NotNull PsiElement element, final @NotNull Problems holder.registerProblem(element, msg); } } - } catch (Throwable e) { - LOG.warn("Error inspection Camel simple: " + text, e); + } catch (Exception e) { + LOG.warn("Error inspection Camel simple: %s".formatted(text), e); } } @@ -189,8 +189,8 @@ private void validateJSonPath(@NotNull PsiElement element, final @NotNull Proble holder.registerProblem(element, msg); } } - } catch (Throwable e) { - LOG.warn("Error inspection Camel jsonpath: " + text, e); + } catch (Exception e) { + LOG.warn("Error inspection Camel jsonpath: %s".formatted(text), e); } } @@ -209,7 +209,7 @@ private void validateEndpoint(@NotNull PsiElement element, final @NotNull Proble // camel catalog expects & as & when it parses so replace all & as & String camelQuery = text; - camelQuery = camelQuery.replaceAll("&", "&"); + camelQuery = camelQuery.replace("&", "&"); // strip up ending incomplete parameter if (camelQuery.endsWith("&") || camelQuery.endsWith("?")) { @@ -219,9 +219,7 @@ private void validateEndpoint(@NotNull PsiElement element, final @NotNull Proble boolean stringFormat = camelIdeaUtils.isFromStringFormatEndpoint(element); if (stringFormat) { // if the node is fromF or toF, then replace all %X with {{%X}} as we cannot parse that value - camelQuery = camelQuery.replaceAll("%s", "\\{\\{\\%s\\}\\}"); - camelQuery = camelQuery.replaceAll("%d", "\\{\\{\\%d\\}\\}"); - camelQuery = camelQuery.replaceAll("%b", "\\{\\{\\%b\\}\\}"); + camelQuery = camelQuery.replaceAll("(%[bds])", "{{$1}}"); } boolean consumerOnly = camelIdeaUtils.isConsumerEndpoint(element); @@ -238,8 +236,8 @@ private void validateEndpoint(@NotNull PsiElement element, final @NotNull Proble extractSetValue(result, result.getUnknown(), text, element, holder, isOnTheFly, new AbstractCamelInspection.UnknownErrorMsg()); extractSetValue(result, result.getNotConsumerOnly(), text, element, holder, isOnTheFly, new AbstractCamelInspection.NotConsumerOnlyErrorMsg()); extractSetValue(result, result.getNotProducerOnly(), text, element, holder, isOnTheFly, new AbstractCamelInspection.NotProducerOnlyErrorMsg()); - } catch (Throwable e) { - LOG.warn("Error inspecting Camel endpoint: " + text, e); + } catch (Exception e) { + LOG.warn("Error inspecting Camel endpoint: %s".formatted(text), e); } } @@ -271,7 +269,7 @@ private static class BooleanErrorMsg implements CamelAnnotatorEndpointMessage entry) { String name = entry.getKey(); - boolean empty = entry.getValue() == null || entry.getValue().length() == 0; + boolean empty = entry.getValue() == null || entry.getValue().isEmpty(); if (empty) { return name + " has empty boolean value"; } else { @@ -381,7 +379,6 @@ public boolean isWarnLevel() { * * @return the summary, or empty if no validation errors */ - @SuppressWarnings("unchecked") private String summaryErrorMessage(EndpointValidationResult result, T entry, CamelAnnotatorEndpointMessage msg) { if (result.getIncapable() != null) { return "Incapable of parsing uri: " + result.getIncapable(); diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/ui/CamelDebuggerEvaluationDialog.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/ui/CamelDebuggerEvaluationDialog.java index c0c73d30..4de81efe 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/ui/CamelDebuggerEvaluationDialog.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/ui/CamelDebuggerEvaluationDialog.java @@ -74,8 +74,6 @@ import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; @@ -83,7 +81,7 @@ public class CamelDebuggerEvaluationDialog extends DialogWrapper { public static final DataKey KEY = DataKey.create("CAMEL_DEBUGGER_EVALUATION_DIALOG"); - //can not use new SHIFT_DOWN_MASK etc because in this case ActionEvent modifiers do not match + //cannot use new SHIFT_DOWN_MASK etc. because in this case ActionEvent modifiers do not match private static final int ADD_WATCH_MODIFIERS = (SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.CTRL_MASK) | InputEvent.SHIFT_MASK; static KeyStroke addWatchKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, ADD_WATCH_MODIFIERS); diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java index 374425a5..1dd52732 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java @@ -55,7 +55,6 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.PsiClassReferenceType; import com.intellij.psi.search.searches.ClassInheritorsSearch; -import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testFramework.LightVirtualFile; @@ -94,7 +93,7 @@ public class JavaCamelIdeaUtils extends CamelIdeaUtils implements CamelIdeaUtils "kamelet", "step", "transacted", "saga", "route", "resequence", "policy", "onException", "onCompletion", "from", "rest", "restConfiguration"); /** - * Name of the methods corresponding to root element of sub DSL. + * Name of the methods corresponding to the root element of sub DSL. */ private static final Set SUB_DSL_ROOTS = Set.of("expression", "dataFormat"); /** @@ -122,6 +121,23 @@ public class JavaCamelIdeaUtils extends CamelIdeaUtils implements CamelIdeaUtils "org.apache.camel.spring.SpringRouteBuilder", "org.apache.camel.builder.endpoint.EndpointRouteBuilder" ); + private static final List BEAN_ANNOTATIONS = Arrays.asList( + "org.springframework.stereotype.Component", + "org.springframework.stereotype.Service", + "org.springframework.stereotype.Repository", + "javax.inject.Named", + "javax.inject.Singleton", + "javax.enterprise.context.ApplicationScoped", + "javax.enterprise.context.SessionScoped", + "javax.enterprise.context.ConversationScoped", + "javax.enterprise.context.RequestScoped", + "jakarta.inject.Named", + "jakarta.inject.Singleton", + "jakarta.enterprise.context.ApplicationScoped", + "jakarta.enterprise.context.SessionScoped", + "jakarta.enterprise.context.ConversationScoped", + "jakarta.enterprise.context.RequestScoped" + ); @Override public boolean isCamelFile(PsiFile file) { @@ -216,10 +232,10 @@ public boolean isCamelExpressionUsedAsPredicate(PsiElement element, String langu // okay dive into the psi and find out which EIP are using the simple PsiElement child = call.getFirstChild(); - if (child instanceof PsiReferenceExpression) { + if (child instanceof PsiReferenceExpression psiReferenceExpression) { // this code is needed as it may be used as a method call as a parameter and this requires // a bit of psi code to unwrap the right elements. - PsiExpression exp = ((PsiReferenceExpression) child).getQualifierExpression(); + PsiExpression exp = psiReferenceExpression.getQualifierExpression(); if (exp == null) { // okay it was not a direct method call, so see if it was passed in as a parameter instead (expression list) element = element.getParent(); @@ -230,8 +246,8 @@ public boolean isCamelExpressionUsedAsPredicate(PsiElement element, String langu exp = PsiTreeUtil.getParentOfType(element.getParent(), PsiMethodCallExpression.class); } } - if (exp instanceof PsiMethodCallExpression) { - PsiMethod method = ((PsiMethodCallExpression) exp).resolveMethod(); + if (exp instanceof PsiMethodCallExpression psiMethodCallExpression) { + PsiMethod method = psiMethodCallExpression.resolveMethod(); if (method != null) { String name = method.getName(); return Arrays.asList(PREDICATE_EIPS).contains(name); @@ -299,7 +315,7 @@ public boolean isFromStringFormatEndpoint(PsiElement element) { public boolean acceptForAnnotatorOrInspection(PsiElement element) { // skip XML limit on siblings if (!IdeaUtils.getService().isFromFileType(element, "xml")) { - // for programming languages you can have complex structures with concat which we don't support yet + // for programming languages you can have complex structures with concat which we don't support it yet. // we currently only support oneliner, so check how many siblings the element has (it has 1 with ending parenthesis which is okay) return countSiblings(element) <= 1; } @@ -310,8 +326,8 @@ public boolean acceptForAnnotatorOrInspection(PsiElement element) { public PsiClass getBeanClass(PsiElement element) { final PsiElement beanPsiElement = getPsiElementForCamelBeanMethod(element); if (beanPsiElement != null) { - if (beanPsiElement instanceof PsiClass) { - return (PsiClass) beanPsiElement; + if (beanPsiElement instanceof PsiClass psiClass) { + return psiClass; } PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.findChildOfType(beanPsiElement, PsiJavaCodeReferenceElement.class); @@ -372,19 +388,22 @@ public boolean isPlaceForEndpointUri(PsiElement location) { } /** - * @return the {@link PsiClass} for the matching bean name by looking for classes annotated with spring Component, Service or Repository + * @return the {@link PsiClass} for the matching bean name by looking for classes annotated with + * Spring Component, Service or Repository or Quarkus javax or jakarta annotations. */ private Optional searchForMatchingBeanClass(String beanName, Project project) { final JavaClassUtils javaClassUtils = JavaClassUtils.getService(); - return javaClassUtils.findBeanClassByName(beanName, "org.springframework.stereotype.Component", project) - .or(() -> javaClassUtils.findBeanClassByName(beanName, "org.springframework.stereotype.Service", project)) - .or(() -> javaClassUtils.findBeanClassByName(beanName, "org.springframework.stereotype.Repository", project)); + + return BEAN_ANNOTATIONS + .stream() + .map(annotation -> javaClassUtils.findBeanClassByName(beanName, annotation, project)) + .flatMap(Optional::stream) + .findFirst(); } private List findEndpoints(Module module, Predicate uriCondition, Predicate elementCondition) { PsiManager manager = PsiManager.getInstance(module.getProject()); - //TODO: use IdeaUtils.ROUTE_BUILDER_OR_EXPRESSION_CLASS_QUALIFIED_NAME somehow - PsiClass routeBuilderClass = ClassUtil.findPsiClass(manager, "org.apache.camel.builder.RouteBuilder"); + PsiClass routeBuilderClass = IdeaUtils.findRouteBuilderClass(manager); List results = new ArrayList<>(); if (routeBuilderClass != null) { @@ -394,8 +413,7 @@ private List findEndpoints(Module module, Predicate uriCondi Collection literals = PsiTreeUtil.findChildrenOfType(routeBuilder, PsiLiteralExpression.class); for (PsiLiteralExpression literal : literals) { Object val = literal.getValue(); - if (val instanceof String) { - String endpointUri = (String) val; + if (val instanceof String endpointUri) { if (uriCondition.test(endpointUri) && elementCondition.test(literal)) { results.add(literal); } @@ -436,7 +454,7 @@ private void format(PsiFile file, Document document, int startOffset, int endOff final VirtualFile vFile = FileDocumentManager.getInstance().getFile(document); if ((vFile == null || vFile instanceof LightVirtualFile) && !ApplicationManager.getApplication().isUnitTestMode()) { // we assume that control flow reaches this place when the document is backed by a "virtual" file so any changes made by - // a formatter affect only PSI and it is out of sync with a document text + // a formatter affect only PSI, and it is out of sync with a document text return; } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/CamelIdeaUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/CamelIdeaUtils.java index 74306070..eb9d6d2d 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/CamelIdeaUtils.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/CamelIdeaUtils.java @@ -20,6 +20,7 @@ import com.github.cameltooling.idea.reference.endpoint.CamelEndpoint; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.Service; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiClass; @@ -34,13 +35,13 @@ import java.util.List; import java.util.Objects; import java.util.function.Predicate; -import java.util.stream.Collectors; /** * Utility methods to work with Camel related {@link com.intellij.psi.PsiElement} elements. *

    * This class is only for Camel related IDEA APIs. If you need only IDEA APIs then use {@link IdeaUtils} instead. */ +@Service public final class CamelIdeaUtils implements Disposable { public static final String[] CAMEL_FILE_EXTENSIONS = {"java", "xml", "yaml", "yml"}; @@ -192,7 +193,7 @@ public boolean isCamelExpressionOrLanguage(PsiClass clazz) { } /** - * Certain elements should be skipped for endpoint validation such as ActiveMQ brokerURL property and others. + * Certain elements should be skipped for endpoint validation, such as ActiveMQ brokerURL property and others. */ public boolean skipEndpointValidation(PsiElement element) { return enabledExtensions.stream() @@ -264,10 +265,9 @@ public List findEndpointDeclarations(Module module, Predicate - * This class is only for IDEA APIs. If you need Camel related APIs as well then use {@link CamelIdeaUtils} instead. + * This class is only for IDEA APIs. If you need Camel related APIs as well, use {@link CamelIdeaUtils} instead. */ +@Service public final class IdeaUtils implements Disposable { - private static final List ROUTE_BUILDER_OR_EXPRESSION_CLASS_QUALIFIED_NAME = Arrays.asList( - "org.apache.camel.builder.RouteBuilder", "org.apache.camel.builder.BuilderSupport", - "org.apache.camel.model.ProcessorDefinition", "org.apache.camel.model.language.ExpressionDefinition"); + private static final List ROUTE_BUILDER_OR_EXPRESSION_CLASS_QUALIFIED_NAME = List.of( + "org.apache.camel.builder.endpoint.EndpointRouteBuilder", + "org.apache.camel.builder.RouteBuilder", + "org.apache.camel.builder.BuilderSupport", + "org.apache.camel.model.ProcessorDefinition", + "org.apache.camel.model.language.ExpressionDefinition" + ); private final List enabledExtensions; private IdeaUtils() { enabledExtensions = Arrays.stream(IdeaUtilsExtension.EP_NAME.getExtensions()) .filter(IdeaUtilsExtension::isExtensionEnabled) - .collect(Collectors.toList()); + .toList(); } public static IdeaUtils getService() { @@ -124,9 +130,9 @@ public String extractTextFromElement(PsiElement element) { * Extract the text value from the {@link PsiElement} from any of the support languages this plugin works with. * * @param element the element - * @param fallBackToGeneric if could find any of the supported languages fallback to generic if true + * @param fallBackToGeneric if it could find any of the supported language-fallbacks to generic if true * @param concatString concatenated the string if it wrapped - * @param stripWhitespace + * @param stripWhitespace strip whitespaces * @return the text or null if the element is not a text/literal kind. */ @Nullable @@ -156,7 +162,7 @@ public String extractTextFromElement(PsiElement element, boolean fallBackToGener } /** - * Is the element from a java setter method (eg setBrokerURL) or from a XML configured bean style + * Is the element from a java setter method (e.g., setBrokerURL) or from an XML configured bean style * configuration using property element. */ public boolean isElementFromSetterProperty(@NotNull PsiElement element, @NotNull String setter) { @@ -181,21 +187,21 @@ public boolean isElementFromAnnotation(@NotNull PsiElement element, @NotNull Str * Is the element from Java language */ public boolean isJavaLanguage(PsiElement element) { - return element != null && PsiUtil.getNotAnyLanguage(element.getNode()).is(JavaLanguage.INSTANCE); + return element != null && PsiUtilCore.getNotAnyLanguage(element.getNode()).is(JavaLanguage.INSTANCE); } /** * Is the element from XML language */ public boolean isXmlLanguage(PsiElement element) { - return element != null && PsiUtil.getNotAnyLanguage(element.getNode()).is(XMLLanguage.INSTANCE); + return element != null && PsiUtilCore.getNotAnyLanguage(element.getNode()).is(XMLLanguage.INSTANCE); } /** * Is the element from YAML language */ public boolean isYamlLanguage(PsiElement element) { - return element != null && PsiUtil.getNotAnyLanguage(element.getNode()).is(YAMLLanguage.INSTANCE); + return element != null && PsiUtilCore.getNotAnyLanguage(element.getNode()).is(YAMLLanguage.INSTANCE); } /** @@ -207,8 +213,8 @@ public boolean isFromFileType(PsiElement element, @NotNull String... extensions) } PsiFile file; - if (element instanceof PsiFile) { - file = (PsiFile) element; + if (element instanceof PsiFile psiFile) { + file = psiFile; } else { file = PsiTreeUtil.getParentOfType(element, PsiFile.class); } @@ -255,7 +261,7 @@ public boolean isFromFileType(PsiElement element, @NotNull String... extensions) } /** - * Is the given class or any of its super classes a class with the qualified name. + * Is the given class or any of its superclasses a class with the qualified name. * * @param target the class * @param fqnClassName the class name to match @@ -273,11 +279,11 @@ private static boolean isClassOrParentOf(@Nullable PsiClass target, @NotNull Str } /** - * Is the element from a constructor call with the given constructor name (eg class name) + * Is the element from a constructor call with the given constructor name (e.g., class name) * * @param element the element - * @param constructorName the name of the constructor (eg class) - * @return true if its a constructor call from the given name, false otherwise + * @param constructorName the name of the constructor (e.g., class) + * @return true if it is a constructor call from the given name, false otherwise */ public boolean isElementFromConstructor(@NotNull PsiElement element, @NotNull String constructorName) { // java constructor @@ -292,7 +298,7 @@ public boolean isElementFromConstructor(@NotNull PsiElement element, @NotNull St } /** - * Is the given element from a Java method call with any of the given method names + * Is the given element from a Java method call with any of the given method names? * * @param element the psi element * @param methods method call names @@ -311,7 +317,7 @@ public boolean isFromJavaMethodCall(PsiElement element, boolean fromRouteBuilder * Returns the first parent of the given element which matches the given condition. * * @param element element from which the search starts - * @param strict if true, element itself cannot be returned if it matches the condition + * @param strict if true, the element itself cannot be returned if it matches the condition * @param matchCondition condition which the parent must match to be returned * @param stopCondition condition which stops the search, causing the method to return null */ @@ -358,7 +364,7 @@ public boolean isFromJavaMethod(PsiMethodCallExpression call, boolean fromRouteB } /** - * Is the given element from a XML tag with any of the given tag names + * Is the given element from an XML tag with any of the given tag names? * * @param xml the xml tag * @param methods xml tag names @@ -370,7 +376,7 @@ public boolean isFromXmlTag(@NotNull XmlTag xml, @NotNull String... methods) { } /** - * Is the given element from a XML tag with any of the given tag names + * Is the given element from an XML tag with any of the given tag names * * @param xml the xml tag * @param parentTag a special parent tag name to match first @@ -416,7 +422,7 @@ public boolean hasParentYAMLKeyValue(@NotNull YAMLKeyValue keyValue, @NotNull St } /** - * Is the given element from a XML tag with the parent and is of any of the given tag names + * Is the given element from an XML tag with the parent and is of any given tag names? * * @param xml the xml tag * @param parentTag a special parent tag name to match first @@ -440,8 +446,8 @@ public void iterateYamlFiles(Module module, Consumer yamlFileConsumer) fileIndex.iterateContent(f -> { if (yamlFiles.contains(f)) { PsiFile file = PsiManager.getInstance(module.getProject()).findFile(f); - if (file instanceof YAMLFile) { - yamlFileConsumer.accept((YAMLFile) file); + if (file instanceof YAMLFile yamlFile) { + yamlFileConsumer.accept(yamlFile); } } return true; @@ -456,8 +462,7 @@ public void iterateXmlDocumentRoots(Module module, Consumer rootTag) { fileIndex.iterateContent(f -> { if (xmlFiles.contains(f)) { PsiFile file = PsiManager.getInstance(module.getProject()).findFile(f); - if (file instanceof XmlFile) { - XmlFile xmlFile = (XmlFile) file; + if (file instanceof XmlFile xmlFile) { XmlTag root = xmlFile.getRootTag(); if (root != null) { rootTag.accept(xmlFile.getRootTag()); @@ -503,7 +508,6 @@ private int getCaretPositionInsidePsiElement(String stringLiteral) { return hackIndex; } - /** * Return the Query parameter at the cursor location for the query parameter. *

      @@ -513,7 +517,7 @@ private int getCaretPositionInsidePsiElement(String stringLiteral) { *
    • timer:trigger?repeatCount=0&delay=<cursor> will return {"delay",""}
    • *
    • jms:qu<cursor> will return {":qu", ""}
    • *
    - * @return a list with the query parameter and the value if present. The query parameter is returned with separator char + * @return an array with the query parameter and the value if present. The query parameter is returned with separator char */ public String[] getQueryParameterAtCursorPosition(PsiElement element) { String positionText = extractTextFromElement(element); @@ -557,10 +561,7 @@ public boolean isCaretAtEndOfLine(PsiElement element) { public boolean isWhiteSpace(PsiElement element) { IElementType type = element.getNode().getElementType(); - if (type == TokenType.WHITE_SPACE) { - return true; - } - return false; + return type == TokenType.WHITE_SPACE; } public boolean isJavaDoc(PsiElement element) { @@ -645,19 +646,20 @@ public static YAMLKeyValue getYamlKeyValueAt(Project project, XSourcePosition po YAMLKeyValue keyValue = null; PsiElement psiElement = XDebuggerUtil.getInstance().findContextElement(file, position.getOffset(), project, false); - //This must be indent element because the position is at the beginning of the line - if (psiElement instanceof LeafPsiElement && "indent".equals(((LeafPsiElement) psiElement).getElementType().toString())) { - psiElement = psiElement.getNextSibling(); //This must be sequence item + // This must be the indent element because the position is at the beginning of the line + if (psiElement instanceof LeafPsiElement leafPsiElement && "indent".equals(leafPsiElement.getElementType().toString())) { + psiElement = psiElement.getNextSibling(); //This must be the sequence item Collection keyValues = null; - if (psiElement instanceof YAMLSequence) { //This is the beginning of sequence, get first item - psiElement = ((YAMLSequence) psiElement).getItems().get(0); + if (psiElement instanceof YAMLSequence yamlSequence) { + // This is the beginning of the sequence; get the first item + psiElement = yamlSequence.getItems().get(0); keyValues = ((YAMLSequenceItem) psiElement).getKeysValues(); - } else if (psiElement instanceof YAMLSequenceItem) { - keyValues = ((YAMLSequenceItem) psiElement).getKeysValues(); - } else if (psiElement instanceof YAMLKeyValue) { - keyValue = (YAMLKeyValue) psiElement; - } else if (psiElement instanceof YAMLMapping) { - keyValues = ((YAMLMapping) psiElement).getKeyValues(); + } else if (psiElement instanceof YAMLSequenceItem yamlSequenceItem) { + keyValues = yamlSequenceItem.getKeysValues(); + } else if (psiElement instanceof YAMLKeyValue yamlKeyValue) { + keyValue = yamlKeyValue; + } else if (psiElement instanceof YAMLMapping yamlMapping) { + keyValues = yamlMapping.getKeyValues(); } if (keyValues != null && !keyValues.isEmpty()) { keyValue = keyValues.iterator().next(); @@ -666,4 +668,13 @@ public static YAMLKeyValue getYamlKeyValueAt(Project project, XSourcePosition po return keyValue; } + + public static PsiClass findRouteBuilderClass(PsiManager manager) { + return ROUTE_BUILDER_OR_EXPRESSION_CLASS_QUALIFIED_NAME + .stream() + .map(fqn -> ClassUtil.findPsiClass(manager, fqn)) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); + } } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/JavaClassUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/JavaClassUtils.java index cae02673..fe71f3ea 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/JavaClassUtils.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/JavaClassUtils.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; @@ -56,6 +55,13 @@ public class JavaClassUtils implements Disposable { * The prefix of all the classes in the java lang package. */ private static final String JAVA_LANG_PACKAGE = "java.lang."; + private static final List BEAN_ANNOTATIONS = Arrays.asList( + "org.springframework.stereotype.Component", + "org.springframework.stereotype.Service", + "org.springframework.stereotype.Repository", + "javax.inject.Named", + "jakarta.inject.Named" + ); public static JavaClassUtils getService() { return ApplicationManager.getApplication().getService(JavaClassUtils.class); @@ -66,11 +72,12 @@ public static JavaClassUtils getService() { * to class name decapitalized */ public String getBeanName(PsiClass clazz) { - final String beanName = getBeanName(clazz, "org.springframework.stereotype.Component") - .orElseGet(() -> getBeanName(clazz, "org.springframework.stereotype.Service") - .orElseGet(() -> getBeanName(clazz, "org.springframework.stereotype.Repository") - .orElse(Introspector.decapitalize(clazz.getText())))); - return beanName; + return BEAN_ANNOTATIONS + .stream() + .map(annotation -> getBeanName(clazz, annotation)) + .flatMap(Optional::stream) + .findFirst() + .orElseGet(() -> Introspector.decapitalize(clazz.getText())); } /** @@ -97,10 +104,9 @@ public Optional findBeanClassByName(String beanName, String annotation if (beanName.equals(StringUtils.stripDoubleQuotes(value))) { return Optional.of(psiClass); } - } } else { - if (Introspector.decapitalize(psiClass.getName()).equalsIgnoreCase(StringUtils.stripDoubleQuotes(beanName))) { + if (StringUtils.stripDoubleQuotes(beanName).equalsIgnoreCase(Introspector.decapitalize(psiClass.getName()))) { return Optional.of(psiClass); } } @@ -127,9 +133,9 @@ private Collection getClassesAnnotatedWith(Project project, String ann public JavaClassReference findClassReference(@NotNull PsiElement element) { List references = Arrays.stream(element.getReferences()) - .filter(r -> r instanceof JavaClassReference) - .map(r -> (JavaClassReference) r) - .collect(Collectors.toList()); + .filter(JavaClassReference.class::isInstance) + .map(JavaClassReference.class::cast) + .toList(); if (!references.isEmpty()) { return references.get(references.size() - 1); } @@ -139,8 +145,8 @@ public JavaClassReference findClassReference(@NotNull PsiElement element) { public PsiClass resolveClassReference(@NotNull PsiReference reference) { final PsiElement resolveElement = reference.resolve(); - if (resolveElement instanceof PsiClass) { - return (PsiClass) resolveElement; + if (resolveElement instanceof PsiClass psiClass) { + return psiClass; } else if (resolveElement instanceof PsiField) { final PsiType psiType = PsiUtil.getTypeByPsiElement(resolveElement); if (psiType != null) { @@ -180,24 +186,12 @@ public String toSimpleType(@Nullable String type) { if (result.startsWith(JAVA_LANG_PACKAGE)) { result = result.substring(JAVA_LANG_PACKAGE.length()); } - switch (result) { - case "string": - case "long": - case "boolean": - case "double": - case "float": - case "short": - case "char": - case "byte": - case "int": - return result; - case "character": - return "char"; - case "integer": - return "int"; - default: - return type; - } + return switch (result) { + case "string", "long", "boolean", "double", "float", "short", "char", "byte", "int" -> result; + case "character" -> "char"; + case "integer" -> "int"; + default -> type; + }; } /** diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index af51e5d7..60bf0870 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -80,8 +80,6 @@ - - From cd2a1802f76e60bd30abdda38a8616c367f2a337 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sun, 22 Oct 2023 16:08:57 +0200 Subject: [PATCH 15/18] Update changelog --- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 60bf0870..568f5ab6 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -11,8 +11,9 @@ +
  • Camel icon shown in plugin marketplace
  • +
  • Add support for Java routes from EndpointRouteBuilder
  • Bug fixes
  • -
  • New marketplace icon
  • ]]>
    From e9b8d5ea218a67285c68ea4c40e0dd3e9365ff49 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sun, 22 Oct 2023 16:13:03 +0200 Subject: [PATCH 16/18] Bump for next version --- build.gradle | 2 +- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index faf445de..22f0c6f3 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ allprojects { } group = 'com.github.camel-tooling' - version = '1.1.4' + version = '1.1.5' } subprojects { diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 568f5ab6..b337ff95 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -1,7 +1,7 @@ org.apache.camel Apache Camel - 1.1.4 + 1.1.5 Apache Camel -
  • Camel icon shown in plugin marketplace
  • -
  • Add support for Java routes from EndpointRouteBuilder
  • Bug fixes
  • ]]> From 8d274b02c44f7f63c4cdb956aed73bdfe1c1fdad Mon Sep 17 00:00:00 2001 From: Nicolas Filotto Date: Mon, 23 Oct 2023 16:35:16 +0200 Subject: [PATCH 17/18] Ref #945: formatting - Exclude new expressions (#948) ## Motivation When using the keyword new in the middle of a Camel route, the formatting doesn't work as expected so it needs to be improved. ## Modifications: * Ensure that new expressions are not seen as method calls --- .../extension/camel/JavaCamelIdeaUtils.java | 11 +++-- .../formatter/CamelPostFormatProcessorIT.java | 8 ++++ .../formatter/after/Formatting945.txt | 48 +++++++++++++++++++ .../formatter/before/Formatting945.java | 48 +++++++++++++++++++ 4 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 camel-idea-plugin/src/test/resources/testData/formatter/after/Formatting945.txt create mode 100644 camel-idea-plugin/src/test/resources/testData/formatter/before/Formatting945.java diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java index 1dd52732..501dee90 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java @@ -32,6 +32,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaResolveResult; import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiCallExpression; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; @@ -656,11 +657,11 @@ private static boolean testMethod(PsiFile file, int offset, Predicate#945
    + * is properly fixed. + */ + public void testFormatting945() { + doTest("Formatting945", null); + } + /** * Ensures that a partial format not including a route has no effect. */ diff --git a/camel-idea-plugin/src/test/resources/testData/formatter/after/Formatting945.txt b/camel-idea-plugin/src/test/resources/testData/formatter/after/Formatting945.txt new file mode 100644 index 00000000..702644d8 --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/formatter/after/Formatting945.txt @@ -0,0 +1,48 @@ +/* + * 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. + */ + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; + +public class Formatting945 extends RouteBuilder { + @Override + public void configure() { + from("direct:start") + .doTry() + .process(new ProcessorFail()) + .to("mock:result") + .doCatch(IOException.class, IllegalStateException.class) + .to("mock:catch") + .doFinally() + .to("mock:finally") + .end(); + + from("direct:start2") + .doTry() + .unmarshal(new JacksonDataFormat(objectMapper, Foo.class)) + .doCatch(JsonProcessingException.class) + .to("direct:deserialization-error-handler") + .end() + } + + public static class ProcessorFail implements Processor { + @Override + public void process(Exchange exchange) throws Exception { + throw new IOException("Forced"); + } + } +} diff --git a/camel-idea-plugin/src/test/resources/testData/formatter/before/Formatting945.java b/camel-idea-plugin/src/test/resources/testData/formatter/before/Formatting945.java new file mode 100644 index 00000000..3cf5936a --- /dev/null +++ b/camel-idea-plugin/src/test/resources/testData/formatter/before/Formatting945.java @@ -0,0 +1,48 @@ +/* + * 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. + */ + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; + +public class Formatting945 extends RouteBuilder { + @Override + public void configure() { + from("direct:start") + .doTry() + .process(new ProcessorFail()) + .to("mock:result") + .doCatch(IOException.class, IllegalStateException.class) + .to("mock:catch") + .doFinally() + .to("mock:finally") + .end(); + + from("direct:start2") + .doTry() + .unmarshal(new JacksonDataFormat(objectMapper, Foo.class)) + .doCatch(JsonProcessingException.class) + .to("direct:deserialization-error-handler") + .end() + } + + public static class ProcessorFail implements Processor { + @Override + public void process(Exchange exchange) throws Exception { + throw new IOException("Forced"); + } + } +} From 6a8a9da831bb9586d0437d33b37f32217657314e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 12:19:30 +0200 Subject: [PATCH 18/18] Bump io.fabric8:kubernetes-model-apiextensions from 6.9.0 to 6.9.1 (#950) Bumps io.fabric8:kubernetes-model-apiextensions from 6.9.0 to 6.9.1. --- updated-dependencies: - dependency-name: io.fabric8:kubernetes-model-apiextensions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- camel-idea-plugin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camel-idea-plugin/build.gradle b/camel-idea-plugin/build.gradle index ce81ab7e..9a50b59a 100644 --- a/camel-idea-plugin/build.gradle +++ b/camel-idea-plugin/build.gradle @@ -68,7 +68,7 @@ dependencies { implementation "org.apache.maven.resolver:maven-resolver-impl:${mavenResolverVersion}" implementation "io.github.classgraph:classgraph:4.8.163" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.3" - implementation "io.fabric8:kubernetes-model-apiextensions:6.9.0" + implementation "io.fabric8:kubernetes-model-apiextensions:6.9.1" testImplementation "org.apache.camel:camel-core:${camelVersion}" testImplementation "org.apache.camel.springboot:camel-spring-boot:${camelVersion}"