diff --git a/CHANGELOG.md b/CHANGELOG.md index 13fea99..21fa453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ # Axon Framework plugin Changelog +## [0.9.2] +- Fix false positive on versions not equal to 4 + ## [0.9.1] - Disable plugin when Axon Framework 5 or greater is detected. The plugin is not compatible with Axon Framework 5 and greater at this time, as it is an experimental branch. Future versions of the plugin will be compatible with Axon Framework 5 and greater, once it approaches release readiness. diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonDependency.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonDependency.kt index d8c4a3d..76242d6 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonDependency.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonDependency.kt @@ -16,35 +16,42 @@ package org.axonframework.intellij.ide.plugin.usage -enum class AxonDependency(val moduleName: String, val checkVersion: Boolean = true) { - Core("axon-core"), // Axon 2 only - Integration("axon-integration"), // Axon 2 only - SpringMessaging("axon-springmessaging"), // Axon 2 only - DistributedCommandBus("axon-distributed-commandbus"), // Axon 2 only - Spring("axon-spring"), // Axon 3 and 4 - SpringAutoconfigure("axon-spring-boot-autoconfigure"), // Axon 3 and 4 - SpringStarter("axon-spring-boot-starter"), // Axon 3 and 4 - Messaging("axon-messaging"), // Axon 4 only - EventSourcing("axon-eventsourcing"), // Axon 4 only - Modelling("axon-modelling"), // Axon 4 only - Configuration("axon-configuration"), // Axon 4 only - Test("axon-test"), // Axon 2, 3 and 4 - Metrics("axon-metrics"), // Axon 3 and 4 - Legacy("axon-legacy"), // Axon 3 and 4 - Micrometer("axon-micrometer"), // Axon 4 only - Disruptor("axon-disruptor"), // Axon 4 only - ServerConnector("axon-server-connector"), // Axon 4 only +enum class AxonDependency( + val groupId: String, + val artifactId: String, + val checkVersion: Boolean = true +) { + Core("org.axonframework", "axon-core"), // Axon 2 only + Integration("org.axonframework", "axon-integration"), // Axon 2 only + SpringMessaging("org.axonframework", "axon-springmessaging"), // Axon 2 only + DistributedCommandBus("org.axonframework", "axon-distributed-commandbus"), // Axon 2 only + Spring("org.axonframework", "axon-spring"), // Axon 3 and 4 + SpringAutoconfigure("org.axonframework", "axon-spring-boot-autoconfigure"), // Axon 3 and 4 + SpringStarter("org.axonframework", "axon-spring-boot-starter"), // Axon 3 and 4 + Messaging("org.axonframework", "axon-messaging"), // Axon 4 only + EventSourcing("org.axonframework", "axon-eventsourcing"), // Axon 4 only + Modelling("org.axonframework", "axon-modelling"), // Axon 4 only + Configuration("org.axonframework", "axon-configuration"), // Axon 4 only + Test("org.axonframework", "axon-test"), // Axon 2, 3 and 4 + Metrics("org.axonframework", "axon-metrics"), // Axon 3 and 4 + Legacy("org.axonframework", "axon-legacy"), // Axon 3 and 4 + Micrometer("org.axonframework", "axon-micrometer"), // Axon 4 only + Disruptor("org.axonframework", "axon-disruptor"), // Axon 4 only + ServerConnector("org.axonframework", "axon-server-connector"), // Axon 4 only // Extensions, used for reporting during bugs, not for version check - Mongo("axon-mongo", false), - Mongo3("axon-mongo3", false), - Amqp("axon-amqp", false), - Jgroups("axon-jgroups", false), - Reactor("axon-reactor", false), - Kotlin("axon-kotlin", false), - Kafka("axon-kafka", false), - Multitenancy("axon-multitenancy", false), - SpringCloud("axon-springcloud", false), - Tracing("axon-tracing", false), - Cdi("axon-cdi", false), + Mongo("org.axonframework.extensions.mongo", "axon-mongo", false), + Amqp("org.axonframework", "axon-amqp", false), + Jgroups("org.axonframework.extensions.jgroups", "axon-jgroups", false), + Reactor("org.axonframework.extensions.reactor", "axon-reactor", false), + Kotlin("org.axonframework.extensions.kotlin", "axon-kotlin", false), + Kafka("org.axonframework.extensions.kafka", "axon-kafka", false), + Multitenancy("org.axonframework.extensions.multitenancy", "axon-multitenancy", false), + SpringCloud("org.axonframework.extensions.springcloud", "axon-springcloud", false), + Tracing("org.axonframework.extensions.tracing", "axon-tracing", false), + Cdi("org.axonframework.extensions.cdi", "axon-cdi", false), + ; + + val moduleName: String + get() = "$groupId:$artifactId" } diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonVersionService.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonVersionService.kt index 67bd273..2a68583 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonVersionService.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonVersionService.kt @@ -23,13 +23,16 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModuleRootEvent import com.intellij.openapi.roots.ModuleRootListener import com.intellij.openapi.roots.OrderEnumerator +import com.intellij.openapi.vfs.VfsUtilCore +import java.util.Properties +import java.util.jar.JarFile class AxonVersionService(val project: Project) { private var enabled = false private var messageShownOutdated = false private var messageShownExperimental = false - private val regex = Regex(".*(axon-.*)-(\\d+)\\.(\\d+)\\.(\\d+)(.*)\\.jar") + private val versionRegex = Regex("(\\d+)\\.(\\d+)\\.(\\d+)(.*)") init { @@ -127,26 +130,49 @@ class AxonVersionService(val project: Project) { private fun List.outdated() = filter { it.dependency.checkVersion && it.major < 4 } private fun List.experimental() = filter { it.dependency.checkVersion && it.major > 4 } - fun getAxonVersions() = OrderEnumerator.orderEntries(project) + fun getAxonVersions(): List = OrderEnumerator.orderEntries(project) .librariesOnly() .productionOnly() .classes() .roots - .filter { !it.presentableName.contains("inspector") } - .filter { it.presentableName.matches(regex) } - .mapNotNull { - extractVersion(it.name) + .filter { it.presentableName.contains("axon") } + .flatMap { root -> + val jarFile = VfsUtilCore.virtualToIoFile(root) + if (jarFile.extension == "jar") { + val jar = JarFile(jarFile) + jar.entries() + .toList() + .filter { it.name.startsWith("META-INF/maven/") && it.name.endsWith("pom.properties") } + .mapNotNull { entry -> + jar.getInputStream(entry).use { input -> + // Process the input stream as needed + val properties = Properties().apply { load(input) } + extractVersion(properties) + } + } + } else { + emptyList() + } } - private fun extractVersion(name: String): AxonDependencyVersion? { - val match = regex.find(name)!! - val (moduleName, majorVersion, minorVersion, patchVersion, remaining) = match.destructured - val dependency = AxonDependency.entries.firstOrNull { it.moduleName == moduleName } ?: return null + private fun extractVersion(properties: Properties): AxonDependencyVersion? { + val groupId = properties.getProperty("groupId") + val artifactId = properties.getProperty("artifactId") + val version = properties.getProperty("version") + if(groupId.isNullOrEmpty() || artifactId.isNullOrEmpty() || version.isNullOrEmpty()) { + return null + } + val dependency = AxonDependency.entries.firstOrNull { it.groupId == groupId && it.artifactId == artifactId } + if(dependency == null) { + return null + } + val (majorVersion, minorVersion, patchVersion, remaining) = versionRegex.find(version)!!.destructured return AxonDependencyVersion( dependency, Integer.parseInt(majorVersion), Integer.parseInt(minorVersion), - Integer.parseInt(patchVersion), remaining + Integer.parseInt(patchVersion), + remaining ) }