├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitignore ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── build.gradle.kts ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── projectSetup.gif ├── settings.gradle.kts └── src ├── main ├── java │ └── krasa │ │ └── mavenhelper │ │ ├── Donate.java │ │ ├── MavenHelperApplicationService.java │ │ ├── MyConfigurable.java │ │ ├── MyProjectService.java │ │ ├── RefreshIconsAction.java │ │ ├── ShortcutStartupActivity.java │ │ ├── action │ │ ├── CreateCustomGoalAction.java │ │ ├── MainMavenActionGroup.java │ │ ├── MavenProjectInfo.java │ │ ├── MyAnAction.java │ │ ├── MyReimportProjectAction.java │ │ ├── OpenTerminalAction.java │ │ ├── ProgramRunnerUtils.java │ │ ├── QuickRunMavenGoalAction.java │ │ ├── QuickRunRootMavenGoalAction.java │ │ ├── RootMavenActionGroup.java │ │ ├── RunConfigurationAction.java │ │ ├── RunGoalAction.java │ │ ├── RunTestFileAction.java │ │ ├── Utils.java │ │ └── debug │ │ │ ├── CreateCustomDebugGoalAction.java │ │ │ ├── Debug.java │ │ │ ├── DebugConfigurationAction.java │ │ │ ├── DebugGoalAction.java │ │ │ ├── DebugTestFileAction.java │ │ │ └── MainMavenDebugActionGroup.java │ │ ├── analyzer │ │ ├── ComparableVersion.java │ │ ├── DefaultArtifactVersion.java │ │ ├── GuiForm.form │ │ ├── GuiForm.java │ │ ├── MyDefaultListModel.java │ │ ├── MyDefaultMutableTreeNode.java │ │ ├── MyFileEditorProvider.java │ │ ├── MyHighlightingTree.java │ │ ├── MyListNode.java │ │ ├── MyTreeUserObject.java │ │ ├── RestoreSelection.java │ │ ├── TreeRenderer.java │ │ ├── TreeUtils.java │ │ ├── UIFormEditor.java │ │ ├── Utils.java │ │ └── action │ │ │ ├── BaseAction.java │ │ │ ├── ExcludeDependencyAction.java │ │ │ ├── JumpToLeftTreeAction.java │ │ │ ├── JumpToLeftTreeListAction.java │ │ │ ├── JumpToSourceAction.java │ │ │ ├── LeftTreePopupHandler.java │ │ │ ├── ListKeyStrokeAdapter.java │ │ │ ├── ListPopupHandler.java │ │ │ ├── RemoveDependencyAction.java │ │ │ └── RightTreePopupHandler.java │ │ ├── gui │ │ ├── AliasEditor.form │ │ ├── AliasEditor.java │ │ ├── AliasRealEditor.java │ │ ├── AliasTable.java │ │ ├── ApplicationSettingsForm.form │ │ ├── ApplicationSettingsForm.java │ │ ├── BorderLayoutPanel.java │ │ ├── FlowLayoutPanel.java │ │ ├── GoalEditor.form │ │ ├── GoalEditor.java │ │ ├── MyDragListener.java │ │ ├── MyListDataListener.java │ │ └── MyListDropHandler.java │ │ ├── icons │ │ └── MyIcons.java │ │ └── model │ │ ├── Alias.java │ │ ├── Aliases.java │ │ ├── ApplicationSettings.java │ │ ├── DomainObject.java │ │ ├── Goal.java │ │ └── Goals.java └── resources │ ├── META-INF │ ├── plugin.xml │ ├── pluginIcon.svg │ └── pluginIcon_dark.svg │ └── icons │ ├── OpenTerminal.svg │ ├── OpenTerminal_dark.svg │ ├── coins_in_hand.png │ ├── coins_in_hand@2x.png │ ├── debug.svg │ ├── debug_dark.svg │ ├── donate.gif │ ├── mavenLogo.svg │ ├── mavenLogo_dark.svg │ ├── phasesClosed.svg │ ├── pluginGoal.svg │ ├── pluginGoal_dark.svg │ ├── runMaven.svg │ └── runMaven_dark.svg └── test ├── java └── krasa │ └── mavenhelper │ └── action │ └── RunTestFileActionTest.java └── lib ├── assertj-core-3.16.1.jar ├── byte-buddy-dep-1.10.10.jar └── mockito-core-3.3.3.jar /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [krasa] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment :** 27 | Use `Help | About | Copy` button 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### java template 3 | .svn/ 4 | .idea/ 5 | .settings/ 6 | target/ 7 | out/ 8 | .classpath 9 | .project 10 | .mymetadata 11 | .DS_Store 12 | rebel.xml 13 | *.ipr 14 | *.iws 15 | *.iml 16 | 17 | 18 | DependencyManager/target/ 19 | 20 | .gradle 21 | .idea 22 | .qodana 23 | build 24 | 25 | .idea-sandbox -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [Unreleased] 4 | 5 | ## [4.30.0-IJ2022.2] - 2025-06-05 6 | 7 | - exception fix 8 | 9 | ## [4.29.0-IJ2022.2] - 2024-10-10 10 | - exception workaround for 2024.2 11 | - Support for submodules using -pl -am 12 | 13 | ## [4.28.0-IJ2022.2] - 2024-04-04 14 | - compatibility with 2024.1 15 | 16 | ## [4.27.1-IJ2022.2] - 2023-11-29 17 | - compatibility with 2023.3 18 | - compatibility with 2022.2 19 | 20 | ## [4.27.0-IJ2022.2] - 2023-11-28 21 | - compatibility with 2023.3 22 | 23 | ## [4.26.0-IJ2022.2] - 2023-09-15 24 | - fixed exception: Slow operations are prohibited on EDT 25 | 26 | ## [4.25.1-IJ2022.2] - 2023-09-06 27 | - exception fix 28 | - context menu actions initialized sooner 29 | 30 | ## [4.24.1-IJ2022.2] - 2023-09-01 31 | - Persist CheckBoxes state of Dependency Analyzer UI 32 | - Dependency Analyzer: allowing all kinds of pom file names 33 | 34 | [Unreleased]: https://github.com/krasa/MavenHelper/compare/v4.30.0-IJ2022.2...HEAD 35 | 36 | [4.30.0-IJ2022.2]: https://github.com/krasa/MavenHelper/compare/v4.29.0-IJ2022.2...v4.30.0-IJ2022.2 37 | [4.29.0-IJ2022.2]: https://github.com/krasa/MavenHelper/compare/v4.28.0-IJ2022.2...v4.29.0-IJ2022.2 38 | [4.28.0-IJ2022.2]: https://github.com/krasa/MavenHelper/compare/v4.27.1-IJ2022.2...v4.28.0-IJ2022.2 39 | [4.27.1-IJ2022.2]: https://github.com/krasa/MavenHelper/compare/v4.27.0-IJ2022.2...v4.27.1-IJ2022.2 40 | [4.27.0-IJ2022.2]: https://github.com/krasa/MavenHelper/compare/v4.26.0-IJ2022.2...v4.27.0-IJ2022.2 41 | [4.26.0-IJ2022.2]: https://github.com/krasa/MavenHelper/compare/v4.25.1-IJ2022.2...v4.26.0-IJ2022.2 42 | [4.25.1-IJ2022.2]: https://github.com/krasa/MavenHelper/compare/v4.24.1-IJ2022.2...v4.25.1-IJ2022.2 43 | [4.24.1-IJ2022.2]: https://github.com/krasa/MavenHelper/commits/v4.24.1-IJ2022.2 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Maven Helper [![Donate][badge-paypal-img]][badge-paypal] 2 | ================== 3 | 4 | IntelliJ Plugin - https://plugins.jetbrains.com/plugin/7179 5 | 6 | --- 7 | 8 | ### Project setup: 9 | 10 | - Manually by guides: [Gif](projectSetup.gif), [MP4](https://mega.nz/#!HupmEChL!zMlxvYjuR3qjnyZnHuvPn6E3BC2aU1VBX_vkB7_cEWs). 11 | - In this case, you need to install a [maven-server-api](https://search.maven.org/search?q=g:com.github.adedayo.intellij.sdk) library manually (because bundled packages of the latest IDEA versions don't support *MavenId* class). 12 | - Use [Plugin](https://plugins.jetbrains.com/plugin/6844-useful-actions). 13 | - `Tools | Add Dependant Bundled Plugins to IntelliJ Platform Plugin SDK` — instead of manual adding of Terminal and 14 | Maven jars to the SDK. 15 | 16 | --- 17 | 18 | ### Sponsored by 19 | 20 | 21 | ![YourKit-Logo](https://www.yourkit.com/images/yklogo.png) 22 | 23 | YourKit supports open source projects with its full-featured Java Profiler. YourKit, LLC is the creator 24 | of [YourKit Java Profiler](https://www.yourkit.com/java/profiler/) 25 | and [YourKit .NET Profiler](https://www.yourkit.com/.net/profiler/), innovative and intelligent tools for profiling Java 26 | and .NET applications. 27 | 28 | 29 | [badge-paypal-img]: https://img.shields.io/badge/donate-paypal-green.svg 30 | [badge-paypal]: https://www.paypal.me/VojtechKrasa 31 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.changelog.Changelog 2 | 3 | fun properties(key: String) = providers.gradleProperty(key) 4 | fun environment(key: String) = providers.environmentVariable(key) 5 | 6 | tasks { 7 | buildSearchableOptions { 8 | enabled = false 9 | } 10 | } 11 | 12 | 13 | plugins { 14 | id("java") // Java support 15 | // alias(libs.plugins.kotlin) 16 | alias(libs.plugins.gradleIntelliJPlugin) // Gradle IntelliJ Plugin 17 | alias(libs.plugins.changelog) // Gradle Changelog Plugin 18 | // alias(libs.plugins.qodana) // Gradle Qodana Plugin 19 | // alias(libs.plugins.kover) // Gradle Kover Plugin 20 | } 21 | 22 | group = properties("pluginGroup").get() 23 | version = properties("pluginVersion").get() 24 | 25 | // Configure project's dependencies 26 | repositories { 27 | mavenCentral() 28 | } 29 | 30 | // Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog 31 | 32 | dependencies { 33 | testImplementation(platform("org.junit:junit-bom:5.9.1")) 34 | testImplementation("org.junit.jupiter:junit-jupiter") 35 | 36 | // https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils 37 | implementation("commons-beanutils:commons-beanutils:1.9.4") { 38 | exclude(group = "commons-logging", module = "commons-logging") 39 | } 40 | 41 | // https://mvnrepository.com/artifact/org.apache.maven.shared/maven-shared-utils 42 | implementation("org.apache.maven.shared:maven-shared-utils:3.3.4") 43 | 44 | 45 | // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 46 | implementation("org.apache.commons:commons-lang3:3.12.0") 47 | 48 | implementation("uk.com.robust-it:cloning:1.9.12") 49 | 50 | // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 51 | implementation("org.apache.commons:commons-lang3:3.17.0") 52 | // https://mvnrepository.com/artifact/org.apache.commons/commons-text 53 | implementation("org.apache.commons:commons-text:1.13.1") 54 | } 55 | 56 | 57 | //// Set the JVM language level used to build the project. Use Java 11 for 2020.3+, and Java 17 for 2022.2+. 58 | //kotlin { 59 | // jvmToolchain(17) 60 | //} 61 | 62 | 63 | // Configure Gradle IntelliJ Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html 64 | intellij { 65 | pluginName = properties("pluginName") 66 | version = properties("platformVersion") 67 | type = properties("platformType") 68 | 69 | // The sandbox directory location is used to save IDEA settings. By default, it is under the build file. To prevent clean, it is placed in the root directory. 70 | // 沙箱目录位置,用于保存IDEA的设置,默认在build文件下面,防止clean,放在根目录下。 71 | sandboxDir.set("${rootProject.rootDir}/.idea-sandbox") 72 | // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file. 73 | plugins = properties("platformPlugins").map { it.split(',').map(String::trim).filter(String::isNotEmpty) } 74 | } 75 | 76 | // Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin 77 | changelog { 78 | groups.empty() 79 | repositoryUrl = properties("pluginRepositoryUrl") 80 | } 81 | 82 | // Configure Gradle Qodana Plugin - read more: https://github.com/JetBrains/gradle-qodana-plugin 83 | //qodana { 84 | // cachePath = provider { file(".qodana").canonicalPath } 85 | // reportPath = provider { file("build/reports/inspections").canonicalPath } 86 | // saveReport = true 87 | // showReport = environment("QODANA_SHOW_REPORT").map { it.toBoolean() }.getOrElse(false) 88 | //} 89 | // 90 | //// Configure Gradle Kover Plugin - read more: https://github.com/Kotlin/kotlinx-kover#configuration 91 | //kover.xmlReport { 92 | // onCheck = true 93 | //} 94 | 95 | tasks { 96 | wrapper { 97 | gradleVersion = properties("gradleVersion").get() 98 | } 99 | 100 | patchPluginXml { 101 | version = properties("pluginVersion") 102 | sinceBuild = properties("pluginSinceBuild") 103 | untilBuild = properties("pluginUntilBuild") 104 | 105 | // // Extract the section from README.md and provide for the plugin's manifest 106 | // pluginDescription = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map { 107 | // val start = "" 108 | // val end = "" 109 | // 110 | // with (it.lines()) { 111 | // if (!containsAll(listOf(start, end))) { 112 | // throw GradleException("Plugin description section not found in README.md:\n$start ... $end") 113 | // } 114 | // subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML) 115 | // } 116 | // } 117 | 118 | val changelog = project.changelog // local variable for configuration cache compatibility 119 | // Get the latest available change notes from the changelog file 120 | changeNotes = properties("pluginVersion").map { pluginVersion -> 121 | with(changelog) { 122 | renderItem( 123 | (getOrNull(pluginVersion) ?: getUnreleased()) 124 | .withHeader(false) 125 | .withEmptySections(false), 126 | Changelog.OutputType.HTML, 127 | ) 128 | } 129 | } 130 | } 131 | 132 | // Configure UI tests plugin 133 | // Read more: https://github.com/JetBrains/intellij-ui-test-robot 134 | runIdeForUiTests { 135 | systemProperty("robot-server.port", "8082") 136 | systemProperty("ide.mac.message.dialogs.as.sheets", "false") 137 | systemProperty("jb.privacy.policy.text", "") 138 | systemProperty("jb.consents.confirmation.enabled", "false") 139 | } 140 | 141 | signPlugin { 142 | certificateChain = environment("CERTIFICATE_CHAIN") 143 | privateKey = environment("PRIVATE_KEY") 144 | password = environment("PRIVATE_KEY_PASSWORD") 145 | } 146 | 147 | publishPlugin { 148 | dependsOn("patchChangelog") 149 | token = environment("PUBLISH_TOKEN") 150 | // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 151 | // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: 152 | // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel 153 | // channels = properties("pluginVersion").map { listOf(it.split('-').getOrElse(1) { "default" }.split('.').first()) } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html 2 | 3 | pluginGroup=com.github.krasa.MavenHelper 4 | pluginName=MavenHelper 5 | pluginRepositoryUrl=https://github.com/krasa/MavenHelper 6 | 7 | # SemVer format -> https://semver.org 8 | pluginVersion=4.30.0-IJ2022.2 9 | 10 | # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html 11 | pluginSinceBuild=222.2964.55 12 | pluginUntilBuild= 13 | 14 | # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension 15 | platformType=IC 16 | platformVersion=2022.3.3 17 | 18 | # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html 19 | # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 20 | platformPlugins=com.intellij.java, org.jetbrains.idea.maven, org.jetbrains.plugins.terminal, com.jetbrains.sh 21 | 22 | # Gradle Releases -> https://github.com/gradle/gradle/releases 23 | gradleVersion=8.1 24 | 25 | # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib 26 | kotlin.stdlib.default.dependency=false 27 | 28 | # Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html 29 | org.gradle.configuration-cache=true 30 | 31 | # Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html 32 | org.gradle.caching=true 33 | 34 | # Enable Gradle Kotlin DSL Lazy Property Assignment -> https://docs.gradle.org/current/userguide/kotlin_dsl.html#kotdsl:assignment 35 | systemProp.org.gradle.unsafe.kotlin.assignment=true 36 | 37 | # Temporary workaround for Kotlin Compiler OutOfMemoryError -> https://jb.gg/intellij-platform-kotlin-oom 38 | kotlin.incremental.useClasspathSnapshot=false 39 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | # https://raw.githubusercontent.com/JetBrains/intellij-platform-plugin-template/main/gradle/libs.versions.toml 2 | [versions] 3 | # libraries 4 | annotations = "24.0.1" 5 | 6 | # plugins 7 | kotlin = "1.9.0" 8 | changelog = "2.1.2" 9 | gradleIntelliJPlugin = "1.15.0" 10 | qodana = "0.1.13" 11 | kover = "0.7.2" 12 | 13 | [libraries] 14 | annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" } 15 | 16 | [plugins] 17 | changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } 18 | gradleIntelliJPlugin = { id = "org.jetbrains.intellij", version.ref = "gradleIntelliJPlugin" } 19 | kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } 20 | kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } 21 | qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/MavenHelper/fd7ced790d2314622b8d915214fc24c2e3eef2f6/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /projectSetup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/MavenHelper/fd7ced790d2314622b8d915214fc24c2e3eef2f6/projectSetup.gif -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "MavenHelper" 2 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/Donate.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper; 2 | 3 | import com.intellij.ide.BrowserUtil; 4 | import com.intellij.openapi.diagnostic.Logger; 5 | import com.intellij.openapi.util.IconLoader; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | import java.awt.event.ActionListener; 10 | 11 | public class Donate { 12 | private static final Logger LOG = Logger.getInstance(Donate.class); 13 | 14 | public static final Icon ICON = IconLoader.getIcon("/icons/coins_in_hand.png", Donate.class); 15 | 16 | public static void init(JButton donate) { 17 | donate.setText("Donate"); 18 | donate.setIcon(ICON); 19 | donate.addActionListener(new ActionListener() { 20 | @Override 21 | public void actionPerformed(ActionEvent e) { 22 | BrowserUtil.browse("https://www.paypal.me/VojtechKrasa"); 23 | } 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/MavenHelperApplicationService.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper; 2 | 3 | import com.intellij.openapi.actionSystem.*; 4 | import com.intellij.openapi.application.ApplicationManager; 5 | import com.intellij.openapi.components.PersistentStateComponent; 6 | import com.intellij.openapi.components.State; 7 | import com.intellij.openapi.components.Storage; 8 | import com.intellij.openapi.diagnostic.Logger; 9 | import com.intellij.openapi.extensions.PluginId; 10 | import krasa.mavenhelper.action.MainMavenActionGroup; 11 | import krasa.mavenhelper.action.RunGoalAction; 12 | import krasa.mavenhelper.action.RunTestFileAction; 13 | import krasa.mavenhelper.action.debug.DebugGoalAction; 14 | import krasa.mavenhelper.action.debug.DebugTestFileAction; 15 | import krasa.mavenhelper.action.debug.MainMavenDebugActionGroup; 16 | import krasa.mavenhelper.icons.MyIcons; 17 | import krasa.mavenhelper.model.ApplicationSettings; 18 | import krasa.mavenhelper.model.Goal; 19 | import org.apache.commons.text.WordUtils; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | @State(name = "MavenRunHelper", storages = {@Storage("mavenRunHelper.xml")}) 23 | public class MavenHelperApplicationService implements PersistentStateComponent { 24 | static final Logger LOG = Logger.getInstance(MavenHelperApplicationService.class); 25 | 26 | public static final String RUN_MAVEN = "Run Maven"; 27 | public static final String DEBUG_MAVEN = "Debug Maven"; 28 | private ApplicationSettings settings = new ApplicationSettings(); 29 | 30 | public void initShortcuts() { 31 | addActionGroup(new MainMavenDebugActionGroup(DEBUG_MAVEN, MyIcons.ICON), DEBUG_MAVEN); 32 | addActionGroup(new MainMavenActionGroup(RUN_MAVEN, MyIcons.RUN_MAVEN_ICON), RUN_MAVEN); 33 | registerActions(); 34 | } 35 | 36 | public void registerActions() { 37 | ActionManager instance = ActionManager.getInstance(); 38 | for (Goal goal : settings.getAllGoals()) { 39 | String actionId = getActionId(goal); 40 | registerAction(instance, actionId, RunGoalAction.create(goal, MyIcons.PLUGIN_GOAL, false, null)); 41 | actionId = getDebugActionId(goal); 42 | registerAction(instance, actionId, DebugGoalAction.createDebug(goal, MyIcons.PLUGIN_GOAL, false, null)); 43 | } 44 | registerAction(instance, "krasa.MavenHelper.RunTestFileAction", new RunTestFileAction().alwaysVisible()); 45 | registerAction(instance, "krasa.MavenHelper.DebugTestFileAction", new DebugTestFileAction().alwaysVisible()); 46 | } 47 | 48 | public void unRegisterActions() { 49 | ActionManager instance = ActionManager.getInstance(); 50 | for (Goal goal : settings.getAllGoals()) { 51 | unRegisterAction(instance, getActionId(goal)); 52 | unRegisterAction(instance, getDebugActionId(goal)); 53 | } 54 | } 55 | 56 | public void registerAction(Goal o, RunGoalAction runGoalAction) { 57 | ActionManager instance = ActionManager.getInstance(); 58 | registerAction(instance, getActionId(o), runGoalAction); 59 | } 60 | 61 | private void registerAction(ActionManager instance, String actionId1, AnAction runGoalAction) { 62 | unRegisterAction(instance, actionId1); 63 | instance.registerAction(actionId1, runGoalAction, PluginId.getId("MavenRunHelper")); 64 | } 65 | 66 | private void unRegisterAction(ActionManager instance, String actionId) { 67 | instance.unregisterAction(actionId); 68 | } 69 | 70 | private String getActionId(Goal goal) { 71 | return "MavenRunHelper" + WordUtils.capitalizeFully(goal.getCommandLine()).replaceAll(" ", ""); 72 | } 73 | 74 | private String getDebugActionId(Goal goal) { 75 | return "MavenRunHelperDebug" + WordUtils.capitalizeFully(goal.getCommandLine()).replaceAll(" ", ""); 76 | 77 | } 78 | 79 | private void addActionGroup(ActionGroup actionGroup, String name) { 80 | DefaultActionGroup editorPopupMenu = (DefaultActionGroup) ActionManager.getInstance().getAction( 81 | "EditorPopupMenu.Run"); 82 | DefaultActionGroup projectViewPopupMenuRunGroup = (DefaultActionGroup) ActionManager.getInstance().getAction( 83 | "ProjectViewPopupMenuRunGroup"); 84 | DefaultActionGroup mavenHelperBaseProjectMenu = (DefaultActionGroup) ActionManager.getInstance().getAction( 85 | "MavenHelper.BaseProjectMenu"); 86 | clear(editorPopupMenu, projectViewPopupMenuRunGroup, mavenHelperBaseProjectMenu, name); 87 | 88 | // Now it splatted to standalone blocks, so actions can be initialized separately. 89 | if (settings.isInitializeEditorPopups()) { 90 | editorPopupMenu.add(actionGroup, Constraints.FIRST); 91 | } 92 | if (settings.isInitializeProjectPopups()) { 93 | projectViewPopupMenuRunGroup.add(actionGroup, Constraints.FIRST); 94 | } 95 | if (settings.isInitializeMavenGroupPopups()) { 96 | mavenHelperBaseProjectMenu.add(actionGroup, Constraints.FIRST); 97 | } 98 | } 99 | 100 | /** Saved for compatibility. */ 101 | @SuppressWarnings("unused") 102 | private void add(ActionGroup actionGroup, DefaultActionGroup editorPopupMenu, 103 | DefaultActionGroup projectViewPopupMenuRunGroup, DefaultActionGroup viewPopupMenuRunGroup) { 104 | editorPopupMenu.add(actionGroup, Constraints.FIRST); 105 | projectViewPopupMenuRunGroup.add(actionGroup, Constraints.FIRST); 106 | viewPopupMenuRunGroup.add(actionGroup, Constraints.FIRST); 107 | } 108 | 109 | /** Saved for compatibility. */ 110 | private void clear(DefaultActionGroup editorPopupMenu, DefaultActionGroup projectViewPopupMenuRunGroup, 111 | DefaultActionGroup mavenHelperBaseProjectMenu, String name) { 112 | clear(editorPopupMenu, name); 113 | clear(projectViewPopupMenuRunGroup, name); 114 | clear(mavenHelperBaseProjectMenu, name); 115 | } 116 | 117 | private void clear(DefaultActionGroup editorPopupMenu, String name) { 118 | AnAction[] childActionsOrStubs = editorPopupMenu.getChildActionsOrStubs(); 119 | for (AnAction childActionsOrStub : childActionsOrStubs) { 120 | if (name.equals(childActionsOrStub.getTemplatePresentation().getText())) { 121 | editorPopupMenu.remove(childActionsOrStub); 122 | } 123 | } 124 | } 125 | 126 | @NotNull 127 | @Override 128 | public ApplicationSettings getState() { 129 | if (settings == null) { 130 | settings = new ApplicationSettings(); 131 | } 132 | return settings; 133 | } 134 | 135 | @Override 136 | public void loadState(ApplicationSettings state) { 137 | settings = state; 138 | ApplicationSettings.addDefaultAliases(settings.getAliases()); 139 | } 140 | 141 | 142 | public static MavenHelperApplicationService getInstance() { 143 | return ApplicationManager.getApplication().getService(MavenHelperApplicationService.class); 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/MyConfigurable.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper; 2 | 3 | import com.intellij.openapi.options.Configurable; 4 | import com.intellij.openapi.options.ConfigurationException; 5 | import krasa.mavenhelper.gui.ApplicationSettingsForm; 6 | import krasa.mavenhelper.model.ApplicationSettings; 7 | import org.jetbrains.annotations.Nls; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | import javax.swing.*; 11 | 12 | public class MyConfigurable implements Configurable { 13 | private ApplicationSettingsForm form; 14 | public ApplicationSettings state; 15 | private MavenHelperApplicationService applicationService; 16 | 17 | public MyConfigurable() { 18 | this.applicationService = MavenHelperApplicationService.getInstance(); 19 | this.state = applicationService.getState(); 20 | } 21 | 22 | @Override 23 | @Nls 24 | public String getDisplayName() { 25 | return "Maven Helper"; 26 | } 27 | 28 | @Override 29 | @Nullable 30 | public String getHelpTopic() { 31 | return null; 32 | } 33 | 34 | @Override 35 | @Nullable 36 | public JComponent createComponent() { 37 | form = new ApplicationSettingsForm(state); 38 | return form.getRootComponent(); 39 | } 40 | 41 | 42 | @Override 43 | public boolean isModified() { 44 | return form != null && form.isSettingsModified(state); 45 | } 46 | 47 | @Override 48 | public void apply() throws ConfigurationException { 49 | applicationService.unRegisterActions(); 50 | state = form.getSettings().clone(); 51 | applicationService.loadState(state); 52 | applicationService.initShortcuts(); 53 | } 54 | 55 | @Override 56 | public void reset() { 57 | if (form != null) { 58 | form.importFrom(state); 59 | } 60 | } 61 | 62 | @Override 63 | public void disposeUIResources() { 64 | form = null; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/MyProjectService.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper; 2 | 3 | import com.intellij.openapi.project.Project; 4 | import com.intellij.openapi.util.Pair; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | import org.jetbrains.idea.maven.project.MavenProject; 8 | import org.jetbrains.idea.maven.project.MavenProjectChanges; 9 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 10 | import org.jetbrains.idea.maven.project.MavenProjectsTree; 11 | import org.jetbrains.idea.maven.server.NativeMavenProjectHolder; 12 | 13 | import javax.swing.*; 14 | import java.util.List; 15 | import java.util.concurrent.CopyOnWriteArrayList; 16 | 17 | public class MyProjectService { 18 | private List myEventListeners = new CopyOnWriteArrayList<>(); 19 | 20 | public static MyProjectService getInstance(Project project) { 21 | return project.getService(MyProjectService.class); 22 | } 23 | 24 | public MyProjectService(Project project) { 25 | MavenProjectsManager.getInstance(project).addProjectsTreeListener(new MavenProjectsTree.Listener() { 26 | @Override 27 | public void profilesChanged() { 28 | 29 | } 30 | 31 | @Override 32 | public void projectsIgnoredStateChanged(@NotNull List ignored, @NotNull List unignored, boolean fromImport) { 33 | 34 | } 35 | 36 | @Override 37 | 38 | public void projectsUpdated(@NotNull List> updated, @NotNull List deleted) { 39 | } 40 | 41 | @Override 42 | public void projectResolved(@NotNull Pair projectWithChanges, @Nullable NativeMavenProjectHolder nativeMavenProject) { 43 | SwingUtilities.invokeLater(new Runnable() { 44 | @Override 45 | public void run() { 46 | for (MyEventListener myEventListener : myEventListeners) { 47 | myEventListener.projectResolved(projectWithChanges, nativeMavenProject); 48 | } 49 | } 50 | }); 51 | } 52 | 53 | @Override 54 | public void pluginsResolved(@NotNull MavenProject project) { 55 | 56 | } 57 | 58 | @Override 59 | public void foldersResolved(@NotNull Pair projectWithChanges) { 60 | 61 | } 62 | 63 | @Override 64 | public void artifactsDownloaded(@NotNull MavenProject project) { 65 | 66 | } 67 | }); 68 | } 69 | 70 | public void register(MyEventListener myEventListener) { 71 | myEventListeners.add(myEventListener); 72 | } 73 | 74 | public void unregister(MyEventListener myEventListener) { 75 | if (myEventListener != null) { 76 | myEventListeners.remove(myEventListener); 77 | } 78 | } 79 | 80 | public interface MyEventListener { 81 | void projectResolved(@NotNull Pair projectWithChanges, @Nullable NativeMavenProjectHolder nativeMavenProject); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/RefreshIconsAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper; 2 | 3 | import com.intellij.openapi.actionSystem.AnAction; 4 | import com.intellij.openapi.actionSystem.AnActionEvent; 5 | 6 | public class RefreshIconsAction extends AnAction { 7 | @Override 8 | public void actionPerformed(AnActionEvent e) { 9 | MavenHelperApplicationService.getInstance().initShortcuts(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/ShortcutStartupActivity.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import com.intellij.openapi.project.DumbAware; 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.openapi.startup.StartupActivity; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.concurrent.atomic.AtomicBoolean; 10 | 11 | public class ShortcutStartupActivity implements StartupActivity, DumbAware { 12 | private static final Logger LOG = com.intellij.openapi.diagnostic.Logger.getInstance(ShortcutStartupActivity.class); 13 | 14 | private static final AtomicBoolean registered = new AtomicBoolean(); 15 | 16 | @Override 17 | public void runActivity(@NotNull Project project) { 18 | if (registered.compareAndSet(false, true)) { 19 | MavenHelperApplicationService.getInstance().initShortcuts(); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/CreateCustomGoalAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.execution.actions.ConfigurationContext; 4 | import com.intellij.ide.util.PropertiesComponent; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import com.intellij.openapi.actionSystem.DataContext; 7 | import com.intellij.openapi.actionSystem.LangDataKeys; 8 | import com.intellij.openapi.project.Project; 9 | import com.intellij.psi.PsiFile; 10 | import krasa.mavenhelper.MavenHelperApplicationService; 11 | import krasa.mavenhelper.gui.GoalEditor; 12 | import krasa.mavenhelper.icons.MyIcons; 13 | import krasa.mavenhelper.model.ApplicationSettings; 14 | import krasa.mavenhelper.model.Goal; 15 | import org.apache.commons.lang3.StringUtils; 16 | import org.jetbrains.annotations.NotNull; 17 | import org.jetbrains.annotations.Nullable; 18 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 19 | import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; 20 | 21 | public class CreateCustomGoalAction extends MyAnAction { 22 | @Nullable 23 | protected MavenProjectInfo mavenProjectInfo; 24 | private boolean runGoal = true; 25 | 26 | public CreateCustomGoalAction() { 27 | } 28 | 29 | public CreateCustomGoalAction(@Nullable String text, @NotNull MavenProjectInfo mavenProjectInfo) { 30 | super(text); 31 | this.mavenProjectInfo = mavenProjectInfo; 32 | } 33 | 34 | @Override 35 | public void actionPerformed(AnActionEvent e) { 36 | MavenProjectInfo mavenProjectInfo = MavenProjectInfo.get(this.mavenProjectInfo, e); 37 | 38 | MavenHelperApplicationService instance = MavenHelperApplicationService.getInstance(); 39 | ApplicationSettings state = instance.getState(); 40 | 41 | DataContext context = e.getDataContext(); 42 | Project project = MavenActionUtil.getProject(context); 43 | String pomDir = Utils.getPomDirAsString(context, mavenProjectInfo); 44 | MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(context); 45 | PsiFile data = LangDataKeys.PSI_FILE.getData(e.getDataContext()); 46 | ConfigurationContext configurationContext = ConfigurationContext.getFromContext(e.getDataContext()); 47 | 48 | 49 | GoalEditor editor = new GoalEditor("Create and Run", "", state, true, e.getProject(), e.getDataContext()); 50 | if (editor.showAndGet()) { 51 | String s = editor.getCmd(); 52 | if (StringUtils.isNotBlank(s)) { 53 | 54 | Goal goal = new Goal(s); 55 | 56 | PropertiesComponent.getInstance().setValue(GoalEditor.SAVE, editor.isPersist(), true); 57 | if (editor.isPersist()) { 58 | state.getGoals().add(goal); 59 | instance.registerAction(goal, getRunGoalAction(goal, null)); 60 | } 61 | 62 | if (runGoal) { 63 | getRunGoalAction(goal, mavenProjectInfo).actionPerformed(project, pomDir, projectsManager, data, configurationContext, mavenProjectInfo); 64 | } 65 | } 66 | } 67 | 68 | } 69 | 70 | protected RunGoalAction getRunGoalAction(Goal goal, MavenProjectInfo mavenProject1) { 71 | return RunGoalAction.create(goal, MyIcons.PLUGIN_GOAL, false, mavenProject1); 72 | } 73 | 74 | 75 | @Override 76 | protected boolean isEnabled(AnActionEvent e) { 77 | return MavenProjectInfo.get(mavenProjectInfo, e).mavenProject != null; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/MainMavenActionGroup.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.execution.RunManager; 4 | import com.intellij.execution.RunnerAndConfigurationSettings; 5 | import com.intellij.execution.executors.DefaultRunExecutor; 6 | import com.intellij.icons.AllIcons; 7 | import com.intellij.openapi.actionSystem.*; 8 | import com.intellij.openapi.diagnostic.Logger; 9 | import com.intellij.openapi.project.DumbAware; 10 | import com.intellij.openapi.project.Project; 11 | import com.intellij.util.PathUtil; 12 | import krasa.mavenhelper.MavenHelperApplicationService; 13 | import krasa.mavenhelper.icons.MyIcons; 14 | import krasa.mavenhelper.model.ApplicationSettings; 15 | import krasa.mavenhelper.model.Goal; 16 | import org.jetbrains.annotations.NotNull; 17 | import org.jetbrains.annotations.Nullable; 18 | import org.jetbrains.idea.maven.execution.MavenRunConfiguration; 19 | import org.jetbrains.idea.maven.execution.MavenRunConfigurationType; 20 | import org.jetbrains.idea.maven.model.MavenPlugin; 21 | import org.jetbrains.idea.maven.project.actions.ReimportProjectAction; 22 | import org.jetbrains.idea.maven.utils.MavenArtifactUtil; 23 | import org.jetbrains.idea.maven.utils.MavenPluginInfo; 24 | 25 | import javax.swing.*; 26 | import java.util.ArrayList; 27 | import java.util.HashSet; 28 | import java.util.List; 29 | import java.util.Set; 30 | 31 | @SuppressWarnings("ComponentNotRegistered") 32 | public class MainMavenActionGroup extends ActionGroup implements DumbAware { 33 | static final Logger LOG = Logger.getInstance(MainMavenActionGroup.class); 34 | 35 | private Set pluginGoalsSet = new HashSet<>(); 36 | 37 | public MainMavenActionGroup() { 38 | } 39 | 40 | public MainMavenActionGroup(String shortName, Icon icon) { 41 | super(shortName, true); 42 | getTemplatePresentation().setIcon(icon); 43 | } 44 | 45 | @NotNull 46 | @Override 47 | public AnAction[] getChildren(@Nullable AnActionEvent e) { 48 | if (e != null) { 49 | return getActions(e.getDataContext(), e.getProject()); 50 | } else { 51 | return new AnAction[0]; 52 | } 53 | } 54 | 55 | public AnAction[] getActions(DataContext dataContext, Project project) { 56 | List result = new ArrayList<>(); 57 | MavenProjectInfo mavenProjectInfo = getMavenProject(dataContext); 58 | if (mavenProjectInfo.mavenProject != null) { 59 | addTestFile(result); 60 | separator(result); 61 | addRunConfigurations(result, project, mavenProjectInfo); 62 | separator(result); 63 | 64 | addGoals(result, mavenProjectInfo); 65 | separator(result); 66 | 67 | List mavenActionGroups = getPlugins(mavenProjectInfo); 68 | 69 | addPluginAwareActions(result, mavenActionGroups, mavenProjectInfo); 70 | separator(result); 71 | 72 | addPlugins(result, mavenActionGroups); 73 | 74 | separator(result); 75 | addReimport(result, mavenProjectInfo); 76 | result.add(getCreateCustomGoalAction(mavenProjectInfo)); 77 | 78 | } 79 | return result.toArray(new AnAction[result.size()]); 80 | } 81 | 82 | @NotNull 83 | protected MavenProjectInfo getMavenProject(DataContext dataContext) { 84 | return new MavenProjectInfo(Utils.getMavenProject(dataContext)); 85 | } 86 | 87 | private void addRunConfigurations(List result, Project project, final MavenProjectInfo mavenProject) { 88 | final List configurationSettings = RunManager.getInstance(project).getConfigurationSettingsList( 89 | MavenRunConfigurationType.getInstance()); 90 | 91 | String directory = PathUtil.getCanonicalPath(mavenProject.mavenProject.getDirectory()); 92 | 93 | for (RunnerAndConfigurationSettings cfg : configurationSettings) { 94 | MavenRunConfiguration mavenRunConfiguration = (MavenRunConfiguration) cfg.getConfiguration(); 95 | if (directory.equals(PathUtil.getCanonicalPath(mavenRunConfiguration.getRunnerParameters().getWorkingDirPath()))) { 96 | result.add(getRunConfigurationAction(project, cfg)); 97 | } 98 | } 99 | } 100 | 101 | protected AnAction getRunConfigurationAction(Project project, RunnerAndConfigurationSettings cfg) { 102 | return new RunConfigurationAction(DefaultRunExecutor.getRunExecutorInstance(), true, project, cfg); 103 | } 104 | 105 | private void addReimport(List result, MavenProjectInfo mavenProject) { 106 | final ReimportProjectAction e = new MyReimportProjectAction(mavenProject); 107 | e.getTemplatePresentation().setText("Reimport"); 108 | e.getTemplatePresentation().setIcon(AllIcons.Actions.Refresh); 109 | e.getTemplatePresentation().setDescription("Reimport selected Maven project"); 110 | result.add(e); 111 | 112 | } 113 | 114 | protected CreateCustomGoalAction getCreateCustomGoalAction(MavenProjectInfo mavenProject) { 115 | return new CreateCustomGoalAction("New Goal...", mavenProject); 116 | } 117 | 118 | protected void addTestFile(List result) { 119 | result.add(new RunTestFileAction()); 120 | } 121 | 122 | private void addPlugins(List anActions, List mavenActionGroups) { 123 | if (!mavenActionGroups.isEmpty()) { 124 | DefaultActionGroup plugins = new DefaultActionGroup("Plugins", true); 125 | for (DefaultActionGroup mavenActionGroup : mavenActionGroups) { 126 | plugins.add(mavenActionGroup); 127 | } 128 | anActions.add(plugins); 129 | } 130 | } 131 | 132 | private void separator(List anActions) { 133 | if (!anActions.isEmpty()) { 134 | AnAction anAction = anActions.get(anActions.size() - 1); 135 | if (!(anAction instanceof Separator)) { 136 | anActions.add(new Separator()); 137 | } 138 | } 139 | } 140 | 141 | private void addGoals(List anActions, MavenProjectInfo mavenProject) { 142 | for (Goal goal : getState().getGoals().getGoals()) { 143 | anActions.add(createGoalRunAction(goal, getRunIcon(), false, mavenProject)); 144 | } 145 | } 146 | 147 | 148 | private ApplicationSettings getState() { 149 | return MavenHelperApplicationService.getInstance().getState(); 150 | } 151 | 152 | private void addPluginAwareActions(List anActions, List mavenActionGroups, MavenProjectInfo mavenProject) { 153 | assert mavenActionGroups != null; // just to be sure that pluginGoalsSet was initialized 154 | for (Goal goal : getState().getPluginAwareGoals().getGoals()) { 155 | if (pluginGoalsSet.contains(goal.getCommandLine())) { 156 | anActions.add(createGoalRunAction(goal, getRunIcon(), false, mavenProject)); 157 | } 158 | } 159 | } 160 | 161 | private List getPlugins(MavenProjectInfo mavenProject) { 162 | List mavenActionGroups = new ArrayList<>(); 163 | List plugins = mavenProject.mavenProject.getDeclaredPlugins(); 164 | for (var mavenPlugin : plugins) { 165 | DefaultActionGroup plugin = new DefaultActionGroup(mavenPlugin.getArtifactId(), true); 166 | plugin.getTemplatePresentation().setIcon(getIcon()); 167 | addPluginGoals(mavenPlugin, plugin, mavenProject); 168 | mavenActionGroups.add(plugin); 169 | } 170 | 171 | return mavenActionGroups; 172 | } 173 | 174 | protected Icon getRunIcon() { 175 | return MyIcons.RUN_MAVEN_ICON; 176 | } 177 | 178 | protected Icon getIcon() { 179 | return MyIcons.PHASES_CLOSED; 180 | } 181 | 182 | private void addPluginGoals(MavenPlugin mavenPlugin, DefaultActionGroup pluginGroup, MavenProjectInfo mavenProject) { 183 | MavenPluginInfo pluginInfo = MavenArtifactUtil.readPluginInfo(mavenProject.mavenProject.getLocalRepository(), mavenPlugin.getMavenId()); 184 | if (pluginInfo != null) { 185 | for (MavenPluginInfo.Mojo mojo : pluginInfo.getMojos()) { 186 | pluginGoalsSet.add(mojo.getDisplayName()); 187 | pluginGroup.add(createGoalRunAction(new Goal(mojo.getDisplayName()), MyIcons.PLUGIN_GOAL, true, mavenProject)); 188 | } 189 | } 190 | } 191 | 192 | protected AnAction createGoalRunAction(Goal goal, final Icon icon, boolean plugin, MavenProjectInfo mavenProject) { 193 | return RunGoalAction.create(goal, icon, true, mavenProject); 194 | } 195 | 196 | @Override 197 | public void update(@NotNull AnActionEvent e) { 198 | super.update(e); 199 | e.getPresentation().setHideGroupIfEmpty(true); 200 | } 201 | 202 | @Override 203 | public @NotNull ActionUpdateThread getActionUpdateThread() { 204 | return ActionUpdateThread.BGT; 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/MavenProjectInfo.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import com.intellij.openapi.actionSystem.DataContext; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.idea.maven.project.MavenProject; 7 | 8 | public class MavenProjectInfo { 9 | 10 | MavenProject mavenProject; 11 | MavenProject childProject; 12 | boolean root; 13 | 14 | public MavenProjectInfo(MavenProject mavenProject) { 15 | this.mavenProject = mavenProject; 16 | } 17 | 18 | public MavenProjectInfo(DataContext dataContext) { 19 | this(Utils.getMavenProject(dataContext)); 20 | } 21 | 22 | public MavenProjectInfo(MavenProject root, MavenProject child) { 23 | this.mavenProject = root; 24 | this.childProject = child; 25 | this.root = true; 26 | } 27 | 28 | @NotNull 29 | public static MavenProjectInfo get(MavenProjectInfo info, AnActionEvent e) { 30 | MavenProjectInfo mavenProjectInfo = info; 31 | if (mavenProjectInfo == null) { 32 | mavenProjectInfo = new MavenProjectInfo(e.getDataContext()); 33 | } 34 | return mavenProjectInfo; 35 | } 36 | 37 | public MavenProject getCurrentOrRootMavenProject() { 38 | return childProject != null ? childProject : mavenProject; 39 | } 40 | 41 | public boolean isRoot() { 42 | return root; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "MavenProjectInfo{" + 48 | "mavenProject=" + mavenProject + 49 | ", root=" + root + 50 | '}'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/MyAnAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.openapi.actionSystem.ActionUpdateThread; 4 | import com.intellij.openapi.actionSystem.AnActionEvent; 5 | import com.intellij.openapi.actionSystem.Presentation; 6 | import com.intellij.openapi.project.DumbAwareAction; 7 | import com.intellij.openapi.util.NlsActions; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.Nullable; 10 | import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; 11 | 12 | import javax.swing.*; 13 | 14 | public abstract class MyAnAction extends DumbAwareAction { 15 | 16 | public MyAnAction() { 17 | } 18 | 19 | @Override 20 | public @NotNull ActionUpdateThread getActionUpdateThread() { 21 | return ActionUpdateThread.BGT; 22 | } 23 | 24 | public MyAnAction(@Nullable @NlsActions.ActionText String text, @Nullable @NlsActions.ActionDescription String description, @Nullable Icon icon) { 25 | super(text, description, icon); 26 | } 27 | 28 | 29 | public MyAnAction(@Nullable Icon icon) { 30 | super(icon); 31 | } 32 | 33 | public MyAnAction(@Nullable @NlsActions.ActionText String text) { 34 | super(text); 35 | } 36 | 37 | 38 | @Override 39 | public void update(AnActionEvent e) { 40 | super.update(e); 41 | Presentation p = e.getPresentation(); 42 | p.setEnabled(isEnabled(e)); 43 | p.setVisible(isVisible(e)); 44 | } 45 | 46 | protected boolean isVisible(AnActionEvent e) { 47 | return MavenActionUtil.isMavenizedProject(e.getDataContext()); 48 | } 49 | 50 | protected boolean isEnabled(AnActionEvent e) { 51 | return MavenActionUtil.hasProject(e.getDataContext()) && Utils.getMavenProject(e.getDataContext()) != null; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/MyReimportProjectAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import com.intellij.openapi.actionSystem.DataContext; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 7 | import org.jetbrains.idea.maven.project.actions.ReimportProjectAction; 8 | import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @author Vojtech Krasa 14 | */ 15 | class MyReimportProjectAction extends ReimportProjectAction { 16 | 17 | private final MavenProjectInfo mavenProjectInfo; 18 | 19 | public MyReimportProjectAction(@NotNull MavenProjectInfo mavenProjectInfo) { 20 | this.mavenProjectInfo = mavenProjectInfo; 21 | } 22 | 23 | @Override 24 | public void actionPerformed(AnActionEvent e) { 25 | final DataContext context = e.getDataContext(); 26 | MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(context); 27 | if (projectsManager != null) { 28 | perform(projectsManager, List.of(mavenProjectInfo.mavenProject), e); 29 | } 30 | } 31 | 32 | @Override 33 | protected boolean isAvailable(AnActionEvent e) { 34 | return mavenProjectInfo.mavenProject != null; 35 | } 36 | 37 | @Override 38 | protected boolean isVisible(AnActionEvent e) { 39 | return mavenProjectInfo.mavenProject != null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/OpenTerminalAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.ide.plugins.IdeaPluginDescriptor; 4 | import com.intellij.ide.plugins.PluginManager; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import com.intellij.openapi.actionSystem.Presentation; 7 | import com.intellij.openapi.extensions.PluginId; 8 | import com.intellij.openapi.project.Project; 9 | import com.intellij.openapi.vfs.VirtualFile; 10 | import org.jetbrains.plugins.terminal.TerminalView; 11 | 12 | public class OpenTerminalAction extends MyAnAction { 13 | 14 | private boolean pluginEnabled; 15 | 16 | public OpenTerminalAction() { 17 | pluginEnabled = isTerminalEnabled(); 18 | } 19 | 20 | @Override 21 | public void actionPerformed(AnActionEvent e) { 22 | Project project = getEventProject(e); 23 | if (project == null) { 24 | return; 25 | } 26 | VirtualFile fileByUrl = Utils.getPomDir(e); 27 | if (fileByUrl != null) { 28 | TerminalView.getInstance(project).openTerminalIn(fileByUrl); 29 | } 30 | } 31 | 32 | @Override 33 | public void update(AnActionEvent e) { 34 | Presentation p = e.getPresentation(); 35 | p.setEnabled(pluginEnabled && isEnabled(e)); 36 | p.setVisible(pluginEnabled && isVisible(e)); 37 | } 38 | 39 | public static boolean isTerminalEnabled() { 40 | IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId("org.jetbrains.plugins.terminal")); 41 | if (plugin != null) { 42 | return plugin.isEnabled(); 43 | } 44 | return false; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/QuickRunRootMavenGoalAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.execution.RunnerAndConfigurationSettings; 4 | import com.intellij.openapi.actionSystem.AnAction; 5 | import com.intellij.openapi.actionSystem.DataContext; 6 | import com.intellij.openapi.actionSystem.DefaultActionGroup; 7 | import com.intellij.openapi.diagnostic.Logger; 8 | import com.intellij.openapi.project.DumbAware; 9 | import com.intellij.openapi.project.Project; 10 | import com.intellij.openapi.ui.popup.JBPopupFactory; 11 | import krasa.mavenhelper.model.Goal; 12 | 13 | import javax.swing.*; 14 | import java.util.List; 15 | 16 | public class QuickRunRootMavenGoalAction extends QuickRunMavenGoalAction implements DumbAware { 17 | 18 | private final Logger LOG = Logger.getInstance("#" + getClass().getCanonicalName()); 19 | 20 | @Override 21 | protected void fillActions(final Project currentProject, DefaultActionGroup group, DataContext dataContext) { 22 | if (currentProject != null) { 23 | group.addAll(new RootMavenActionGroup() { 24 | 25 | @Override 26 | protected void addTestFile(List result) { 27 | QuickRunRootMavenGoalAction.this.addTestFile(result); 28 | } 29 | 30 | @Override 31 | protected AnAction getRunConfigurationAction(Project project, RunnerAndConfigurationSettings cfg) { 32 | return QuickRunRootMavenGoalAction.this.getRunConfigurationAction(project, cfg); 33 | } 34 | @Override 35 | protected AnAction createGoalRunAction(Goal goal, final Icon icon, boolean plugin, MavenProjectInfo mavenProject) { 36 | return QuickRunRootMavenGoalAction.this.createGoalRunAction(goal, icon, plugin, mavenProject); 37 | } 38 | }.getActions(dataContext, currentProject)); 39 | } 40 | } 41 | 42 | 43 | @Override 44 | protected JBPopupFactory.ActionSelectionAid getAidMethod() { 45 | return JBPopupFactory.ActionSelectionAid.SPEEDSEARCH; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/RootMavenActionGroup.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.openapi.actionSystem.DataContext; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.idea.maven.model.MavenId; 6 | import org.jetbrains.idea.maven.project.MavenProject; 7 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 8 | import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; 9 | 10 | import java.util.List; 11 | 12 | @SuppressWarnings("ComponentNotRegistered") 13 | public class RootMavenActionGroup extends MainMavenActionGroup { 14 | @NotNull 15 | @Override 16 | protected MavenProjectInfo getMavenProject(DataContext dataContext) { 17 | MavenProject childProject = Utils.getMavenProject(dataContext); 18 | MavenProject mavenProject = childProject; 19 | if (mavenProject == null) { 20 | return new MavenProjectInfo((MavenProject) null); 21 | } 22 | MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(dataContext); 23 | List rootProjects = projectsManager.getRootProjects(); 24 | 25 | MavenProject root = null; 26 | if (rootProjects.contains(mavenProject)) { 27 | root = mavenProject; 28 | } else { 29 | MavenId parentId = mavenProject.getParentId(); 30 | while (parentId != null) { 31 | mavenProject = projectsManager.findProject(parentId); 32 | if (mavenProject == null) { 33 | break; 34 | } 35 | if (rootProjects.contains(mavenProject)) { 36 | root = mavenProject; 37 | break; 38 | } 39 | parentId = mavenProject.getParentId(); 40 | } 41 | } 42 | 43 | return new MavenProjectInfo(root, childProject); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/RunConfigurationAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.execution.Executor; 4 | import com.intellij.execution.RunnerAndConfigurationSettings; 5 | import com.intellij.openapi.actionSystem.ActionUpdateThread; 6 | import com.intellij.openapi.actionSystem.AnActionEvent; 7 | import com.intellij.openapi.project.DumbAwareAction; 8 | import com.intellij.openapi.project.Project; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | /** 12 | * @author Vojtech Krasa 13 | */ 14 | public class RunConfigurationAction extends DumbAwareAction { 15 | 16 | protected final Executor myExecutor; 17 | protected final boolean myEnabled; 18 | protected final Project myProject; 19 | protected final RunnerAndConfigurationSettings mySettings; 20 | 21 | public RunConfigurationAction(Executor executor, 22 | boolean enabled, 23 | Project project, 24 | RunnerAndConfigurationSettings settings) { 25 | super(settings.getName(), null, executor.getIcon()); 26 | myExecutor = executor; 27 | myEnabled = enabled; 28 | myProject = project; 29 | mySettings = settings; 30 | } 31 | 32 | @Override 33 | public void actionPerformed(AnActionEvent event) { 34 | if (!myEnabled) return; 35 | ProgramRunnerUtils.executeConfiguration(myProject, myExecutor, mySettings); 36 | } 37 | 38 | @Override 39 | public void update(AnActionEvent e) { 40 | super.update(e); 41 | e.getPresentation().setEnabled(myEnabled); 42 | } 43 | 44 | @Override 45 | public @NotNull ActionUpdateThread getActionUpdateThread() { 46 | return ActionUpdateThread.BGT; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/RunGoalAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.execution.actions.ConfigurationContext; 4 | import com.intellij.openapi.actionSystem.AnActionEvent; 5 | import com.intellij.openapi.actionSystem.DataContext; 6 | import com.intellij.openapi.actionSystem.LangDataKeys; 7 | import com.intellij.openapi.project.Project; 8 | import com.intellij.psi.PsiFile; 9 | import krasa.mavenhelper.model.ApplicationSettings; 10 | import krasa.mavenhelper.model.Goal; 11 | import org.jetbrains.annotations.Nullable; 12 | import org.jetbrains.idea.maven.execution.MavenRunnerParameters; 13 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 14 | import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; 15 | 16 | import javax.swing.*; 17 | import java.util.List; 18 | 19 | public class RunGoalAction extends MyAnAction { 20 | 21 | private final Goal goal; 22 | @Nullable 23 | private final MavenProjectInfo mavenProjectInfo; 24 | 25 | protected RunGoalAction(Goal goal, String text, String description, Icon icon, @Nullable MavenProjectInfo mavenProjectInfo) { 26 | super(text, description, icon); 27 | this.goal = goal; 28 | this.mavenProjectInfo = mavenProjectInfo; 29 | } 30 | 31 | public static RunGoalAction create(Goal goal, Icon icon, boolean popupAction, MavenProjectInfo mavenProject) { 32 | if (popupAction) { 33 | return new RunGoalAction(goal, goal.getPresentableName(), goal.getCommandLine(), icon, mavenProject); 34 | } else { 35 | return new RunGoalAction(goal, "Run: " + goal.getPresentableName(), "Run: " + goal.getCommandLine(), icon, mavenProject); 36 | } 37 | } 38 | 39 | public Goal getGoal() { 40 | return goal; 41 | } 42 | 43 | @Override 44 | public void actionPerformed(AnActionEvent e) { 45 | final DataContext context = e.getDataContext(); 46 | MavenProjectInfo mavenProjectInfo = MavenProjectInfo.get(this.mavenProjectInfo, e); 47 | 48 | Project project = MavenActionUtil.getProject(context); 49 | String pomDir = Utils.getPomDirAsString(context, mavenProjectInfo); 50 | MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(context); 51 | PsiFile data = LangDataKeys.PSI_FILE.getData(e.getDataContext()); 52 | ConfigurationContext configurationContext = ConfigurationContext.getFromContext(e.getDataContext()); 53 | 54 | actionPerformed(project, pomDir, projectsManager, data, configurationContext, mavenProjectInfo); 55 | } 56 | 57 | public void actionPerformed(Project project, String pomDir, MavenProjectsManager projectsManager, PsiFile psiFile, ConfigurationContext configurationContext, MavenProjectInfo mavenProjectInfo) { 58 | if (pomDir != null) { 59 | List goalsToRun = goal.parse(psiFile, configurationContext, mavenProjectInfo, projectsManager); 60 | MavenRunnerParameters params = new MavenRunnerParameters(true, pomDir, null, goalsToRun, projectsManager.getExplicitProfiles()); 61 | params.setResolveToWorkspace(ApplicationSettings.get().isResolveWorkspaceArtifacts()); 62 | run(params, project); 63 | } 64 | } 65 | 66 | protected void run(MavenRunnerParameters params, Project project) { 67 | ProgramRunnerUtils.run(project, params); 68 | } 69 | 70 | @Override 71 | protected boolean isEnabled(AnActionEvent e) { 72 | return MavenProjectInfo.get(mavenProjectInfo, e).mavenProject != null; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/RunTestFileAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.execution.actions.ConfigurationContext; 4 | import com.intellij.openapi.actionSystem.*; 5 | import com.intellij.openapi.diagnostic.Logger; 6 | import com.intellij.openapi.project.DumbAwareAction; 7 | import com.intellij.openapi.project.DumbService; 8 | import com.intellij.openapi.project.Project; 9 | import com.intellij.openapi.ui.Messages; 10 | import com.intellij.openapi.vfs.VirtualFile; 11 | import com.intellij.psi.PsiClassOwner; 12 | import com.intellij.psi.PsiFile; 13 | import krasa.mavenhelper.analyzer.ComparableVersion; 14 | import krasa.mavenhelper.icons.MyIcons; 15 | import krasa.mavenhelper.model.ApplicationSettings; 16 | import org.apache.maven.shared.utils.io.MatchPatterns; 17 | import org.jdom.Element; 18 | import org.jetbrains.annotations.NotNull; 19 | import org.jetbrains.annotations.Nullable; 20 | import org.jetbrains.idea.maven.execution.MavenRunnerParameters; 21 | import org.jetbrains.idea.maven.model.MavenPlugin; 22 | import org.jetbrains.idea.maven.project.MavenProject; 23 | import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; 24 | 25 | import javax.swing.*; 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | public class RunTestFileAction extends DumbAwareAction { 30 | private final Logger LOG = Logger.getInstance("#" + getClass().getCanonicalName()); 31 | protected boolean alwaysVisible; 32 | 33 | public RunTestFileAction() { 34 | super("Test file", "Run current File with Maven", MyIcons.MAVEN_LOGO); 35 | } 36 | 37 | public RunTestFileAction(String text, @Nullable String description, @Nullable Icon icon) { 38 | super(text, description, icon); 39 | } 40 | 41 | @Override 42 | public @NotNull ActionUpdateThread getActionUpdateThread() { 43 | return ActionUpdateThread.BGT; 44 | } 45 | 46 | @Override 47 | public void actionPerformed(AnActionEvent e) { 48 | MavenProject mavenProject = Utils.getMavenProject(e.getDataContext()); 49 | if (mavenProject != null) { 50 | 51 | PsiFile psiFile = LangDataKeys.PSI_FILE.getData(e.getDataContext()); 52 | if (psiFile instanceof PsiClassOwner) { 53 | List goals = getGoals(e, (PsiClassOwner) psiFile, mavenProject); 54 | 55 | final DataContext context = e.getDataContext(); 56 | MavenRunnerParameters params = new MavenRunnerParameters(true, mavenProject.getDirectory(), null, goals, 57 | MavenActionUtil.getProjectsManager(context).getExplicitProfiles()); 58 | params.setResolveToWorkspace(ApplicationSettings.get().isResolveWorkspaceArtifacts()); 59 | run(context, params); 60 | } else { 61 | Messages.showWarningDialog(e.getProject(), "Cannot run for current file", "Maven Test File"); 62 | } 63 | } 64 | } 65 | 66 | protected void run(DataContext context, MavenRunnerParameters params) { 67 | Project project = MavenActionUtil.getProject(context); 68 | ProgramRunnerUtils.run(project, params); 69 | } 70 | 71 | protected List getGoals(AnActionEvent e, PsiClassOwner psiFile, MavenProject mavenProject) { 72 | List goals = new ArrayList(); 73 | boolean skipTests = isSkipTests(mavenProject); 74 | // so many possibilities... 75 | if (skipTests || isExcludedFromSurefire(psiFile, mavenProject)) { 76 | MavenPlugin failsafePlugin = mavenProject.findPlugin("org.apache.maven.plugins", "maven-failsafe-plugin"); 77 | if (failsafePlugin != null) { 78 | addFailSafeParameters(e, psiFile, goals, failsafePlugin); 79 | } else { 80 | addSurefireParameters(e, psiFile, goals); 81 | } 82 | goals.add("verify"); 83 | } else { 84 | addSurefireParameters(e, psiFile, goals); 85 | goals.add("test-compile"); 86 | goals.add("surefire:test"); 87 | } 88 | 89 | return goals; 90 | } 91 | 92 | private void addSurefireParameters(AnActionEvent e, PsiClassOwner psiFile, List goals) { 93 | goals.add("-Dtest=" + Utils.getTestArgument(psiFile, ConfigurationContext.getFromContext(e.getDataContext()))); 94 | } 95 | 96 | private void addFailSafeParameters(AnActionEvent e, PsiClassOwner psiFile, List goals, MavenPlugin mavenProjectPlugin) { 97 | ComparableVersion version = new ComparableVersion(mavenProjectPlugin.getVersion()); 98 | ComparableVersion minimumForMethodTest = new ComparableVersion("2.7.3"); 99 | if (minimumForMethodTest.compareTo(version) == 1) { 100 | goals.add("-Dit.test=" + Utils.getTestArgumentWithoutMethod(e, psiFile)); 101 | } else { 102 | goals.add("-Dit.test=" + Utils.getTestArgument(psiFile, ConfigurationContext.getFromContext(e.getDataContext()))); 103 | } 104 | } 105 | 106 | private boolean isExcludedFromSurefire(PsiClassOwner psiFile, MavenProject mavenProject) { 107 | boolean excluded = false; 108 | try { 109 | Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", 110 | "maven-surefire-plugin"); 111 | excluded = false; 112 | String fullName = null; 113 | if (pluginConfiguration != null) { 114 | Element excludes = pluginConfiguration.getChild("excludes"); 115 | if (excludes != null) { 116 | List exclude = excludes.getChildren("exclude"); 117 | for (Element element : exclude) { 118 | if (fullName == null) { 119 | fullName = getPsiFilePath(psiFile); 120 | } 121 | excluded = matchClassRegexPatter(fullName, element.getText()); 122 | if (excluded) { 123 | break; 124 | } 125 | } 126 | } 127 | } 128 | } catch (Exception e) { 129 | LOG.warn(e); 130 | } 131 | return excluded; 132 | } 133 | 134 | protected static boolean matchClassRegexPatter(String testClassFile, String classPattern) { 135 | return MatchPatterns.from(classPattern).matches(testClassFile, true); 136 | } 137 | 138 | @NotNull 139 | private String getPsiFilePath(PsiClassOwner psiFile) { 140 | String packageName = psiFile.getPackageName(); 141 | String fullName; 142 | if (packageName.isEmpty()) { 143 | fullName = psiFile.getName(); 144 | } else { 145 | fullName = packageName.replace(".", "/") + "/" + psiFile.getVirtualFile().getName(); 146 | } 147 | return fullName; 148 | } 149 | 150 | private boolean isSkipTests(MavenProject mavenProject) { 151 | Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", 152 | "maven-surefire-plugin"); 153 | boolean skipTests = false; 154 | if (pluginConfiguration != null) { 155 | Element skip; 156 | if ((skip = pluginConfiguration.getChild("skip")) != null) { 157 | skipTests = Boolean.parseBoolean(skip.getText()); 158 | } else if ((skip = pluginConfiguration.getChild("skipTests")) != null) { 159 | skipTests = Boolean.parseBoolean(skip.getText()); 160 | } 161 | } 162 | return skipTests; 163 | } 164 | 165 | @Override 166 | public void update(AnActionEvent e) { 167 | super.update(e); 168 | Project eventProject = getEventProject(e); 169 | if (eventProject == null) { 170 | return; 171 | } 172 | if (DumbService.isDumb(eventProject)) { 173 | Presentation p = e.getPresentation(); 174 | p.setVisible(false); 175 | return; 176 | } 177 | if (!MavenActionUtil.isMavenizedProject(e.getDataContext())) { 178 | Presentation p = e.getPresentation(); 179 | p.setVisible(false); 180 | return; 181 | } 182 | 183 | //TODO #71 perhaps by com.intellij.execution.actions.BaseRunConfigurationAction.fullUpdate 184 | PsiFile psiFile = PlatformDataKeys.PSI_FILE.getData(e.getDataContext()); 185 | boolean isTest = psiFile != null; 186 | boolean available = isAvailable(e); 187 | boolean visible = isVisible(e); 188 | 189 | Presentation p = e.getPresentation(); 190 | p.setEnabled(isTest && available); 191 | p.setVisible(alwaysVisible || (isTest && available)); 192 | if (isTest && available && visible) { 193 | VirtualFile virtualFile = psiFile.getVirtualFile(); 194 | String name; 195 | if (virtualFile != null) { 196 | name = virtualFile.getNameWithoutExtension(); 197 | } else { 198 | name = psiFile.getName(); 199 | } 200 | p.setText(getText(name)); 201 | } 202 | } 203 | 204 | protected String getText(String s) { 205 | return "Test " + s; 206 | } 207 | 208 | protected boolean isAvailable(AnActionEvent e) { 209 | boolean isFile = false; 210 | VirtualFile data = PlatformDataKeys.VIRTUAL_FILE.getData(e.getDataContext()); 211 | if (data != null) { 212 | isFile = !data.isDirectory(); 213 | } 214 | 215 | return isFile && MavenActionUtil.hasProject(e.getDataContext()); 216 | } 217 | 218 | protected boolean isVisible(AnActionEvent e) { 219 | MavenProject mavenProject = Utils.getMavenProject(e.getDataContext()); 220 | return mavenProject != null; 221 | } 222 | 223 | public AnAction alwaysVisible() { 224 | alwaysVisible = true; 225 | return this; 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/Utils.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import com.intellij.execution.RunnerAndConfigurationSettings; 4 | import com.intellij.execution.actions.ConfigurationContext; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import com.intellij.openapi.actionSystem.CommonDataKeys; 7 | import com.intellij.openapi.actionSystem.DataContext; 8 | import com.intellij.openapi.diagnostic.Logger; 9 | import com.intellij.openapi.vfs.VirtualFile; 10 | import com.intellij.openapi.vfs.VirtualFileManager; 11 | import com.intellij.psi.PsiClassOwner; 12 | import com.intellij.psi.PsiFile; 13 | import krasa.mavenhelper.model.ApplicationSettings; 14 | import org.apache.commons.lang3.StringUtils; 15 | import org.jetbrains.annotations.Nullable; 16 | import org.jetbrains.idea.maven.model.MavenConstants; 17 | import org.jetbrains.idea.maven.project.MavenProject; 18 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 19 | import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; 20 | 21 | import java.io.File; 22 | import java.util.List; 23 | 24 | import static org.apache.commons.lang3.StringUtils.isNotBlank; 25 | 26 | public class Utils { 27 | private static final Logger LOG = com.intellij.openapi.diagnostic.Logger.getInstance(Utils.class); 28 | public static final String NOT_RESOLVED = "NOT_RESOLVED"; 29 | 30 | static VirtualFile getPomDir(AnActionEvent e) { 31 | VirtualFile fileByUrl = null; 32 | String pomDir = getPomDirAsString(e.getDataContext(), null); 33 | if (pomDir != null) { 34 | fileByUrl = VirtualFileManager.getInstance().findFileByUrl("file://" + pomDir); 35 | 36 | } 37 | return fileByUrl; 38 | } 39 | 40 | @Nullable 41 | static String getPomDirAsString(DataContext dataContext, @Nullable MavenProjectInfo mavenProjectInfo) { 42 | ApplicationSettings state = ApplicationSettings.get(); 43 | 44 | 45 | String pomDir = null; 46 | if (mavenProjectInfo != null && mavenProjectInfo.root) { 47 | return mavenProjectInfo.mavenProject.getDirectory(); 48 | } 49 | if (state.isUseIgnoredPoms()) { 50 | VirtualFile data = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); 51 | if (data != null) { 52 | File focusedFile = new File(data.getPath()); 53 | pomDir = getNearbyPOMDir(focusedFile); 54 | } 55 | } else { 56 | MavenProject mavenProject = Utils.getMavenProject(dataContext); 57 | if (mavenProject != null) { 58 | pomDir = mavenProject.getDirectory(); 59 | } 60 | } 61 | return pomDir; 62 | } 63 | 64 | @Nullable 65 | public static MavenProject getMavenProject(DataContext context) { 66 | MavenProject mavenProject = MavenActionUtil.getMavenProject(context); 67 | if (mavenProject != null) { 68 | return mavenProject; 69 | } 70 | 71 | MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(context); 72 | if (projectsManager != null) { 73 | List projects = projectsManager.getProjects(); 74 | if (projects.size() == 1) { 75 | return projects.get(0); 76 | } 77 | } 78 | return null; 79 | } 80 | 81 | private static String getNearbyPOMDir(File focusFile) { 82 | if (focusFile == null || !focusFile.exists()) 83 | return null; 84 | File dir = (focusFile.isDirectory() ? focusFile : focusFile.getParentFile()); 85 | return isPomDir(dir) ? dir.getAbsolutePath() : getNearbyPOMDir(dir == null ? null : dir.getParentFile()); 86 | } 87 | 88 | private static boolean isPomDir(File file) { 89 | if (file == null || !file.exists() || !file.isDirectory()) 90 | return false; 91 | return new File(file.getAbsolutePath() + File.separator + MavenConstants.POM_XML).exists(); 92 | } 93 | 94 | public static String getTestArgument(@Nullable PsiFile psiFile, ConfigurationContext context) { 95 | RunnerAndConfigurationSettings configuration = context.getConfiguration(); 96 | String classAndMethod = null; 97 | if (configuration != null) { 98 | classAndMethod = configuration.getName().replace(".", "#"); 99 | } 100 | 101 | String result; 102 | String packageName = null; 103 | if (psiFile instanceof PsiClassOwner) { 104 | packageName = ((PsiClassOwner) psiFile).getPackageName(); 105 | } 106 | 107 | if (isNotBlank(packageName) && isNotBlank(classAndMethod)) { 108 | result = packageName + "." + classAndMethod; 109 | } else if (isNotBlank(classAndMethod)) { 110 | result = classAndMethod; 111 | } else { 112 | result = NOT_RESOLVED; 113 | } 114 | return result; 115 | } 116 | 117 | public static String getQualifiedName(@Nullable PsiFile psiFile) { 118 | String result = NOT_RESOLVED; 119 | 120 | if (psiFile != null) { 121 | String packageName = null; 122 | if (psiFile instanceof PsiClassOwner) { 123 | packageName = ((PsiClassOwner) psiFile).getPackageName(); 124 | } 125 | String name = psiFile.getName(); 126 | name = StringUtils.substringBefore(name, "."); 127 | 128 | if (isNotBlank(packageName) && isNotBlank(name)) { 129 | result = packageName + "." + name; 130 | } else if (isNotBlank(name)) { 131 | result = name; 132 | } 133 | } 134 | 135 | return result; 136 | } 137 | 138 | public static String getTestArgumentWithoutMethod(AnActionEvent e, PsiFile psiFile) { 139 | return StringUtils.substringBefore(getTestArgument(psiFile, ConfigurationContext.getFromContext(e.getDataContext())), "#"); 140 | } 141 | 142 | 143 | public static String limitLength(String text) { 144 | if (text == null) { 145 | return null; 146 | } 147 | 148 | int max = 200; 149 | if (text.length() > max) text = text.substring(0, max - 3) + "..."; 150 | return text; 151 | } 152 | 153 | 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/debug/CreateCustomDebugGoalAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action.debug; 2 | 3 | import krasa.mavenhelper.action.CreateCustomGoalAction; 4 | import krasa.mavenhelper.action.MavenProjectInfo; 5 | import krasa.mavenhelper.action.RunGoalAction; 6 | import krasa.mavenhelper.icons.MyIcons; 7 | import krasa.mavenhelper.model.Goal; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public class CreateCustomDebugGoalAction extends CreateCustomGoalAction { 11 | 12 | public CreateCustomDebugGoalAction(@Nullable String text, MavenProjectInfo mavenProject) { 13 | super(text, mavenProject); 14 | } 15 | 16 | @Override 17 | protected RunGoalAction getRunGoalAction(Goal goal, MavenProjectInfo mavenProject1) { 18 | return DebugGoalAction.createDebug(goal, MyIcons.ICON, false, mavenProject1); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/debug/Debug.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action.debug; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * @author Vojtech Krasa 8 | */ 9 | public class Debug { 10 | 11 | public static final List DEBUG_FORK_MODE = Arrays.asList("-DforkCount=0", "-DreuseForks=false"); 12 | 13 | public static final List DEBUG_FORK_MODE_LEGACY = Arrays.asList("-DforkMode=never", "-DforkCount=0", 14 | "-DreuseForks=false"); 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/debug/DebugConfigurationAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action.debug; 2 | 3 | import com.intellij.execution.Executor; 4 | import com.intellij.execution.RunnerAndConfigurationSettings; 5 | import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl; 6 | import com.intellij.openapi.actionSystem.ActionUpdateThread; 7 | import com.intellij.openapi.actionSystem.AnActionEvent; 8 | import com.intellij.openapi.project.Project; 9 | import krasa.mavenhelper.action.ProgramRunnerUtils; 10 | import krasa.mavenhelper.action.RunConfigurationAction; 11 | import org.jetbrains.annotations.NotNull; 12 | import org.jetbrains.idea.maven.execution.MavenRunConfiguration; 13 | 14 | /** 15 | * @author Vojtech Krasa 16 | */ 17 | public class DebugConfigurationAction extends RunConfigurationAction { 18 | public DebugConfigurationAction(Executor executor, boolean enabled, Project project, RunnerAndConfigurationSettings settings) { 19 | super(executor, enabled, project, settings); 20 | } 21 | 22 | @Override 23 | public void actionPerformed(final AnActionEvent event) { 24 | if (!myEnabled) return; 25 | 26 | final RunnerAndConfigurationSettings configurationSettings = clone(mySettings); 27 | addForkMode(configurationSettings); 28 | 29 | ProgramRunnerUtils.executeDebugConfiguration(myProject, myExecutor, configurationSettings); 30 | } 31 | 32 | private RunnerAndConfigurationSettings clone(RunnerAndConfigurationSettings configSettings) { 33 | RunnerAndConfigurationSettingsImpl runnerAndConfigurationSettings = (RunnerAndConfigurationSettingsImpl) configSettings; 34 | return runnerAndConfigurationSettings.clone(); 35 | } 36 | 37 | private void addForkMode(RunnerAndConfigurationSettings configSettings) { 38 | MavenRunConfiguration mavenRunConfiguration = (MavenRunConfiguration) configSettings.getConfiguration(); 39 | mavenRunConfiguration.getRunnerParameters().getGoals().addAll(Debug.DEBUG_FORK_MODE); 40 | } 41 | 42 | @Override 43 | public @NotNull ActionUpdateThread getActionUpdateThread() { 44 | return ActionUpdateThread.BGT; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/debug/DebugGoalAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action.debug; 2 | 3 | import com.intellij.openapi.actionSystem.AnAction; 4 | import com.intellij.openapi.project.Project; 5 | import krasa.mavenhelper.action.MavenProjectInfo; 6 | import krasa.mavenhelper.action.ProgramRunnerUtils; 7 | import krasa.mavenhelper.action.RunGoalAction; 8 | import krasa.mavenhelper.model.Goal; 9 | import org.jetbrains.idea.maven.execution.MavenRunnerParameters; 10 | 11 | import javax.swing.*; 12 | 13 | public class DebugGoalAction extends RunGoalAction { 14 | 15 | private DebugGoalAction(Goal goal, String text, String description, Icon icon, MavenProjectInfo mavenProject) { 16 | super(goal, text, description, icon, mavenProject); 17 | } 18 | 19 | public static DebugGoalAction createDebug(Goal goal, Icon icon, boolean popupAction, MavenProjectInfo mavenProject) { 20 | if (popupAction) { 21 | return new DebugGoalAction(goal, goal.getPresentableName(), goal.getCommandLine(), icon, mavenProject); 22 | } else { 23 | return new DebugGoalAction(goal, "Debug: " + goal.getPresentableName(), "Debug: " + goal.getCommandLine(), icon, mavenProject); 24 | } 25 | } 26 | 27 | public static AnAction createDebug(Goal goal, String name, Icon icon, MavenProjectInfo mavenProject) { 28 | return new DebugGoalAction(goal, name, "Debug: " + goal.getPresentableName(), icon, mavenProject); 29 | 30 | } 31 | 32 | @Override 33 | protected void run(final MavenRunnerParameters params, Project project) { 34 | params.getGoals().addAll(Debug.DEBUG_FORK_MODE); 35 | runInternal(project, params); 36 | } 37 | 38 | private void runInternal(final Project project, final MavenRunnerParameters params) { 39 | ProgramRunnerUtils.debugConfiguration(project, params, null); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/debug/DebugTestFileAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action.debug; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import com.intellij.openapi.actionSystem.DataContext; 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.psi.PsiClassOwner; 7 | import krasa.mavenhelper.action.ProgramRunnerUtils; 8 | import krasa.mavenhelper.action.RunTestFileAction; 9 | import krasa.mavenhelper.analyzer.ComparableVersion; 10 | import krasa.mavenhelper.icons.MyIcons; 11 | import org.jetbrains.idea.maven.execution.MavenRunnerParameters; 12 | import org.jetbrains.idea.maven.model.MavenPlugin; 13 | import org.jetbrains.idea.maven.project.MavenProject; 14 | import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; 15 | 16 | import java.util.List; 17 | 18 | public class DebugTestFileAction extends RunTestFileAction { 19 | 20 | public DebugTestFileAction() { 21 | super("Debug file", "Debug current File with Maven", MyIcons.ICON); 22 | } 23 | 24 | @Override 25 | protected String getText(String s) { 26 | return "Debug " + s; 27 | } 28 | 29 | @Override 30 | protected List getGoals(AnActionEvent e, PsiClassOwner psiFile, MavenProject mavenProject) { 31 | List goals = super.getGoals(e, psiFile, mavenProject); 32 | addParams(mavenProject, goals); 33 | return goals; 34 | } 35 | 36 | private void addParams(MavenProject mavenProject, List goals) { 37 | MavenPlugin surefire = mavenProject.findPlugin("org.apache.maven.plugins", "maven-surefire-plugin"); 38 | if (surefire != null) { 39 | ComparableVersion version = new ComparableVersion(surefire.getVersion()); 40 | if (new ComparableVersion("2.14").compareTo(version) >= 1) { 41 | goals.addAll(Debug.DEBUG_FORK_MODE_LEGACY); 42 | } else { 43 | goals.addAll(Debug.DEBUG_FORK_MODE); 44 | } 45 | } else { 46 | goals.addAll(Debug.DEBUG_FORK_MODE); 47 | } 48 | } 49 | 50 | @Override 51 | protected void run(final DataContext context, final MavenRunnerParameters params) { 52 | runInternal(MavenActionUtil.getProject(context), params); 53 | } 54 | 55 | private void runInternal(final Project project, final MavenRunnerParameters params) { 56 | ProgramRunnerUtils.debugConfiguration(project, params, null); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/action/debug/MainMavenDebugActionGroup.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action.debug; 2 | 3 | import com.intellij.execution.RunnerAndConfigurationSettings; 4 | import com.intellij.execution.executors.DefaultDebugExecutor; 5 | import com.intellij.openapi.actionSystem.AnAction; 6 | import com.intellij.openapi.project.Project; 7 | import krasa.mavenhelper.action.CreateCustomGoalAction; 8 | import krasa.mavenhelper.action.MainMavenActionGroup; 9 | import krasa.mavenhelper.action.MavenProjectInfo; 10 | import krasa.mavenhelper.action.RunConfigurationAction; 11 | import krasa.mavenhelper.icons.MyIcons; 12 | import krasa.mavenhelper.model.Goal; 13 | 14 | import javax.swing.*; 15 | import java.util.List; 16 | 17 | @SuppressWarnings("ComponentNotRegistered") 18 | public class MainMavenDebugActionGroup extends MainMavenActionGroup { 19 | 20 | public MainMavenDebugActionGroup(String shortName, final Icon pluginGoal) { 21 | super(shortName, pluginGoal); 22 | } 23 | 24 | @Override 25 | protected CreateCustomGoalAction getCreateCustomGoalAction(MavenProjectInfo mavenProject) { 26 | return new CreateCustomDebugGoalAction("New Goal...", mavenProject); 27 | } 28 | 29 | @Override 30 | protected void addTestFile(List result) { 31 | result.add(new DebugTestFileAction()); 32 | } 33 | 34 | @Override 35 | protected Icon getRunIcon() { 36 | return MyIcons.ICON; 37 | } 38 | 39 | @Override 40 | protected AnAction createGoalRunAction(Goal basicPhase, final Icon icon, boolean plugin, MavenProjectInfo mavenProject) { 41 | return DebugGoalAction.createDebug(basicPhase, icon, true, mavenProject); 42 | } 43 | 44 | @Override 45 | protected RunConfigurationAction getRunConfigurationAction(Project project, RunnerAndConfigurationSettings cfg) { 46 | return new DebugConfigurationAction(DefaultDebugExecutor.getDebugExecutorInstance(), true, project, cfg); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/DefaultArtifactVersion.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | /* 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | import java.util.StringTokenizer; 23 | 24 | /** 25 | * http://grepcode.com/file_/repo1.maven.org/maven2/org.apache.maven/maven-artifact/3.1.1/org/apache/maven/artifact/ 26 | * versioning/DefaultArtifactVersion.java/?v=source 27 | *

