From 107d9e4cf39889e0407b3a34cd1c50ef3528dc07 Mon Sep 17 00:00:00 2001 From: Gaurav Gupta Date: Mon, 3 Aug 2026 19:58:52 +0530 Subject: [PATCH] Add Payara Server Maven Plugin NetBeans integration module --- enterprise/maven.j2ee/nbproject/project.xml | 1 + .../micro/project/MicroProjectHook.java | 14 +- enterprise/payara.server.maven/build.xml | 25 + enterprise/payara.server.maven/manifest.mf | 5 + .../nbproject/project.properties | 18 + .../payara.server.maven/nbproject/project.xml | 172 +++++++ .../modules/payara/server/maven/layer.xml | 5 + .../payara/server/maven/plugin/Constants.java | 120 +++++ .../server/maven/project/ActionType.java | 65 +++ .../server/maven/project/Bundle.properties | 27 ++ .../maven/project/LookupProviderImpl.java | 46 ++ .../maven/project/PayaraAIModelRegistry.java | 201 ++++++++ .../project/ServerMavenActionsProvider.java | 151 ++++++ .../maven/project/ServerMavenApplication.java | 163 +++++++ .../ServerMavenApplicationContent.java | 108 +++++ .../server/maven/project/ServerMavenIcon.java | 67 +++ .../maven/project/ServerMavenProjectHook.java | 57 +++ .../project/ServerMavenPropertiesPanel.java | 436 ++++++++++++++++++ .../ServerMavenPropertiesPanelProvider.java | 75 +++ .../project/resources/action-mapping.xml | 176 +++++++ .../resources/payara-server-maven-build.png | Bin 0 -> 1029 bytes .../payara-server-maven-clean-build.png | Bin 0 -> 1112 bytes .../resources/payara-server-maven-clean.png | Bin 0 -> 1083 bytes .../resources/payara-server-maven-debug.png | Bin 0 -> 968 bytes .../resources/payara-server-maven-profile.png | Bin 0 -> 1125 bytes .../resources/payara-server-maven-reload.png | Bin 0 -> 993 bytes .../resources/payara-server-maven-restart.png | Bin 0 -> 794 bytes .../resources/payara-server-maven-start.png | Bin 0 -> 837 bytes .../project/resources/payara-server-maven.png | Bin 0 -> 1085 bytes .../payara.tooling/nbproject/project.xml | 1 + java/maven.embedder/nbproject/project.xml | 1 + java/maven.model/nbproject/project.xml | 1 + java/maven/nbproject/project.xml | 1 + nbbuild/cluster.properties | 1 + 34 files changed, 1929 insertions(+), 8 deletions(-) create mode 100644 enterprise/payara.server.maven/build.xml create mode 100644 enterprise/payara.server.maven/manifest.mf create mode 100644 enterprise/payara.server.maven/nbproject/project.properties create mode 100644 enterprise/payara.server.maven/nbproject/project.xml create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/layer.xml create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/plugin/Constants.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ActionType.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/Bundle.properties create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/LookupProviderImpl.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/PayaraAIModelRegistry.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenActionsProvider.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenApplication.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenApplicationContent.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenIcon.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenProjectHook.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenPropertiesPanel.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenPropertiesPanelProvider.java create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/action-mapping.xml create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-build.png create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-clean-build.png create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-clean.png create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-debug.png create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-profile.png create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-reload.png create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-restart.png create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-start.png create mode 100644 enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven.png diff --git a/enterprise/maven.j2ee/nbproject/project.xml b/enterprise/maven.j2ee/nbproject/project.xml index a70354b63829..71488f740e42 100644 --- a/enterprise/maven.j2ee/nbproject/project.xml +++ b/enterprise/maven.j2ee/nbproject/project.xml @@ -542,6 +542,7 @@ org.netbeans.modules.maven.jaxws org.netbeans.modules.payara.micro + org.netbeans.modules.payara.server.maven org.netbeans.modules.jakarta.transformer org.netbeans.modules.maven.j2ee org.netbeans.modules.maven.j2ee.execution diff --git a/enterprise/payara.micro/src/org/netbeans/modules/fish/payara/micro/project/MicroProjectHook.java b/enterprise/payara.micro/src/org/netbeans/modules/fish/payara/micro/project/MicroProjectHook.java index d13d0a9a8649..973ebc3733ee 100644 --- a/enterprise/payara.micro/src/org/netbeans/modules/fish/payara/micro/project/MicroProjectHook.java +++ b/enterprise/payara.micro/src/org/netbeans/modules/fish/payara/micro/project/MicroProjectHook.java @@ -61,16 +61,14 @@ public void projectClosed() { } } } - + private void updateMicroIcon() { - SpecialIcon specialIcon = project.getLookup().lookup(SpecialIcon.class); - MicroIcon microIcon; - if (specialIcon instanceof MicroIcon) { - microIcon = (MicroIcon) specialIcon; - } else { - return; + for (SpecialIcon specialIcon : project.getLookup().lookupAll(SpecialIcon.class)) { + if (specialIcon instanceof MicroIcon) { + ((MicroIcon) specialIcon).setProject(project); + return; + } } - microIcon.setProject(project); } private void addDeployOnSaveManager(Project project) { diff --git a/enterprise/payara.server.maven/build.xml b/enterprise/payara.server.maven/build.xml new file mode 100644 index 000000000000..77735508b360 --- /dev/null +++ b/enterprise/payara.server.maven/build.xml @@ -0,0 +1,25 @@ + + + + Builds, tests, and runs the project org.netbeans.modules.payara.server.maven + + diff --git a/enterprise/payara.server.maven/manifest.mf b/enterprise/payara.server.maven/manifest.mf new file mode 100644 index 000000000000..905f2f29e066 --- /dev/null +++ b/enterprise/payara.server.maven/manifest.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +AutoUpdate-Show-In-Client: false +OpenIDE-Module: org.netbeans.modules.payara.server.maven/0 +OpenIDE-Module-Layer: org/netbeans/modules/payara/server/maven/layer.xml +OpenIDE-Module-Specification-Version: 1.0 diff --git a/enterprise/payara.server.maven/nbproject/project.properties b/enterprise/payara.server.maven/nbproject/project.properties new file mode 100644 index 000000000000..0f4ec98bc91a --- /dev/null +++ b/enterprise/payara.server.maven/nbproject/project.properties @@ -0,0 +1,18 @@ +# 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. +javac.source=1.8 +javac.compilerargs=-Xlint -Xlint:-serial diff --git a/enterprise/payara.server.maven/nbproject/project.xml b/enterprise/payara.server.maven/nbproject/project.xml new file mode 100644 index 000000000000..4afc7e065835 --- /dev/null +++ b/enterprise/payara.server.maven/nbproject/project.xml @@ -0,0 +1,172 @@ + + + + org.netbeans.modules.apisupport.project + + + org.netbeans.modules.payara.server.maven + + + org.netbeans.api.annotations.common + + + + 1 + 1.27.1 + + + + org.netbeans.modules.j2eeapis + + + + 1 + 1.35.1 + + + + org.netbeans.modules.j2eeserver + + + + 4 + 1.116 + + + + org.netbeans.modules.maven + + + + 2 + 2.133 + + + + org.netbeans.modules.maven.embedder + + + + 2 + 2.58 + + + + org.netbeans.modules.maven.j2ee + + + + 1 + 1.65 + + + + org.netbeans.modules.payara.tooling + + + + 0 + 2.5 + + + + org.netbeans.modules.projectapi + + + + 1 + 1.72 + + + + org.netbeans.modules.projectuiapi + + + + 1 + 1.88.1.8 + + + + org.netbeans.modules.projectuiapi.base + + + + 1 + 1.85.1.9 + + + + org.openide.execution + + + + 9.3.1 + + + + org.openide.filesystems + + + + 9.10.1 + + + + org.openide.util + + + + 9.7.1 + + + + org.openide.util.lookup + + + + 8.33.1 + + + + org.openide.awt + + + + 7.73 + + + + org.openide.util.ui + + + + 9.6.1 + + + + + org.netbeans.modules.payara.server.maven.plugin + + + + diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/layer.xml b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/layer.xml new file mode 100644 index 000000000000..5ff55e39af13 --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/layer.xml @@ -0,0 +1,5 @@ + + + + diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/plugin/Constants.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/plugin/Constants.java new file mode 100644 index 000000000000..7bf7cb719654 --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/plugin/Constants.java @@ -0,0 +1,120 @@ +/* + * 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.netbeans.modules.payara.server.maven.plugin; + +import org.netbeans.api.annotations.common.StaticResource; +import org.netbeans.modules.maven.api.NbMavenProject; +import org.netbeans.spi.project.ActionProvider; + +/** + * @author Gaurav Gupta + */ +public interface Constants { + + String WAR_PACKAGING = "war"; + + String MAVEN_WAR_PROJECT_TYPE = "org-netbeans-modules-maven/" + NbMavenProject.TYPE_WAR; + + String PAYARA_SERVER_MAVEN_PLUGIN = "fish.payara.maven.plugins:payara-server-maven-plugin"; + + String PLUGIN_GROUP_ID = "fish.payara.maven.plugins"; + String PLUGIN_ARTIFACT_ID = "payara-server-maven-plugin"; + + String RUN_SINGLE_ACTION = ActionProvider.COMMAND_RUN_SINGLE + ".deploy"; + String DEBUG_SINGLE_ACTION = ActionProvider.COMMAND_DEBUG_SINGLE + ".deploy"; + String PROFILE_SINGLE_ACTION = ActionProvider.COMMAND_PROFILE_SINGLE + ".deploy"; + + // ── Preference keys (stored per-project via ProjectUtils.getPreferences) ── + String PREF_SERVER_VERSION = "payaraServerVersion"; + String PREF_SERVER_PATH = "payaraServerPath"; + String PREF_DOMAIN_NAME = "domainName"; + String PREF_CONTEXT_ROOT = "contextRoot"; + String PREF_EXPLODED = "exploded"; + String PREF_REMOTE = "remote"; + String PREF_HOST_NAME = "hostName"; + String PREF_ADMIN_PORT = "adminPort"; + String PREF_ADMIN_USER = "adminUser"; + String PREF_INSTANCE_NAME = "instanceName"; + String PREF_HOT_DEPLOY = "hotDeploy"; + String PREF_AUTO_DEPLOY = "autoDeploy"; + String PREF_LIVE_RELOAD = "liveReload"; + String PREF_KEEP_STATE = "keepState"; + String PREF_TRIM_LOG = "trimLog"; + String PREF_DAEMON = "daemon"; + String PREF_IGNORE_TEST = "ignoreTestChanges"; + + // ── Maven property names (passed as -D arguments to the plugin) ────────── + String MVNPROP_SERVER_VERSION = "payara.server.version"; + String MVNPROP_SERVER_PATH = "payara.server.path"; + String MVNPROP_DOMAIN_NAME = "payara.domain.name"; + String MVNPROP_CONTEXT_ROOT = "payara.context.root"; + String MVNPROP_EXPLODED = "payara.exploded"; + String MVNPROP_REMOTE = "payara.remote"; + String MVNPROP_HOST_NAME = "payara.host.name"; + String MVNPROP_ADMIN_PORT = "payara.admin.port"; + String MVNPROP_ADMIN_USER = "payara.admin.user"; + String MVNPROP_INSTANCE_NAME = "payara.instance.name"; + String MVNPROP_HOT_DEPLOY = "payara.hot.deploy"; + String MVNPROP_AUTO_DEPLOY = "payara.auto.deploy"; + String MVNPROP_LIVE_RELOAD = "payara.live.reload"; + String MVNPROP_KEEP_STATE = "payara.keep.state"; + String MVNPROP_TRIM_LOG = "payara.trim.log"; + String MVNPROP_DAEMON = "payara.daemon"; + String MVNPROP_IGNORE_TEST = "payara.ignore.test.changes"; + String PREF_AI_AGENT = "aiAgent"; + String PREF_AI_API_KEY = "aiApiKey"; + String PREF_AI_PROVIDER = "aiProvider"; + String PREF_AI_PROVIDER_LOC = "aiProviderLocation"; + String PREF_AI_MODEL = "aiModel"; + + String ENV_AI_API_KEY = "PAYARA_AI_API_KEY"; + + String MVNPROP_AI_AGENT = "payara.ai.agent"; + String MVNPROP_AI_API_KEY = "payara.ai.api.key"; + String MVNPROP_AI_PROVIDER = "payara.ai.provider"; + String MVNPROP_AI_PROVIDER_LOC = "payara.ai.provider.location"; + String MVNPROP_AI_MODEL = "payara.ai.model"; + + @StaticResource + String PROJECT_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven.png"; + + @StaticResource + String CLEAN_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-clean.png"; + + @StaticResource + String BUILD_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-build.png"; + + @StaticResource + String REBUILD_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-clean-build.png"; + + @StaticResource + String START_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-start.png"; + + @StaticResource + String RESTART_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-restart.png"; + + @StaticResource + String RELOAD_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-reload.png"; + + @StaticResource + String DEBUG_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-debug.png"; + + @StaticResource + String PROFILE_ICON = "org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-profile.png"; +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ActionType.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ActionType.java new file mode 100644 index 000000000000..0638d7f07c20 --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ActionType.java @@ -0,0 +1,65 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import static org.netbeans.modules.payara.server.maven.plugin.Constants.BUILD_ICON; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.CLEAN_ICON; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.DEBUG_ICON; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.PROFILE_ICON; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.REBUILD_ICON; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.RELOAD_ICON; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.START_ICON; + +/** + * @author Gaurav Gupta + */ +public enum ActionType { + + CLEAN(CLEAN_ICON), + BUILD(BUILD_ICON), + BUILD_WITH_DEPENDENCIES(BUILD_ICON), + REBUILD(REBUILD_ICON), + + SERVER_MAVEN_DEV(RELOAD_ICON), + + RUN(START_ICON), + DEBUG(DEBUG_ICON), + PROFILE(PROFILE_ICON); + + private final String icon; + + private ActionType(String icon) { + this.icon = icon; + } + + public String getIcon() { + return icon; + } + + public static ActionType toAction(String actionType) { + if (actionType == null) { + return null; + } + try { + return ActionType.valueOf(actionType.toUpperCase()); + } catch (IllegalArgumentException e) { + return null; + } + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/Bundle.properties b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/Bundle.properties new file mode 100644 index 000000000000..9bea6f63cd3a --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/Bundle.properties @@ -0,0 +1,27 @@ +ServerMavenPropertiesPanel.section.ai=AI Agent +ServerMavenPropertiesPanel.aiAgentLabel.text=Enable AI Agent: +ServerMavenPropertiesPanel.aiApiKeyLabel.text=API Key: +ServerMavenPropertiesPanel.aiProviderLabel.text=Provider: +ServerMavenPropertiesPanel.aiProviderLocLabel.text=Provider Location: +ServerMavenPropertiesPanel.aiModelLabel.text=Model: +ServerMavenPropertiesPanel.section.server=Server Configuration +ServerMavenPropertiesPanel.section.remote=Remote Connection +ServerMavenPropertiesPanel.section.devmode=Dev Mode +ServerMavenPropertiesPanel.serverVersionLabel.text=Payara Server Version: +ServerMavenPropertiesPanel.serverPathLabel.text=Server Path: +ServerMavenPropertiesPanel.serverPathBrowse.tooltip=Browse for Payara Server installation directory +ServerMavenPropertiesPanel.domainNameLabel.text=Domain Name: +ServerMavenPropertiesPanel.contextRootLabel.text=Context Root: +ServerMavenPropertiesPanel.instanceNameLabel.text=Instance Name: +ServerMavenPropertiesPanel.explodedLabel.text=Exploded: +ServerMavenPropertiesPanel.remoteLabel.text=Remote: +ServerMavenPropertiesPanel.hostNameLabel.text=Host Name: +ServerMavenPropertiesPanel.adminPortLabel.text=Admin Port: +ServerMavenPropertiesPanel.adminUserLabel.text=Admin User: +ServerMavenPropertiesPanel.hotDeployLabel.text=Hot Deploy: +ServerMavenPropertiesPanel.autoDeployLabel.text=Auto Deploy: +ServerMavenPropertiesPanel.liveReloadLabel.text=Live Reload: +ServerMavenPropertiesPanel.keepStateLabel.text=Keep State: +ServerMavenPropertiesPanel.trimLogLabel.text=Trim Log: +ServerMavenPropertiesPanel.daemonLabel.text=Daemon: +ServerMavenPropertiesPanel.ignoreTestLabel.text=Ignore Test Changes: diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/LookupProviderImpl.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/LookupProviderImpl.java new file mode 100644 index 000000000000..bf50f2ad79e0 --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/LookupProviderImpl.java @@ -0,0 +1,46 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import org.netbeans.api.project.Project; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.MAVEN_WAR_PROJECT_TYPE; +import org.netbeans.spi.project.LookupProvider; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.ProxyLookup; + +/** + * Adds {@link ServerMavenApplicationContent} to every Maven WAR project, plus + * a dynamic extra lookup that receives a {@link ServerMavenIcon} only when the + * project is detected as a payara-server-maven-plugin project. This ensures the + * icon only appears in server-maven project lookups and never interferes with + * Micro or plain WAR project icon resolution. + * + * @author Gaurav Gupta + */ +@LookupProvider.Registration(projectType = MAVEN_WAR_PROJECT_TYPE) +public class LookupProviderImpl implements LookupProvider { + + @Override + public Lookup createAdditionalLookup(Lookup lookup) { + Project project = lookup.lookup(Project.class); + ServerMavenApplicationContent content = new ServerMavenApplicationContent(project); + return new ProxyLookup(Lookups.singleton(content), content.getExtraLookup()); + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/PayaraAIModelRegistry.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/PayaraAIModelRegistry.java new file mode 100644 index 000000000000..8e90df082f4e --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/PayaraAIModelRegistry.java @@ -0,0 +1,201 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Fetches available AI model names for each provider. + *

+ * Cloud providers: fetched from OpenRouter's public API with a 30-minute cache.
+ * Local providers (Ollama, LM Studio, GPT4All): fetched live from the local + * server API using the configured or default base URL. + * + * @author Gaurav Gupta + */ +public final class PayaraAIModelRegistry { + + // ── Cloud (OpenRouter) ──────────────────────────────────────────────────── + + private static final String OPENROUTER_URL = "https://openrouter.ai/api/v1/models"; + private static final long CACHE_TTL_MS = Duration.ofMinutes(30).toMillis(); + + private static final Pattern ID_PATTERN = Pattern.compile("\"id\"\\s*:\\s*\"([^\"]+)\""); + private static final Pattern NAME_PATTERN = Pattern.compile("\"name\"\\s*:\\s*\"([^\"]+)\""); + + private static volatile List CACHE = Collections.emptyList(); + private static volatile long lastFetch = 0; + + private PayaraAIModelRegistry() {} + + // ── Local providers ─────────────────────────────────────────────────────── + + public static final Set LOCAL_PROVIDERS = new HashSet<>( + Arrays.asList("OLLAMA", "LM_STUDIO", "GPT4ALL")); + + private static final Map DEFAULT_BASE_URLS = new LinkedHashMap<>(); + static { + DEFAULT_BASE_URLS.put("OLLAMA", "http://localhost:11434"); + DEFAULT_BASE_URLS.put("LM_STUDIO", "http://localhost:1234"); + DEFAULT_BASE_URLS.put("GPT4ALL", "http://localhost:4891"); + } + + /** + * Returns model names for a local provider by querying its running server. + * Falls back to an empty list if the server is not reachable. + * + * @param provider local provider key (OLLAMA, LM_STUDIO, GPT4ALL) + * @param providerLocation custom base URL, or empty/null to use the default + */ + public static List getLocalModels(String provider, String providerLocation) { + String base = (providerLocation != null && !providerLocation.trim().isEmpty()) + ? providerLocation.trim().replaceAll("/$", "") + : DEFAULT_BASE_URLS.getOrDefault(provider, "http://localhost:8080"); + try { + if ("OLLAMA".equals(provider)) { + return fetchNames(base + "/api/tags", NAME_PATTERN); + } else { + // LM Studio and GPT4All both expose an OpenAI-compatible /v1/models + return fetchIds(base + "/v1/models"); + } + } catch (Exception ignored) { + return Collections.emptyList(); + } + } + + // ── Cloud providers (OpenRouter) ────────────────────────────────────────── + + private static final Map> PROVIDER_PREFIXES = new LinkedHashMap<>(); + static { + PROVIDER_PREFIXES.put("OPEN_AI", Arrays.asList("openai/")); + PROVIDER_PREFIXES.put("ANTHROPIC", Arrays.asList("anthropic/")); + PROVIDER_PREFIXES.put("GOOGLE", Arrays.asList("google/")); + PROVIDER_PREFIXES.put("MISTRAL", Arrays.asList("mistralai/", "mistral/")); + PROVIDER_PREFIXES.put("GROQ", Arrays.asList("meta-llama/", "groq/", "mixtral", "llama")); + PROVIDER_PREFIXES.put("DEEPSEEK", Arrays.asList("deepseek/")); + PROVIDER_PREFIXES.put("DEEPINFRA", Collections.emptyList()); + PROVIDER_PREFIXES.put("CUSTOM_OPEN_AI", Collections.emptyList()); + } + + public static List getModels() { + if (!CACHE.isEmpty() + && (System.currentTimeMillis() - lastFetch) < CACHE_TTL_MS) { + return CACHE; + } + synchronized (PayaraAIModelRegistry.class) { + if (!CACHE.isEmpty() + && (System.currentTimeMillis() - lastFetch) < CACHE_TTL_MS) { + return CACHE; + } + try { + List fetched = fetchIds(OPENROUTER_URL); + if (!fetched.isEmpty()) { + CACHE = fetched; + lastFetch = System.currentTimeMillis(); + } + } catch (Exception ignored) { + } + return CACHE; + } + } + + public static List getModelsForProvider(String provider) { + List all = getModels(); + List prefixes = PROVIDER_PREFIXES.get(provider); + if (prefixes == null || prefixes.isEmpty()) { + return all; + } + List filtered = new ArrayList<>(); + for (String id : all) { + for (String prefix : prefixes) { + if (id.startsWith(prefix)) { + int slash = id.indexOf('/'); + filtered.add(slash >= 0 ? id.substring(slash + 1) : id); + break; + } + } + } + return filtered; + } + + // ── HTTP helpers ────────────────────────────────────────────────────────── + + private static String httpGet(String apiUrl) throws Exception { + HttpURLConnection conn = (HttpURLConnection) new URL(apiUrl).openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(3_000); + conn.setReadTimeout(5_000); + conn.setRequestProperty("Accept", "application/json"); + try { + if (conn.getResponseCode() != 200) { + return ""; + } + StringBuilder sb = new StringBuilder(); + try (InputStream is = conn.getInputStream(); + BufferedReader br = new BufferedReader( + new InputStreamReader(is, StandardCharsets.UTF_8))) { + String line; + while ((line = br.readLine()) != null) { + sb.append(line); + } + } + return sb.toString(); + } finally { + conn.disconnect(); + } + } + + /** Extracts all {@code "id":"value"} entries from a JSON response. */ + private static List fetchIds(String apiUrl) throws Exception { + String json = httpGet(apiUrl); + List ids = new ArrayList<>(); + Matcher m = ID_PATTERN.matcher(json); + while (m.find()) { + ids.add(m.group(1)); + } + return ids; + } + + /** Extracts all {@code "name":"value"} entries from a JSON response (Ollama). */ + private static List fetchNames(String apiUrl, Pattern pattern) throws Exception { + String json = httpGet(apiUrl); + List names = new ArrayList<>(); + Matcher m = pattern.matcher(json); + while (m.find()) { + names.add(m.group(1)); + } + return names; + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenActionsProvider.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenActionsProvider.java new file mode 100644 index 000000000000..c7d1f7d3a6cb --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenActionsProvider.java @@ -0,0 +1,151 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import static org.netbeans.modules.payara.server.maven.plugin.Constants.*; +import java.io.InputStream; +import java.util.Set; +import java.util.prefs.Preferences; +import org.netbeans.api.annotations.common.StaticResource; +import org.netbeans.api.project.Project; +import static org.netbeans.api.project.ProjectUtils.getPreferences; +import org.netbeans.modules.maven.api.NbMavenProject; +import org.netbeans.modules.maven.api.execute.RunConfig; +import org.netbeans.modules.maven.execute.model.NetbeansActionMapping; +import org.netbeans.modules.maven.spi.actions.AbstractMavenActionsProvider; +import org.netbeans.modules.maven.spi.actions.MavenActionsProvider; +import static org.netbeans.spi.project.ActionProvider.COMMAND_DEBUG; +import static org.netbeans.spi.project.ActionProvider.COMMAND_PROFILE; +import static org.netbeans.spi.project.ActionProvider.COMMAND_RUN; +import org.netbeans.spi.project.ProjectServiceProvider; +import org.openide.util.Lookup; + +/** + * @author Gaurav Gupta + */ +@ProjectServiceProvider( + service = MavenActionsProvider.class, + projectType = MAVEN_WAR_PROJECT_TYPE +) +public class ServerMavenActionsProvider implements MavenActionsProvider { + + @StaticResource + static final String ACTION_MAPPINGS = + "org/netbeans/modules/payara/server/maven/project/resources/action-mapping.xml"; + + final AbstractMavenActionsProvider actionsProvider = new AbstractMavenActionsProvider() { + @Override + protected InputStream getActionDefinitionStream() { + return ServerMavenActionsProvider.class + .getClassLoader() + .getResourceAsStream(ACTION_MAPPINGS); + } + + @Override + public boolean isActionEnable(String action, Project project, Lookup lookup) { + NbMavenProject nbMavenProject = project.getLookup().lookup(NbMavenProject.class); + if (nbMavenProject == null || !WAR_PACKAGING.equals(nbMavenProject.getPackagingType())) { + return false; + } + switch (action) { + case COMMAND_RUN: + case COMMAND_DEBUG: + case COMMAND_PROFILE: + case RUN_SINGLE_ACTION: + case DEBUG_SINGLE_ACTION: + case PROFILE_SINGLE_ACTION: + break; + default: + return false; + } + return ServerMavenApplication.getInstance(project) != null; + } + }; + + @Override + public RunConfig createConfigForDefaultAction(String actionName, Project project, Lookup lookup) { + if (ServerMavenApplication.getInstance(project) == null) { + return null; + } + RunConfig rc = actionsProvider.createConfigForDefaultAction(actionName, project, lookup); + if (rc == null) { + return null; + } + Preferences pref = getPreferences(project, ServerMavenApplication.class, true); + setIfNotEmpty(rc, MVNPROP_SERVER_VERSION, pref.get(PREF_SERVER_VERSION, "")); + setIfNotEmpty(rc, MVNPROP_SERVER_PATH, pref.get(PREF_SERVER_PATH, "")); + setIfNotEmpty(rc, MVNPROP_DOMAIN_NAME, pref.get(PREF_DOMAIN_NAME, "")); + setIfNotEmpty(rc, MVNPROP_CONTEXT_ROOT, pref.get(PREF_CONTEXT_ROOT, "")); + setIfNotEmpty(rc, MVNPROP_INSTANCE_NAME, pref.get(PREF_INSTANCE_NAME, "")); + if (pref.getBoolean(PREF_REMOTE, false)) { + rc.setProperty(MVNPROP_REMOTE, Boolean.TRUE.toString()); + setIfNotEmpty(rc, MVNPROP_HOST_NAME, pref.get(PREF_HOST_NAME, "")); + setIfNotEmpty(rc, MVNPROP_ADMIN_PORT, pref.get(PREF_ADMIN_PORT, "")); + setIfNotEmpty(rc, MVNPROP_ADMIN_USER, pref.get(PREF_ADMIN_USER, "")); + } + if (pref.getBoolean(PREF_EXPLODED, true)) rc.setProperty(MVNPROP_EXPLODED, Boolean.TRUE.toString()); + if (pref.getBoolean(PREF_HOT_DEPLOY, false)) rc.setProperty(MVNPROP_HOT_DEPLOY, Boolean.TRUE.toString()); + if (pref.getBoolean(PREF_AUTO_DEPLOY, true)) rc.setProperty(MVNPROP_AUTO_DEPLOY, Boolean.TRUE.toString()); + if (pref.getBoolean(PREF_LIVE_RELOAD, true)) rc.setProperty(MVNPROP_LIVE_RELOAD, Boolean.TRUE.toString()); + if (pref.getBoolean(PREF_KEEP_STATE, true)) rc.setProperty(MVNPROP_KEEP_STATE, Boolean.TRUE.toString()); + if (pref.getBoolean(PREF_TRIM_LOG, true)) rc.setProperty(MVNPROP_TRIM_LOG, Boolean.TRUE.toString()); + if (pref.getBoolean(PREF_DAEMON, false)) rc.setProperty(MVNPROP_DAEMON, Boolean.TRUE.toString()); + if (!pref.getBoolean(PREF_IGNORE_TEST, true)) rc.setProperty(MVNPROP_IGNORE_TEST, Boolean.FALSE.toString()); + if (pref.getBoolean(PREF_AI_AGENT, false)) { + rc.setProperty(MVNPROP_AI_AGENT, Boolean.TRUE.toString()); + String apiKey = pref.get(PREF_AI_API_KEY, ""); + if (apiKey.isEmpty()) { + apiKey = System.getenv(ENV_AI_API_KEY); + } + setIfNotEmpty(rc, MVNPROP_AI_API_KEY, apiKey != null ? apiKey : ""); + setIfNotEmpty(rc, MVNPROP_AI_PROVIDER, pref.get(PREF_AI_PROVIDER, "")); + setIfNotEmpty(rc, MVNPROP_AI_PROVIDER_LOC, pref.get(PREF_AI_PROVIDER_LOC, "")); + setIfNotEmpty(rc, MVNPROP_AI_MODEL, pref.get(PREF_AI_MODEL, "")); + } + return rc; + } + + @Override + public NetbeansActionMapping getMappingForAction(String actionName, Project project) { + if (ServerMavenApplication.getInstance(project) != null) { + return actionsProvider.getMappingForAction(actionName, project); + } + return null; + } + + @Override + public boolean isActionEnable(String action, Project project, Lookup lookup) { + if (ServerMavenApplication.getInstance(project) != null) { + return actionsProvider.isActionEnable(action, project, lookup); + } + return false; + } + + @Override + public Set getSupportedDefaultActions() { + return actionsProvider.getSupportedDefaultActions(); + } + + private static void setIfNotEmpty(org.netbeans.modules.maven.api.execute.RunConfig rc, + String key, String value) { + if (value != null && !value.isEmpty()) { + rc.setProperty(key, value); + } + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenApplication.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenApplication.java new file mode 100644 index 000000000000..c59a46c9d31e --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenApplication.java @@ -0,0 +1,163 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.maven.project.MavenProject; +import org.netbeans.api.project.Project; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.PAYARA_SERVER_MAVEN_PLUGIN; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.PLUGIN_ARTIFACT_ID; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.PLUGIN_GROUP_ID; +import org.netbeans.modules.maven.api.NbMavenProject; +import org.openide.execution.ExecutorTask; + +/** + * @author Gaurav Gupta + */ +public class ServerMavenApplication { + + private final Project project; + + private final MavenProject mavenProject; + + private volatile ActionType buildActionType; + + private volatile boolean buildAction; + + private volatile ActionType runActionType; + + private final AtomicInteger runActionCount = new AtomicInteger(); + + private volatile boolean reloadAction; + + private final List runningTasks = new ArrayList<>(); + + private static final String SINGLE = ".single.deploy"; + + public ServerMavenApplication(Project project) { + this.project = project; + NbMavenProject nbMavenProject = project.getLookup().lookup(NbMavenProject.class); + this.mavenProject = nbMavenProject.getMavenProject(); + } + + public Project getProject() { + return project; + } + + public MavenProject getMavenProject() { + return mavenProject; + } + + public void setBuilding(boolean buildAction, String actionType) { + ActionType at = ActionType.toAction(actionType.replace("-", "_")); + this.buildActionType = at; + setBuilding(buildAction); + } + + public void setBuilding(boolean buildAction) { + this.buildAction = buildAction; + NbMavenProject.fireMavenProjectReload(project); + } + + public ActionType getBuildActionType() { + return buildActionType; + } + + public boolean isBuilding() { + return buildAction; + } + + public void setRunning(boolean running, String actionType) { + ActionType at = ActionType.toAction(actionType.replace(SINGLE, "")); + this.runActionType = at; + setRunning(running); + } + + public void setRunning(boolean running) { + if (running) { + runActionCount.incrementAndGet(); + } else if (isRunning()) { + runActionCount.decrementAndGet(); + } + NbMavenProject.fireMavenProjectReload(project); + } + + public boolean isRunning() { + return runActionCount.get() > 0; + } + + public int getRunningInstanceCount() { + return runActionCount.get(); + } + + public ActionType getRunActionType() { + return runActionType; + } + + public void setLoading(boolean loading) { + this.reloadAction = loading; + NbMavenProject.fireMavenProjectReload(project); + } + + public boolean isLoading() { + return reloadAction; + } + + public synchronized void addRunningTask(ExecutorTask task) { + runningTasks.add(task); + } + + public synchronized void stopAllRunningTasks() { + for (ExecutorTask task : runningTasks) { + task.stop(); + } + runningTasks.clear(); + } + + public static ServerMavenApplication getInstance(Project project) { + if (project != null) { + ServerMavenApplicationContent content = project.getLookup().lookup(ServerMavenApplicationContent.class); + if (content != null) { + return content.getApplication(); + } + } + return null; + } + + public static boolean isPayaraServerMavenProject(Project project) { + if (project == null) { + return false; + } + NbMavenProject nbMavenProject = project.getLookup().lookup(NbMavenProject.class); + if (nbMavenProject == null) { + return false; + } + MavenProject mp = nbMavenProject.getMavenProject(); + // Check resolved artifacts first (populated after Maven resolution) + if (mp.getPluginArtifactMap().containsKey(PAYARA_SERVER_MAVEN_PLUGIN)) { + return true; + } + // Check declared build plugins (populated from the POM model, no resolution needed) + return mp.getBuildPlugins().stream() + .anyMatch(p -> PLUGIN_GROUP_ID.equals(p.getGroupId()) + && PLUGIN_ARTIFACT_ID.equals(p.getArtifactId())); + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenApplicationContent.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenApplicationContent.java new file mode 100644 index 000000000000..6a2e3addead4 --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenApplicationContent.java @@ -0,0 +1,108 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import java.beans.PropertyChangeListener; +import javax.swing.SwingUtilities; +import org.netbeans.api.project.Project; +import org.netbeans.modules.maven.api.NbMavenProject; +import org.openide.util.Lookup; +import org.openide.util.lookup.AbstractLookup; +import org.openide.util.lookup.InstanceContent; + +/** + * Lookup-registered wrapper that carries a {@link ServerMavenApplication}. + *

+ * Detection is deferred to the first call of {@link #getApplication()} that + * occurs after the Maven project model has fully loaded, so it is safe to call + * from the Event Dispatch Thread without causing I/O hangs. + *

+ * When a server-maven project is detected, a {@link ServerMavenIcon} is added + * to {@link #getExtraLookup()} so the icon is only present in server-maven + * project lookups — not in plain WAR or Micro project lookups. + *

+ * If the Maven model has not yet loaded at construction time, a + * {@link NbMavenProject#PROP_PROJECT} listener is registered to trigger + * detection as soon as Maven finishes loading. + * + * @author Gaurav Gupta + */ +public class ServerMavenApplicationContent { + + private final Project project; + private volatile boolean initialized; + private volatile ServerMavenApplication application; + + private final InstanceContent extraServices = new InstanceContent(); + private final Lookup extraLookup = new AbstractLookup(extraServices); + + private PropertyChangeListener mavenLoadListener; + + public ServerMavenApplicationContent(Project project) { + this.project = project; + NbMavenProject nbmp = project.getLookup().lookup(NbMavenProject.class); + if (nbmp != null) { + if (nbmp.isMavenProjectLoaded()) { + getApplication(); + } else { + mavenLoadListener = evt -> { + if (NbMavenProject.PROP_PROJECT.equals(evt.getPropertyName())) { + getApplication(); + if (initialized) { + nbmp.removePropertyChangeListener(mavenLoadListener); + mavenLoadListener = null; + } + } + }; + nbmp.addPropertyChangeListener(mavenLoadListener); + } + } + } + + public Lookup getExtraLookup() { + return extraLookup; + } + + public ServerMavenApplication getApplication() { + if (!initialized) { + NbMavenProject nbmp = project.getLookup().lookup(NbMavenProject.class); + if (nbmp != null && nbmp.isMavenProjectLoaded()) { + synchronized (this) { + if (!initialized) { + if (ServerMavenApplication.isPayaraServerMavenProject(project)) { + application = new ServerMavenApplication(project); + ServerMavenIcon icon = new ServerMavenIcon(); + icon.setProject(project); + extraServices.add(icon); + SwingUtilities.invokeLater( + () -> NbMavenProject.fireMavenProjectReload(project)); + } + initialized = true; + } + } + } + } + return application; + } + + synchronized void setApplication(ServerMavenApplication application) { + this.application = application; + this.initialized = true; + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenIcon.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenIcon.java new file mode 100644 index 000000000000..b706f9643210 --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenIcon.java @@ -0,0 +1,67 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import static org.netbeans.modules.payara.server.maven.plugin.Constants.PROJECT_ICON; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.RELOAD_ICON; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.RESTART_ICON; +import javax.swing.Icon; +import org.netbeans.api.project.Project; +import org.netbeans.modules.maven.j2ee.ui.EEIcons.WarIcon; +import org.netbeans.modules.maven.spi.nodes.SpecialIcon; +import static org.openide.util.ImageUtilities.loadImageIcon; + +/** + * Provides the Payara Server Maven project icon. + *

+ * Not registered globally — added to the project lookup dynamically by + * {@link ServerMavenApplicationContent} only when the project is confirmed to + * use the payara-server-maven-plugin. This ensures it never appears in plain + * WAR or Micro project lookups. + * + * @author Gaurav Gupta + */ +public class ServerMavenIcon extends WarIcon { + + private volatile Project project; + + public void setProject(Project project) { + this.project = project; + } + + @Override + public Icon getIcon() { + ServerMavenApplication application = ServerMavenApplication.getInstance(project); + String icon = PROJECT_ICON; + if (application == null) { + return super.getIcon(); + } else if (application.isLoading()) { + icon = RELOAD_ICON; + } else if (application.isBuilding() && application.getBuildActionType() != null) { + icon = application.getBuildActionType().getIcon(); + } else if (application.isRunning()) { + if (application.getRunningInstanceCount() > 1) { + icon = RESTART_ICON; + } else if (application.getRunActionType() != null) { + icon = application.getRunActionType().getIcon(); + } + } + return loadImageIcon(icon, true); + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenProjectHook.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenProjectHook.java new file mode 100644 index 000000000000..133f0bb7988d --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenProjectHook.java @@ -0,0 +1,57 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import org.netbeans.api.project.Project; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.MAVEN_WAR_PROJECT_TYPE; +import org.netbeans.modules.maven.j2ee.ProjectHookImpl; +import org.netbeans.spi.project.ProjectServiceProvider; +import org.netbeans.spi.project.ui.ProjectOpenedHook; + +/** + * @author Gaurav Gupta + */ +@ProjectServiceProvider( + service = ProjectOpenedHook.class, + projectType = MAVEN_WAR_PROJECT_TYPE +) +public class ServerMavenProjectHook extends ProjectHookImpl { + + private final Project project; + + public ServerMavenProjectHook(Project project) { + super(project); + this.project = project; + } + + @Override + public void projectOpened() { + // ServerMavenApplicationContent.getApplication() handles detection + // and dynamically registers ServerMavenIcon when Maven model loads. + ServerMavenApplication.getInstance(project); + } + + @Override + public void projectClosed() { + ServerMavenApplication app = ServerMavenApplication.getInstance(project); + if (app != null) { + app.stopAllRunningTasks(); + } + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenPropertiesPanel.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenPropertiesPanel.java new file mode 100644 index 000000000000..d3b99a12dc6c --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenPropertiesPanel.java @@ -0,0 +1,436 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import java.awt.BorderLayout; +import java.io.File; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.prefs.Preferences; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.JTextField; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import org.netbeans.api.project.Project; +import static org.netbeans.api.project.ProjectUtils.getPreferences; +import static org.netbeans.modules.payara.server.maven.plugin.Constants.*; +import org.netbeans.modules.maven.api.customizer.ModelHandle2; +import org.netbeans.modules.payara.tooling.data.PayaraPlatformVersion; +import org.netbeans.modules.payara.tooling.data.PayaraPlatformVersionAPI; +import org.openide.util.NbBundle; +import org.openide.util.RequestProcessor; + +/** + * Project Properties panel for the Payara Server Maven Plugin, + * organised into collapsible sections. + * + * @author Gaurav Gupta + */ +public class ServerMavenPropertiesPanel extends JPanel implements Scrollable { + + private final Preferences pref; + + private static final RequestProcessor RP = new RequestProcessor(ServerMavenPropertiesPanel.class); + + // Server Configuration + private final JComboBox serverVersionCombo = new JComboBox<>(); + private final JTextField serverPathField = new JTextField(); + private final JTextField domainNameField = new JTextField(); + private final JTextField contextRootField = new JTextField(); + private final JTextField instanceNameField = new JTextField(); + + // Remote Connection + private final JCheckBox remoteCheckBox = new JCheckBox(); + private final JTextField hostNameField = new JTextField(); + private final JTextField adminPortField = new JTextField(); + private final JTextField adminUserField = new JTextField(); + + // Dev Mode + private final JCheckBox explodedCheckBox = new JCheckBox(); + private final JCheckBox hotDeployCheckBox = new JCheckBox(); + private final JCheckBox autoDeployCheckBox = new JCheckBox(); + private final JCheckBox liveReloadCheckBox = new JCheckBox(); + private final JCheckBox keepStateCheckBox = new JCheckBox(); + private final JCheckBox trimLogCheckBox = new JCheckBox(); + private final JCheckBox ignoreTestCheckBox = new JCheckBox(); + + // AI Agent + private final JCheckBox aiAgentCheckBox = new JCheckBox(); + private final JTextField aiApiKeyField = new JTextField(); + private final JComboBox aiProviderCombo = new JComboBox<>(); + private final JTextField aiProviderLocField = new JTextField(); + private final JComboBox aiModelCombo = new JComboBox<>(); + + public ServerMavenPropertiesPanel(ModelHandle2 handle, Project project) { + pref = getPreferences(project, ServerMavenApplication.class, true); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); + + remoteCheckBox.addActionListener(e -> updateRemoteEnabled()); + + // ── Section 1: Server Configuration ────────────────────────────────── + CollapsibleSection serverSection = new CollapsibleSection(msg("section.server"), true); + serverVersionCombo.setEditable(true); + serverVersionCombo.addItem("Loading..."); + serverSection.addComboRow(msg("serverVersionLabel.text"), serverVersionCombo); + + JButton serverPathBrowseButton = new JButton("..."); + serverPathBrowseButton.setToolTipText(msg("serverPathBrowse.tooltip")); + serverPathBrowseButton.addActionListener(e -> { + JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + String current = serverPathField.getText().trim(); + if (!current.isEmpty()) { + chooser.setCurrentDirectory(new File(current)); + } + if (chooser.showOpenDialog(ServerMavenPropertiesPanel.this) == JFileChooser.APPROVE_OPTION) { + serverPathField.setText(chooser.getSelectedFile().getAbsolutePath()); + } + }); + JPanel serverPathPanel = new JPanel(new BorderLayout(4, 0)); + serverPathPanel.setOpaque(false); + serverPathPanel.add(serverPathField, BorderLayout.CENTER); + serverPathPanel.add(serverPathBrowseButton, BorderLayout.EAST); + serverSection.addComponentRow(msg("serverPathLabel.text"), serverPathPanel); + serverSection.addRow(msg("domainNameLabel.text"), domainNameField); + serverSection.addRow(msg("contextRootLabel.text"), contextRootField); + serverSection.addRow(msg("instanceNameLabel.text"), instanceNameField); + + // ── Section 2: Remote Connection ────────────────────────────────────── + CollapsibleSection remoteSection = new CollapsibleSection(msg("section.remote"), false); + remoteSection.addCheckRow(msg("remoteLabel.text"), remoteCheckBox); + remoteSection.addRow(msg("hostNameLabel.text"), hostNameField); + remoteSection.addRow(msg("adminPortLabel.text"), adminPortField); + remoteSection.addRow(msg("adminUserLabel.text"), adminUserField); + + // ── Section 3: Dev Mode ─────────────────────────────────────────────── + CollapsibleSection devSection = new CollapsibleSection(msg("section.devmode"), true); + devSection.addCheckRow(msg("explodedLabel.text"), explodedCheckBox); + devSection.addCheckRow(msg("hotDeployLabel.text"), hotDeployCheckBox); + devSection.addCheckRow(msg("autoDeployLabel.text"), autoDeployCheckBox); + devSection.addCheckRow(msg("liveReloadLabel.text"), liveReloadCheckBox); + devSection.addCheckRow(msg("keepStateLabel.text"), keepStateCheckBox); + devSection.addCheckRow(msg("trimLogLabel.text"), trimLogCheckBox); + devSection.addCheckRow(msg("ignoreTestLabel.text"), ignoreTestCheckBox); + + // ── Section 4: AI Agent ─────────────────────────────────────────────── + CollapsibleSection aiSection = new CollapsibleSection(msg("section.ai"), false); + aiSection.addCheckRow(msg("aiAgentLabel.text"), aiAgentCheckBox); + aiSection.addRow(msg("aiApiKeyLabel.text"), aiApiKeyField); + for (String p : AI_PROVIDERS) aiProviderCombo.addItem(p); + aiProviderCombo.setEditable(true); + aiSection.addComboRow(msg("aiProviderLabel.text"), aiProviderCombo); + aiSection.addRow(msg("aiProviderLocLabel.text"), aiProviderLocField); + aiModelCombo.setEditable(true); + aiModelCombo.addItem(""); + aiSection.addComboRow(msg("aiModelLabel.text"), aiModelCombo); + + add(serverSection); + add(Box.createVerticalStrut(6)); + add(remoteSection); + add(Box.createVerticalStrut(6)); + add(devSection); + add(Box.createVerticalStrut(6)); + add(aiSection); + add(Box.createVerticalGlue()); + + loadPreferences(); + updateRemoteEnabled(); + } + + private void loadPreferences() { + loadServerVersions(pref.get(PREF_SERVER_VERSION, "")); + serverPathField.setText(pref.get(PREF_SERVER_PATH, "")); + domainNameField.setText(pref.get(PREF_DOMAIN_NAME, "")); + contextRootField.setText(pref.get(PREF_CONTEXT_ROOT, "")); + instanceNameField.setText(pref.get(PREF_INSTANCE_NAME, "")); + + remoteCheckBox.setSelected(pref.getBoolean(PREF_REMOTE, false)); + hostNameField.setText(pref.get(PREF_HOST_NAME, "")); + adminPortField.setText(pref.get(PREF_ADMIN_PORT, "")); + adminUserField.setText(pref.get(PREF_ADMIN_USER, "")); + + explodedCheckBox.setSelected(pref.getBoolean(PREF_EXPLODED, true)); + hotDeployCheckBox.setSelected(pref.getBoolean(PREF_HOT_DEPLOY, false)); + autoDeployCheckBox.setSelected(pref.getBoolean(PREF_AUTO_DEPLOY, true)); + liveReloadCheckBox.setSelected(pref.getBoolean(PREF_LIVE_RELOAD, true)); + keepStateCheckBox.setSelected(pref.getBoolean(PREF_KEEP_STATE, true)); + trimLogCheckBox.setSelected(pref.getBoolean(PREF_TRIM_LOG, true)); + ignoreTestCheckBox.setSelected(pref.getBoolean(PREF_IGNORE_TEST, true)); + aiAgentCheckBox.setSelected(pref.getBoolean(PREF_AI_AGENT, false)); + String storedKey = pref.get(PREF_AI_API_KEY, ""); + aiApiKeyField.setText(storedKey); + String envKey = System.getenv(ENV_AI_API_KEY); + if (envKey != null && !envKey.isEmpty()) { + String tip = storedKey.isEmpty() + ? "Using $" + ENV_AI_API_KEY + " env var (enter a key here to override it)" + : "This key overrides the $" + ENV_AI_API_KEY + " env var"; + aiApiKeyField.setToolTipText(tip); + } + String savedProvider = pref.get(PREF_AI_PROVIDER, ""); + if (!savedProvider.isEmpty()) aiProviderCombo.setSelectedItem(savedProvider); + // Listen to provider changes to update model list + aiProviderCombo.addActionListener(e -> { + Object prov = aiProviderCombo.getSelectedItem(); + Object model = aiModelCombo.getSelectedItem(); + loadModelsForProvider( + prov != null ? prov.toString() : "", + model != null ? model.toString() : ""); + }); + loadModelsForProvider(savedProvider, pref.get(PREF_AI_MODEL, "")); + aiProviderLocField.setText(pref.get(PREF_AI_PROVIDER_LOC, "")); + } + + public void applyChanges() { + Object selVer = serverVersionCombo.getSelectedItem(); + pref.put(PREF_SERVER_VERSION, selVer != null ? selVer.toString().trim() : ""); + pref.put(PREF_SERVER_PATH, serverPathField.getText().trim()); + pref.put(PREF_DOMAIN_NAME, domainNameField.getText().trim()); + pref.put(PREF_CONTEXT_ROOT, contextRootField.getText().trim()); + pref.put(PREF_INSTANCE_NAME, instanceNameField.getText().trim()); + + pref.putBoolean(PREF_REMOTE, remoteCheckBox.isSelected()); + pref.put(PREF_HOST_NAME, hostNameField.getText().trim()); + pref.put(PREF_ADMIN_PORT, adminPortField.getText().trim()); + pref.put(PREF_ADMIN_USER, adminUserField.getText().trim()); + + pref.putBoolean(PREF_EXPLODED, explodedCheckBox.isSelected()); + pref.putBoolean(PREF_HOT_DEPLOY, hotDeployCheckBox.isSelected()); + pref.putBoolean(PREF_AUTO_DEPLOY, autoDeployCheckBox.isSelected()); + pref.putBoolean(PREF_LIVE_RELOAD, liveReloadCheckBox.isSelected()); + pref.putBoolean(PREF_KEEP_STATE, keepStateCheckBox.isSelected()); + pref.putBoolean(PREF_TRIM_LOG, trimLogCheckBox.isSelected()); + pref.putBoolean(PREF_IGNORE_TEST, ignoreTestCheckBox.isSelected()); + pref.putBoolean(PREF_AI_AGENT, aiAgentCheckBox.isSelected()); + pref.put(PREF_AI_API_KEY, aiApiKeyField.getText().trim()); + Object selProv = aiProviderCombo.getSelectedItem(); + pref.put(PREF_AI_PROVIDER, selProv != null ? selProv.toString().trim() : ""); + Object selModel = aiModelCombo.getSelectedItem(); + pref.put(PREF_AI_MODEL, selModel != null ? selModel.toString().trim() : ""); + pref.put(PREF_AI_PROVIDER_LOC, aiProviderLocField.getText().trim()); + } + + private void updateRemoteEnabled() { + boolean remote = remoteCheckBox.isSelected(); + hostNameField.setEnabled(remote); + adminPortField.setEnabled(remote); + adminUserField.setEnabled(remote); + } + + /** GenAIProvider enum values from ecosystem-ai (user can type custom values). */ + private static final List AI_PROVIDERS = Arrays.asList( + "", "OPEN_AI", "ANTHROPIC", "GOOGLE", "MISTRAL", "GROQ", + "DEEPSEEK", "DEEPINFRA", "OLLAMA", "LM_STUDIO", "GPT4ALL", "CUSTOM_OPEN_AI" + ); + + /** + * Populates the model combobox for the selected provider. + * Local providers use static lists; cloud providers fetch filtered models from OpenRouter. + */ + private void loadModelsForProvider(String provider, String savedModel) { + RP.post(() -> { + List models = new ArrayList<>(); + models.add(""); + if (provider != null && PayaraAIModelRegistry.LOCAL_PROVIDERS.contains(provider)) { + models.addAll(PayaraAIModelRegistry.getLocalModels( + provider, aiProviderLocField.getText().trim())); + } else if (provider != null && !provider.isEmpty()) { + // Cloud provider: fetch provider-filtered models from OpenRouter + models.addAll(PayaraAIModelRegistry.getModelsForProvider(provider)); + } + SwingUtilities.invokeLater(() -> { + Object current = aiModelCombo.getSelectedItem(); + String keep = (savedModel != null && !savedModel.isEmpty()) + ? savedModel : (current != null ? current.toString() : ""); + aiModelCombo.removeAllItems(); + models.forEach(aiModelCombo::addItem); + if (!keep.isEmpty()) { + aiModelCombo.setSelectedItem(keep); + if (!keep.equals(aiModelCombo.getSelectedItem())) { + aiModelCombo.addItem(keep); + aiModelCombo.setSelectedItem(keep); + } + } + }); + }); + } + + /** Loads Payara Server versions from the tooling API on a background thread. */ + private void loadServerVersions(String saved) { + RP.post(() -> { + List versions = new ArrayList<>(); + versions.add(""); // blank = "let the plugin decide" + try { + List fetched = PayaraPlatformVersion.getVersions(); + fetched.stream() + .sorted(Collections.reverseOrder()) + .forEach(v -> versions.add(v.toString())); + } catch (Exception ex) { + // network unavailable — fall through with empty list + } + SwingUtilities.invokeLater(() -> { + serverVersionCombo.removeAllItems(); + versions.forEach(serverVersionCombo::addItem); + if (!saved.isEmpty()) { + serverVersionCombo.setSelectedItem(saved); + if (!saved.equals(serverVersionCombo.getSelectedItem())) { + // version not in list (e.g. custom) — add and select it + serverVersionCombo.addItem(saved); + serverVersionCombo.setSelectedItem(saved); + } + } + }); + }); + } + + private static String msg(String key) { + return NbBundle.getMessage(ServerMavenPropertiesPanel.class, + "ServerMavenPropertiesPanel." + key); + } + + // ── Scrollable — tracks viewport width so no horizontal bar appears ──────── + + @Override public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } + @Override public int getScrollableUnitIncrement(Rectangle r, int o, int d) { return 16; } + @Override public int getScrollableBlockIncrement(Rectangle r, int o, int d) { return 64; } + @Override public boolean getScrollableTracksViewportWidth() { return true; } + @Override public boolean getScrollableTracksViewportHeight() { return false; } + + // ── Collapsible section widget ──────────────────────────────────────────── + + private static final class CollapsibleSection extends JPanel { + + private static final String EXPANDED_ARROW = "▼ "; + private static final String COLLAPSED_ARROW = "► "; + + private boolean expanded; + private final String title; + private final JButton toggle; + private final JPanel content; + private final GridBagConstraints gbc; + private int rowIndex; + + CollapsibleSection(String title, boolean expanded) { + this.title = title; + this.expanded = expanded; + setLayout(new BorderLayout()); + setOpaque(false); + setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); + + // ── Header ───────────────────────────────────────────────────── + toggle = new JButton((expanded ? EXPANDED_ARROW : COLLAPSED_ARROW) + title); + toggle.setHorizontalAlignment(SwingConstants.LEFT); + toggle.setFont(toggle.getFont().deriveFont(Font.BOLD)); + toggle.setBorderPainted(false); + toggle.setContentAreaFilled(false); + toggle.setFocusPainted(false); + toggle.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + toggle.addActionListener(e -> toggleExpanded()); + + JPanel header = new JPanel(new BorderLayout(4, 0)); + header.setOpaque(false); + header.add(toggle, BorderLayout.WEST); + header.add(new JSeparator(), BorderLayout.CENTER); + + // ── Content ──────────────────────────────────────────────────── + content = new JPanel(new GridBagLayout()); + content.setOpaque(false); + content.setBorder(BorderFactory.createEmptyBorder(4, 20, 4, 0)); + + gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets = new Insets(3, 0, 3, 8); + gbc.gridy = 0; + + add(header, BorderLayout.NORTH); + if (expanded) { + add(content, BorderLayout.CENTER); + } + } + + void addComponentRow(String labelText, JPanel component) { + gbc.gridy = rowIndex++; + gbc.gridx = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.WEST; + content.add(new JLabel(labelText), gbc); + gbc.gridx = 1; gbc.weightx = 1.0; + content.add(component, gbc); + } + + void addRow(String labelText, JTextField field) { + gbc.gridy = rowIndex++; + gbc.gridx = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.WEST; + content.add(new JLabel(labelText), gbc); + gbc.gridx = 1; gbc.weightx = 1.0; + content.add(field, gbc); + } + + void addComboRow(String labelText, JComboBox combo) { + gbc.gridy = rowIndex++; + gbc.gridx = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.WEST; + content.add(new JLabel(labelText), gbc); + gbc.gridx = 1; gbc.weightx = 1.0; + content.add(combo, gbc); + } + + void addCheckRow(String labelText, JCheckBox check) { + gbc.gridy = rowIndex++; + gbc.gridx = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.WEST; + content.add(new JLabel(labelText), gbc); + gbc.gridx = 1; gbc.weightx = 1.0; + content.add(check, gbc); + } + + private void toggleExpanded() { + expanded = !expanded; + toggle.setText((expanded ? EXPANDED_ARROW : COLLAPSED_ARROW) + title); + if (expanded) { + add(content, BorderLayout.CENTER); + } else { + remove(content); + } + revalidate(); + repaint(); + // propagate layout change up to the containing scroll pane / panel + java.awt.Container p = getParent(); + if (p != null) { + p.revalidate(); + p.repaint(); + } + } + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenPropertiesPanelProvider.java b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenPropertiesPanelProvider.java new file mode 100644 index 000000000000..3f45d0f49ad9 --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/ServerMavenPropertiesPanelProvider.java @@ -0,0 +1,75 @@ +/* + * 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.netbeans.modules.payara.server.maven.project; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JScrollPane; +import org.netbeans.api.project.Project; +import org.netbeans.modules.maven.api.customizer.ModelHandle2; +import org.netbeans.spi.project.ui.support.ProjectCustomizer; +import org.openide.util.Lookup; + +/** + * Contributes the "Payara Server Maven Plugin" category to the Maven WAR project's + * Project Properties dialog when the project declares + * {@code payara-server-maven-plugin}. + * + * @author Gaurav Gupta + */ +public class ServerMavenPropertiesPanelProvider + implements ProjectCustomizer.CompositeCategoryProvider { + + @ProjectCustomizer.CompositeCategoryProvider.Registration( + projectType = "org-netbeans-modules-maven", + position = 306 + ) + public static ServerMavenPropertiesPanelProvider createServerMaven() { + return new ServerMavenPropertiesPanelProvider(); + } + + @Override + public ProjectCustomizer.Category createCategory(Lookup context) { + Project project = context.lookup(Project.class); + if (ServerMavenApplication.getInstance(project) == null) { + return null; + } + return ProjectCustomizer.Category.create( + "PayaraServerMaven", // NOI18N + "Payara Server Maven Plugin", // NOI18N + null); + } + + @Override + public JComponent createComponent(ProjectCustomizer.Category category, Lookup context) { + Project project = context.lookup(Project.class); + if (ServerMavenApplication.getInstance(project) == null) { + return null; + } + ModelHandle2 handle = context.lookup(ModelHandle2.class); + ServerMavenPropertiesPanel panel = new ServerMavenPropertiesPanel(handle, project); + category.setStoreListener(e -> panel.applyChanges()); + JScrollPane scroll = new JScrollPane(panel); + scroll.setBorder(BorderFactory.createEmptyBorder()); + scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scroll.getVerticalScrollBar().setUnitIncrement(16); + return scroll; + } +} diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/action-mapping.xml b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/action-mapping.xml new file mode 100644 index 000000000000..8f293f7f02d3 --- /dev/null +++ b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/action-mapping.xml @@ -0,0 +1,176 @@ + + + + + + + run + + war + + + package + payara-server:dev + + + false + + + + + run.single.deploy + + war + + + package + payara-server:dev + + + false + ${webpagePath} + + + + + + + debug + + war + + + package + payara-server:dev + + + -agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=${jpda.address} + true + false + + + + + debug.single.deploy + + war + + + package + payara-server:stop + payara-server:start + + + -agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=${jpda.address} + true + ${webpagePath} + false + + + + + + profile + + war + + + package + payara-server:stop + payara-server:start + + + + java + false + true + + + + + profile.single.deploy + + war + + + package + payara-server:stop + payara-server:start + + + + java + false + true + ${webpagePath} + + + + + + server-maven-dev + + war + + + package + payara-server:dev + + + false + + + + + server-maven-dev-debug + + war + + + package + payara-server:dev + + + -agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=${jpda.address} + true + false + + + + + + server-maven-stop + + payara-server:stop + + + + diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-build.png b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-build.png new file mode 100644 index 0000000000000000000000000000000000000000..b42e45e37284c70c616a98c1f1b9aa0a1cc8d555 GIT binary patch literal 1029 zcmV+g1p51lP)N2bZe?^J zG%heMF*h@ApJM<31A<9JK~y+TjZ+IqlWQ3M4&5-@#aa6|cQLYvqEnO|I7XR4(Zy=TSD3;^`Q^ST+; z^l9mTK7Cv_QGa9HkIUW!K}Xm=@j4+aVl2R$i| zW#MUFMuZ4`O~O8VIcqK{I#BkTsZnouf2>~HS))49(4cMZ);1eI)M=Vr4ab!&=Sr8Q zJo$C%S~S#1WqvL~=r@QgM5I@aqWA1A?g)*Hz<|>QJ-v@15c~&TzkLhA&4oK&4qG~)RC^ZE@=LNRR!yR?pMyC84Jl)b94da&U@dQFz#85gyaF!=Yq*@gcG#wDyS`Gcn8u{xccWl0_3DHJ`0bb-2U$ss`y)y-7jlTu zlASdxv3A@f;JwaX|kA#SSz#`&J$P00000NkvXXu0mjf6%gCi literal 0 HcmV?d00001 diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-clean-build.png b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-clean-build.png new file mode 100644 index 0000000000000000000000000000000000000000..c541df5116db36c4543afb9c5a0d96ecf90091db GIT binary patch literal 1112 zcmV-e1gHCnP)N2bZe?^J zG%heMF*h@ApJM<31Jy}HK~y+TbyRyyQ)d+ah;eLSTh>zg1WX(*8nb0#xZtvl#o>$z z=z@!xLtrvl87Ao&Uew%Fs@E`b5hT-(BYE6WY4U{jY%3$HS-|76afH= znKp2BgfnF!&?x+wUVZ{zHR~PR%o`xuQowKFk4}EhWYeD_z)d{MOvg%?>0Ak<(b$dh z})LjHvA`8{N(g+4=43t4C}C)g+qVpXxLXn6$FCSGyWgkrcOb&=8dafaJd z0jrANNy{S$=@SKHm0MH-(VBe6ZxhUh?Bai@IA|CDOU5I(RnX_R@-GBz!ihkO_&=&B zZsNPI?}-!8HV6fpMUBx)AxH8Ix$kaL5cKKUGLM|apwk}0qh&FCwd^e1%s)Pb=Y|ZWprKa9swsu;Y?1a(MxKMAhUQpN7ZPseF&;BKi z6T6j+)!1jTo6uAPZ^xr16oW0I_CwYtxHUHq-}jz_Y1|KY?%spB`P&d6!ti5nUqD{D zPjRC%E}m`@pJ0Txw5QCfw0bzz+Yi+>wQy||10sAA28V{hY-UdwxM>aY={^2(bi)GD5(PJlel$*2iMk4<#{Oc~>Svgz2ueFvbX z^E4F8WYAUhit}xj!W;PNfL-(x`8-Pv zS-`^Y^JrGAp-d>e@kyPrL7fL@of5$MT`+#~ApFr#0Kc2^VX!6_M!u^A<3}$XLtZWO zRlil>Chtz0N6E;f^$(F=r1Kh;+hMf-Yrroag}(=_;O>^g_%{+5`Z5nX%U>HWdYij} zPG1r+t8>ai1$q}8vq@ln>S5}H6ns6O!pM;_Fn+x5hus@EPYmtjh!JEJhGbpW zpxn>|hg5lR(zXk*?tHjt-va$jTR`$|qAEQdEhm2+up}v?=Q2L%d%466YYM-Dw472{ zpOJQ@dOHuR&f_lZ-Ih49HDlRED(|TVj}mc&FD_#zXD^Z|$c~RscuBxQ=|UFTC}yJd eTrOGx0O)@^FJAv`56IpC0000N2bZe?^J zG%heMF*h@ApJM<31Gq^0BJhh?<)_Lj%gIcJtk!d@&x=SINA znJgMZhR)$k9WVh|K-#qOT4g*ev=CeRpqderjczKNlex{z44sqJxe^qpVoQPcwuLks zMCTUv@0|9QkWIei%f0`(-}n9J-t%AdFx*uMH+eM)I<8z4uHt1Ie9dCDTgh+YmZAVa zOC}o=YeJUfIksJTiCg|3##DkVUyGzKWKIUZjvDrs@kQLDD12IpZrYX#(e1%IojTDZqkvr3M4`tEq6*nk^FG=X+$z*Qc%hO-Hg%D2JQX-7i|K*f5 z1zhDT^Ei7HLCxbd?(#bkgiJ~I{B3kNXq5dy>VQ%9H?EyNJ$=!yr+#GHq#o8F`-e33 zX{pg$@_3qyL5Mxhw8uIHJCdgHdv{|)U|b_Ac9#lxoNONMY5{M&PV}m;g|d4!BFE?f zBtSzI2|T=;nOG1Z+eW+YR`8x8rf1XAmjgb97|RZ;EJvHPzS43<#>l~V*{FiI&UGj* z8%?xIau&Gcw<;Z)@d#=df?gyk*Cifw0a+uXqRsMGR*NKM2jU>okvHJC&EPE!0&wm8LUrxfnS>=PCs*SZ= z3=Zm$IU?o`=0M1rG8o$xVZg|QN6J=+NYK{}IlZjoQwTflFnjAP1g~~M|H*^!Ny!sC zBSArvEKE)SAE$R=NXVS@z*8&SMl^;3iTJd7^Pkrmc7vn!J?N|60gk4qXLN4x2+WMt3b&IGf`&Zmjqi@V4cB%1;ijnw`kQyd)nj=u zaH0%4K3IQ6U%WOB`C2IzYh*6q>-S{HSRHlIt$yrjE`yxf3iXb}qXXw#V7$)){wpRJ zI;VlbGe=;gw-LIJyzEqN7faAsHUBxko*u>jj@hl?WpMs^l)gnhsoup5g?_W+?_!4A z-!y~g+jN2bZe?^J zG%heMF*h@ApJM<314T(hK~y+TeN=5oQ&AW`e$46SbZ+YI-G`b=MoAJyU{M%|6!xPZ z(J-53qJ_9p)KJtkTauX{Q*>%-Nc2PdlYvE)6cy1A$v(u7rOwaoZqr6dNm-rVv)wJf z@_~o*zVAKHbKY~$xfgAOi6Y^_X^ps!P5%qM+H1S9D!ABC=y!uHIe;;8o2v{ev)&5% z%``}#v*mS|D)Nsv)<|AjTSKs^jvATH@e{F+957Z(>J~b}@WSmd3`U>EE^wj^1%8Jo zONFN<%L3A&)6+AR!A-D`eU7<7YS!m*BUrfubJdbGrwQSFN2s07d@bkOLa{!Nf0C6u zV9^B9u*w%Q!P=tuZmOqk7M=Vn$;~?XGUV@#TDs4qrCu=g(n+RC{)a4Ttft0?(s?v% zgAmgwYjCb)X;v)2zPmwSp3#WZhKv4ucA5)@Qh&irxhT$9L*1L!i2BDfkUtvE7Ym@9 zMW+!VQ%~zB@&!>u6tio$XT|+Y4vAs(cy#TYJJj4u5)n0;#gmU02)638xd~{tR-#;K zLTGN1wGrW9CgOvLuWY0}NKOz@6yY9G80ns?-03!!%kyH(2$`GYtwcQE9>)KuT)hhqLM4&>bFGdSfSv<1&OF3*)5WXjUUWZ>R{4ohlcdnQwR88@K|Crds-H zOG1LJU!}r?5HF9YR9xr|zgz5ck>n?`#e>LLOBFFX*<%==l1s+aQGJGD-*6BGJX0z$ z?(D?4s|%ADYMexk2*3W^vx=mKrb_+xn6&gbd^@d%0zoYMDi9Ibjk>!r?(HQ;zlKv% zf)YxE_=)9?izMHlDR{uj)&q<@VLSG15#Bv|ba6?_V3!EAUejRunHv_pp`?7rO_XyHBM-{M< q(PoUgvW?zR5$zVKj^zBSWAqmw8Y!M&oy&{>0000N2bZe?^J zG%heMF*h@ApJM<31L8?UK~y+TbyN#XQ&$+iI#~zOmX+BDE!0h-Q5c!ovc$zKEL+ee zCe{qyLXbj`*S0bskk*u!*zpicTUcA#6~ryh%*UpkxJ@Zl7-MtHtqX;<&|YXu-?dYM zm=XDRZ+mNuxG(u~?tjkrfB%2)Ip-ozgI%2TrbCh}C&K@QRq*T%cPG6bJxV!2Oho~J ztXt^V)ExLc?V-0PR-JMJ#VXh53=9y#-GM>T~;EJfj#GUTED%@8`Z88D-n z*~+*~R7BZ3*OZh$*Zh15)+yiFL04ggA{t*$iqBe0+Crp9u^?p>$4qbr`?(Ru;wKr@ zalu-PABL2xt?P>};WByStd@9TM7v ztrVdm({;&YteeG{5l(M6%WAJ9ZxaXvq{71Tt)hmO6XIiSt}0=}DmMCr^)0f>;{Dl% ziqtJO5qYb%ij;%6WQ_M8H^J#sv30n~M-{~d9SV*4it!gP+ud;b(sh`g^TOcGThOH% zKtC)mJ(62p9Up1ar{ZYwA__FbL%jyq5o8Zp<6>tu! zAdHQM-^_6H&sk_!Xl!|W{wq^3+#)&v)ZN8sZcp_Gql(e6!%TgDW7)$AX!aR@(T zUOCf%)+cT+C=-N7ts$87JOH!z0ZiFkV7dGmd@-!`w2zj7(WQkk&l#w{Rs!2wNym`+ zCdz9b10yLD!|Kz*?+?H^>rrSMISeVqaTk(yB3vSEEz;A| zDVbSWqQ*|8Yt%FgXmANGk57T@nsT5@zXzHPxsa5<{#W|WxGYS*4*PY$Q;9D!7z{dx z!{NQVKlf5mg&=hBa1msez1^Q7rUUKZ20iuVxK}aVGZFoh29GmR2@{e?q?ZyB5^@p~ r6M6BJ4X>|fARolD5e~i{)dKP#c@lkVdRLEo00000NkvXXu0mjfKb{WW literal 0 HcmV?d00001 diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-reload.png b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-reload.png new file mode 100644 index 0000000000000000000000000000000000000000..44174e42555703f9a23756ef3d7fb0d3cbc13c99 GIT binary patch literal 993 zcmV<710MW|P)N2bZe?^J zG%heMF*h@ApJM<3171l)K~y+TV;CCXUbTSTqZZ)_P%chzE0;~{S+`it{Yt(rs1OAF z|Ifhqv{SU<^=!GnFD6SJfC^)Pht>Qp&-%m)o8;=V4grHIo@T^yS!rOTY z|KHA6_zyJb_MJRdo%PR6lH~hW(`7z^_%El+ z{08zbKAR}H_xVJLLoX&tJ$Nxq<{!w?XT1`4ucdNHLXBZycrjIaGR&q|Gi2Wa{k;mP z;pO8Nq1^lV{M=AwaB#n#pZ9T-ki)Y+iPeu zrM&7OP5Oq$EK!}IZYh%zwwKQ@`dzXx?|;_pr1u$pF?09#`y1S?;8nX-!0yKIq+dK7 z*$@zZIZb*F$dD^p4BWxh{(XBlrHrM2WiRlO@k3^oBn^d~?tLy7dMB)2GHS z^{MyBjGYiXzx!b6|B4MM{|nc|{Wr`vwPbiXL*@)v^9<><*K_2rz+45wFQ-et_pWg{ zAOYh2F&I_OSG8&ayNTpD1}3n0IE~ui&+W>W2fX4vYU*-KL#c>!SWQ?#}$5 zx-jB@*0SjTwL8=P$1e}~<ZFx6b0#Z9mVp5P7ogMmFO~Or P00000NkvXXu0mjfl-%<9 literal 0 HcmV?d00001 diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-restart.png b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven-restart.png new file mode 100644 index 0000000000000000000000000000000000000000..361b3f8833b3725dfb2bd3e8f335bcc5946b4d25 GIT binary patch literal 794 zcmV+#1LgdQP)N2bZe?^J zG%heMF*h@ApJM<30+&fdK~y+TV;CCXUbTSTqZZ)_P%chzE0;~{S+`it{Yt(rs1OAF z|Ifhqv{SU<^=!GnFD6SJfC^)Pht>Qp&-%m)o8;=V4grHIo@T^yS!rOTY z|KHA6_zyJb_MJRdo%PR6lH~hW(`7z^_%El+ z{08zbKAR}H_xVJLLoX&tJ$Nxq<{!w?XT1`4ucdNHLXBZycrjIaGR&q|Gi2Wa{k;mP z;pO8Nq1^lV{Jc zrM&8G8?ydK&XD>Kq+7PPrpqJoCj$8z`i92rwcZSJw+h(Z7@qWtha(#T!Y`*u&jHyS zK2`GnyQR%<^HA zP{NzJkaPn~0-ql?3i!I!3jE*wYB3yR<6CF(HiHd%)-O^0V!HHBAiW2a$X-m4*n7W* zM-wFHSjPK*N2bZe?^J zG%heMF*h@ApJM<30>Vi|K~y+TV;CCXUbTSTqZZ)_P%chzE0;~{S+`it{Yt(rs1OAF z|Ifhqv{SU<^=!GnFD6SJfC^)Pht>Qp&-%m)o8;=V4grHIo@T^yS!rOTY z|KHA6_zyJb_MJRdo%PR6lH~hW(`7z^_%El+ z{08zbKAR}H_xVJLLoX&tJ$Nxq<{!w?XT1`4ucdNHLXBZycrjIaGR&q|Gi2Wa{k;mP z;pO8Nq1^lV{Jc zrM&7OP5Oq$9Bmu2{zuM``VXSFx2Br{#n@}T8RTx}aLL@Q;8nX-!0yKIq+dK7*$@zZ zIZb*F$dD^p4BS9XV&PLI|KIy{{y&IL?)Cit^~Dj{;&46TJH=ewAa!8ya+=I6kmfgY z<-Wh3EB_Y6emzI-{fmhbb78nshitA2bShgVcDp2>n0yZX*f?i2)7b0~-PYPg;aC?zf3qK5P<7crzE0 zZh%SP^TS2~U#JoWw_1V!yI(DaV-Vjui+9uYe0CP75@2fXm#BU*U3w>w-UCWxFD6Lr zyh67;i z@Y@z}|6lpA=Rb&cNz?z&#m=G#6laAhAs&Fzk5vvQI2{4G4iHhA00ssCpC+Ra#YQ08 P00000NkvXXu0mjf9Kw9# literal 0 HcmV?d00001 diff --git a/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven.png b/enterprise/payara.server.maven/src/org/netbeans/modules/payara/server/maven/project/resources/payara-server-maven.png new file mode 100644 index 0000000000000000000000000000000000000000..c14ecccce0777219c06f69a737127e71ed234c42 GIT binary patch literal 1085 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=AqSK$x*9nN#8IXksPAt^OIGtXB2{qFth3YjUk>fxro2EGN(sTr9bRYj@6RemAKRoTgwDeCri zyj(UFRzMSSQ%e#RDspr3imfVamB0pD0ofp7eI+}aqLehNAQv~N3Lwu`DWjyMz)D}g zyu4hm+*mKaC|%#s($Z4jz)0W7NEfI=x41H|B(Xv_uUHvsfJi^MBT&`V?*5(W8)NaQ$q`*G{Yn%sP!e8 zX$brCilM;(3=n;gjJ~0s0m#W9wv~TTW-8DXAS>+*ZNTyZJYI!GSVI&;R{8Y5J0%7v18o%-Xhs zQM<`PL!@wnpI_A7HIsu~G6h+dZe1DRxKOmaquGz|AM>LJix#}o%UXR+j5jxV){!Ni zm#2S!Z8hb@Yvs~w=PS-z-v4boo%>I=z?Q_mMd-nUp6DOBe-@1L{;1PGF6AIZ6&MoVmwrtDqeKV|B zm?W+qyK^h%ArJS8xkua|E4Y;UWOi&Qx^n-Wf3RO-Xm8C^_l^3dH-CIfzwl^E*+u!_ z`6j2mG#MFMw&d_UKu?t zIcokAXD*RGg%(xS<({rjUG!gmo_c=u@hbW2(>WQQ$i1slV0vW45V31-;o`*SXIItT zj@mf?n@{+uce!Fl6E)J`uyA*A>nxbFZtr=wlV`T}ZL84Q;bO^a+Upkj->db;@}-;C zR`2}rGh;go!>w(T=NIuaGMu_8tvgp$UQcmLfw9rMYkM+Y>Rh}O>D21~g}Gr%?%lE! zPKJ&J>BW~jH-7uuS+2CAW$(kV0MDn13=^gqvvj61B+PMjy;0v?bn9wm?bB7}SGc?y zY$q^CNT>G5WN>Xul&sokx8vqM(tiKdf86lRt*Uip>#T$89`fd} zE_J;4u)niVFo;c&ar2`6t5WM_U!IyWzxr%_^Q@=8yfZDT87<@IYJXL2EB org.netbeans.modules.payara.micro + org.netbeans.modules.payara.server.maven org.netbeans.modules.payara.common org.netbeans.modules.payara.eecommon org.netbeans.modules.payara.jakartaee diff --git a/java/maven.embedder/nbproject/project.xml b/java/maven.embedder/nbproject/project.xml index c53f48f76c96..63fb43604500 100644 --- a/java/maven.embedder/nbproject/project.xml +++ b/java/maven.embedder/nbproject/project.xml @@ -176,6 +176,7 @@ org.vaadin.netbeans.maven org.netbeans.modules.payara.tooling org.netbeans.modules.payara.micro + org.netbeans.modules.payara.server.maven org.netbeans.modules.jakarta.transformer org.netbeans.modules.j2ee.appengine diff --git a/java/maven.model/nbproject/project.xml b/java/maven.model/nbproject/project.xml index 0820307c5f28..c1377db8a77c 100644 --- a/java/maven.model/nbproject/project.xml +++ b/java/maven.model/nbproject/project.xml @@ -231,6 +231,7 @@ org.vaadin.netbeans.maven org.netbeans.modules.payara.micro + org.netbeans.modules.payara.server.maven org.netbeans.modules.jakarta.transformer org.netbeans.modules.j2ee.appengine diff --git a/java/maven/nbproject/project.xml b/java/maven/nbproject/project.xml index 94ff3287ed83..b498d6d5c5aa 100644 --- a/java/maven/nbproject/project.xml +++ b/java/maven/nbproject/project.xml @@ -654,6 +654,7 @@ org.vaadin.netbeans.maven org.netbeans.modules.payara.micro + org.netbeans.modules.payara.server.maven org.netbeans.modules.jakarta.transformer org.netbeans.modules.j2ee.appengine diff --git a/nbbuild/cluster.properties b/nbbuild/cluster.properties index ffd892f7ba01..f3ba33465b05 100644 --- a/nbbuild/cluster.properties +++ b/nbbuild/cluster.properties @@ -785,6 +785,7 @@ nb.cluster.enterprise=\ payara.eecommon,\ payara.jakartaee,\ payara.micro,\ + payara.server.maven,\ payara.tooling,\ profiler.j2ee,\ projectimport.eclipse.web,\