From f18c1ade6bfdd75219ea45db214e9102bf7da6bb Mon Sep 17 00:00:00 2001 From: Darwin Esteban Algarin Sarmiento Date: Sat, 28 Dec 2024 10:21:29 -0500 Subject: [PATCH 1/2] fix message for macos setup. --- .../labs/jmeter/ide/settings/JMeterNewToolchainDialog.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/kotlin/co/anbora/labs/jmeter/ide/settings/JMeterNewToolchainDialog.kt b/src/main/kotlin/co/anbora/labs/jmeter/ide/settings/JMeterNewToolchainDialog.kt index 5d6361d..2fc1633 100644 --- a/src/main/kotlin/co/anbora/labs/jmeter/ide/settings/JMeterNewToolchainDialog.kt +++ b/src/main/kotlin/co/anbora/labs/jmeter/ide/settings/JMeterNewToolchainDialog.kt @@ -134,6 +134,9 @@ class JMeterNewToolchainDialog(private val toolchainFilter: Condition, pro val version = JMeterConfigurationUtil.guessToolchainVersion(model.toolchainLocation) if (version == JMeterConfigurationUtil.UNDEFINED_VERSION) { + if (model.toolchainLocation.contains("homebrew")) { + return error("JMeter location is invalid, for homebrew installation please select libexec folder") + } return error("JMeter location is invalid, can't get version. Please check that bin folder contains ${JMeterConfigurationUtil.STANDARD_JMETER_CONFIG}") } From bb181a1f05460bbebe5c2149eb6721753666e3c5 Mon Sep 17 00:00:00 2001 From: Darwin Esteban Algarin Sarmiento Date: Fri, 17 Jan 2025 15:21:10 -0500 Subject: [PATCH 2/2] add download feature. --- build.gradle.kts | 2 +- .../apache/jmeter/treebuilder/TreeBuilder.kt | 199 ------------------ .../jmeter/treebuilder/dsl/TreeBuilders.kt | 31 --- gradle.properties | 9 +- src/main/html/change-notes.html | 4 +- .../labs/jmeter/ide/license/CheckLicense.java | 41 ++-- .../ide/listeners/JMeterSelectionListener.kt | 2 + .../settings/JMeterDownloadToolchainDialog.kt | 2 +- .../jmeter/ide/startup/InitConfigFiles.kt | 1 + src/main/resources/META-INF/plugin.xml | 4 +- 10 files changed, 34 insertions(+), 261 deletions(-) delete mode 100644 core/src/main/kotlin/org/apache/jmeter/treebuilder/TreeBuilder.kt delete mode 100644 core/src/main/kotlin/org/apache/jmeter/treebuilder/dsl/TreeBuilders.kt diff --git a/build.gradle.kts b/build.gradle.kts index c507184..9ab2cf6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ fun environment(key: String) = providers.environmentVariable(key) plugins { id("java") - id("org.jetbrains.kotlin.jvm") version "1.9.24" + id("org.jetbrains.kotlin.jvm") version "2.0.0" id("org.jetbrains.intellij.platform") version "2.2.1" } diff --git a/core/src/main/kotlin/org/apache/jmeter/treebuilder/TreeBuilder.kt b/core/src/main/kotlin/org/apache/jmeter/treebuilder/TreeBuilder.kt deleted file mode 100644 index 3ce8079..0000000 --- a/core/src/main/kotlin/org/apache/jmeter/treebuilder/TreeBuilder.kt +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.jmeter.treebuilder - -import org.apache.jmeter.testelement.TestElement -import org.apache.jmeter.testelement.TestElementSchema -import org.apache.jorphan.collections.ListedHashTree -import org.apiguardian.api.API -import kotlin.reflect.KClass - -/** - * Provides a programmatic way to build test plans. - * - * Sample Kotlin: - * - * testTree { - * TestPlan::class { - * OpenModelThreadGroup::class { - * name = "Thread Group" - * scheduleString = "rate(50 / sec) random_arrivals(100 ms) pause(2 s)" - * +DebugSampler() - * } - * } - * } - * - * Sample Java: - * - * testTree(b -> { - * b.add(TestPlan.class, tp -> { - * b.add(OpenModelThreadGroup.class, tg ->{ - * name = "Thread Group" - * scheduleString = "rate(50 / sec) random_arrivals(100 ms) pause(2 s)" - * b.add(new DebugSampler()); - * }); - * }); - * }); - * - * @since 5.6 - */ -@API(status = API.Status.EXPERIMENTAL, since = "5.6") -public class TreeBuilder { - /** - * Resulting tree. - */ - public val tree: ListedHashTree = ListedHashTree() - - private var currentSubtreePrivate: ListedHashTree = tree - - /** - * Subtree for the currently built element. - */ - public val currentSubtree: ListedHashTree get() = currentSubtreePrivate - - private val elementStackPrivate = mutableListOf() - - /** - * Path to the current element from the root. - * The first element is the root, and the last element is the recently added one. - */ - public val elementStack: List get() = elementStackPrivate - - public val currentElement: TestElement get() = elementStack.last() - - public val parent: TestElement? get() = elementStack.getOrNull(elementStack.lastIndex - 1) - - /** - * Contains the stack of configuration actions. The action will be discarded after the builder scope finishes, - * and every scope can contain a list of actions which is null when no actions exist in the scope. - */ - private val actionsStack = mutableListOf>?>(null) - - /** - * Adds a test element to the test tree. - */ - @JvmName("add") - public operator fun TestElement.unaryPlus() { - currentSubtreePrivate.add(this) - runConfigurations(this) - } - - /** - * Adds a test element to the test tree. - */ - @JvmName("add") - public operator fun KClass.unaryPlus() { - +this.java - } - - /** - * Adds a test element to the test tree. - */ - @JvmName("add") - public operator fun Class.unaryPlus() { - +getDeclaredConstructor().newInstance() - } - - /** - * Creates a test element and adds it to the test tree. - * The test element class should have a no-argument constructor. - * @param configure block that configures the newly created test element, and optionally adds children elements - */ - @JvmName("add") - public operator fun KClass.invoke(configure: Action = Action {}) { - java(configure) - } - - /** - * Creates a test element and adds it to the test tree. - * The test element class should have a no-argument constructor. - * @param configure block that configures the newly created test element, and optionally adds children elements - */ - @JvmName("add") - public operator fun Class.invoke(configure: Action = Action {}) { - getDeclaredConstructor().newInstance()(configure) - } - - /** - * Adds a test element to the test tree. - * @param configure block that configures the test element, and optionally adds children elements - */ - @JvmName("add") - public operator fun T.invoke(configure: Action = Action {}) { - val prevTree = currentSubtreePrivate - try { - currentSubtreePrivate = currentSubtreePrivate.add(this) - elementStackPrivate.add(this) - actionsStack.add(null) - configure.run { execute() } - // Execute configurations after user-provided "constructor" actions were run - runConfigurations(this) - } finally { - currentSubtreePrivate = prevTree - elementStackPrivate.removeLast() - actionsStack.removeLast() - } - } - - private fun runConfigurations(testElement: TestElement) { - if (testElement.getPropertyOrNull(TestElementSchema.testClass) == null) { - testElement[TestElementSchema.testClass] = testElement::class.java - } - for (actions in actionsStack) { - actions?.forEach { it(testElement) } - } - } - - /** - * Add an [Action] that will be executed after each element is added to the tree. - */ - public fun configureAll(configure: Action) { - configureEach(configure) - } - - /** - * Add an [Action] that will be executed after elements of given type (or its subtype) are added to the tree. - */ - public inline fun configureEach(configure: Action) { - configureEach(T::class, configure) - } - - /** - * Add an [Action] that will be executed after elements of given type (or its subtype) are added to the tree. - */ - public fun configureEach(klass: KClass, configure: Action) { - configureEach(klass.java, configure) - } - - /** - * Add an [Action] that will be executed after elements of given type (or its subtype) are added to the tree. - */ - public fun configureEach(klass: Class, configure: Action) { - // TODO: should we configure already created elements in the scope? - var actions = actionsStack.last() - if (actions == null) { - actions = mutableListOf() - actionsStack[actionsStack.lastIndex] = actions - } - actions += Action { - if (klass.isInstance(this)) { - configure(klass.cast(this)) - } - } - } -} diff --git a/core/src/main/kotlin/org/apache/jmeter/treebuilder/dsl/TreeBuilders.kt b/core/src/main/kotlin/org/apache/jmeter/treebuilder/dsl/TreeBuilders.kt deleted file mode 100644 index 6b4bd09..0000000 --- a/core/src/main/kotlin/org/apache/jmeter/treebuilder/dsl/TreeBuilders.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@file:JvmName("TreeBuilders") -package org.apache.jmeter.treebuilder.dsl - -import org.apache.jmeter.treebuilder.Action -import org.apache.jmeter.treebuilder.TreeBuilder -import org.apache.jorphan.collections.ListedHashTree -import org.apiguardian.api.API - -/** - * Creates a test tree. - */ -@API(status = API.Status.EXPERIMENTAL, since = "5.6") -public fun testTree(body: Action): ListedHashTree = - TreeBuilder().apply(body).tree diff --git a/gradle.properties b/gradle.properties index 711e04a..3e47452 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,15 +4,16 @@ kotlin.stdlib.default.dependency=false pluginGroup = co.anbora.labs pluginName = JMeter Viewer # SemVer format -> https://semver.org -pluginVersion = 1.6.5 +pluginVersion = 1.7.0 # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html -pluginSinceBuild = 243 -pluginUntilBuild = 243.* +pluginSinceBuild = 251 +pluginUntilBuild = 251.* # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType = IC -platformVersion = 243.12818.47 +platformVersion = 251.14649.49 +#platformVersion = LATEST-EAP-SNAPSHOT # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformPlugins = com.jetbrains.php:203.4449.22, org.intellij.scala:2023.3.27@EAP diff --git a/src/main/html/change-notes.html b/src/main/html/change-notes.html index 193e44d..95adad1 100644 --- a/src/main/html/change-notes.html +++ b/src/main/html/change-notes.html @@ -1,11 +1,11 @@ Versions:
    -
  • All Intellij products support: 1.6.5
  • +
  • All Intellij products support: 1.7.0

Plugin updates:
    -
  • 1.6.5 (2024-12-18) - add feature +
  • 1.7.0 (2025-01-17) - add feature
    • Download JMeter
    diff --git a/src/main/java/co/anbora/labs/jmeter/ide/license/CheckLicense.java b/src/main/java/co/anbora/labs/jmeter/ide/license/CheckLicense.java index 2a3db3b..ffaf2b8 100644 --- a/src/main/java/co/anbora/labs/jmeter/ide/license/CheckLicense.java +++ b/src/main/java/co/anbora/labs/jmeter/ide/license/CheckLicense.java @@ -1,9 +1,7 @@ package co.anbora.labs.jmeter.ide.license; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.ui.LicensingFacade; @@ -143,7 +141,7 @@ public static Boolean isLicensed() { return false; } - /*public static void requestLicense(final String message) { + public static void requestLicense(final String message) { // ensure the dialog is appeared from UI thread and in a non-modal context ApplicationManager.getApplication().invokeLater( () @@ -162,10 +160,15 @@ private static void showRegisterDialog(final String productCode, registerAction = actionManager.getAction("Register"); } if (registerAction != null) { - registerAction.actionPerformed(AnActionEvent.createFromDataContext( - "", new Presentation(), asDataContext(productCode, message))); + ActionUtil.performActionDumbAwareWithCallbacks(registerAction, AnActionEvent.createEvent( + asDataContext(productCode, message), + new Presentation(), + "", + ActionUiKind.NONE, + null + )); } - }*/ + } // This creates a DataContext providing additional information for the license // UI The "Register*" actions show the registration dialog and expect to find @@ -174,24 +177,20 @@ private static void showRegisterDialog(final String productCode, // pre-selected in the opened dialog // - message: optional message explaining the reason why the dialog has been // shown - /*@NotNull + @NotNull private static DataContext asDataContext(final String productCode, @Nullable String message) { return dataId -> { - switch (dataId) { - // the same code as registered in plugin.xml, 'product-descriptor' tag - case "register.product-descriptor.code": - return productCode; - - // optional message to be shown in the registration dialog that appears - case "register.message": - return message; + return switch (dataId) { + // the same code as registered in plugin.xml, 'product-descriptor' tag + case "register.product-descriptor.code" -> productCode; - default: - return null; - } + // optional message to be shown in the registration dialog that appears + case "register.message" -> message; + default -> null; + }; }; - }*/ + } private static boolean isEvaluationValid(String expirationTime) { try { diff --git a/src/main/kotlin/co/anbora/labs/jmeter/ide/listeners/JMeterSelectionListener.kt b/src/main/kotlin/co/anbora/labs/jmeter/ide/listeners/JMeterSelectionListener.kt index cc75a0d..577251f 100644 --- a/src/main/kotlin/co/anbora/labs/jmeter/ide/listeners/JMeterSelectionListener.kt +++ b/src/main/kotlin/co/anbora/labs/jmeter/ide/listeners/JMeterSelectionListener.kt @@ -2,6 +2,7 @@ package co.anbora.labs.jmeter.ide.listeners import co.anbora.labs.jmeter.ide.checker.CheckerFlavor import co.anbora.labs.jmeter.ide.editor.gui.JMeterFileEditor +import co.anbora.labs.jmeter.ide.license.CheckLicense import co.anbora.labs.jmeter.ide.notifications.JMeterNotifications import co.anbora.labs.jmeter.ide.utils.toPath import com.intellij.openapi.fileEditor.FileEditorManagerEvent @@ -13,6 +14,7 @@ class JMeterSelectionListener: FileEditorManagerListener { val editor = event.newEditor if (editor is JMeterFileEditor) { if (!CheckerFlavor.isSupported()) { + CheckLicense.requestLicense("Support plugin") JMeterNotifications.supportNotification(editor.getProject()) } val fileName = event.newFile?.path?.toPath()?.toFile()?.name.orEmpty() diff --git a/src/main/kotlin/co/anbora/labs/jmeter/ide/settings/JMeterDownloadToolchainDialog.kt b/src/main/kotlin/co/anbora/labs/jmeter/ide/settings/JMeterDownloadToolchainDialog.kt index 540268f..25de943 100644 --- a/src/main/kotlin/co/anbora/labs/jmeter/ide/settings/JMeterDownloadToolchainDialog.kt +++ b/src/main/kotlin/co/anbora/labs/jmeter/ide/settings/JMeterDownloadToolchainDialog.kt @@ -44,7 +44,7 @@ class JMeterDownloadToolchainDialog( .withTitle("Select Directory") .withPathToTextConvertor(::getPresentablePath) .withTextToPathConvertor(::getCanonicalPath) - textFieldWithBrowseButton("JMeter Directory", project, fileChooserDescriptor) + textFieldWithBrowseButton(fileChooserDescriptor, project) .align(AlignX.FILL) .bindText(model::location) .trimmedTextValidation(CHECK_NON_EMPTY, CHECK_DIRECTORY) diff --git a/src/main/kotlin/co/anbora/labs/jmeter/ide/startup/InitConfigFiles.kt b/src/main/kotlin/co/anbora/labs/jmeter/ide/startup/InitConfigFiles.kt index d5baee3..66c752f 100644 --- a/src/main/kotlin/co/anbora/labs/jmeter/ide/startup/InitConfigFiles.kt +++ b/src/main/kotlin/co/anbora/labs/jmeter/ide/startup/InitConfigFiles.kt @@ -2,6 +2,7 @@ package co.anbora.labs.jmeter.ide.startup import co.anbora.labs.jmeter.ide.actions.SetupFilesAction import co.anbora.labs.jmeter.ide.checker.CheckerFlavor +import co.anbora.labs.jmeter.ide.license.CheckLicense import co.anbora.labs.jmeter.ide.notifications.JMeterNotifications import co.anbora.labs.jmeter.ide.toolchain.JMeterToolchainService.Companion.toolchainSettings import co.anbora.labs.jmeter.loader.JMeterLoader diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index ea4dfa4..fa27427 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -2,9 +2,9 @@ co.anbora.labs.jmeter.jmeter-intellij JMeter Viewer - Anbora-labs + Anbora-labs - +