diff --git a/bundles/fish.payara.eclipse.tools.micro/plugin.properties b/bundles/fish.payara.eclipse.tools.micro/plugin.properties index 7ffbb32..cbb483d 100644 --- a/bundles/fish.payara.eclipse.tools.micro/plugin.properties +++ b/bundles/fish.payara.eclipse.tools.micro/plugin.properties @@ -25,5 +25,5 @@ payara.xhtml.BeanWebRegionWizard.description=Create a new XHTML Page payara.restfulfrompatternlabel=RESTful Web Service from Pattern (Java EE 6) payara.restfulfrompattern.BeanWebRegionWizard.description=Create RESTful Web Service from Pattern -payara.micro.project.wizard.title=Payara Micro Project -payara.micro.project.wizard.description=Create a Payara Micro Maven project +payara.micro.project.wizard.title=Payara Starter Project +payara.micro.project.wizard.description=Create a Payara Server or Payara Micro Maven project diff --git a/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/Messages.java b/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/Messages.java index 39b63a7..d41deec 100644 --- a/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/Messages.java +++ b/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/Messages.java @@ -35,6 +35,10 @@ public class Messages extends org.eclipse.osgi.util.NLS { public static String microSettingsPageTitle; public static String microSettingsPageDescription; + public static String platformComponentLabel; + public static String platformValidationMessage; + public static String platformMicroOption; + public static String platformServerOption; public static String contextPathComponentLabel; public static String microVersionComponentLabel; public static String autobindComponentLabel; diff --git a/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/Messages.properties b/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/Messages.properties index 9c56f70..218a2bb 100644 --- a/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/Messages.properties +++ b/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/Messages.properties @@ -1,5 +1,5 @@ -microProjectTitle=New Payara Micro project +microProjectTitle=New Payara Starter project microProjectSettingsPageTitle=Project settings microProjectSettingsPageDescription=Enter a group id and artifact id of application groupIdComponentLabel=Group Id: @@ -9,23 +9,27 @@ packageComponentLabel=Package: versionValidationMessage=Enter a version for the application. packageValidationMessage=Invalid package name -microProjectLocationPageTitle=New Payara Micro project +microProjectLocationPageTitle=New Payara Starter project microProjectLocationPageDescription=Select project name and location projectArchetypeJobFailed=Failed to create project "{0}" projectPomAlreadyExists=A pom.xml file already exists in the destination folder. projectArchetypeJobCreating=Creating {0} -microSettingsPageTitle=Payara Micro settings -microSettingsPageDescription=Enter the context root of application and Payara Micro version +microSettingsPageTitle=Payara Starter settings +microSettingsPageDescription=Choose the runtime, context root and Payara version +platformComponentLabel=Runtime: +platformValidationMessage=Choose a Payara runtime +platformMicroOption=Payara Micro +platformServerOption=Payara Server contextPathComponentLabel=Context path: -microVersionComponentLabel=Payara Micro version: +microVersionComponentLabel=Payara version: autobindComponentLabel=Auto Bind HTTP: contextPathValidationMessage=Enter the Context path of application -microVersionValidationMessage=Enter the Payara Micro version +microVersionValidationMessage=Enter the Payara version microProjectTabTitle=Micro Project projectBuildNotFound=Project build type not detected buildArtifactComponentLabel=Build Artifact debugPortComponentLabel=Debug Port reloadArtifactComponentLabel=Reload Artifact on save -reloadArtifactComponentTooltip=Reload Artifact feature is only available for Exploded War \ No newline at end of file +reloadArtifactComponentTooltip=Reload Artifact feature is only available for Exploded War diff --git a/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/MicroProjectWizard.java b/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/MicroProjectWizard.java index 47dcc2a..283ab4b 100644 --- a/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/MicroProjectWizard.java +++ b/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/MicroProjectWizard.java @@ -18,7 +18,6 @@ import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -65,6 +64,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.XMLConstants; public class MicroProjectWizard extends Wizard implements INewWizard { @@ -92,10 +92,13 @@ public MicroProjectWizard() { public static final String ARCHETYPE_VERSION_5X = "1.5.0"; //$NON-NLS-1$ public static final String STARTER_ARCHETYPE_GROUP_ID = "fish.payara.starter"; public static final String STARTER_ARCHETYPE_ARTIFACT_ID = "payara-starter-archetype"; - public static final String ARCHETYPE_VERSION_6X = "1.0-beta9"; //$NON-NLS-1$ + public static final String STARTER_ARCHETYPE_VERSION = "2.2.1"; //$NON-NLS-1$ private static final String ARCHETYPE_JDK_VERSION = "jdkVersion"; //$NON-NLS-1$ private static final String ARCHETYPE_JDK_VERSION_DEFAULT_VALUE = "1.8"; //$NON-NLS-1$ + public static final String ARCHETYPE_JAVA_VERSION = "javaVersion"; //$NON-NLS-1$ + private static final String ARCHETYPE_JAVA_VERSION_DEFAULT_VALUE = "17"; //$NON-NLS-1$ public static final String ARCHETYPE_MICRO_VERSION = "payaraMicroVersion"; //$NON-NLS-1$ + public static final String ARCHETYPE_PAYARA_VERSION = "payaraVersion"; //$NON-NLS-1$ public static final String ARCHETYPE_AUTOBIND_HTTP = "autoBindHttp"; //$NON-NLS-1$ private static final String ARCHETYPE_CONCURRENT_API = "addConcurrentApi"; //$NON-NLS-1$ private static final String ARCHETYPE_RESOURCE_API = "addResourceApi"; //$NON-NLS-1$ @@ -106,57 +109,80 @@ public MicroProjectWizard() { public static final String ARCHETYPE_CONTEXT_ROOT = "contextRoot"; //$NON-NLS-1$ private static final String ARCHETYPE_CONTEXT_ROOT_DEFAULT_VALUE = "/"; //$NON-NLS-1$ private static final String ARCHETYPE_DEPLOY_WAR = "deployWar"; //$NON-NLS-1$ + public static final String ARCHETYPE_PLATFORM = "platform"; //$NON-NLS-1$ + public static final String PLATFORM_SERVER = "server"; //$NON-NLS-1$ + public static final String PLATFORM_MICRO = "micro"; //$NON-NLS-1$ private static final String EMPTY = ""; //$NON-NLS-1$ public static final String DEFAULT_REPOSITORY_URL = "https://repo1.maven.org/maven2/"; // NOI18N - private static final String METADATA_URL = "fish/payara/extras/payara-micro/maven-metadata.xml"; // NOI18N + private static final String PAYARA_BOM_METADATA_URL = "fish/payara/api/payara-bom/maven-metadata.xml"; // NOI18N + private static final String PAYARA_MICRO_METADATA_URL = "fish/payara/extras/payara-micro/maven-metadata.xml"; // NOI18N - private static final List versions = new ArrayList<>(); + private static final Map> versions = new HashMap<>(); public static List getVersions() { - if (versions.isEmpty()) { - try { - // Construct the full URL - String urlString = DEFAULT_REPOSITORY_URL + METADATA_URL; - URL url = new URL(urlString); - - // Open connection - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - - // Read the response - BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); - StringBuilder xmlResponse = new StringBuilder(); - String line; - while ((line = in.readLine()) != null) { - xmlResponse.append(line); - } - in.close(); - - // Parse the XML response - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(new InputSource(new StringReader(xmlResponse.toString()))); - - String latest = doc.getElementsByTagName("latest").item(0).getTextContent(); - // Extract versions - NodeList versionNodes = doc.getElementsByTagName("version"); - for (int i = versionNodes.getLength() - 1; i >= 0; i--) { - String version = versionNodes.item(i).getTextContent(); - if ((version.contains("Alpha") || version.contains("Beta") || version.contains("SNAPSHOT")) // NOI18N - && !version.equals(latest)) { - continue; - }; - versions.add(version); - } + return getVersions(PLATFORM_MICRO); + } - } catch (Exception e) { - e.printStackTrace(); - } + public static List getVersions(String platform) { + return versions.computeIfAbsent(platform, MicroProjectWizard::loadVersions); + } + public static String getDefaultVersion(String platform) { + List resolvedVersions = getVersions(platform); + return resolvedVersions.isEmpty() ? EMPTY : resolvedVersions.get(0); + } + + private static List loadVersions(String platform) { + List resolvedVersions = new ArrayList<>(); + try { + // Construct the full URL + String metadataUrl = PLATFORM_SERVER.equals(platform) ? PAYARA_BOM_METADATA_URL : PAYARA_MICRO_METADATA_URL; + String urlString = DEFAULT_REPOSITORY_URL + metadataUrl; + URL url = new URL(urlString); + + // Open connection + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + // Read the response + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + StringBuilder xmlResponse = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) { + xmlResponse.append(line); + } + in.close(); + + // Parse the XML response + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$ + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); //$NON-NLS-1$ + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //$NON-NLS-1$ + factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, EMPTY); + factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, EMPTY); + factory.setXIncludeAware(false); + factory.setExpandEntityReferences(false); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(xmlResponse.toString()))); + + String latest = doc.getElementsByTagName("latest").item(0).getTextContent(); + // Extract versions + NodeList versionNodes = doc.getElementsByTagName("version"); + for (int i = versionNodes.getLength() - 1; i >= 0; i--) { + String version = versionNodes.item(i).getTextContent(); + if ((version.contains("Alpha") || version.contains("Beta") || version.contains("SNAPSHOT")) // NOI18N + && !version.equals(latest)) { + continue; + }; + resolvedVersions.add(version); + } + } catch (Exception e) { + e.printStackTrace(); } - return versions; + return resolvedVersions; } @Override @@ -190,10 +216,13 @@ private Archetype getArchetype() { Archetype archetype = new Archetype(); archetype.setGroupId(STARTER_ARCHETYPE_GROUP_ID); archetype.setArtifactId(STARTER_ARCHETYPE_ARTIFACT_ID); - archetype.setVersion(ARCHETYPE_VERSION_6X); + archetype.setVersion(STARTER_ARCHETYPE_VERSION); Properties properties = new Properties(); properties.put(ARCHETYPE_JDK_VERSION, ARCHETYPE_JDK_VERSION_DEFAULT_VALUE); - properties.put(ARCHETYPE_MICRO_VERSION, getVersions().get(0)); + properties.put(ARCHETYPE_JAVA_VERSION, ARCHETYPE_JAVA_VERSION_DEFAULT_VALUE); + properties.put(ARCHETYPE_PLATFORM, PLATFORM_MICRO); + properties.put(ARCHETYPE_MICRO_VERSION, getDefaultVersion(PLATFORM_MICRO)); + properties.put(ARCHETYPE_PAYARA_VERSION, getDefaultVersion(PLATFORM_MICRO)); properties.put(ARCHETYPE_AUTOBIND_HTTP, TRUE.toString()); properties.put(ARCHETYPE_CONCURRENT_API, FALSE.toString()); properties.put(ARCHETYPE_RESOURCE_API, FALSE.toString()); @@ -210,6 +239,7 @@ private Archetype getArchetype() { @Override public boolean performFinish() { Archetype archetype = microSettingsPage.getArchetype(); + microSettingsPage.configureBuildTool(); final String groupId = projectSettingsPage.getGroupId(); final String artifactId = projectSettingsPage.getArtifactId(); final String version = projectSettingsPage.getVersion(); diff --git a/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/MicroSettingsWizardPage.java b/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/MicroSettingsWizardPage.java index 95903cb..8edadb9 100644 --- a/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/MicroSettingsWizardPage.java +++ b/bundles/fish.payara.eclipse.tools.micro/src/fish/payara/eclipse/tools/micro/ui/wizards/MicroSettingsWizardPage.java @@ -11,17 +11,24 @@ import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_AUTOBIND_HTTP; import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_CONTEXT_ROOT; +import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_JAVA_VERSION; import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_MICRO_VERSION; +import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_PAYARA_VERSION; +import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_PLATFORM; import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_VERSION_5X; -import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_VERSION_6X; import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_GROUP_ID; import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.ARCHETYPE_ARTIFACT_ID; +import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.PLATFORM_MICRO; +import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.PLATFORM_SERVER; import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.STARTER_ARCHETYPE_GROUP_ID; import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.STARTER_ARCHETYPE_ARTIFACT_ID; +import static fish.payara.eclipse.tools.micro.ui.wizards.MicroProjectWizard.STARTER_ARCHETYPE_VERSION; import static java.nio.charset.StandardCharsets.UTF_8; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -44,10 +51,14 @@ public class MicroSettingsWizardPage extends AbstractMavenWizardPage { private Combo microVersionCombo; + private Combo platformCombo; + private Button autobindCheckbox; private Archetype archetype; + private final Map runtimeOptions = new LinkedHashMap<>(); + public MicroSettingsWizardPage(ProjectImportConfiguration projectImportConfiguration) { super(MicroSettingsWizardPage.class.getSimpleName(), projectImportConfiguration); setTitle(Messages.microSettingsPageTitle); @@ -58,12 +69,26 @@ public MicroSettingsWizardPage(ProjectImportConfiguration projectImportConfigura public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NULL); composite.setLayout(new GridLayout(3, false)); + runtimeOptions.clear(); + runtimeOptions.put(Messages.platformMicroOption, PLATFORM_MICRO); + runtimeOptions.put(Messages.platformServerOption, PLATFORM_SERVER); createUI(composite); validate(); setControl(composite); } private void createUI(Composite parent) { + Label platformLabel = new Label(parent, SWT.NONE); + platformLabel.setText(Messages.platformComponentLabel); + + platformCombo = new Combo(parent, SWT.READ_ONLY); + platformCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); + platformCombo.setItems(runtimeOptions.keySet().toArray(new String[0])); + platformCombo.addModifyListener(e -> { + refreshVersions(getSelectedPlatform(), microVersionCombo.getText().trim()); + validate(); + }); + Label contextPathlabel = new Label(parent, SWT.NONE); contextPathlabel.setText(Messages.contextPathComponentLabel); @@ -80,7 +105,7 @@ private void createUI(Composite parent) { microVersionCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); microVersionCombo.setData("name", ARCHETYPE_MICRO_VERSION); //$NON-NLS-1$ microVersionCombo.addModifyListener(e -> validate()); - microVersionCombo.setItems(MicroProjectWizard.getVersions().toArray(new String[0])); + microVersionCombo.setItems(MicroProjectWizard.getVersions(PLATFORM_MICRO).toArray(new String[0])); Label autobindLabel = new Label(parent, SWT.NONE); autobindLabel.setText(Messages.autobindComponentLabel); @@ -101,8 +126,10 @@ public void setVisible(boolean visible) { void setArchetype(Archetype archetype) { this.archetype = archetype; + selectPlatform((String) archetype.getProperties().get(ARCHETYPE_PLATFORM)); contextPathCombo.setText((String) archetype.getProperties().get(ARCHETYPE_CONTEXT_ROOT)); - microVersionCombo.setText((String) archetype.getProperties().get(ARCHETYPE_MICRO_VERSION)); + String payaraVersion = (String) archetype.getProperties().get(ARCHETYPE_PAYARA_VERSION); + refreshVersions(getSelectedPlatform(), payaraVersion); autobindCheckbox.setSelection(Boolean.valueOf((String) archetype.getProperties().get(ARCHETYPE_AUTOBIND_HTTP))); } @@ -119,6 +146,10 @@ private boolean isVisible() { } private String validateInput() { + if (getSelectedPlatform() == null) { + return Messages.platformValidationMessage; + } + String contextPathValue = contextPathCombo.getText().trim(); if (contextPathValue.length() == 0) { return Messages.contextPathValidationMessage; @@ -133,22 +164,21 @@ private String validateInput() { } public Archetype getArchetype() { - String[] versionToken = microVersionCombo.getText().trim().split("\\."); - if (versionToken.length > 1 && Integer.parseInt(versionToken[0]) < 6) { + if (isLegacyMicroProject()) { archetype.setGroupId(ARCHETYPE_GROUP_ID); archetype.setArtifactId(ARCHETYPE_ARTIFACT_ID); archetype.setVersion(ARCHETYPE_VERSION_5X); - MavenBuildTool.setStartCommand("start"); } else { archetype.setGroupId(STARTER_ARCHETYPE_GROUP_ID); archetype.setArtifactId(STARTER_ARCHETYPE_ARTIFACT_ID); - archetype.setVersion(ARCHETYPE_VERSION_6X); + archetype.setVersion(STARTER_ARCHETYPE_VERSION); } return archetype; } public Map getProperties() { + boolean legacyMicroProject = isLegacyMicroProject(); Map properties = archetype.getProperties() .entrySet() .stream() @@ -161,8 +191,65 @@ public Map getProperties() { } catch (UnsupportedEncodingException ex) { throw new IllegalStateException("Invalid context root value " + contextRoot); } - properties.put(ARCHETYPE_MICRO_VERSION, microVersionCombo.getText()); + if (legacyMicroProject) { + properties.put(ARCHETYPE_MICRO_VERSION, microVersionCombo.getText()); + properties.remove(ARCHETYPE_PLATFORM); + properties.remove(ARCHETYPE_PAYARA_VERSION); + properties.remove(ARCHETYPE_JAVA_VERSION); + } else { + properties.put(ARCHETYPE_PLATFORM, getSelectedPlatform()); + properties.put(ARCHETYPE_PAYARA_VERSION, microVersionCombo.getText()); + properties.put(ARCHETYPE_JAVA_VERSION, properties.getOrDefault(ARCHETYPE_JAVA_VERSION, "17")); + properties.remove(ARCHETYPE_MICRO_VERSION); + } properties.put(ARCHETYPE_AUTOBIND_HTTP, String.valueOf(autobindCheckbox.getSelection())); return properties; } + + void configureBuildTool() { + MavenBuildTool.setStartCommand(isLegacyMicroProject() ? "start" : "dev"); + } + + private void selectPlatform(String platform) { + String resolvedPlatform = platform == null || platform.isBlank() ? PLATFORM_MICRO : platform; + runtimeOptions.entrySet().stream() + .filter(entry -> entry.getValue().equals(resolvedPlatform)) + .findFirst() + .ifPresent(entry -> platformCombo.setText(entry.getKey())); + } + + private String getSelectedPlatform() { + return runtimeOptions.get(platformCombo.getText()); + } + + private void refreshVersions(String platform, String selectedVersion) { + List versions = MicroProjectWizard.getVersions(platform); + microVersionCombo.setItems(versions.toArray(new String[0])); + if (selectedVersion != null && versions.contains(selectedVersion)) { + microVersionCombo.setText(selectedVersion); + } else if (!versions.isEmpty()) { + microVersionCombo.setText(versions.get(0)); + } else { + microVersionCombo.setText(""); + } + } + + private boolean isLegacyMicroProject() { + return usesLegacyMicroArchetype(getSelectedPlatform(), microVersionCombo.getText().trim()); + } + + private boolean usesLegacyMicroArchetype(String platform, String version) { + return PLATFORM_MICRO.equals(platform) && extractMajorVersion(version) < 6; + } + + private int extractMajorVersion(String version) { + try { + String[] versionToken = version.trim().split("\\."); + return versionToken.length == 0 || versionToken[0].isBlank() + ? Integer.MAX_VALUE + : Integer.parseInt(versionToken[0]); + } catch (NumberFormatException ex) { + return Integer.MAX_VALUE; + } + } }