28 | * Default implementation of artifact versioning. 29 | * 30 | * @author Brett Porter 31 | */ 32 | public class DefaultArtifactVersion { 33 | private Integer majorVersion; 34 | 35 | private Integer minorVersion; 36 | 37 | private Integer incrementalVersion; 38 | 39 | private Integer buildNumber; 40 | 41 | private String qualifier; 42 | 43 | private ComparableVersion comparable; 44 | 45 | public DefaultArtifactVersion(String version) { 46 | parseVersion(version); 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | return 11 + comparable.hashCode(); 52 | } 53 | 54 | @Override 55 | public boolean equals(Object other) { 56 | if (this == other) { 57 | return true; 58 | } 59 | 60 | if (!(other instanceof DefaultArtifactVersion)) { 61 | return false; 62 | } 63 | 64 | return compareTo((DefaultArtifactVersion) other) == 0; 65 | } 66 | 67 | public int compareTo(DefaultArtifactVersion otherVersion) { 68 | if (otherVersion instanceof DefaultArtifactVersion) { 69 | return this.comparable.compareTo(otherVersion.comparable); 70 | } else { 71 | return compareTo(new DefaultArtifactVersion(otherVersion.toString())); 72 | } 73 | } 74 | 75 | public int getMajorVersion() { 76 | return majorVersion != null ? majorVersion : 0; 77 | } 78 | 79 | public int getMinorVersion() { 80 | return minorVersion != null ? minorVersion : 0; 81 | } 82 | 83 | public int getIncrementalVersion() { 84 | return incrementalVersion != null ? incrementalVersion : 0; 85 | } 86 | 87 | public int getBuildNumber() { 88 | return buildNumber != null ? buildNumber : 0; 89 | } 90 | 91 | public String getQualifier() { 92 | return qualifier; 93 | } 94 | 95 | public final void parseVersion(String version) { 96 | comparable = new ComparableVersion(version); 97 | 98 | int index = version.indexOf("-"); 99 | 100 | String part1; 101 | String part2 = null; 102 | 103 | if (index < 0) { 104 | part1 = version; 105 | } else { 106 | part1 = version.substring(0, index); 107 | part2 = version.substring(index + 1); 108 | } 109 | 110 | if (part2 != null) { 111 | try { 112 | if ((part2.length() == 1) || !part2.startsWith("0")) { 113 | buildNumber = Integer.valueOf(part2); 114 | } else { 115 | qualifier = part2; 116 | } 117 | } catch (NumberFormatException e) { 118 | qualifier = part2; 119 | } 120 | } 121 | 122 | if ((!part1.contains(".")) && !part1.startsWith("0")) { 123 | try { 124 | majorVersion = Integer.valueOf(part1); 125 | } catch (NumberFormatException e) { 126 | // qualifier is the whole version, including "-" 127 | qualifier = version; 128 | buildNumber = null; 129 | } 130 | } else { 131 | boolean fallback = false; 132 | 133 | StringTokenizer tok = new StringTokenizer(part1, "."); 134 | try { 135 | majorVersion = getNextIntegerToken(tok); 136 | if (tok.hasMoreTokens()) { 137 | minorVersion = getNextIntegerToken(tok); 138 | } 139 | if (tok.hasMoreTokens()) { 140 | incrementalVersion = getNextIntegerToken(tok); 141 | } 142 | if (tok.hasMoreTokens()) { 143 | fallback = true; 144 | } 145 | 146 | // string tokenzier won't detect these and ignores them 147 | if (part1.contains("..") || part1.startsWith(".") || part1.endsWith(".")) { 148 | fallback = true; 149 | } 150 | } catch (NumberFormatException e) { 151 | fallback = true; 152 | } 153 | 154 | if (fallback) { 155 | // qualifier is the whole version, including "-" 156 | qualifier = version; 157 | majorVersion = null; 158 | minorVersion = null; 159 | incrementalVersion = null; 160 | buildNumber = null; 161 | } 162 | } 163 | } 164 | 165 | private static Integer getNextIntegerToken(StringTokenizer tok) { 166 | String s = tok.nextToken(); 167 | if ((s.length() > 1) && s.startsWith("0")) { 168 | throw new NumberFormatException("Number part has a leading 0: '" + s + "'"); 169 | } 170 | return Integer.valueOf(s); 171 | } 172 | 173 | @Override 174 | public String toString() { 175 | StringBuilder buf = new StringBuilder(); 176 | if (majorVersion != null) { 177 | buf.append(majorVersion); 178 | } 179 | if (minorVersion != null) { 180 | buf.append("."); 181 | buf.append(minorVersion); 182 | } 183 | if (incrementalVersion != null) { 184 | buf.append("."); 185 | buf.append(incrementalVersion); 186 | } 187 | if (buildNumber != null) { 188 | buf.append("-"); 189 | buf.append(buildNumber); 190 | } else if (qualifier != null) { 191 | if (buf.length() > 0) { 192 | buf.append("-"); 193 | } 194 | buf.append(qualifier); 195 | } 196 | return buf.toString(); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/MyDefaultListModel.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import com.jgoodies.common.collect.ArrayListModel; 4 | 5 | import java.util.Comparator; 6 | 7 | public class MyDefaultListModel extends ArrayListModel { 8 | public static final Comparator DEEP_SIZE = new Comparator() { 9 | @Override 10 | public int compare(MyListNode t0, MyListNode t1) { 11 | return Long.compare(t1.getTotalSize(), t0.getTotalSize()); 12 | } 13 | }; 14 | public static final Comparator GROUP_ID = new Comparator() { 15 | @Override 16 | public int compare(MyListNode t0, MyListNode t1) { 17 | int i = t0.getGroupId().compareTo(t1.getGroupId()); 18 | if (i == 0) { 19 | i = t0.getArtifactId().compareTo(t1.getArtifactId()); 20 | } 21 | return i; 22 | } 23 | }; 24 | public static final Comparator ARTIFACT_ID = new Comparator() { 25 | @Override 26 | public int compare(MyListNode t0, MyListNode t1) { 27 | return t0.getArtifactId().compareTo(t1.getArtifactId()); 28 | } 29 | }; 30 | public static final Comparator SHALLOW_SIZE = new Comparator() { 31 | @Override 32 | public int compare(MyListNode t0, MyListNode t1) { 33 | return Long.compare(t1.getSize(), t0.getSize()); 34 | } 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/MyDefaultMutableTreeNode.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import org.jetbrains.idea.maven.model.MavenArtifact; 4 | 5 | import javax.swing.tree.DefaultMutableTreeNode; 6 | import java.util.Collections; 7 | import java.util.Comparator; 8 | import java.util.Enumeration; 9 | import java.util.Vector; 10 | 11 | public class MyDefaultMutableTreeNode extends DefaultMutableTreeNode { 12 | public static final Comparator DEEP_SIZE = new Comparator() { 13 | @Override 14 | public int compare(MyDefaultMutableTreeNode t0, MyDefaultMutableTreeNode t1) { 15 | MyTreeUserObject userObject0 = t0.getUserObject(); 16 | MyTreeUserObject userObject1 = t1.getUserObject(); 17 | return Long.compare(userObject1.getTotalSize(), userObject0.getTotalSize()); 18 | } 19 | }; 20 | 21 | public static final Comparator GROUP_ID = new Comparator() { 22 | @Override 23 | public int compare(MyDefaultMutableTreeNode t0, MyDefaultMutableTreeNode t1) { 24 | MavenArtifact a0 = t0.getUserObject().getArtifact(); 25 | MavenArtifact a1 = t1.getUserObject().getArtifact(); 26 | int i = a0.getGroupId().compareTo(a1.getGroupId()); 27 | if (i == 0) { 28 | i = a0.getArtifactId().compareTo(a1.getArtifactId()); 29 | } 30 | return i; 31 | } 32 | }; 33 | public static final Comparator ARTIFACT_ID = new Comparator() { 34 | @Override 35 | public int compare(MyDefaultMutableTreeNode t0, MyDefaultMutableTreeNode t1) { 36 | MavenArtifact a0 = t0.getUserObject().getArtifact(); 37 | MavenArtifact a1 = t1.getUserObject().getArtifact(); 38 | return a0.getArtifactId().compareTo(a1.getArtifactId()); 39 | } 40 | }; 41 | public static final Comparator SHALLOW_SIZE = new Comparator() { 42 | @Override 43 | public int compare(MyDefaultMutableTreeNode t0, MyDefaultMutableTreeNode t1) { 44 | MyTreeUserObject userObject0 = t0.getUserObject(); 45 | MyTreeUserObject userObject1 = t1.getUserObject(); 46 | return Long.compare(userObject1.getSize(), userObject0.getSize()); 47 | } 48 | }; 49 | 50 | public MyDefaultMutableTreeNode() { 51 | } 52 | 53 | public MyDefaultMutableTreeNode(Object userObject) { 54 | super(userObject); 55 | } 56 | 57 | public MyDefaultMutableTreeNode(Object userObject, boolean allowsChildren) { 58 | super(userObject, allowsChildren); 59 | } 60 | 61 | @Override 62 | public MyTreeUserObject getUserObject() { 63 | return (MyTreeUserObject) this.userObject; 64 | } 65 | 66 | public void sortBySize(Comparator comparator) { 67 | Vector children1 = children; 68 | if (children1 != null) { 69 | Collections.sort(children1, comparator); 70 | for (Object child : children1) { 71 | MyDefaultMutableTreeNode t1 = (MyDefaultMutableTreeNode) child; 72 | t1.sortBySize(comparator); 73 | } 74 | } 75 | } 76 | 77 | public Enumeration getChildren() { 78 | return (Enumeration) super.children(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/MyFileEditorProvider.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import com.intellij.openapi.fileEditor.FileEditor; 5 | import com.intellij.openapi.fileEditor.FileEditorPolicy; 6 | import com.intellij.openapi.fileEditor.FileEditorProvider; 7 | import com.intellij.openapi.fileEditor.FileEditorState; 8 | import com.intellij.openapi.project.DumbAware; 9 | import com.intellij.openapi.project.Project; 10 | import com.intellij.openapi.util.Disposer; 11 | import com.intellij.openapi.util.io.FileUtilRt; 12 | import com.intellij.openapi.vfs.VirtualFile; 13 | import com.intellij.util.ArrayUtil; 14 | import org.jdom.Element; 15 | import org.jetbrains.annotations.NotNull; 16 | import org.jetbrains.idea.maven.model.MavenConstants; 17 | import org.jetbrains.idea.maven.project.MavenProject; 18 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 19 | 20 | /** 21 | * @author Vojtech Krasa 22 | */ 23 | public class MyFileEditorProvider implements FileEditorProvider, DumbAware { 24 | private static final Logger LOG = Logger.getInstance("#krasa.mavenrun.analyzer.MyFileEditorProvider"); 25 | 26 | @Override 27 | public boolean accept(@NotNull final Project project, @NotNull final VirtualFile file) { 28 | return isPomFile(project, file); 29 | } 30 | 31 | 32 | private boolean isPomFile(@NotNull final Project project, @NotNull final VirtualFile file) { 33 | String name = file.getName(); 34 | if (!isPotentialPomFile(name)) return false; 35 | 36 | MavenProjectsManager instance = MavenProjectsManager.getInstance(project); 37 | final MavenProject mavenProject = instance == null ? null : instance.findProject(file); 38 | if (mavenProject != null) { 39 | return mavenProject.getFile().equals(file); 40 | } 41 | return false; 42 | } 43 | 44 | 45 | public static boolean isPotentialPomFile(String nameOrPath) { 46 | return ArrayUtil.contains(FileUtilRt.getExtension(nameOrPath), MavenConstants.POM_EXTENSIONS); 47 | } 48 | 49 | @Override 50 | @NotNull 51 | public FileEditor createEditor(@NotNull final Project project, @NotNull final VirtualFile file) { 52 | LOG.assertTrue(accept(project, file)); 53 | return new UIFormEditor(project, file); 54 | } 55 | 56 | @Override 57 | public void disposeEditor(@NotNull final FileEditor editor) { 58 | Disposer.dispose(editor); 59 | } 60 | 61 | @Override 62 | @NotNull 63 | public FileEditorState readState(@NotNull final Element element, @NotNull final Project project, 64 | @NotNull final VirtualFile file) { 65 | return UIFormEditor.MY_EDITOR_STATE; 66 | } 67 | 68 | @Override 69 | public void writeState(@NotNull final FileEditorState state, @NotNull final Project project, 70 | @NotNull final Element element) { 71 | } 72 | 73 | @Override 74 | @NotNull 75 | public String getEditorTypeId() { 76 | return "MavenHelperPluginDependencyAnalyzer"; 77 | } 78 | 79 | @Override 80 | @NotNull 81 | public FileEditorPolicy getPolicy() { 82 | return FileEditorPolicy.PLACE_AFTER_DEFAULT_EDITOR; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/MyHighlightingTree.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import com.intellij.openapi.actionSystem.CommonDataKeys; 4 | import com.intellij.openapi.actionSystem.DataProvider; 5 | import com.intellij.openapi.actionSystem.PlatformCoreDataKeys; 6 | import com.intellij.openapi.project.Project; 7 | import com.intellij.ui.JBColor; 8 | import com.intellij.ui.treeStructure.Tree; 9 | import com.intellij.util.ui.UIUtil; 10 | import krasa.mavenhelper.MavenHelperApplicationService; 11 | import krasa.mavenhelper.analyzer.action.BaseAction; 12 | import krasa.mavenhelper.model.ApplicationSettings; 13 | import org.jetbrains.annotations.NotNull; 14 | import org.jetbrains.annotations.Nullable; 15 | import org.jetbrains.idea.maven.project.MavenProject; 16 | 17 | import javax.swing.tree.DefaultMutableTreeNode; 18 | import java.awt.*; 19 | 20 | import static com.intellij.ui.ColorUtil.darker; 21 | import static com.intellij.ui.ColorUtil.softer; 22 | 23 | public class MyHighlightingTree extends Tree implements DataProvider { 24 | private Project project; 25 | private MavenProject mavenProject; 26 | 27 | public MyHighlightingTree() { 28 | setOpaque(false); 29 | } 30 | 31 | public void setProject(Project project) { 32 | this.project = project; 33 | } 34 | 35 | public void setMavenProject(MavenProject mavenProject) { 36 | this.mavenProject = mavenProject; 37 | } 38 | 39 | @Override 40 | public Color getFileColorFor(Object object) { 41 | if (object instanceof MyTreeUserObject) { 42 | if (((MyTreeUserObject) object).isHighlight()) { 43 | ApplicationSettings state = MavenHelperApplicationService.getInstance().getState(); 44 | if (UIUtil.isUnderDarcula()) { 45 | return darker(new JBColor(new Color(state.getSearchBackgroundColor()), new Color(state.getSearchBackgroundColor())), 8); 46 | } else { 47 | return softer(new JBColor(new Color(state.getSearchBackgroundColor()), new Color(state.getSearchBackgroundColor()))); 48 | } 49 | } 50 | } 51 | return super.getFileColorFor(object); 52 | } 53 | 54 | @Override 55 | public boolean isFileColorsEnabled() { 56 | return true; 57 | } 58 | 59 | @Nullable 60 | @Override 61 | public Object getData(String s) { 62 | try { 63 | if (PlatformCoreDataKeys.BGT_DATA_PROVIDER.is(s)) { 64 | return (DataProvider) slowId -> getSlowData(slowId); 65 | } 66 | 67 | return null; 68 | } catch (NoSuchFieldError e) { // https://github.com/krasa/MavenHelper/issues/111 java.lang.NoSuchFieldError: BGT_DATA_PROVIDER 69 | return getSlowData(s); 70 | } 71 | } 72 | 73 | private @Nullable Object getSlowData(@NotNull String s) { 74 | if (CommonDataKeys.NAVIGATABLE.is(s)) { 75 | final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) this.getLastSelectedPathComponent(); 76 | if (selectedNode == null) { 77 | return null; 78 | } 79 | if (project == null) { 80 | return null; 81 | } 82 | final MyTreeUserObject myTreeUserObject = (MyTreeUserObject) selectedNode.getUserObject(); 83 | return BaseAction.getNavigatable(myTreeUserObject.getMavenArtifactNode(), project, mavenProject); 84 | } 85 | 86 | return null; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/MyListNode.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 6 | import org.jetbrains.idea.maven.model.MavenArtifactState; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author Vojtech Krasa 13 | */ 14 | public class MyListNode { 15 | private static final Logger LOG = Logger.getInstance(MyListNode.class); 16 | 17 | protected final String artifactKey; 18 | private List artifacts; 19 | @Nullable 20 | protected MavenArtifactNode rightArtifact; 21 | protected boolean conflict; 22 | private Long size; 23 | private Long totalSize; 24 | private String groupId; 25 | private String artifactId; 26 | 27 | public MyListNode(Map.Entry> s) { 28 | artifactKey = s.getKey(); 29 | artifacts = s.getValue(); 30 | initRightArtifact(); 31 | initConflict(); 32 | } 33 | 34 | public List getArtifacts() { 35 | return artifacts; 36 | } 37 | 38 | @Nullable 39 | public MavenArtifactNode getRightArtifact() { 40 | return rightArtifact; 41 | } 42 | 43 | public long getSize() { 44 | if (size == null) { 45 | if (rightArtifact != null) { 46 | size = rightArtifact.getArtifact().getFile().length() / 1024; 47 | } else { 48 | size = -1L; 49 | } 50 | } 51 | return size; 52 | } 53 | 54 | public long getTotalSize() { 55 | if (totalSize == null) { 56 | totalSize = getTotalSize(rightArtifact); 57 | } 58 | return totalSize; 59 | } 60 | 61 | private long getTotalSize(MavenArtifactNode current) { 62 | if (current == null) { 63 | return -1; 64 | } 65 | long size = current.getArtifact().getFile().length() / 1024; 66 | for (MavenArtifactNode dependency : current.getDependencies()) { 67 | size += getTotalSize(dependency); 68 | } 69 | return size; 70 | } 71 | 72 | private void initRightArtifact() { 73 | if (artifacts != null && !artifacts.isEmpty()) { 74 | for (MavenArtifactNode mavenArtifactNode : artifacts) { 75 | 76 | groupId = mavenArtifactNode.getArtifact().getGroupId(); 77 | artifactId = mavenArtifactNode.getArtifact().getArtifactId(); 78 | 79 | if (mavenArtifactNode.getState() == MavenArtifactState.ADDED) { 80 | rightArtifact = mavenArtifactNode; 81 | break; 82 | } 83 | } 84 | if (LOG.isDebugEnabled()) { 85 | if (rightArtifact == null) { 86 | StringBuilder sb = new StringBuilder(artifactKey + "["); 87 | for (MavenArtifactNode artifact : artifacts) { 88 | sb.append(artifact.getArtifact()); 89 | sb.append("-"); 90 | sb.append(artifact.getState()); 91 | sb.append(";"); 92 | } 93 | sb.append("]"); 94 | 95 | LOG.debug(sb.toString()); 96 | } 97 | } 98 | 99 | } 100 | } 101 | 102 | private void initConflict() { 103 | if (artifacts != null && !artifacts.isEmpty()) { 104 | for (MavenArtifactNode mavenArtifactNode : artifacts) { 105 | if (Utils.isOmitted(mavenArtifactNode) || Utils.isConflictAlternativeMethod(mavenArtifactNode)) { 106 | conflict = true; 107 | break; 108 | } 109 | } 110 | } 111 | } 112 | 113 | public boolean isConflict() { 114 | return conflict; 115 | } 116 | 117 | @Nullable 118 | public String getRightVersion() { 119 | if (rightArtifact == null) { 120 | return null; 121 | } 122 | return rightArtifact.getArtifact().getVersion(); 123 | } 124 | 125 | @Override 126 | public String toString() { 127 | return artifactKey; 128 | } 129 | 130 | @Override 131 | public boolean equals(Object o) { 132 | if (this == o) 133 | return true; 134 | if (o == null || getClass() != o.getClass()) 135 | return false; 136 | 137 | MyListNode that = (MyListNode) o; 138 | 139 | if (artifactKey != null ? !artifactKey.equals(that.artifactKey) : that.artifactKey != null) 140 | return false; 141 | 142 | return true; 143 | } 144 | 145 | @Override 146 | public int hashCode() { 147 | return artifactKey != null ? artifactKey.hashCode() : 0; 148 | } 149 | 150 | public String getGroupId() { 151 | return groupId; 152 | } 153 | 154 | public String getArtifactId() { 155 | return artifactId; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/MyTreeUserObject.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import org.jetbrains.idea.maven.model.MavenArtifact; 4 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 5 | 6 | /** 7 | * @author Vojtech Krasa 8 | */ 9 | public class MyTreeUserObject { 10 | 11 | private MavenArtifactNode mavenArtifactNode; 12 | 13 | boolean showOnlyVersion = false; 14 | boolean highlight; 15 | private Long size; 16 | private Long totalSize; 17 | 18 | public MyTreeUserObject(MavenArtifactNode mavenArtifactNode) { 19 | this.mavenArtifactNode = mavenArtifactNode; 20 | } 21 | 22 | 23 | public MavenArtifact getArtifact() { 24 | return mavenArtifactNode.getArtifact(); 25 | } 26 | 27 | public MavenArtifactNode getMavenArtifactNode() { 28 | return mavenArtifactNode; 29 | } 30 | 31 | public boolean isHighlight() { 32 | return highlight; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return mavenArtifactNode.getArtifact().getArtifactId(); 38 | } 39 | 40 | public long getSize() { 41 | if (size == null) { 42 | size = getArtifact().getFile().length() / 1024; 43 | } 44 | return size; 45 | } 46 | 47 | public long getTotalSize() { 48 | if (totalSize == null) { 49 | totalSize = getTotalSize(mavenArtifactNode); 50 | } 51 | return totalSize; 52 | } 53 | 54 | private long getTotalSize(MavenArtifactNode current) { 55 | long size = current.getArtifact().getFile().length() / 1024; 56 | for (MavenArtifactNode dependency : current.getDependencies()) { 57 | size += getTotalSize(dependency); 58 | } 59 | return size; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/RestoreSelection.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import com.intellij.ui.components.JBList; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import javax.swing.tree.TreePath; 7 | import java.util.Enumeration; 8 | 9 | public class RestoreSelection { 10 | private MyListNode selectedListNode; 11 | @NotNull 12 | private final JBList leftPanelList; 13 | @NotNull 14 | private final MyHighlightingTree leftTree; 15 | private TreePath selectionPath; 16 | 17 | public RestoreSelection(JBList leftPanelList, MyHighlightingTree leftTree) { 18 | selectedListNode = (MyListNode) leftPanelList.getSelectedValue(); 19 | this.leftPanelList = leftPanelList; 20 | selectionPath = leftTree.getSelectionPath(); 21 | this.leftTree = leftTree; 22 | } 23 | 24 | public void restore() { 25 | if (selectedListNode != null) { 26 | MyDefaultListModel model = (MyDefaultListModel) leftPanelList.getModel(); 27 | for (MyListNode o : model) { 28 | if (o.getRightArtifact() != null && o.getRightArtifact().equals(selectedListNode.rightArtifact)) { 29 | leftPanelList.setSelectedValue(o, true); 30 | break; 31 | } 32 | } 33 | } 34 | 35 | if (selectionPath != null) { 36 | Object[] path = selectionPath.getPath(); 37 | MyDefaultMutableTreeNode root = (MyDefaultMutableTreeNode) leftTree.getModel().getRoot(); 38 | MyDefaultMutableTreeNode matchingNode = TreeUtils.getMatchingNode(path, root, 1); 39 | if (matchingNode != null && matchingNode != root) { 40 | leftTree.getSelectionModel().addSelectionPath(new TreePath(matchingNode.getPath())); 41 | leftTree.scrollPathToVisible(new TreePath(matchingNode.getPath())); 42 | } 43 | } 44 | } 45 | 46 | private void matches(MyDefaultMutableTreeNode o, MyDefaultMutableTreeNode root) { 47 | Enumeration children1 = root.getChildren(); 48 | while (children1.hasMoreElements()) { 49 | MyDefaultMutableTreeNode myDefaultMutableTreeNode = children1.nextElement(); 50 | MyTreeUserObject userObject = myDefaultMutableTreeNode.getUserObject(); 51 | MyTreeUserObject userObject1 = o.getUserObject(); 52 | if (userObject.getMavenArtifactNode().equals(userObject1.getMavenArtifactNode())) { 53 | 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/TreeRenderer.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import com.intellij.ui.ColoredTreeCellRenderer; 4 | import com.intellij.ui.JBColor; 5 | import com.intellij.ui.SimpleTextAttributes; 6 | import krasa.mavenhelper.MavenHelperApplicationService; 7 | import krasa.mavenhelper.model.ApplicationSettings; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.Nullable; 10 | import org.jetbrains.idea.maven.model.MavenArtifact; 11 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 12 | import org.jetbrains.idea.maven.model.MavenArtifactState; 13 | 14 | import javax.swing.*; 15 | import javax.swing.tree.DefaultMutableTreeNode; 16 | import java.awt.*; 17 | 18 | /** 19 | * @author Vojtech Krasa 20 | */ 21 | public class TreeRenderer extends ColoredTreeCellRenderer { 22 | 23 | private final JCheckBox showGroupId; 24 | private final JCheckBox showSize; 25 | private final GuiForm guiForm; 26 | 27 | private final SimpleTextAttributes testAttributes; 28 | private final SimpleTextAttributes testBoldAttributes; 29 | 30 | private final SimpleTextAttributes providedAttributes; 31 | private final SimpleTextAttributes providedBoldAttributes; 32 | 33 | private final SimpleTextAttributes runtimeAttributes; 34 | private final SimpleTextAttributes runtimeBoldAttributes; 35 | public static final SimpleTextAttributes ERROR_BOLD = MavenHelperApplicationService.getInstance().getState().getErrorAttributes().derive(SimpleTextAttributes.STYLE_BOLD, null, null, null); 36 | 37 | public TreeRenderer(JCheckBox showGroupId, JCheckBox showSize, GuiForm guiForm) { 38 | this.showGroupId = showGroupId; 39 | this.showSize = showSize; 40 | this.guiForm = guiForm; 41 | 42 | testAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, new JBColor(new Color(4, 111, 0), new Color(0x69AF80))); 43 | testBoldAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, testAttributes.getFgColor()); 44 | 45 | providedAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, new JBColor(new Color(0x02516D), new Color(0x028BBA))); 46 | providedBoldAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, providedAttributes.getFgColor()); 47 | 48 | runtimeAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, new JBColor(new Color(0x8D4E81), new Color(0xB264A5))); 49 | runtimeBoldAttributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, runtimeAttributes.getFgColor()); 50 | } 51 | 52 | @Override 53 | public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, 54 | int row, boolean hasFocus) { 55 | DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value; 56 | Object userObject = treeNode.getUserObject(); 57 | if (!(userObject instanceof MyTreeUserObject)) 58 | return; 59 | 60 | MyTreeUserObject myTreeUserObject = (MyTreeUserObject) userObject; 61 | final MavenArtifact artifact = myTreeUserObject.getArtifact(); 62 | 63 | String classifier = artifact.getClassifier(); 64 | if (classifier != null) { 65 | classifier = classifier + " - "; 66 | } else { 67 | classifier = ""; 68 | } 69 | MavenArtifactNode mavenArtifactNode = myTreeUserObject.getMavenArtifactNode(); 70 | boolean omitted = Utils.isOmitted(mavenArtifactNode); 71 | boolean conflict_AlternativeMethod = Utils.isConflictAlternativeMethod(mavenArtifactNode); 72 | boolean error = omitted || conflict_AlternativeMethod; 73 | boolean added = "ADDED".equals(mavenArtifactNode.getState().name()); 74 | String currentVersion = artifact.getVersion(); 75 | 76 | if (showSize.isSelected()) { 77 | Utils.appendSize(this, myTreeUserObject.getSize(), myTreeUserObject.getTotalSize()); 78 | } 79 | ApplicationSettings state = MavenHelperApplicationService.getInstance().getState(); 80 | if (myTreeUserObject.showOnlyVersion) { 81 | SimpleTextAttributes attributes = SimpleTextAttributes.REGULAR_ATTRIBUTES; 82 | SimpleTextAttributes versionAttributes = SimpleTextAttributes.REGULAR_ATTRIBUTES; 83 | if (added) { 84 | versionAttributes = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES; 85 | } 86 | 87 | if (error) { 88 | attributes = state.getErrorAttributes(); 89 | versionAttributes = state.getErrorAttributes(); 90 | } 91 | append(currentVersion, versionAttributes); 92 | append(" [" + classifier + artifact.getScope() + "]", attributes); 93 | 94 | checkForBug(myTreeUserObject); 95 | if (!omitted && conflict_AlternativeMethod) { 96 | conflict_AlternativeMethod(mavenArtifactNode, attributes, getConflictWinner(mavenArtifactNode)); 97 | } 98 | } else { 99 | SimpleTextAttributes attributes; 100 | SimpleTextAttributes boldAttributes; 101 | if (error) { 102 | attributes = state.getErrorAttributes(); 103 | boldAttributes = state.getErrorBoldAttributes(); 104 | } else if ("test".equals(myTreeUserObject.getArtifact().getScope())) { 105 | attributes = testAttributes; 106 | boldAttributes = testBoldAttributes; 107 | } else if ("provided".equals(myTreeUserObject.getArtifact().getScope())) { 108 | attributes = providedAttributes; 109 | boldAttributes = providedBoldAttributes; 110 | } else if ("runtime".equals(myTreeUserObject.getArtifact().getScope())) { 111 | attributes = runtimeAttributes; 112 | boldAttributes = runtimeBoldAttributes; 113 | } else if ("compile".equals(myTreeUserObject.getArtifact().getScope())) { 114 | attributes = SimpleTextAttributes.REGULAR_ATTRIBUTES; 115 | boldAttributes = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES; 116 | } else { 117 | attributes = SimpleTextAttributes.GRAYED_ATTRIBUTES; 118 | boldAttributes = SimpleTextAttributes.GRAYED_BOLD_ATTRIBUTES; 119 | } 120 | 121 | if (showGroupId.isSelected()) { 122 | append(artifact.getGroupId() + " : ", attributes); 123 | } 124 | append(artifact.getArtifactId(), boldAttributes); 125 | append(" : " + currentVersion, attributes); 126 | append(" [" + classifier + artifact.getScope() + "]", attributes); 127 | 128 | if (error) { 129 | String winner = getConflictWinner(mavenArtifactNode); 130 | 131 | if (omitted) { 132 | append(" (omitted for conflict with: " + winner + ")", attributes); 133 | checkForBug(myTreeUserObject); 134 | } else {//conflict_AlternativeMethod 135 | conflict_AlternativeMethod(mavenArtifactNode, attributes, winner); 136 | } 137 | } 138 | 139 | } 140 | 141 | } 142 | 143 | private void conflict_AlternativeMethod(MavenArtifactNode mavenArtifactNode, SimpleTextAttributes attributes, String realArtifact) { 144 | append(" (artifact state: " + mavenArtifactNode.getState() + ", conflict with: " + realArtifact, attributes); 145 | append(")", attributes); 146 | append(" - 2)", ERROR_BOLD); 147 | guiForm.falsePositive.setVisible(true); 148 | } 149 | 150 | @Nullable 151 | private String getConflictWinner(MavenArtifactNode mavenArtifactNode) { 152 | String realArtifact = "null"; 153 | MavenArtifact conflictWinner = mavenArtifactNode.getRelatedArtifact(); 154 | 155 | if (conflictWinner != null) { 156 | String realVersion; 157 | String realClassifier; 158 | realVersion = conflictWinner.getVersion(); 159 | realClassifier = conflictWinner.getClassifier(); 160 | String scope = conflictWinner.getScope(); 161 | if (realClassifier != null) { 162 | realClassifier = realClassifier + " - "; 163 | } else { 164 | realClassifier = ""; 165 | } 166 | realArtifact = realVersion; 167 | // realArtifact = realVersion + " [" + realClassifier + scope + "]"; 168 | } 169 | return realArtifact; 170 | } 171 | 172 | private void checkForBug(MyTreeUserObject myTreeUserObject) { 173 | MavenArtifactNode mavenArtifactNode = myTreeUserObject.getMavenArtifactNode(); 174 | if (mavenArtifactNode.getState() == MavenArtifactState.CONFLICT && !Utils.isVersionMismatch(myTreeUserObject.getMavenArtifactNode())) { 175 | append(" - 1)", ERROR_BOLD); 176 | guiForm.intellijBugLabel.setVisible(true); 177 | } 178 | } 179 | 180 | 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/TreeUtils.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 4 | 5 | import javax.swing.*; 6 | import javax.swing.tree.DefaultMutableTreeNode; 7 | import javax.swing.tree.DefaultTreeModel; 8 | import javax.swing.tree.TreeNode; 9 | import javax.swing.tree.TreePath; 10 | import java.util.*; 11 | 12 | public class TreeUtils { 13 | public static void expandAll(JTree rightTree) { 14 | expandAll(rightTree, new TreePath(((DefaultMutableTreeNode) rightTree.getModel().getRoot()).getPath())); 15 | } 16 | 17 | public static void expandAll(JTree tree, TreePath parent) { 18 | TreeNode node = (TreeNode) parent.getLastPathComponent(); 19 | if (node.getChildCount() >= 0) { 20 | for (Enumeration e = node.children(); e.hasMoreElements(); ) { 21 | TreeNode n = (TreeNode) e.nextElement(); 22 | TreePath path = parent.pathByAddingChild(n); 23 | expandAll(tree, path); 24 | } 25 | } 26 | tree.expandPath(parent); 27 | } 28 | 29 | public static void nodesChanged(DefaultTreeModel rightTreeModel) { 30 | DefaultMutableTreeNode root = (DefaultMutableTreeNode) rightTreeModel.getRoot(); 31 | Enumeration enumeration = root.breadthFirstEnumeration(); 32 | while (enumeration.hasMoreElements()) { 33 | DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode) enumeration.nextElement(); 34 | rightTreeModel.nodeChanged(defaultMutableTreeNode); 35 | } 36 | } 37 | 38 | public static void selectRows(MyHighlightingTree leftTree, MyDefaultMutableTreeNode root, MavenArtifactNode myArtifact) { 39 | List path = new ArrayList<>(); 40 | MavenArtifactNode node = myArtifact; 41 | while (node != null) { 42 | path.add(node); 43 | node = node.getParent(); 44 | if (path.size() > 1000) { 45 | throw new RuntimeException(path.toString()); 46 | } 47 | } 48 | Collections.reverse(path); 49 | MyDefaultMutableTreeNode matchingNode = getMatchingNode(path, root, 0); 50 | if (matchingNode != null && matchingNode != root) { 51 | leftTree.getSelectionModel().addSelectionPath(new TreePath(matchingNode.getPath())); 52 | leftTree.scrollPathToVisible(new TreePath(matchingNode.getPath())); 53 | } 54 | } 55 | 56 | 57 | public static MyDefaultMutableTreeNode getMatchingNode(List path, MyDefaultMutableTreeNode root, int i) { 58 | if (path.size() <= i) { 59 | return root; 60 | } 61 | MavenArtifactNode old = path.get(i); 62 | 63 | Enumeration children1 = root.getChildren(); 64 | while (children1.hasMoreElements()) { 65 | MyDefaultMutableTreeNode currentNode = children1.nextElement(); 66 | MyTreeUserObject userObject = currentNode.getUserObject(); 67 | if (userObject.getMavenArtifactNode().equals(old)) { 68 | return getMatchingNode(path, currentNode, i + 1); 69 | } 70 | } 71 | return null; 72 | } 73 | 74 | 75 | public static MyDefaultMutableTreeNode getMatchingNode(Object[] path, MyDefaultMutableTreeNode root, int i) { 76 | if (path.length <= i) { 77 | return root; 78 | } 79 | MyDefaultMutableTreeNode old = (MyDefaultMutableTreeNode) path[i]; 80 | 81 | Enumeration children1 = root.getChildren(); 82 | while (children1.hasMoreElements()) { 83 | MyDefaultMutableTreeNode currentNode = children1.nextElement(); 84 | MyTreeUserObject userObject = currentNode.getUserObject(); 85 | MyTreeUserObject userObject1 = old.getUserObject(); 86 | if (userObject.getMavenArtifactNode().equals(userObject1.getMavenArtifactNode())) { 87 | return getMatchingNode(path, currentNode, i + 1); 88 | } 89 | } 90 | return null; 91 | } 92 | 93 | 94 | public static String sortByVersion(List value) { 95 | Collections.sort(value, new Comparator() { 96 | @Override 97 | public int compare(MavenArtifactNode o1, MavenArtifactNode o2) { 98 | DefaultArtifactVersion version = new DefaultArtifactVersion(o1.getArtifact().getVersion()); 99 | DefaultArtifactVersion version1 = new DefaultArtifactVersion(o2.getArtifact().getVersion()); 100 | return version1.compareTo(version); 101 | } 102 | }); 103 | return value.get(0).getArtifact().getVersion(); 104 | } 105 | 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/UIFormEditor.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import com.intellij.codeHighlighting.BackgroundEditorHighlighter; 4 | import com.intellij.ide.structureView.StructureViewBuilder; 5 | import com.intellij.openapi.fileEditor.FileEditor; 6 | import com.intellij.openapi.fileEditor.FileEditorLocation; 7 | import com.intellij.openapi.fileEditor.FileEditorState; 8 | import com.intellij.openapi.fileEditor.FileEditorStateLevel; 9 | import com.intellij.openapi.project.Project; 10 | import com.intellij.openapi.util.UserDataHolderBase; 11 | import com.intellij.openapi.vfs.VirtualFile; 12 | import org.jetbrains.annotations.NotNull; 13 | import org.jetbrains.idea.maven.project.MavenProject; 14 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import javax.swing.*; 19 | import java.beans.PropertyChangeListener; 20 | 21 | public final class UIFormEditor extends UserDataHolderBase implements /* Navigatable */FileEditor { 22 | private static final Logger log = LoggerFactory.getLogger(UIFormEditor.class); 23 | 24 | public static final FileEditorState MY_EDITOR_STATE = new FileEditorState() { 25 | @Override 26 | public boolean canBeMergedWith(FileEditorState otherState, FileEditorStateLevel level) { 27 | return false; 28 | } 29 | }; 30 | private final VirtualFile file; 31 | private GuiForm myEditor; 32 | 33 | public UIFormEditor(@NotNull Project project, final VirtualFile file) { 34 | this.file = file; 35 | final MavenProject mavenProject = MavenProjectsManager.getInstance(project).findProject(file); 36 | if (mavenProject != null) { 37 | myEditor = new GuiForm(project, file, mavenProject); 38 | } else { 39 | log.warn("MavenProject not found for file " + file.getPath(), new RuntimeException()); 40 | } 41 | } 42 | 43 | @Override 44 | @NotNull 45 | public JComponent getComponent() { 46 | if (myEditor != null) { 47 | return myEditor.getRootComponent(); 48 | } 49 | return new JLabel("Unexpected error. Try it again."); 50 | } 51 | 52 | @Override 53 | public void dispose() { 54 | if (myEditor != null) { 55 | myEditor.dispose(); 56 | } 57 | } 58 | 59 | @Override 60 | public VirtualFile getFile() { 61 | return file; 62 | } 63 | 64 | @Override 65 | public JComponent getPreferredFocusedComponent() { 66 | if (myEditor != null) { 67 | return myEditor.getPreferredFocusedComponent(); 68 | } 69 | return null; 70 | } 71 | 72 | @Override 73 | @NotNull 74 | public String getName() { 75 | return "Dependency Analyzer"; 76 | } 77 | 78 | @Override 79 | public boolean isModified() { 80 | return false; 81 | } 82 | 83 | @Override 84 | public boolean isValid() { 85 | return true; 86 | } 87 | 88 | @Override 89 | public void selectNotify() { 90 | if (myEditor != null) { 91 | myEditor.selectNotify(); 92 | } 93 | } 94 | 95 | @Override 96 | public void deselectNotify() { 97 | } 98 | 99 | @Override 100 | public void addPropertyChangeListener(@NotNull final PropertyChangeListener listener) { 101 | } 102 | 103 | @Override 104 | public void removePropertyChangeListener(@NotNull final PropertyChangeListener listener) { 105 | } 106 | 107 | @Override 108 | public BackgroundEditorHighlighter getBackgroundHighlighter() { 109 | return null; 110 | } 111 | 112 | @Override 113 | public FileEditorLocation getCurrentLocation() { 114 | return null; 115 | } 116 | 117 | @Override 118 | @NotNull 119 | public FileEditorState getState(@NotNull final FileEditorStateLevel ignored) { 120 | return MY_EDITOR_STATE; 121 | } 122 | 123 | @Override 124 | public void setState(@NotNull final FileEditorState state) { 125 | } 126 | 127 | @Override 128 | public StructureViewBuilder getStructureViewBuilder() { 129 | return null; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/Utils.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import com.intellij.ui.SimpleColoredComponent; 5 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 6 | import org.jetbrains.idea.maven.model.MavenArtifactState; 7 | 8 | import java.text.DecimalFormat; 9 | import java.text.DecimalFormatSymbols; 10 | import java.text.NumberFormat; 11 | import java.util.Locale; 12 | 13 | public class Utils { 14 | private static final Logger LOG = com.intellij.openapi.diagnostic.Logger.getInstance(Utils.class); 15 | 16 | // myRelatedArtifact is a conflict winner, null means there was no conflict (probably) 17 | public static boolean isVersionMatch(MavenArtifactNode mavenArtifactNode) { 18 | return mavenArtifactNode.getRelatedArtifact() != null && mavenArtifactNode.getRelatedArtifact().getVersion().equals(mavenArtifactNode.getArtifact().getVersion()); 19 | } 20 | 21 | public static boolean isVersionMismatch(MavenArtifactNode mavenArtifactNode) { 22 | return mavenArtifactNode.getRelatedArtifact() != null && !mavenArtifactNode.getRelatedArtifact().getVersion().equals(mavenArtifactNode.getArtifact().getVersion()); 23 | } 24 | 25 | static boolean isOmitted(MavenArtifactNode mavenArtifactNode) { 26 | return mavenArtifactNode.getState() == MavenArtifactState.CONFLICT || isVersionMismatch(mavenArtifactNode); 27 | } 28 | 29 | static boolean isConflictAlternativeMethod(MavenArtifactNode mavenArtifactNode) { 30 | return mavenArtifactNode.getState() != MavenArtifactState.ADDED && mavenArtifactNode.getState() != MavenArtifactState.EXCLUDED && !isVersionMatch(mavenArtifactNode); 31 | } 32 | 33 | 34 | public static void appendSize(SimpleColoredComponent r, long size, long totalSize) { 35 | r.append(formatThousands(totalSize) + " KB (" + formatThousands(size) + " KB) - ", GuiForm.SIZE_ATTRIBUTES); 36 | } 37 | 38 | static String formatThousands(long l) { 39 | DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US); 40 | DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols(); 41 | symbols.setGroupingSeparator(' '); 42 | formatter.setDecimalFormatSymbols(symbols); 43 | return formatter.format(l); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/ExcludeDependencyAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.notification.Notification; 4 | import com.intellij.notification.NotificationType; 5 | import com.intellij.notification.Notifications; 6 | import com.intellij.openapi.actionSystem.AnActionEvent; 7 | import com.intellij.openapi.application.ApplicationManager; 8 | import com.intellij.openapi.command.CommandProcessor; 9 | import com.intellij.openapi.project.Project; 10 | import com.intellij.util.xml.DomFileElement; 11 | import org.jetbrains.idea.maven.dom.model.*; 12 | import org.jetbrains.idea.maven.model.MavenArtifact; 13 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 14 | import org.jetbrains.idea.maven.project.MavenProject; 15 | 16 | /** 17 | * @author Vojtech Krasa 18 | */ 19 | public abstract class ExcludeDependencyAction extends BaseAction { 20 | 21 | public ExcludeDependencyAction(Project project, MavenProject mavenProject, MavenArtifactNode myTreeNode) { 22 | super(project, mavenProject, myTreeNode, "Exclude"); 23 | } 24 | 25 | 26 | 27 | private void exclude() { 28 | final MavenArtifact artifactToExclude = myArtifact.getArtifact(); 29 | final MavenArtifactNode oldestParent = getOldestParentMavenArtifact(); 30 | 31 | DomFileElement domFileElement = getDomFileElement(oldestParent); 32 | 33 | if (domFileElement != null) { 34 | final MavenDomProjectModel rootElement = (MavenDomProjectModel) domFileElement.getRootElement(); 35 | final MavenDomDependencies dependencies = rootElement.getDependencies(); 36 | boolean found = false; 37 | 38 | for (MavenDomDependency mavenDomDependency : dependencies.getDependencies()) { 39 | boolean sameDependency = isSameDependency(oldestParent.getArtifact(), mavenDomDependency); 40 | if (!sameDependency) { 41 | debugLog(oldestParent.getArtifact(), mavenDomDependency); 42 | } 43 | if (sameDependency) { 44 | found = true; 45 | final MavenDomExclusions exclusions = mavenDomDependency.getExclusions(); 46 | for (MavenDomExclusion mavenDomExclusion : exclusions.getExclusions()) { 47 | if (isSameDependency(artifactToExclude, mavenDomExclusion)) { 48 | return; 49 | } 50 | } 51 | createExclusion(artifactToExclude, exclusions); 52 | dependencyExcluded(); 53 | } 54 | } 55 | if (!found) { 56 | final Notification notification = new Notification(MAVEN_HELPER_DEPENDENCY_ANALYZER_NOTIFICATION, "", 57 | "Parent dependency not found, it is probably in the parent pom", NotificationType.WARNING); 58 | ApplicationManager.getApplication().invokeLater(new Runnable() { 59 | @Override 60 | public void run() { 61 | Notifications.Bus.notify(notification, myProject); 62 | } 63 | }); 64 | } 65 | } 66 | } 67 | 68 | 69 | private void createExclusion(MavenArtifact artifactToExclude, MavenDomExclusions exclusions) { 70 | MavenDomExclusion exclusion = exclusions.addExclusion(); 71 | exclusion.getGroupId().setValue(artifactToExclude.getGroupId()); 72 | exclusion.getArtifactId().setValue(artifactToExclude.getArtifactId()); 73 | } 74 | 75 | @Override 76 | public void actionPerformed(AnActionEvent e) { 77 | // CommandProcessor for undo and formatting 78 | CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { 79 | @Override 80 | public void run() { 81 | ApplicationManager.getApplication().runWriteAction(new Runnable() { 82 | @Override 83 | public void run() { 84 | exclude(); 85 | } 86 | }); 87 | } 88 | }, "Exclude", "MavenRunHelper"); 89 | } 90 | 91 | public abstract void dependencyExcluded(); 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/JumpToLeftTreeAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import com.intellij.openapi.project.Project; 5 | import krasa.mavenhelper.analyzer.GuiForm; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 8 | import org.jetbrains.idea.maven.project.MavenProject; 9 | 10 | /** 11 | * @author Vojtech Krasa 12 | */ 13 | public class JumpToLeftTreeAction extends BaseAction { 14 | 15 | private final GuiForm guiForm; 16 | 17 | public JumpToLeftTreeAction(Project project, MavenProject mavenProject, MavenArtifactNode myTreeNode, GuiForm guiForm) { 18 | super(project, mavenProject, myTreeNode, getLabel()); 19 | this.guiForm = guiForm; 20 | } 21 | 22 | @NotNull 23 | private static String getLabel() { 24 | return "Jump to Left Tree"; 25 | } 26 | 27 | @Override 28 | public void actionPerformed(AnActionEvent e) { 29 | guiForm.switchToLeftTree(myArtifact); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/JumpToLeftTreeListAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import com.intellij.openapi.actionSystem.KeyboardShortcut; 5 | import com.intellij.openapi.actionSystem.Shortcut; 6 | import com.intellij.openapi.keymap.KeymapManager; 7 | import com.intellij.openapi.project.Project; 8 | import com.intellij.ui.KeyStrokeAdapter; 9 | import krasa.mavenhelper.analyzer.GuiForm; 10 | import org.jetbrains.annotations.NotNull; 11 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 12 | import org.jetbrains.idea.maven.project.MavenProject; 13 | 14 | /** 15 | * @author Vojtech Krasa 16 | */ 17 | public class JumpToLeftTreeListAction extends BaseAction { 18 | 19 | private final GuiForm guiForm; 20 | 21 | public JumpToLeftTreeListAction(Project project, MavenProject mavenProject, MavenArtifactNode myTreeNode, GuiForm guiForm) { 22 | super(project, mavenProject, myTreeNode, getLabel()); 23 | this.guiForm = guiForm; 24 | } 25 | 26 | @Override 27 | public void actionPerformed(AnActionEvent e) { 28 | guiForm.switchToLeftTree(myArtifact); 29 | } 30 | 31 | @NotNull 32 | private static String getLabel() { 33 | Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("EditSource"); 34 | if (shortcuts.length > 0) { 35 | Shortcut shortcut = shortcuts[0]; 36 | if (shortcut.isKeyboard()) { 37 | KeyboardShortcut key = (KeyboardShortcut) shortcut; 38 | String s = KeyStrokeAdapter.toString(key.getFirstKeyStroke()); 39 | if (s != null) { 40 | return "Jump to Left Tree [" + s.toUpperCase() + "]"; 41 | } 42 | } 43 | } 44 | return "Jump to Left Tree"; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/JumpToSourceAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.notification.Notification; 4 | import com.intellij.notification.NotificationType; 5 | import com.intellij.notification.Notifications; 6 | import com.intellij.openapi.actionSystem.AnActionEvent; 7 | import com.intellij.openapi.actionSystem.KeyboardShortcut; 8 | import com.intellij.openapi.actionSystem.Shortcut; 9 | import com.intellij.openapi.application.ApplicationManager; 10 | import com.intellij.openapi.application.ReadAction; 11 | import com.intellij.openapi.keymap.KeymapManager; 12 | import com.intellij.openapi.project.Project; 13 | import com.intellij.pom.Navigatable; 14 | import com.intellij.ui.KeyStrokeAdapter; 15 | import org.jetbrains.annotations.NotNull; 16 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 17 | import org.jetbrains.idea.maven.project.MavenProject; 18 | 19 | /** 20 | * @author Vojtech Krasa 21 | */ 22 | public class JumpToSourceAction extends BaseAction { 23 | 24 | public JumpToSourceAction(Project project, MavenProject mavenProject, MavenArtifactNode myTreeNode) { 25 | super(project, mavenProject, myTreeNode, getLabel()); 26 | } 27 | 28 | @NotNull 29 | private static String getLabel() { 30 | Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("EditSource"); 31 | if (shortcuts.length > 0) { 32 | Shortcut shortcut = shortcuts[0]; 33 | if (shortcut.isKeyboard()) { 34 | KeyboardShortcut key = (KeyboardShortcut) shortcut; 35 | String s = KeyStrokeAdapter.toString(key.getFirstKeyStroke()); 36 | if (s != null) { 37 | return "Jump to Source [" + s.toUpperCase() + "]"; 38 | } 39 | } 40 | } 41 | return "Jump to Source"; 42 | } 43 | 44 | @Override 45 | public void actionPerformed(AnActionEvent e) { 46 | ApplicationManager.getApplication().executeOnPooledThread(() -> { 47 | final Navigatable navigatable = ReadAction.compute(() -> getNavigatable(myArtifact, myProject, myMavenProject)); 48 | if (navigatable != null && navigatable.canNavigate()) { 49 | ApplicationManager.getApplication().invokeLater(() -> { 50 | navigatable.navigate(true); 51 | }); 52 | } else { 53 | final Notification notification = new Notification(MAVEN_HELPER_DEPENDENCY_ANALYZER_NOTIFICATION, "", "Parent dependency not found, strange...", 54 | NotificationType.WARNING); 55 | ApplicationManager.getApplication().invokeLater(() -> Notifications.Bus.notify(notification, myProject)); 56 | } 57 | }); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/LeftTreePopupHandler.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.openapi.actionSystem.ActionManager; 4 | import com.intellij.openapi.actionSystem.DefaultActionGroup; 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.ui.PopupHandler; 7 | import krasa.mavenhelper.analyzer.MyTreeUserObject; 8 | import org.jetbrains.idea.maven.model.MavenArtifact; 9 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 10 | import org.jetbrains.idea.maven.project.MavenProject; 11 | 12 | import javax.swing.*; 13 | import javax.swing.tree.DefaultMutableTreeNode; 14 | import javax.swing.tree.DefaultTreeModel; 15 | import java.awt.*; 16 | import java.util.ArrayList; 17 | import java.util.Enumeration; 18 | 19 | /** 20 | * @author Vojtech Krasa 21 | */ 22 | public class LeftTreePopupHandler extends PopupHandler { 23 | private final Project project; 24 | private final MavenProject mavenProject; 25 | protected final JTree tree; 26 | private JPopupMenu popup; 27 | 28 | public LeftTreePopupHandler(Project project, MavenProject mavenProject, JTree tree) { 29 | this.project = project; 30 | this.mavenProject = mavenProject; 31 | this.tree = tree; 32 | } 33 | 34 | private DefaultMutableTreeNode getRoot() { 35 | return (DefaultMutableTreeNode) getModel().getRoot(); 36 | } 37 | 38 | private DefaultTreeModel getModel() { 39 | return (DefaultTreeModel) tree.getModel(); 40 | } 41 | 42 | @Override 43 | @SuppressWarnings("Duplicates") 44 | public void invokePopup(final Component comp, final int x, final int y) { 45 | final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); 46 | if (selectedNode == null) { 47 | return; 48 | } 49 | final MyTreeUserObject myTreeUserObject = (MyTreeUserObject) selectedNode.getUserObject(); 50 | final MavenArtifactNode mavenArtifactNode = myTreeUserObject.getMavenArtifactNode(); 51 | DefaultActionGroup actionGroup = new DefaultActionGroup(); 52 | 53 | if (myTreeUserObject.getMavenArtifactNode().getParent() == null) { 54 | actionGroup.add(new JumpToSourceAction(project, mavenProject, mavenArtifactNode)); 55 | actionGroup.add(new RemoveDependencyAction(project, mavenProject, mavenArtifactNode) { 56 | @Override 57 | public void dependencyDeleted() { 58 | getModel().removeNodeFromParent(selectedNode); 59 | } 60 | }); 61 | } else { 62 | actionGroup.add(new JumpToSourceAction(project, mavenProject, mavenArtifactNode)); 63 | actionGroup.add(new ExcludeDependencyAction(project, mavenProject, mavenArtifactNode) { 64 | 65 | @Override 66 | public void dependencyExcluded() {// 67 | // root 68 | // | d1 69 | // | L d2 70 | // | | L d3 71 | // | L d3 72 | // L ... 73 | // After d3 is excluded; remove d3 in the whole subtree. 74 | // getModel().removeNodeFromParent(selectedNode); 75 | 76 | DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) selectedNode.getPath()[1]; 77 | Enumeration enumeration = treeNode.breadthFirstEnumeration(); 78 | MavenArtifact excludedArtifact = myArtifact.getArtifact(); 79 | java.util.List toRemove = new ArrayList(); 80 | while (enumeration.hasMoreElements()) { 81 | DefaultMutableTreeNode o = (DefaultMutableTreeNode) enumeration.nextElement(); 82 | MyTreeUserObject userObject = (MyTreeUserObject) o.getUserObject(); 83 | MavenArtifact artifact = userObject.getArtifact(); 84 | if (artifact.getArtifactId().equals(excludedArtifact.getArtifactId()) 85 | && artifact.getGroupId().equals(excludedArtifact.getGroupId())) { 86 | toRemove.add(o); 87 | } 88 | } 89 | for (DefaultMutableTreeNode node : toRemove) { 90 | getModel().removeNodeFromParent(node); 91 | } 92 | 93 | } 94 | }); 95 | } 96 | popup = ActionManager.getInstance().createActionPopupMenu("MavenHelper", actionGroup).getComponent(); 97 | popup.show(comp, x, y); 98 | } 99 | 100 | public void hidePopup() { 101 | if (popup != null && popup.isVisible()) { 102 | popup.setVisible(false); 103 | popup = null; 104 | } 105 | } 106 | 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/ListKeyStrokeAdapter.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.openapi.actionSystem.KeyboardShortcut; 4 | import com.intellij.openapi.actionSystem.Shortcut; 5 | import com.intellij.openapi.keymap.KeymapManager; 6 | import com.intellij.ui.KeyStrokeAdapter; 7 | import krasa.mavenhelper.analyzer.GuiForm; 8 | 9 | import javax.swing.*; 10 | import java.awt.event.KeyEvent; 11 | 12 | public class ListKeyStrokeAdapter extends KeyStrokeAdapter { 13 | private final GuiForm guiForm; 14 | 15 | public ListKeyStrokeAdapter(GuiForm guiForm) { 16 | this.guiForm = guiForm; 17 | } 18 | 19 | @Override 20 | public void keyPressed(KeyEvent event) { 21 | Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("EditSource"); 22 | if (shortcuts.length > 0) { 23 | Shortcut shortcut = shortcuts[0]; 24 | if (shortcut.isKeyboard()) { 25 | KeyboardShortcut key = (KeyboardShortcut) shortcut; 26 | KeyStroke firstKeyStroke = key.getFirstKeyStroke(); 27 | KeyStroke keyStrokeForEvent = KeyStroke.getKeyStrokeForEvent(event); 28 | if (keyStrokeForEvent.equals(firstKeyStroke)) { 29 | guiForm.switchToLeftTree(); 30 | } 31 | } 32 | } 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/ListPopupHandler.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.openapi.actionSystem.ActionManager; 4 | import com.intellij.openapi.actionSystem.DefaultActionGroup; 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.ui.PopupHandler; 7 | import com.intellij.ui.components.JBList; 8 | import krasa.mavenhelper.analyzer.GuiForm; 9 | import krasa.mavenhelper.analyzer.MyListNode; 10 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 11 | import org.jetbrains.idea.maven.project.MavenProject; 12 | 13 | import javax.swing.*; 14 | import java.awt.*; 15 | 16 | /** 17 | * @author Vojtech Krasa 18 | */ 19 | public class ListPopupHandler extends PopupHandler { 20 | private final Project project; 21 | private final MavenProject mavenProject; 22 | protected final JBList list; 23 | private final GuiForm guiForm; 24 | private JPopupMenu popup; 25 | 26 | public ListPopupHandler(Project project, MavenProject mavenProject, JBList list, GuiForm guiForm) { 27 | this.project = project; 28 | this.mavenProject = mavenProject; 29 | this.list = list; 30 | this.guiForm = guiForm; 31 | } 32 | 33 | @Override 34 | @SuppressWarnings("Duplicates") 35 | public void invokePopup(final Component comp, final int x, final int y) { 36 | final MyListNode selectedNode = (MyListNode) list.getSelectedValue(); 37 | if (selectedNode == null) { 38 | return; 39 | } 40 | final MavenArtifactNode mavenArtifactNode = selectedNode.getRightArtifact(); 41 | if (mavenArtifactNode == null) { 42 | return; 43 | } 44 | 45 | DefaultActionGroup actionGroup = new DefaultActionGroup(); 46 | actionGroup.add(new JumpToLeftTreeListAction(project, mavenProject, mavenArtifactNode, guiForm)); 47 | popup = ActionManager.getInstance().createActionPopupMenu("MavenHelper", actionGroup).getComponent(); 48 | popup.show(comp, x, y); 49 | } 50 | 51 | public void hidePopup() { 52 | if (popup != null && popup.isVisible()) { 53 | popup.setVisible(false); 54 | popup = null; 55 | } 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/RemoveDependencyAction.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.notification.Notification; 4 | import com.intellij.notification.NotificationType; 5 | import com.intellij.notification.Notifications; 6 | import com.intellij.openapi.actionSystem.AnActionEvent; 7 | import com.intellij.openapi.application.ApplicationManager; 8 | import com.intellij.openapi.command.CommandProcessor; 9 | import com.intellij.openapi.project.Project; 10 | import com.intellij.util.xml.DomFileElement; 11 | import org.jetbrains.idea.maven.dom.model.MavenDomDependencies; 12 | import org.jetbrains.idea.maven.dom.model.MavenDomDependency; 13 | import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel; 14 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 15 | import org.jetbrains.idea.maven.project.MavenProject; 16 | 17 | /** 18 | * @author Vojtech Krasa 19 | */ 20 | public class RemoveDependencyAction extends BaseAction { 21 | 22 | public RemoveDependencyAction(Project project, MavenProject mavenProject, MavenArtifactNode myTreeNode) { 23 | super(project, mavenProject, myTreeNode, "Remove"); 24 | } 25 | 26 | private void exclude() { 27 | DomFileElement domFileElement = getDomFileElement(myArtifact); 28 | 29 | if (domFileElement != null) { 30 | final MavenDomProjectModel rootElement = (MavenDomProjectModel) domFileElement.getRootElement(); 31 | final MavenDomDependencies dependencies = rootElement.getDependencies(); 32 | boolean found = false; 33 | 34 | for (MavenDomDependency mavenDomDependency : dependencies.getDependencies()) { 35 | boolean sameDependency = isSameDependency(myArtifact.getArtifact(), mavenDomDependency); 36 | if (!sameDependency) { 37 | debugLog(myArtifact.getArtifact(), mavenDomDependency); 38 | } 39 | if (sameDependency) { 40 | found = true; 41 | mavenDomDependency.undefine(); 42 | dependencyDeleted(); 43 | } 44 | } 45 | if (!found) { 46 | final Notification notification = new Notification(MAVEN_HELPER_DEPENDENCY_ANALYZER_NOTIFICATION, "", 47 | "Parent dependency not found, it is probably in the parent pom", NotificationType.WARNING); 48 | ApplicationManager.getApplication().invokeLater(new Runnable() { 49 | @Override 50 | public void run() { 51 | Notifications.Bus.notify(notification, myProject); 52 | } 53 | }); 54 | } 55 | } 56 | } 57 | 58 | @Override 59 | public void actionPerformed(AnActionEvent e) { 60 | // CommandProcessor for undo and formatting 61 | CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { 62 | @Override 63 | public void run() { 64 | ApplicationManager.getApplication().runWriteAction(new Runnable() { 65 | @Override 66 | public void run() { 67 | exclude(); 68 | } 69 | }); 70 | } 71 | }, "Remove", "MavenRunHelper"); 72 | } 73 | 74 | public void dependencyDeleted() { 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/analyzer/action/RightTreePopupHandler.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.analyzer.action; 2 | 3 | import com.intellij.openapi.actionSystem.ActionManager; 4 | import com.intellij.openapi.actionSystem.DefaultActionGroup; 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.ui.PopupHandler; 7 | import krasa.mavenhelper.analyzer.GuiForm; 8 | import krasa.mavenhelper.analyzer.MyTreeUserObject; 9 | import org.jetbrains.idea.maven.model.MavenArtifactNode; 10 | import org.jetbrains.idea.maven.project.MavenProject; 11 | 12 | import javax.swing.*; 13 | import javax.swing.tree.DefaultMutableTreeNode; 14 | import javax.swing.tree.DefaultTreeModel; 15 | import javax.swing.tree.MutableTreeNode; 16 | import javax.swing.tree.TreeNode; 17 | import java.awt.*; 18 | import java.util.ArrayList; 19 | import java.util.Enumeration; 20 | 21 | /** 22 | * @author Vojtech Krasa 23 | */ 24 | public class RightTreePopupHandler extends PopupHandler { 25 | private final Project project; 26 | private final MavenProject mavenProject; 27 | protected final JTree tree; 28 | private final GuiForm guiForm; 29 | private JPopupMenu popup; 30 | 31 | public RightTreePopupHandler(Project project, MavenProject mavenProject, JTree tree, GuiForm guiForm) { 32 | this.project = project; 33 | this.mavenProject = mavenProject; 34 | this.tree = tree; 35 | this.guiForm = guiForm; 36 | } 37 | 38 | private DefaultMutableTreeNode getRoot() { 39 | return (DefaultMutableTreeNode) getModel().getRoot(); 40 | } 41 | 42 | private DefaultTreeModel getModel() { 43 | return (DefaultTreeModel) tree.getModel(); 44 | } 45 | 46 | @Override 47 | @SuppressWarnings("Duplicates") 48 | public void invokePopup(final Component comp, final int x, final int y) { 49 | final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); 50 | if (selectedNode == null) { 51 | return; 52 | } 53 | final MyTreeUserObject myTreeUserObject = (MyTreeUserObject) selectedNode.getUserObject(); 54 | final MavenArtifactNode mavenArtifactNode = myTreeUserObject.getMavenArtifactNode(); 55 | DefaultActionGroup actionGroup = new DefaultActionGroup(); 56 | 57 | if (myTreeUserObject.getMavenArtifactNode().getParent() == null) { 58 | actionGroup.add(new JumpToLeftTreeAction(project, mavenProject, mavenArtifactNode, guiForm)); 59 | actionGroup.add(new JumpToSourceAction(project, mavenProject, mavenArtifactNode)); 60 | } else { 61 | actionGroup.add(new JumpToLeftTreeAction(project, mavenProject, mavenArtifactNode, guiForm)); 62 | actionGroup.add(new JumpToSourceAction(project, mavenProject, mavenArtifactNode)); 63 | actionGroup.add(getExcludeAction(selectedNode, mavenArtifactNode)); 64 | } 65 | 66 | popup = ActionManager.getInstance().createActionPopupMenu("MavenHelper", actionGroup).getComponent(); 67 | popup.show(comp, x, y); 68 | } 69 | 70 | public void hidePopup() { 71 | if (popup != null && popup.isVisible()) { 72 | popup.setVisible(false); 73 | popup = null; 74 | } 75 | } 76 | 77 | private ExcludeDependencyAction getExcludeAction(final DefaultMutableTreeNode selectedNode, 78 | MavenArtifactNode mavenArtifactNode) { 79 | return new ExcludeDependencyAction(project, mavenProject, mavenArtifactNode) { 80 | @Override 81 | public void dependencyExcluded() { 82 | removeTreeNodes(); 83 | } 84 | 85 | private void removeTreeNodes() { 86 | // imagine conflict for d3 87 | // root 88 | // L d1 89 | // | L d2 90 | // | | L d3 91 | // | L d3 92 | // L ... something else containing d3 93 | // After d3 is excluded; must remove d2 and also d1 from the tree. But when d2 is excluded, remove only 94 | // d2. 95 | 96 | if (selectedNode.getParent() == null) { 97 | throw new IllegalStateException("selectedNode.getParent() == null " + selectedNode); 98 | } 99 | 100 | if (selectedNode.getParent() != getRoot()) { 101 | removeNodeNearestToRoot(selectedNode); 102 | return; 103 | } 104 | 105 | // find d1 106 | DefaultMutableTreeNode oldestParentDependency = (DefaultMutableTreeNode) selectedNode.getFirstChild(); 107 | while (oldestParentDependency.getChildCount() > 0) { 108 | oldestParentDependency = (DefaultMutableTreeNode) oldestParentDependency.getFirstChild(); 109 | } 110 | // find d1, d2 111 | java.util.List leafsForRemoval = findAllLeafs((MyTreeUserObject) oldestParentDependency.getUserObject()); 112 | // remove both d3s for d1 and d2 113 | for (DefaultMutableTreeNode defaultMutableTreeNode : leafsForRemoval) { 114 | removeNodeNearestToRoot(defaultMutableTreeNode); 115 | } 116 | } 117 | 118 | private void removeNodeNearestToRoot(DefaultMutableTreeNode nodeForRemoval) { 119 | TreeNode nodeForRemovalNearestToRoot = nodeForRemoval; 120 | while (nodeForRemovalNearestToRoot.getParent() != null 121 | && nodeForRemovalNearestToRoot.getParent().getParent() != null //https://github.com/krasa/MavenHelper/issues/58 122 | && nodeForRemovalNearestToRoot.getParent() != getRoot()) { 123 | nodeForRemovalNearestToRoot = nodeForRemovalNearestToRoot.getParent(); 124 | } 125 | getModel().removeNodeFromParent((MutableTreeNode) nodeForRemovalNearestToRoot); 126 | } 127 | 128 | private java.util.List findAllLeafs(MyTreeUserObject userObject) { 129 | final ArrayList result = new ArrayList(); 130 | visitAllNodes(getRoot(), userObject, result); 131 | return result; 132 | } 133 | 134 | private void visitAllNodes(DefaultMutableTreeNode node, MyTreeUserObject lookedUpObject, 135 | ArrayList result) { 136 | 137 | if (node.getChildCount() > 0) { 138 | for (Enumeration e = node.children(); e.hasMoreElements(); ) { 139 | DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement(); 140 | visitAllNodes(n, lookedUpObject, result); 141 | } 142 | } else { 143 | // only leafs 144 | process(node, lookedUpObject, result); 145 | } 146 | } 147 | 148 | private void process(DefaultMutableTreeNode node, MyTreeUserObject lookedUpObject, 149 | ArrayList result) { 150 | final MyTreeUserObject userObject = (MyTreeUserObject) node.getUserObject(); 151 | if (userObject != null && lookedUpObject.getArtifact().equals(userObject.getArtifact())) { 152 | result.add(node); 153 | } 154 | } 155 | }; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/AliasEditor.form: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
50 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/AliasEditor.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.gui; 2 | 3 | import com.intellij.openapi.ui.DialogWrapper; 4 | import com.intellij.ui.DocumentAdapter; 5 | import krasa.mavenhelper.model.ApplicationSettings; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | import javax.swing.*; 10 | import javax.swing.event.DocumentEvent; 11 | 12 | public class AliasEditor extends DialogWrapper { 13 | private JTextField fromField; 14 | private JPanel myPanel; 15 | private final Validator myValidator; 16 | private GoalEditor goalEditor; 17 | 18 | public interface Validator { 19 | boolean isOK(String name, String value); 20 | } 21 | 22 | public AliasEditor(String title, String macroName, String value, Validator validator) { 23 | super(true); 24 | setTitle(title); 25 | myValidator = validator; 26 | 27 | goalEditor = new GoalEditor(null, value, ApplicationSettings.get(), false, null, null) { 28 | @Override 29 | protected void updateControls() { 30 | if (goalEditor != null) { 31 | AliasEditor.this.updateControls(); 32 | } 33 | } 34 | }; 35 | goalEditor.commandLineLabel.setText("To:"); 36 | //noinspection deprecation 37 | fromField.setNextFocusableComponent(goalEditor.getPreferredFocusedComponent()); 38 | 39 | fromField.getDocument().addDocumentListener(new DocumentAdapter() { 40 | @Override 41 | public void textChanged(@NotNull DocumentEvent event) { 42 | updateControls(); 43 | } 44 | }); 45 | 46 | fromField.setText(macroName); 47 | init(); 48 | updateControls(); 49 | } 50 | 51 | private void updateControls() { 52 | getOKAction().setEnabled(myValidator.isOK(getFrom(), getTo())); 53 | } 54 | 55 | @Override 56 | public JComponent getPreferredFocusedComponent() { 57 | return fromField; 58 | } 59 | 60 | @Override 61 | protected String getHelpId() { 62 | return null; 63 | } 64 | 65 | @Override 66 | protected void doOKAction() { 67 | if (!myValidator.isOK(getFrom(), getTo())) return; 68 | super.doOKAction(); 69 | } 70 | 71 | public String getFrom() { 72 | return fromField.getText().trim(); 73 | } 74 | 75 | public String getTo() { 76 | return goalEditor.getCmd(); 77 | } 78 | 79 | @Override 80 | protected JComponent createNorthPanel() { 81 | return myPanel; 82 | } 83 | 84 | @Override 85 | protected JComponent createCenterPanel() { 86 | return goalEditor.createCenterPanel(); 87 | } 88 | 89 | @Override 90 | @Nullable 91 | protected String getDimensionServiceKey() { 92 | // return null; 93 | return GoalEditor.DIMENSION; 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/AliasRealEditor.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.gui; 2 | 3 | import com.intellij.ide.util.PropertiesComponent; 4 | import com.intellij.openapi.ui.DialogWrapper; 5 | import com.intellij.openapi.ui.popup.JBPopupFactory; 6 | import com.intellij.ui.CheckBoxList; 7 | import com.intellij.ui.components.JBScrollPane; 8 | import com.intellij.ui.components.JBTextField; 9 | import com.intellij.util.ui.FormBuilder; 10 | import com.intellij.util.ui.JBUI; 11 | import krasa.mavenhelper.action.MavenProjectInfo; 12 | import krasa.mavenhelper.model.ApplicationSettings; 13 | import org.apache.commons.collections.CollectionUtils; 14 | import org.apache.commons.collections.MapUtils; 15 | import org.apache.commons.lang3.StringUtils; 16 | import org.apache.commons.lang3.Validate; 17 | import org.jetbrains.annotations.NotNull; 18 | import org.jetbrains.annotations.Nullable; 19 | import org.jetbrains.idea.maven.project.MavenProject; 20 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 21 | 22 | import javax.swing.*; 23 | import java.util.*; 24 | import java.util.regex.Matcher; 25 | import java.util.regex.Pattern; 26 | import java.util.stream.Collectors; 27 | import java.util.stream.IntStream; 28 | 29 | /** 30 | * Class Name is AliasRealEditor 31 | * 32 | * @author LiJun 33 | * Created on 2024/6/25 17:28 34 | */ 35 | public class AliasRealEditor extends DialogWrapper { 36 | 37 | private static final String PROPERTIES_KEY = "MavenHelper.AliasRealEditor."; 38 | 39 | private static final Set ALIAS = Set.of(ApplicationSettings.MODULES, ApplicationSettings.VERSION); 40 | 41 | // $xxx$ pattern 42 | private static final Pattern REGEX = Pattern.compile("\\$(.*?)\\$"); 43 | 44 | private CheckBoxList modules = null; 45 | private JBTextField versionField; 46 | private List versionSuggests; 47 | private final Map editorFields; 48 | private final MavenProject mavenProject; 49 | 50 | public AliasRealEditor(String command, @NotNull MavenProjectInfo mavenProjectInfo, @NotNull MavenProjectsManager manager) { 51 | super(false); 52 | MavenProject mavenProject = Validate.notNull(mavenProjectInfo.getCurrentOrRootMavenProject(), "Maven project not found"); 53 | this.mavenProject = mavenProject; 54 | if (command.contains(ApplicationSettings.MODULES)) { 55 | Collection projects = manager.findInheritors(mavenProject); 56 | this.modules = new CheckBoxList<>(); 57 | this.modules.setItems(new ArrayList<>(projects), MavenProject::getDisplayName); 58 | List lastSelected = PropertiesComponent.getInstance().getList(PROPERTIES_KEY + mavenProject.getDisplayName()); 59 | // history 60 | if (CollectionUtils.isNotEmpty(lastSelected)) { 61 | Set lastSelectedSet = new HashSet<>(lastSelected); 62 | for (MavenProject project : projects) { 63 | if (lastSelectedSet.contains(project.getDisplayName())) { 64 | this.modules.setItemSelected(project, true); 65 | } 66 | } 67 | } else { 68 | projects.forEach(p -> modules.setItemSelected(p, true)); 69 | } 70 | } 71 | if (command.contains(ApplicationSettings.VERSION)) { 72 | String version = StringUtils.defaultString(mavenProject.getMavenId().getVersion()); 73 | this.versionField = new JBTextField(version); 74 | this.versionSuggests = new ArrayList<>(); 75 | this.versionSuggests.add(version); 76 | if (StringUtils.endsWith(version, "-SNAPSHOT")) { 77 | this.versionSuggests.add(StringUtils.removeEnd(version, "-SNAPSHOT")); 78 | this.versionSuggests.add(version.substring(0, version.length() - 9) + "-preon-SNAPSHOT"); 79 | this.versionSuggests.add(version.substring(0, version.length() - 9) + "-PREON-SNAPSHOT"); 80 | } else { 81 | this.versionSuggests.add(version + "-SNAPSHOT"); 82 | } 83 | } 84 | editorFields = new LinkedHashMap<>(); 85 | Matcher matcher = REGEX.matcher(command); 86 | while (matcher.find()) { 87 | String field = matcher.group(0); 88 | if (!editorFields.containsKey(field)) { 89 | editorFields.put(field, new JBTextField()); 90 | } 91 | } 92 | setTitle("Edit Custom Info..."); 93 | init(); 94 | } 95 | 96 | public static boolean needEditor(String command) { 97 | if (StringUtils.isBlank(command)) { 98 | return false; 99 | } 100 | if (ALIAS.stream().anyMatch(command::contains)) { 101 | return true; 102 | } 103 | Matcher matcher = REGEX.matcher(command); 104 | if (matcher.find()) { 105 | return true; 106 | } 107 | return false; 108 | } 109 | 110 | public static String alias(String command, @NotNull MavenProjectInfo mavenProjectInfo, MavenProjectsManager manager) { 111 | if (null == manager || !needEditor(command)) { 112 | return command; 113 | } 114 | AliasRealEditor editor = new AliasRealEditor(command, mavenProjectInfo, manager); 115 | if (editor.showAndGet()) { 116 | if (command.contains(ApplicationSettings.MODULES)) { 117 | String project = editor.getSelectModules().stream().map(MavenProject::getDisplayName).collect(Collectors.joining(",")); 118 | command = command.replace(ApplicationSettings.MODULES, project); 119 | } 120 | if (command.contains(ApplicationSettings.VERSION)) { 121 | String version = editor.versionField.getText(); 122 | command = command.replace(ApplicationSettings.VERSION, version); 123 | } 124 | } 125 | return command; 126 | } 127 | 128 | @Override 129 | protected @Nullable JComponent createCenterPanel() { 130 | FormBuilder builder = FormBuilder.createFormBuilder(); 131 | if (null != modules) { 132 | // builder.addComponent(new JLabel("$modules$")); 133 | builder.addLabeledComponentFillVertically("$modules$ = ", modules); 134 | } 135 | if (null != versionField) { 136 | versionField.setPreferredSize(JBUI.size(200, 30)); 137 | builder.addComponent(versionField); 138 | BorderLayoutPanel panel = BorderLayoutPanel.getInstance(0, 0).center(versionField).right(suggestButton()); 139 | builder.addLabeledComponent("$version$ = ", panel); 140 | } 141 | if (MapUtils.isNotEmpty(editorFields)) { 142 | editorFields.forEach(builder::addLabeledComponent); 143 | } 144 | builder.addVerticalGap(-1); 145 | JBScrollPane pane = new JBScrollPane(builder.getPanel()); 146 | pane.setMaximumSize(JBUI.size(500, 800)); 147 | pane.setPreferredSize(JBUI.size(400, 200)); 148 | pane.setMinimumSize(JBUI.size(50, 100)); 149 | return pane; 150 | } 151 | 152 | @NotNull 153 | public List getSelectModules() { 154 | int count; 155 | if (null == modules || (count = modules.getItemsCount()) == 0) { 156 | return List.of(); 157 | } 158 | return IntStream.range(0, count).mapToObj(modules::getItemAt).filter(Objects::nonNull) 159 | .filter(modules::isItemSelected).toList(); 160 | } 161 | 162 | @Override 163 | protected Action @NotNull [] createActions() { 164 | return new Action[]{getOKAction()}; 165 | } 166 | 167 | @Override 168 | protected void dispose() { 169 | super.dispose(); 170 | if (modules != null) { 171 | List lastSelected = getSelectModules().stream().map(MavenProject::getDisplayName) 172 | .collect(Collectors.toList()); 173 | if (CollectionUtils.isNotEmpty(lastSelected)) { 174 | PropertiesComponent.getInstance().setList(PROPERTIES_KEY + mavenProject.getDisplayName(), lastSelected); 175 | } else { 176 | PropertiesComponent.getInstance().unsetValue(PROPERTIES_KEY + mavenProject.getDisplayName()); 177 | } 178 | } 179 | 180 | } 181 | 182 | private JButton suggestButton() { 183 | JButton button = new JButton(); 184 | button.setText("Choose..."); 185 | button.addActionListener(event -> JBPopupFactory.getInstance().createPopupChooserBuilder(versionSuggests) 186 | .setItemChosenCallback(versionField::setText) 187 | .createPopup() 188 | .showUnderneathOf(button)); 189 | return button; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/AliasTable.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package krasa.mavenhelper.gui; 3 | 4 | import com.intellij.openapi.diagnostic.Logger; 5 | import com.intellij.ui.JBColor; 6 | import com.intellij.ui.table.JBTable; 7 | import krasa.mavenhelper.model.Alias; 8 | import krasa.mavenhelper.model.ApplicationSettings; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import javax.swing.*; 12 | import javax.swing.table.AbstractTableModel; 13 | import javax.swing.table.DefaultTableCellRenderer; 14 | import javax.swing.table.TableColumn; 15 | import java.awt.*; 16 | import java.util.ArrayList; 17 | import java.util.Arrays; 18 | import java.util.Collections; 19 | import java.util.List; 20 | 21 | public class AliasTable extends JBTable { 22 | private static final Logger LOG = Logger.getInstance(AliasTable.class); 23 | private final MyTableModel myTableModel = new MyTableModel(); 24 | private static final int NAME_COLUMN = 0; 25 | private static final int VALUE_COLUMN = 1; 26 | 27 | private final List myAliases = new ArrayList<>(); 28 | 29 | public AliasTable(ApplicationSettings original) { 30 | setModel(myTableModel); 31 | TableColumn column = getColumnModel().getColumn(NAME_COLUMN); 32 | column.setCellRenderer(new DefaultTableCellRenderer() { 33 | @Override 34 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 35 | final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 36 | final String macroValue = getAliasValueAt(row); 37 | component.setForeground(macroValue.length() == 0 38 | ? new JBColor(original.getConflictsForegroundColor(), original.getConflictsForegroundColor()) 39 | : isSelected ? table.getSelectionForeground() : table.getForeground()); 40 | return component; 41 | } 42 | }); 43 | setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 44 | } 45 | 46 | public String getAliasValueAt(int row) { 47 | return (String) getValueAt(row, VALUE_COLUMN); 48 | } 49 | 50 | public void addAlias() { 51 | final AliasEditor macroEditor = new AliasEditor("Add alias", "", "", new EditValidator()); 52 | if (macroEditor.showAndGet()) { 53 | final String name = macroEditor.getFrom(); 54 | myAliases.add(Alias.of(name, macroEditor.getTo())); 55 | final int index = indexOfAliasWithName(name); 56 | LOG.assertTrue(index >= 0); 57 | myTableModel.fireTableDataChanged(); 58 | setRowSelectionInterval(index, index); 59 | } 60 | } 61 | 62 | private boolean isValidRow(int selectedRow) { 63 | return selectedRow >= 0 && selectedRow < myAliases.size(); 64 | } 65 | 66 | public void moveUp() { 67 | int selectedRow = getSelectedRow(); 68 | int index1 = selectedRow - 1; 69 | if (selectedRow != -1) { 70 | Collections.swap(myAliases, selectedRow, index1); 71 | } 72 | setRowSelectionInterval(index1, index1); 73 | } 74 | 75 | public void moveDown() { 76 | int selectedRow = getSelectedRow(); 77 | int index1 = selectedRow + 1; 78 | if (selectedRow != -1) { 79 | Collections.swap(myAliases, selectedRow, index1); 80 | } 81 | setRowSelectionInterval(index1, index1); 82 | } 83 | 84 | 85 | public void removeSelectedAliases() { 86 | final int[] selectedRows = getSelectedRows(); 87 | if (selectedRows.length == 0) return; 88 | Arrays.sort(selectedRows); 89 | final int originalRow = selectedRows[0]; 90 | for (int i = selectedRows.length - 1; i >= 0; i--) { 91 | final int selectedRow = selectedRows[i]; 92 | if (isValidRow(selectedRow)) { 93 | myAliases.remove(selectedRow); 94 | } 95 | } 96 | myTableModel.fireTableDataChanged(); 97 | if (originalRow < getRowCount()) { 98 | setRowSelectionInterval(originalRow, originalRow); 99 | } else if (getRowCount() > 0) { 100 | final int index = getRowCount() - 1; 101 | setRowSelectionInterval(index, index); 102 | } 103 | } 104 | 105 | public void commit(ApplicationSettings settings) { 106 | settings.getAliases().setAliases(new ArrayList<>(myAliases)); 107 | } 108 | 109 | public void resetDefaultAliases() { 110 | ApplicationSettings.resetDefaultAliases(myAliases); 111 | myTableModel.fireTableDataChanged(); 112 | } 113 | 114 | public void reset(ApplicationSettings settings) { 115 | obtainAliases(myAliases, settings); 116 | myTableModel.fireTableDataChanged(); 117 | } 118 | 119 | 120 | private int indexOfAliasWithName(String name) { 121 | for (int i = 0; i < myAliases.size(); i++) { 122 | final Alias pair = myAliases.get(i); 123 | if (name.equals(pair.getFrom())) { 124 | return i; 125 | } 126 | } 127 | return -1; 128 | } 129 | 130 | private void obtainAliases(@NotNull List aliases, ApplicationSettings settings) { 131 | aliases.clear(); 132 | aliases.addAll(settings.getAliases().getAliases()); 133 | } 134 | 135 | public boolean editAlias() { 136 | if (getSelectedRowCount() != 1) { 137 | return false; 138 | } 139 | final int selectedRow = getSelectedRow(); 140 | final Alias alias = myAliases.get(selectedRow); 141 | final AliasEditor editor = new AliasEditor("Edit Alias", alias.getFrom(), alias.getTo(), new EditValidator()); 142 | if (editor.showAndGet()) { 143 | alias.setFrom(editor.getFrom()); 144 | alias.setTo(editor.getTo()); 145 | myTableModel.fireTableDataChanged(); 146 | } 147 | return true; 148 | } 149 | 150 | public boolean isModified(ApplicationSettings settings) { 151 | final ArrayList aliases = new ArrayList<>(); 152 | obtainAliases(aliases, settings); 153 | return !aliases.equals(myAliases); 154 | } 155 | 156 | 157 | private class MyTableModel extends AbstractTableModel { 158 | @Override 159 | public int getColumnCount() { 160 | return 2; 161 | } 162 | 163 | @Override 164 | public int getRowCount() { 165 | return myAliases.size(); 166 | } 167 | 168 | @Override 169 | public Class getColumnClass(int columnIndex) { 170 | return String.class; 171 | } 172 | 173 | @Override 174 | public Object getValueAt(int rowIndex, int columnIndex) { 175 | final Alias pair = myAliases.get(rowIndex); 176 | switch (columnIndex) { 177 | case NAME_COLUMN: 178 | return pair.getFrom(); 179 | case VALUE_COLUMN: 180 | return pair.getTo(); 181 | } 182 | LOG.error("Wrong indices"); 183 | return null; 184 | } 185 | 186 | @Override 187 | public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 188 | } 189 | 190 | @Override 191 | public String getColumnName(int columnIndex) { 192 | switch (columnIndex) { 193 | case NAME_COLUMN: 194 | return "From"; 195 | case VALUE_COLUMN: 196 | return "To"; 197 | } 198 | return null; 199 | } 200 | 201 | @Override 202 | public boolean isCellEditable(int rowIndex, int columnIndex) { 203 | return false; 204 | } 205 | } 206 | 207 | private static class EditValidator implements AliasEditor.Validator { 208 | 209 | @Override 210 | public boolean isOK(String name, String value) { 211 | return !name.isEmpty() && !value.isEmpty(); 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/BorderLayoutPanel.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.gui; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | 8 | /** 9 | * Class Name is BorderLayoutPanel 10 | * 11 | * @author LiJun 12 | * Created on 2022/4/18 16:31 13 | */ 14 | public class BorderLayoutPanel extends JPanel { 15 | 16 | public BorderLayoutPanel() { 17 | super(new BorderLayout()); 18 | } 19 | 20 | public BorderLayoutPanel(int hgap, int vgap) { 21 | super(new BorderLayout(hgap, vgap)); 22 | } 23 | 24 | public static BorderLayoutPanel getInstance() { 25 | return new BorderLayoutPanel(); 26 | } 27 | 28 | public static BorderLayoutPanel getInstance(int hgap, int vgap) { 29 | return new BorderLayoutPanel(hgap, vgap); 30 | } 31 | 32 | @NotNull 33 | public final BorderLayoutPanel center(@NotNull Component comp) { 34 | add(comp, BorderLayout.CENTER); 35 | return this; 36 | } 37 | 38 | 39 | @NotNull 40 | public final BorderLayoutPanel right(@NotNull Component comp) { 41 | add(comp, BorderLayout.EAST); 42 | return this; 43 | } 44 | 45 | @NotNull 46 | public final BorderLayoutPanel left(@NotNull Component comp) { 47 | add(comp, BorderLayout.WEST); 48 | return this; 49 | } 50 | 51 | @NotNull 52 | public final BorderLayoutPanel top(@NotNull Component comp) { 53 | add(comp, BorderLayout.NORTH); 54 | return this; 55 | } 56 | 57 | @NotNull 58 | public final BorderLayoutPanel bottom(@NotNull Component comp) { 59 | add(comp, BorderLayout.SOUTH); 60 | return this; 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/FlowLayoutPanel.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.gui; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.util.List; 6 | 7 | /** 8 | * Class Name is FlowLayoutPanel 9 | * 10 | * @author LiJun 11 | * Created on 2021/8/25 4:27 下午 12 | */ 13 | public class FlowLayoutPanel extends JPanel { 14 | 15 | public FlowLayoutPanel(int align) { 16 | super(new FlowLayout(align)); 17 | } 18 | 19 | public FlowLayoutPanel(int align, int hgap, int vgap) { 20 | super(new FlowLayout(align, hgap, vgap)); 21 | } 22 | 23 | public static FlowLayoutPanel getInstance(int align) { 24 | return new FlowLayoutPanel(align); 25 | } 26 | 27 | public static FlowLayoutPanel getInstance(int align, int hgap, int vgap) { 28 | return new FlowLayoutPanel(align, hgap, vgap); 29 | } 30 | 31 | public static FlowLayoutPanel leftInstance() { 32 | return new FlowLayoutPanel(FlowLayout.LEFT); 33 | } 34 | 35 | public static FlowLayoutPanel leftInstance(int hgap, int vgap) { 36 | return new FlowLayoutPanel(FlowLayout.LEFT, hgap, vgap); 37 | } 38 | 39 | public static FlowLayoutPanel centerInstance() { 40 | return new FlowLayoutPanel(FlowLayout.CENTER); 41 | } 42 | 43 | public static FlowLayoutPanel rightInstance() { 44 | return new FlowLayoutPanel(FlowLayout.RIGHT); 45 | } 46 | 47 | public FlowLayoutPanel add(JComponent component) { 48 | super.add(component); 49 | return this; 50 | } 51 | 52 | public FlowLayoutPanel addMore(JComponent... components) { 53 | for (JComponent component : components) { 54 | super.add(component); 55 | } 56 | return this; 57 | } 58 | 59 | public FlowLayoutPanel add(List components) { 60 | for (JComponent component : components) { 61 | super.add(component); 62 | } 63 | return this; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/GoalEditor.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 |
106 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/MyDragListener.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.gui; 2 | 3 | import javax.swing.*; 4 | import java.awt.datatransfer.StringSelection; 5 | import java.awt.dnd.*; 6 | 7 | /** 8 | * @author Vojtech Krasa 9 | */ 10 | 11 | class MyDragListener implements DragSourceListener, DragGestureListener { 12 | JList list; 13 | 14 | DragSource ds = new DragSource(); 15 | 16 | public MyDragListener(JList list) { 17 | this.list = list; 18 | DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(list, DnDConstants.ACTION_MOVE, this); 19 | 20 | } 21 | 22 | @Override 23 | public void dragGestureRecognized(DragGestureEvent dge) { 24 | StringSelection transferable = new StringSelection(Integer.toString(list.getSelectedIndex())); 25 | ds.startDrag(dge, DragSource.DefaultMoveDrop, transferable, this); 26 | } 27 | 28 | @Override 29 | public void dragEnter(DragSourceDragEvent dsde) { 30 | } 31 | 32 | @Override 33 | public void dragExit(DragSourceEvent dse) { 34 | } 35 | 36 | @Override 37 | public void dragOver(DragSourceDragEvent dsde) { 38 | } 39 | 40 | @Override 41 | public void dragDropEnd(DragSourceDropEvent dsde) { 42 | } 43 | 44 | @Override 45 | public void dropActionChanged(DragSourceDragEvent dsde) { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/MyListDataListener.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.gui; 2 | 3 | import krasa.mavenhelper.model.Goal; 4 | import krasa.mavenhelper.model.Goals; 5 | 6 | import javax.swing.*; 7 | import javax.swing.event.ListDataEvent; 8 | import javax.swing.event.ListDataListener; 9 | import java.util.List; 10 | 11 | /** 12 | * @author Vojtech Krasa 13 | */ 14 | public class MyListDataListener implements ListDataListener { 15 | private DefaultListModel model; 16 | private Goals goals; 17 | 18 | public MyListDataListener(DefaultListModel model, Goals goals) { 19 | this.model = model; 20 | this.goals = goals; 21 | } 22 | 23 | @Override 24 | public void intervalAdded(ListDataEvent e) { 25 | listChanged(); 26 | } 27 | 28 | @Override 29 | public void intervalRemoved(ListDataEvent e) { 30 | listChanged(); 31 | } 32 | 33 | @Override 34 | public void contentsChanged(ListDataEvent e) { 35 | listChanged(); 36 | } 37 | 38 | private void listChanged() { 39 | List list = this.goals.getGoals(); 40 | list.clear(); 41 | for (int i = 0; i < model.getSize(); i++) { 42 | list.add(model.getElementAt(i)); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/gui/MyListDropHandler.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.gui; 2 | 3 | import com.intellij.ui.components.JBList; 4 | 5 | import javax.swing.*; 6 | import java.awt.datatransfer.DataFlavor; 7 | import java.awt.datatransfer.Transferable; 8 | 9 | /** 10 | * @author Vojtech Krasa 11 | */ 12 | class MyListDropHandler extends TransferHandler { 13 | JBList list; 14 | 15 | public MyListDropHandler(JBList list) { 16 | this.list = list; 17 | } 18 | 19 | @Override 20 | public boolean canImport(TransferHandler.TransferSupport support) { 21 | if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) { 22 | return false; 23 | } 24 | JList.DropLocation dl = (JList.DropLocation) support.getDropLocation(); 25 | if (dl.getIndex() == -1) { 26 | return false; 27 | } else { 28 | return true; 29 | } 30 | } 31 | 32 | @Override 33 | public boolean importData(TransferHandler.TransferSupport support) { 34 | if (!canImport(support)) { 35 | return false; 36 | } 37 | 38 | Transferable transferable = support.getTransferable(); 39 | String indexString; 40 | try { 41 | indexString = (String) transferable.getTransferData(DataFlavor.stringFlavor); 42 | } catch (Exception e) { 43 | return false; 44 | } 45 | 46 | int index = Integer.parseInt(indexString); 47 | JList.DropLocation dl = (JList.DropLocation) support.getDropLocation(); 48 | int dropTargetIndex = dl.getIndex(); 49 | 50 | DefaultListModel model = (DefaultListModel) list.getModel(); 51 | Object elementAt = model.getElementAt(index); 52 | 53 | model.insertElementAt(elementAt, dropTargetIndex); 54 | model.remove(getActualRemoveIndex(index, dropTargetIndex)); 55 | 56 | int actualDropIndex = getActualDropIndex(index, dropTargetIndex); 57 | list.getSelectionModel().setSelectionInterval(actualDropIndex, actualDropIndex); 58 | // list.repaint(); 59 | return true; 60 | } 61 | 62 | private int getActualRemoveIndex(int index, int dropTargetIndex) { 63 | int index1; 64 | if (dropTargetIndex < index) { 65 | index1 = index + 1; 66 | } else { 67 | index1 = index; 68 | } 69 | return index1; 70 | } 71 | 72 | private int getActualDropIndex(int index, int dropTargetIndex) { 73 | int index1; 74 | if (dropTargetIndex < index) { 75 | index1 = dropTargetIndex; 76 | } else { 77 | index1 = dropTargetIndex - 1; 78 | } 79 | return index1; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/icons/MyIcons.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.icons; 2 | 3 | import com.intellij.openapi.util.IconLoader; 4 | 5 | public class MyIcons { 6 | public static final javax.swing.Icon ICON = IconLoader.getIcon("/icons/debug.svg", MyIcons.class); 7 | public static final javax.swing.Icon RUN_MAVEN_ICON = IconLoader.getIcon("/icons/runMaven.svg", MyIcons.class); 8 | public static final javax.swing.Icon PHASES_CLOSED = IconLoader.getIcon("/icons/phasesClosed.svg", MyIcons.class); 9 | public static final javax.swing.Icon PLUGIN_GOAL = IconLoader.getIcon("/icons/pluginGoal.svg", MyIcons.class); 10 | public static final javax.swing.Icon OPEN_TERMINAL = IconLoader.getIcon("/icons/OpenTerminal.svg", MyIcons.class); 11 | public static final javax.swing.Icon MAVEN_LOGO = IconLoader.getIcon("/icons/mavenLogo.svg", MyIcons.class); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/model/Alias.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.model; 2 | public class Alias extends DomainObject { 3 | private String from; 4 | private String to; 5 | 6 | public Alias() { 7 | } 8 | 9 | public Alias(String from, String to) { 10 | this.from = from; 11 | this.to = to; 12 | } 13 | 14 | public static Alias of(String name, String value) { 15 | return new Alias(name, value); 16 | } 17 | 18 | public String getFrom() { 19 | return from; 20 | } 21 | 22 | public void setFrom(String from) { 23 | this.from = from; 24 | } 25 | 26 | public String getTo() { 27 | return to; 28 | } 29 | 30 | public void setTo(String to) { 31 | this.to = to; 32 | } 33 | 34 | public String applyTo(String commandLine) { 35 | if (from != null && to != null) { 36 | return commandLine.replace(from, to); 37 | } 38 | return commandLine; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/model/Aliases.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public class Aliases extends DomainObject { 9 | private List aliases = new ArrayList(); 10 | 11 | public Aliases() { 12 | } 13 | 14 | public Aliases(List aliases) { 15 | this.aliases = aliases; 16 | } 17 | 18 | public List getAliases() { 19 | return aliases; 20 | } 21 | 22 | public void setAliases(List aliases) { 23 | this.aliases = aliases; 24 | } 25 | 26 | public boolean remove(Alias o) { 27 | return aliases.remove(o); 28 | } 29 | 30 | public boolean add(Alias o) { 31 | if (aliases.stream().anyMatch(alias -> alias.getFrom().equals(o.getFrom()))) { 32 | return false; 33 | } 34 | return aliases.add(o); 35 | } 36 | 37 | 38 | public void add(String s, String to) { 39 | aliases.add(new Alias(s, to)); 40 | } 41 | 42 | public int size() { 43 | return aliases.size(); 44 | } 45 | 46 | public boolean remove(Object goal) { 47 | return aliases.remove(goal); 48 | } 49 | 50 | public String applyAliases(String commandLine) { 51 | for (Alias alias : aliases) { 52 | commandLine = alias.applyTo(commandLine); 53 | } 54 | return commandLine; 55 | } 56 | 57 | public Map asMap() { 58 | HashMap stringStringHashMap = new HashMap<>(); 59 | for (Alias alias : aliases) { 60 | stringStringHashMap.put(alias.getFrom(), alias.getTo()); 61 | } 62 | return stringStringHashMap; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/model/DomainObject.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.model; 2 | 3 | import org.apache.commons.lang3.builder.EqualsBuilder; 4 | import org.apache.commons.lang3.builder.HashCodeBuilder; 5 | import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 6 | 7 | public abstract class DomainObject { 8 | 9 | @Override 10 | public boolean equals(Object obj) { 11 | return EqualsBuilder.reflectionEquals(this, obj, false); 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return ReflectionToStringBuilder.toString(this); 17 | } 18 | 19 | @Override 20 | public int hashCode() { 21 | return HashCodeBuilder.reflectionHashCode(this); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/model/Goal.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.model; 2 | 3 | import com.intellij.execution.actions.ConfigurationContext; 4 | import com.intellij.execution.configurations.CommandLineTokenizer; 5 | import com.intellij.openapi.util.text.StringUtil; 6 | import com.intellij.psi.PsiFile; 7 | import com.intellij.util.containers.ContainerUtil; 8 | import krasa.mavenhelper.action.MavenProjectInfo; 9 | import krasa.mavenhelper.action.Utils; 10 | import org.jetbrains.annotations.NotNull; 11 | import org.jetbrains.idea.maven.project.MavenProjectsManager; 12 | 13 | import java.util.List; 14 | 15 | public class Goal extends DomainObject { 16 | private String commandLine; 17 | 18 | public Goal() { 19 | } 20 | 21 | public Goal(@NotNull String s) { 22 | commandLine = s.trim(); 23 | } 24 | 25 | public String getCommandLine() { 26 | return commandLine; 27 | } 28 | 29 | public void setCommandLine(String commandLine) { 30 | this.commandLine = commandLine; 31 | } 32 | 33 | public String getPresentableName() { 34 | return Utils.limitLength(commandLine); 35 | } 36 | 37 | public List parse(PsiFile psiFile, ConfigurationContext configurationContext, @NotNull MavenProjectInfo mavenProjectInfo, MavenProjectsManager manager) { 38 | String cmd = getCommandLine(); 39 | cmd = ApplicationSettings.get().applyAliases(cmd, psiFile, configurationContext, mavenProjectInfo, manager); 40 | 41 | if (ApplicationSettings.get().isUseTerminalCommand()) { 42 | return List.of(cmd); 43 | } 44 | 45 | return ContainerUtil.newArrayList(StringUtil.tokenize(new CommandLineTokenizer(cmd))); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/krasa/mavenhelper/model/Goals.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Goals extends DomainObject { 7 | private List goals = new ArrayList(); 8 | 9 | public Goals() { 10 | } 11 | 12 | public Goals(List goals) { 13 | this.goals = goals; 14 | } 15 | 16 | public List getGoals() { 17 | return goals; 18 | } 19 | 20 | public void setGoals(List goals) { 21 | this.goals = goals; 22 | } 23 | 24 | public List asStrings() { 25 | return getStrings(goals); 26 | } 27 | 28 | public boolean remove(Goal o) { 29 | return goals.remove(o); 30 | } 31 | 32 | public boolean add(Goal o) { 33 | return goals.add(o); 34 | } 35 | 36 | public List getGoalsAsStrings() { 37 | return getStrings(goals); 38 | } 39 | 40 | private List getStrings(final List goals1) { 41 | List strings = new ArrayList(); 42 | for (Goal goal : goals1) { 43 | strings.add(goal.getCommandLine()); 44 | } 45 | return strings; 46 | } 47 | 48 | public void add(String s) { 49 | goals.add(new Goal(s)); 50 | } 51 | 52 | public int size() { 53 | return goals.size(); 54 | } 55 | 56 | public boolean remove(Object goal) { 57 | return goals.remove(goal); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | MavenRunHelper 4 | Maven Helper 5 | 6 | Vojtech Krasa 7 | 8 | 10 |
    11 |
  • easy way for analyzing and excluding conflicting dependencies
  • 12 |
  • actions to run/debug maven goals for a module that contains the current file or on the root module
  • 13 |
  • action to open terminal at the current maven module path
  • 14 |
  • actions to run/debug the current test file. 15 |
  • 16 |
17 |
18 | Usage:
19 |
    20 |
  • Right click in Editor | Run Maven
    21 |
  • Right click in Project View Toolbar | (Run|Debug) Maven
    22 |
  • CTRL + ALT + R - "Run Maven Goal" popup (you can use Delete key in the popup)
    23 |
  • CTRL + SHIFT + ALT + R - "Run Maven Goal on Root Module" popup (you can use Delete key in the popup)
    24 |
    25 |
  • Customize goals: Settings | Other Settings | Maven Helper
    26 |
  • Define shortcuts: Settings | Keymap | Plug-ins | Maven Helper
    27 |
    28 |
  • Open pom file, click on 'Dependency Analyzer' tab, right click in the tree for context actions.
    29 |
  • 30 |
31 |
If maven-surefire-plugin is configured to skip or exclude the test, 'verify' goal will be used, see different configuration styles at https://github.com/harishkannarao/MavenSurefireFailsafeExamples 32 | 33 |

34 | Donations | GitHub | Issues 35 | ]]>
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 58 | 59 | 60 | 61 | 64 | 65 | 66 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 88 | 89 | 90 | 91 | 92 | org.jetbrains.idea.maven 93 | org.jetbrains.plugins.terminal 94 | com.jetbrains.sh 95 | com.intellij.modules.java 96 | 97 |
98 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/pluginIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 51 | 57 | 58 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/pluginIcon_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 51 | 57 | 58 | -------------------------------------------------------------------------------- /src/main/resources/icons/OpenTerminal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/icons/OpenTerminal_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/icons/coins_in_hand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/MavenHelper/fd7ced790d2314622b8d915214fc24c2e3eef2f6/src/main/resources/icons/coins_in_hand.png -------------------------------------------------------------------------------- /src/main/resources/icons/coins_in_hand@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/MavenHelper/fd7ced790d2314622b8d915214fc24c2e3eef2f6/src/main/resources/icons/coins_in_hand@2x.png -------------------------------------------------------------------------------- /src/main/resources/icons/debug.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/icons/debug_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/icons/donate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/MavenHelper/fd7ced790d2314622b8d915214fc24c2e3eef2f6/src/main/resources/icons/donate.gif -------------------------------------------------------------------------------- /src/main/resources/icons/mavenLogo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/icons/mavenLogo_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/icons/phasesClosed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/icons/pluginGoal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/icons/pluginGoal_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/icons/runMaven.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/icons/runMaven_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/test/java/krasa/mavenhelper/action/RunTestFileActionTest.java: -------------------------------------------------------------------------------- 1 | package krasa.mavenhelper.action; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Test; 7 | 8 | public class RunTestFileActionTest { 9 | 10 | @Test 11 | public void testMatchClassRegexPatter() throws Exception { 12 | assertTrue(RunTestFileAction.matchClassRegexPatter("com/foo/FailsafeSampleIT.java", "**/*IT.java")); 13 | assertFalse(RunTestFileAction.matchClassRegexPatter("com/foo/FailsafeSampleTest.java", "**/*IT.java")); 14 | } 15 | } -------------------------------------------------------------------------------- /src/test/lib/assertj-core-3.16.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/MavenHelper/fd7ced790d2314622b8d915214fc24c2e3eef2f6/src/test/lib/assertj-core-3.16.1.jar -------------------------------------------------------------------------------- /src/test/lib/byte-buddy-dep-1.10.10.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/MavenHelper/fd7ced790d2314622b8d915214fc24c2e3eef2f6/src/test/lib/byte-buddy-dep-1.10.10.jar -------------------------------------------------------------------------------- /src/test/lib/mockito-core-3.3.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/MavenHelper/fd7ced790d2314622b8d915214fc24c2e3eef2f6/src/test/lib/mockito-core-3.3.3.jar --------------------------------------------------------------------------------