瀏覽代碼

Simplified the version info scheming

Toni Helenius 2 年之前
父節點
當前提交
22215af54f

+ 5 - 5
jme3-templates/src/com/jme3/gde/templates/files/freemarker/build.gradle.ftl

@@ -41,7 +41,7 @@ dependencies {
   <#if lwjglLibrary.isCoreJmeLibrary == true>
   implementation "${lwjglLibrary.groupId}:${lwjglLibrary.artifactId}:$jmeVer"
   <#else>
-  implementation "${lwjglLibrary.groupId}:${lwjglLibrary.artifactId}:${lwjglLibrary.version}"
+  implementation "${lwjglLibrary.groupId}:${lwjglLibrary.artifactId}:${lwjglLibrary.versionInfo.versionString}"
   </#if>
 
   // Suppress errors / warnings building in SDK
@@ -53,7 +53,7 @@ dependencies {
   <#if guiLibrary.isCoreJmeLibrary == true>
   implementation "${guiLibrary.groupId}:${guiLibrary.artifactId}:$jmeVer"
   <#else>
-  implementation "${guiLibrary.groupId}:${guiLibrary.artifactId}:${guiLibrary.version}"
+  implementation "${guiLibrary.groupId}:${guiLibrary.artifactId}:${guiLibrary.versionInfo.versionString}"
   </#if>
   </#if>
   <#if physicsLibrary.label != "">
@@ -62,7 +62,7 @@ dependencies {
   <#if physicsLibrary.isCoreJmeLibrary == true>
   implementation "${physicsLibrary.groupId}:${physicsLibrary.artifactId}:$jmeVer"
   <#else>
-  implementation "${physicsLibrary.groupId}:${physicsLibrary.artifactId}:${physicsLibrary.version}"
+  implementation "${physicsLibrary.groupId}:${physicsLibrary.artifactId}:${physicsLibrary.versionInfo.versionString}"
   </#if>
   </#if>
   <#if networkingLibrary.label != "">
@@ -71,7 +71,7 @@ dependencies {
   <#if networkingLibrary.isCoreJmeLibrary == true>
   implementation "${networkingLibrary.groupId}:${networkingLibrary.artifactId}:$jmeVer"
   <#else>
-  implementation "${networkingLibrary.groupId}:${networkingLibrary.artifactId}:${networkingLibrary.version}"
+  implementation "${networkingLibrary.groupId}:${networkingLibrary.artifactId}:${networkingLibrary.versionInfo.versionString}"
   </#if>
   </#if>
 
@@ -80,7 +80,7 @@ dependencies {
   <#if additionalLibrary.isCoreJmeLibrary == true>
   implementation "${additionalLibrary.groupId}:${additionalLibrary.artifactId}:$jmeVer"
   <#else>
-  implementation "${additionalLibrary.groupId}:${additionalLibrary.artifactId}:${additionalLibrary.version}"
+  implementation "${additionalLibrary.groupId}:${additionalLibrary.artifactId}:${additionalLibrary.versionInfo.versionString}"
   </#if>
   </#list>
 

+ 3 - 3
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/AdditionalLibrary.java

@@ -134,7 +134,7 @@ public enum AdditionalLibrary implements TemplateLibrary {
     /**
      * Default artifact version to be used
      */
-    private final String defaultVersion;
+    private final VersionInfo defaultVersion;
     /**
      * Is this library a core jMonkeyEngine library? True if the library is a
      * part of jMonkeyengine, false if it is 3rd party.
@@ -158,7 +158,7 @@ public enum AdditionalLibrary implements TemplateLibrary {
         this.description = description;
         this.groupId = groupId;
         this.artifactId = artifactId;
-        this.defaultVersion = defaultVersion;
+        this.defaultVersion = defaultVersion != null ? SemanticPlusTagVersionInfo.of(defaultVersion) : null;
         this.isCoreJmeLibrary = isCoreJmeLibrary;
     }
 
@@ -199,7 +199,7 @@ public enum AdditionalLibrary implements TemplateLibrary {
     }
 
     @Override
-    public String getVersion() {
+    public VersionInfo getVersionInfo() {
         return defaultVersion;
     }
 }

+ 35 - 52
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/CachedOptionsContainer.java

@@ -45,7 +45,6 @@ import java.util.Optional;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -62,20 +61,16 @@ public class CachedOptionsContainer {
 
     private static final Logger logger = Logger.getLogger(CachedOptionsContainer.class.getName());
 
-    private static final Map<TemplateLibrary, VersionFilter> LIBRARY_VERSION_FILTERS = Map.ofEntries(
-            entry(PhysicsLibrary.MINIE, new VersionFilter<>((versionString) -> {
-                return new SemanticPlusTagVersionInfo(versionString);
-            }, (version) -> {
+    private static final Map<TemplateLibrary, Predicate<VersionInfo>> LIBRARY_VERSION_FILTERS = Map.ofEntries(
+            entry(PhysicsLibrary.MINIE, (version) -> {
                 return version.getType() == null;
-            })),
-            entry(AdditionalLibrary.HEART, new VersionFilter<>((versionString) -> {
-                return new SemanticPlusTagVersionInfo(versionString);
-            }, (version) -> {
+            }),
+            entry(AdditionalLibrary.HEART, (version) -> {
                 return version.getType() == null;
-            }))
+            })
     );
 
-    private List<LibraryVersion<JMEVersionInfo>> jmeVersions;
+    private List<LibraryVersion> jmeVersions;
     private List<TemplateLibrary> additionalLibraries;
     private List<TemplateLibrary> guiLibraries;
     private List<TemplateLibrary> networkingLibraries;
@@ -105,11 +100,8 @@ public class CachedOptionsContainer {
                 (jmeVersion) -> {
                     return "stable".equalsIgnoreCase(jmeVersion.getType());
                 },
-                new JMEVersionComparator(),
                 JMEVersion.values(), (result) -> {
             jmeVersions = result;
-        }, (version) -> {
-            return new JMEVersionInfo(version);
         },
                 JMEVersion.DEFAULT_PATCH_NOTES_PATH);
         additionalLibraries = initLibaries(mavenVersionChecker, AdditionalLibrary.values());
@@ -123,7 +115,7 @@ public class CachedOptionsContainer {
         for (TemplateLibrary templateLibrary : libraries) {
             libs.add(new TemplateLibrary() {
 
-                private String version;
+                private VersionInfo version;
 
                 {
                     if (templateLibrary.getGroupId() != null && templateLibrary.getArtifactId() != null) {
@@ -136,15 +128,15 @@ public class CachedOptionsContainer {
                                     return;
                                 }
 
-                                VersionFilter versionFilter = LIBRARY_VERSION_FILTERS.get(templateLibrary);
+                                Predicate<VersionInfo> versionFilter = LIBRARY_VERSION_FILTERS.get(templateLibrary);
                                 Optional<VersionInfo> latestInfo = result.stream()
                                         .map((versionString) -> {
-                                            return versionFilter.getVersionInfoSupplier().apply(versionString);
+                                    return SemanticPlusTagVersionInfo.of(versionString);
                                         })
-                                        .filter(versionFilter.getVersionInfoFilter())
+                                        .filter(versionFilter)
                                         .max(Comparator.naturalOrder());
                                 if (latestInfo.isPresent()) {
-                                            version = latestInfo.get().getVersionString();
+                                    version = latestInfo.get();
                                         }
                                     });
                         } else {
@@ -154,9 +146,9 @@ public class CachedOptionsContainer {
                                             logMavenCheckFailure(exception);
 
                                             return;
-                                        }
+                                }
 
-                                        version = result;
+                                version = SemanticPlusTagVersionInfo.of(result);
                                     });
                         }
                     }
@@ -193,13 +185,13 @@ public class CachedOptionsContainer {
                 }
 
                 @Override
-                public String getVersion() {
-                    return version != null ? version : templateLibrary.getVersion();
+                public String toString() {
+                    return templateLibrary.getLabel();
                 }
 
                 @Override
-                public String toString() {
-                    return templateLibrary.getLabel();
+                public VersionInfo getVersionInfo() {
+                    return version != null ? version : templateLibrary.getVersionInfo();
                 }
 
             });
@@ -224,7 +216,7 @@ public class CachedOptionsContainer {
         return physicsLibraries;
     }
 
-    public List<LibraryVersion<JMEVersionInfo>> getJmeVersions() {
+    public List<LibraryVersion> getJmeVersions() {
         return jmeVersions;
     }
 
@@ -237,23 +229,19 @@ public class CachedOptionsContainer {
      * @param artifactId Maven artifact ID
      * @param versionFilter predicate for version inclusion, may be null (all
      * versions are accepted)
-     * @param versionComparator comparer used to compare the versions
-     * (duplicates and ordering)
      * @param versions the hard coded list of versions, guaranteed to be
      * included in the listing
      * @param completedVersionsConsumer consumer for the versions listing that
      * has been compiled from hard coded list and Maven version results. Only
      * triggers if Maven version check is successful
-     * @param versionInfoSupplier supplier for the type of version data this
-     * library version scheme uses
      * @param defaultPatchNotes for versions from Maven API, we don't get their
      * release notes. Supply default patch notes
      * @return returns a listing of hard coded versions immediately
      */
-    private static <T extends VersionInfo> List<LibraryVersion<T>> initVersions(MavenVersionChecker mavenVersionChecker, String groupId,
-            String artifactId, Predicate<T> versionFilter, Comparator<LibraryVersion<T>> versionComparator,
-            LibraryVersion<T>[] versions, Consumer<List<LibraryVersion<T>>> completedVersionsConsumer,
-            Function<String, T> versionInfoSupplier, String defaultPatchNotes) {
+    private static List<LibraryVersion> initVersions(MavenVersionChecker mavenVersionChecker, String groupId,
+            String artifactId, Predicate<VersionInfo> versionFilter,
+            LibraryVersion[] versions, Consumer<List<LibraryVersion>> completedVersionsConsumer,
+            String defaultPatchNotes) {
         mavenVersionChecker.getAllVersions(groupId, artifactId).whenComplete((result, exception) -> {
 
             if (exception != null || result == null) {
@@ -263,29 +251,29 @@ public class CachedOptionsContainer {
                 return;
             }
 
-            initVersionList(result, versionFilter, versionComparator, versions, groupId, artifactId, completedVersionsConsumer, versionInfoSupplier, defaultPatchNotes);
+            initVersionList(result, versionFilter, versions, groupId, artifactId, completedVersionsConsumer, defaultPatchNotes);
         });
 
         return Collections.unmodifiableList(Arrays.asList(versions));
     }
 
-    private static <T extends VersionInfo> void initVersionList(List<String> result, Predicate<T> versionFilter,
-            Comparator<LibraryVersion<T>> versionComparator, LibraryVersion<T>[] versions,
-            String groupId, String artifactId, Consumer<List<LibraryVersion<T>>> completedVersionsConsumer,
-            Function<String, T> versionInfoSupplier, String defaultPatchNotes) {
+    private static void initVersionList(List<String> result, Predicate<VersionInfo> versionFilter,
+            LibraryVersion[] versions, String groupId, String artifactId,
+            Consumer<List<LibraryVersion>> completedVersionsConsumer,
+            String defaultPatchNotes) {
 
         // Filter the versions list
-        Stream<T> versionStream = result.stream().map(versionInfoSupplier);
+        Stream<VersionInfo> versionStream = result.stream().map((versionString) -> SemanticPlusTagVersionInfo.of(versionString));
         if (versionFilter != null) {
             versionStream = versionStream.filter(versionFilter);
         }
-        List<T> versionInfoList = versionStream.collect(Collectors.toList());
+        List<VersionInfo> versionInfoList = versionStream.collect(Collectors.toList());
 
         // Compile the results
-        final SortedSet<LibraryVersion<T>> allVersions = new TreeSet<>(versionComparator);
+        final SortedSet<LibraryVersion> allVersions = new TreeSet<>(Comparator.comparing(LibraryVersion::getVersionInfo, Comparator.reverseOrder()));
         allVersions.addAll(Arrays.asList(versions));
-        for (T versionInfo : versionInfoList) {
-            allVersions.add(new LibraryVersion<T>() {
+        for (VersionInfo versionInfo : versionInfoList) {
+            allVersions.add(new LibraryVersion() {
 
                 @Override
                 public String getGroupId() {
@@ -297,11 +285,6 @@ public class CachedOptionsContainer {
                     return artifactId;
                 }
 
-                @Override
-                public String getVersion() {
-                    return versionInfo.getVersionString();
-                }
-
                 @Override
                 public String getPatchNotesPath() {
                     return defaultPatchNotes;
@@ -309,11 +292,11 @@ public class CachedOptionsContainer {
 
                 @Override
                 public String toString() {
-                    return getVersion();
+                    return getVersionInfo().getVersionString();
                 }
 
                 @Override
-                public T getVersionInfo() {
+                public VersionInfo getVersionInfo() {
                     return versionInfo;
                 }
 
@@ -335,7 +318,7 @@ public class CachedOptionsContainer {
                     }
                     final LibraryVersion other = (LibraryVersion) obj;
 
-                    return Objects.equals(getVersion(), other.getVersion());
+                    return Objects.equals(getVersionInfo().getVersionString(), other.getVersionInfo().getVersionString());
                 }
 
             });

+ 3 - 3
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/GUILibrary.java

@@ -99,7 +99,7 @@ public enum GUILibrary implements TemplateLibrary {
     /**
      * Default artifact version to be used
      */
-    private final String defaultVersion;
+    private final VersionInfo defaultVersion;
     /**
      * Is this library a core jMonkeyEngine library? True if the library is a
      * part of jMonkeyengine, false if it is 3rd party.
@@ -123,7 +123,7 @@ public enum GUILibrary implements TemplateLibrary {
         this.description = description;
         this.groupId = groupId;
         this.artifactId = artifactId;
-        this.defaultVersion = defaultVersion;
+        this.defaultVersion = defaultVersion != null ? SemanticPlusTagVersionInfo.of(defaultVersion) : null;
         this.isCoreJmeLibrary = isCoreJmeLibrary;
     }
 
@@ -164,7 +164,7 @@ public enum GUILibrary implements TemplateLibrary {
     }
 
     @Override
-    public String getVersion() {
+    public VersionInfo getVersionInfo() {
         return defaultVersion;
     }
 }

+ 4 - 9
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/JMEVersion.java

@@ -54,7 +54,7 @@ package com.jme3.gde.templates.gradledesktop.options;
  *
  * @author peedeeboy
  */
-public enum JMEVersion implements LibraryVersion<JMEVersionInfo> {
+public enum JMEVersion implements LibraryVersion {
 
     JME_3_5_2("3.5.2-stable",
             "/com/jme3/gde/templates/files/patchnotes/352-stable.html"),
@@ -93,7 +93,7 @@ public enum JMEVersion implements LibraryVersion<JMEVersionInfo> {
      */
     private final String patchNotesPath;
 
-    private final JMEVersionInfo versionInfo;
+    private final VersionInfo versionInfo;
 
     /**
      * Private constructor to create an instance of this enum.
@@ -105,7 +105,7 @@ public enum JMEVersion implements LibraryVersion<JMEVersionInfo> {
     JMEVersion(String label, String patchNotesPath) {
         this.label = label;
         this.patchNotesPath = patchNotesPath;
-        this.versionInfo = new JMEVersionInfo(label);
+        this.versionInfo = new SemanticPlusTagVersionInfo(label);
     }
 
     /**
@@ -144,12 +144,7 @@ public enum JMEVersion implements LibraryVersion<JMEVersionInfo> {
     }
 
     @Override
-    public String getVersion() {
-        return label;
-    }
-
-    @Override
-    public JMEVersionInfo getVersionInfo() {
+    public VersionInfo getVersionInfo() {
         return versionInfo;
     }
 }

+ 0 - 46
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/JMEVersionComparator.java

@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2009-2023 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.jme3.gde.templates.gradledesktop.options;
-
-import java.util.Comparator;
-
-/**
- * Compares jME versions, sorts them in descending order (newest first)
- */
-public class JMEVersionComparator implements Comparator<LibraryVersion<JMEVersionInfo>> {
-
-    @Override
-    public int compare(LibraryVersion o1, LibraryVersion o2) {
-        return -(o1.getVersionInfo().compareTo(o2.getVersionInfo()));
-    }
-
-}

+ 0 - 111
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/JMEVersionInfo.java

@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2009-2023 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.jme3.gde.templates.gradledesktop.options;
-
-import java.text.Collator;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * jMonkeyEngine version information
- */
-public final class JMEVersionInfo implements VersionInfo<JMEVersionInfo> {
-
-    private static final Pattern VERSION_PATTERN = Pattern.compile("(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<release>\\d+)-(?<type>.*)");
-
-    private final int major;
-    private final int minor;
-    private final int release;
-    private final String type;
-    private final String versionString;
-
-    public JMEVersionInfo(String versionString) {
-        this.versionString = versionString;
-
-        Matcher m = VERSION_PATTERN.matcher(versionString);
-        if (m.find()) {
-            this.major = Integer.parseInt(m.group("major"));
-            this.minor = Integer.parseInt(m.group("minor"));
-            this.release = Integer.parseInt(m.group("release"));
-            this.type = m.group("type");
-        } else {
-            this.major = 0;
-            this.minor = 0;
-            this.release = 0;
-            this.type = "";
-        }
-    }
-
-    @Override
-    public int getMajor() {
-        return major;
-    }
-
-    @Override
-    public Integer getMinor() {
-        return minor;
-    }
-
-    @Override
-    public Integer getRelease() {
-        return release;
-    }
-
-    @Override
-    public String getType() {
-        return type;
-    }
-
-    @Override
-    public String getVersionString() {
-        return versionString;
-    }
-
-    @Override
-    public int compareTo(JMEVersionInfo o) {
-        int result = Integer.compare(major, o.major);
-        if (result != 0) {
-            return result;
-        }
-        result = Integer.compare(minor, o.minor);
-        if (result != 0) {
-            return result;
-        }
-        result = Integer.compare(release, o.release);
-        if (result != 0) {
-            return result;
-        }
-
-        return Collator.getInstance().compare(type, o.type);
-    }
-
-}

+ 1 - 1
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/LWJGLLibrary.java

@@ -136,7 +136,7 @@ public enum LWJGLLibrary implements TemplateLibrary {
     }
 
     @Override
-    public String getVersion() {
+    public VersionInfo getVersionInfo() {
         return null;
     }
 }

+ 1 - 3
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/LibraryVersion.java

@@ -34,7 +34,7 @@ package com.jme3.gde.templates.gradledesktop.options;
 /**
  * Represents a Maven library version info (with patch notes)
  */
-public interface LibraryVersion<T extends VersionInfo> extends MavenArtifact {
+public interface LibraryVersion extends MavenArtifact {
 
     /**
      * Get the path to the .html file containing the Patch Notes for this
@@ -44,6 +44,4 @@ public interface LibraryVersion<T extends VersionInfo> extends MavenArtifact {
      */
     String getPatchNotesPath();
 
-    T getVersionInfo();
-
 }

+ 3 - 3
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/MavenArtifact.java

@@ -53,10 +53,10 @@ public interface MavenArtifact {
     String getArtifactId();
 
     /**
-     * Get the artifact version string
+     * Get the artifact version info
      *
-     * @return version string
+     * @return version info
      */
-    String getVersion();
+    VersionInfo getVersionInfo();
 
 }

+ 3 - 3
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/NetworkingLibrary.java

@@ -102,7 +102,7 @@ public enum NetworkingLibrary implements TemplateLibrary {
     /**
      * Default artifact version to be used
      */
-    private final String defaultVersion;
+    private final VersionInfo defaultVersion;
     /**
      * Is this library a core jMonkeyEngine library? True if the library is a
      * part of jMonkeyengine, false if it is 3rd party.
@@ -126,7 +126,7 @@ public enum NetworkingLibrary implements TemplateLibrary {
         this.description = description;
         this.groupId = groupId;
         this.artifactId = artifactId;
-        this.defaultVersion = defaultVersion;
+        this.defaultVersion = defaultVersion != null ? SemanticPlusTagVersionInfo.of(defaultVersion) : null;
         this.isCoreJmeLibrary = isCoreJmeLibrary;
     }
 
@@ -167,7 +167,7 @@ public enum NetworkingLibrary implements TemplateLibrary {
     }
 
     @Override
-    public String getVersion() {
+    public VersionInfo getVersionInfo() {
         return defaultVersion;
     }
 }

+ 3 - 3
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/PhysicsLibrary.java

@@ -98,7 +98,7 @@ public enum PhysicsLibrary implements TemplateLibrary {
     /**
      * Default artifact version to be used
      */
-    private final String defaultVersion;
+    private final VersionInfo defaultVersion;
     /**
      * Is this library a core jMonkeyEngine library? True if the library is a
      * part of jMonkeyengine, false if it is 3rd party.
@@ -122,7 +122,7 @@ public enum PhysicsLibrary implements TemplateLibrary {
         this.description = description;
         this.groupId = groupId;
         this.artifactId = artifactId;
-        this.defaultVersion = defaultVersion;
+        this.defaultVersion = defaultVersion != null ? SemanticPlusTagVersionInfo.of(defaultVersion) : null;
         this.isCoreJmeLibrary = isCoreJmeLibrary;
     }
 
@@ -163,7 +163,7 @@ public enum PhysicsLibrary implements TemplateLibrary {
     }
 
     @Override
-    public String getVersion() {
+    public VersionInfo getVersionInfo() {
         return defaultVersion;
     }
 }

+ 65 - 20
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/SemanticPlusTagVersionInfo.java

@@ -32,19 +32,25 @@
 package com.jme3.gde.templates.gradledesktop.options;
 
 import java.text.Collator;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 /**
- * Versioning scheme like x.x.x and/or x.x.x+tag
+ * Versioning scheme like x.x.x with or without a tag/type. Tries to parse
+ * versions as broadly and leniently as possible
  */
-public final class SemanticPlusTagVersionInfo implements VersionInfo<SemanticPlusTagVersionInfo> {
+public final class SemanticPlusTagVersionInfo implements VersionInfo {
 
-    private static final Pattern VERSION_PATTERN = Pattern.compile("(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<release>\\d+)\\+?(?<tag>.*)");
+    private static final Logger logger = Logger.getLogger(SemanticPlusTagVersionInfo.class.getName());
 
-    private final int major;
-    private final int minor;
-    private final int release;
+    private static final Pattern VERSION_PATTERN = Pattern.compile("(?<major>\\d+).?(?<minor>\\d*).?(?<release>\\d*)\\W?(?<tag>.*)");
+
+    private final Integer major;
+    private final Integer minor;
+    private final Integer release;
     private final String tag;
     private final String versionString;
 
@@ -53,21 +59,30 @@ public final class SemanticPlusTagVersionInfo implements VersionInfo<SemanticPlu
 
         Matcher m = VERSION_PATTERN.matcher(versionString);
         if (m.find()) {
-            this.major = Integer.parseInt(m.group("major"));
-            this.minor = Integer.parseInt(m.group("minor"));
-            this.release = Integer.parseInt(m.group("release"));
-            String t = m.group("tag");
-            this.tag = t.isEmpty() ? null : t;
+            String group = m.group("major");
+            this.major = group.isEmpty() ? null : Integer.valueOf(group);
+            group = m.group("minor");
+            this.minor = group.isEmpty() ? null : Integer.valueOf(group);
+            group = m.group("release");
+            this.release = group.isEmpty() ? null : Integer.valueOf(group);
+            group = m.group("tag");
+            this.tag = group.isEmpty() ? null : group;
         } else {
-            this.major = 0;
-            this.minor = 0;
-            this.release = 0;
+            this.major = null;
+            this.minor = null;
+            this.release = null;
             this.tag = null;
+
+            logger.log(Level.INFO, "Failed to parse version information from version string {0}", versionString);
         }
     }
 
+    public static VersionInfo of(String versionString) {
+        return new SemanticPlusTagVersionInfo(versionString);
+    }
+
     @Override
-    public int getMajor() {
+    public Integer getMajor() {
         return major;
     }
 
@@ -92,21 +107,51 @@ public final class SemanticPlusTagVersionInfo implements VersionInfo<SemanticPlu
     }
 
     @Override
-    public int compareTo(SemanticPlusTagVersionInfo o) {
-        int result = Integer.compare(major, o.major);
+    public int compareTo(VersionInfo o) {
+        int result = Integer.compare((getMajor() != null ? getMajor() : 0), (o.getMajor() != null ? o.getMajor() : 0));
         if (result != 0) {
             return result;
         }
-        result = Integer.compare(minor, o.minor);
+        result = Integer.compare((getMinor() != null ? getMinor() : 0), (o.getMinor() != null ? o.getMinor() : 0));
         if (result != 0) {
             return result;
         }
-        result = Integer.compare(release, o.release);
+        result = Integer.compare((getRelease() != null ? getRelease() : 0), (o.getRelease() != null ? o.getRelease() : 0));
         if (result != 0) {
             return result;
         }
 
-        return Collator.getInstance().compare(tag != null ? tag : "", o.tag != null ? o.tag : "");
+        result = Collator.getInstance().compare(getType() != null ? getType() : "", o.getType() != null ? o.getType() : "");
+        if (result != 0) {
+            return result;
+        }
+
+        return Collator.getInstance().compare(getVersionString(), o.getVersionString());
+    }
+
+    @Override
+    public String toString() {
+        return versionString;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.versionString);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof VersionInfo)) {
+            return false;
+        }
+        final VersionInfo other = (VersionInfo) obj;
+        return Objects.equals(this.versionString, other.getVersionString());
     }
 
 }

+ 0 - 60
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/VersionFilter.java

@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2009-2023 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- *   may be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.jme3.gde.templates.gradledesktop.options;
-
-import java.util.function.Function;
-import java.util.function.Predicate;
-
-/**
- * Simple version filter for getting the latest version of a library. Used i.e.
- * if the versions come in many flavors.
- */
-class VersionFilter<T extends VersionInfo<T>> {
-
-    private final Function<String, T> versionInfoSupplier;
-
-    private final Predicate<T> versionInfoFilter;
-
-    public VersionFilter(Function<String, T> versionInfoSupplier, Predicate<T> versionInfoFilter) {
-        this.versionInfoSupplier = versionInfoSupplier;
-        this.versionInfoFilter = versionInfoFilter;
-    }
-
-    public Function<String, T> getVersionInfoSupplier() {
-        return versionInfoSupplier;
-    }
-
-    public Predicate<T> getVersionInfoFilter() {
-        return versionInfoFilter;
-    }
-
-}

+ 3 - 6
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/VersionInfo.java

@@ -34,19 +34,16 @@ package com.jme3.gde.templates.gradledesktop.options;
 /**
  * Represents version information that can be compared between each other (which
  * one is more new etc.)
- *
- * @param <T> The concrete class should be passed as type for correct comparable
- * implementation
  */
-public interface VersionInfo<T extends VersionInfo> extends Comparable<T> {
+public interface VersionInfo extends Comparable<VersionInfo> {
 
     /**
      * Get major version number. Maybe the only version indicator on some
      * schemes
      *
-     * @return major version number
+     * @return major version number or <code>null</code> if not exists
      */
-    int getMajor();
+    Integer getMajor();
 
     /**
      * Get minor version number