浏览代码

Allow to filter the library versions

Toni Helenius 2 年之前
父节点
当前提交
324c8546b2

+ 72 - 28
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/CachedOptionsContainer.java

@@ -38,15 +38,19 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
+import static java.util.Map.entry;
 import java.util.Objects;
+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;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Singleton that contains all the options. Tries to go online to get all the
@@ -58,6 +62,19 @@ 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) -> {
+                return version.getType() == null;
+            })),
+            entry(AdditionalLibrary.HEART, new VersionFilter<>((versionString) -> {
+                return new SemanticPlusTagVersionInfo(versionString);
+            }, (version) -> {
+                return version.getType() == null;
+            }))
+    );
+
     private List<LibraryVersion<JMEVersionInfo>> jmeVersions;
     private List<TemplateLibrary> additionalLibraries;
     private List<TemplateLibrary> guiLibraries;
@@ -85,7 +102,10 @@ public class CachedOptionsContainer {
         jmeVersions = initVersions(mavenVersionChecker,
                 MavenArtifact.JME_GROUP_ID,
                 JMEVersion.JME_ARTIFACT_ID,
-                "-stable$", new JMEVersionComparator(),
+                (jmeVersion) -> {
+                    return "stable".equalsIgnoreCase(jmeVersion.getType());
+                },
+                new JMEVersionComparator(),
                 JMEVersion.values(), (result) -> {
             jmeVersions = result;
         }, (version) -> {
@@ -107,20 +127,46 @@ public class CachedOptionsContainer {
 
                 {
                     if (templateLibrary.getGroupId() != null && templateLibrary.getArtifactId() != null) {
-                        mavenVersionChecker.getLatestVersion(templateLibrary.getGroupId(), templateLibrary.getArtifactId())
-                                .whenComplete((result, exception) -> {
-
-                                    if (exception != null || result == null) {
-                                        logger.log(Level.WARNING, exception,
-                                        () -> String.format("Failed to acquire version information for Maven artifact %s (%s:%s)", new Object[]{getLabel(), getGroupId(), getArtifactId()}));
-
-                                return;
-                            }
-                            version = result;
-                                });
+                        if (LIBRARY_VERSION_FILTERS.containsKey(templateLibrary)) {
+                            mavenVersionChecker.getAllVersions(templateLibrary.getGroupId(), templateLibrary.getArtifactId())
+                                    .whenComplete((result, exception) -> {
+                                        if (exception != null || result == null) {
+                                            logMavenCheckFailure(exception);
+
+                                    return;
+                                }
+
+                                VersionFilter versionFilter = LIBRARY_VERSION_FILTERS.get(templateLibrary);
+                                Optional<VersionInfo> latestInfo = result.stream()
+                                        .map((versionString) -> {
+                                            return versionFilter.getVersionInfoSupplier().apply(versionString);
+                                        })
+                                        .filter(versionFilter.getVersionInfoFilter())
+                                        .max(Comparator.naturalOrder());
+                                if (latestInfo.isPresent()) {
+                                            version = latestInfo.get().getVersionString();
+                                        }
+                                    });
+                        } else {
+                            mavenVersionChecker.getLatestVersion(templateLibrary.getGroupId(), templateLibrary.getArtifactId())
+                                    .whenComplete((result, exception) -> {
+                                        if (exception != null || result == null) {
+                                            logMavenCheckFailure(exception);
+
+                                            return;
+                                        }
+
+                                        version = result;
+                                    });
+                        }
                     }
                 }
 
+                private void logMavenCheckFailure(Throwable exception) {
+                    logger.log(Level.WARNING, exception,
+                            () -> String.format("Failed to acquire version information for Maven artifact %s (%s:%s)", new Object[]{getLabel(), getGroupId(), getArtifactId()}));
+                }
+
                 @Override
                 public String getLabel() {
                     return templateLibrary.getLabel();
@@ -189,8 +235,8 @@ public class CachedOptionsContainer {
      * @param mavenVersionChecker access to Maven version information
      * @param groupId Maven group ID
      * @param artifactId Maven artifact ID
-     * @param pattern pattern for version inclusion, may be null (all versions
-     * are accepted)
+     * @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
@@ -205,7 +251,7 @@ public class CachedOptionsContainer {
      * @return returns a listing of hard coded versions immediately
      */
     private static <T extends VersionInfo> List<LibraryVersion<T>> initVersions(MavenVersionChecker mavenVersionChecker, String groupId,
-            String artifactId, String pattern, Comparator<LibraryVersion<T>> versionComparator,
+            String artifactId, Predicate<T> versionFilter, Comparator<LibraryVersion<T>> versionComparator,
             LibraryVersion<T>[] versions, Consumer<List<LibraryVersion<T>>> completedVersionsConsumer,
             Function<String, T> versionInfoSupplier, String defaultPatchNotes) {
         mavenVersionChecker.getAllVersions(groupId, artifactId).whenComplete((result, exception) -> {
@@ -217,32 +263,30 @@ public class CachedOptionsContainer {
                 return;
             }
 
-            initVersionList(result, pattern, versionComparator, versions, groupId, artifactId, completedVersionsConsumer, versionInfoSupplier, defaultPatchNotes);
+            initVersionList(result, versionFilter, versionComparator, versions, groupId, artifactId, completedVersionsConsumer, versionInfoSupplier, defaultPatchNotes);
         });
 
         return Collections.unmodifiableList(Arrays.asList(versions));
     }
 
-    private static <T extends VersionInfo> void initVersionList(List<String> result, String pattern,
+    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) {
 
         // Filter the versions list
-        List<String> vList = result;
-        if (pattern != null) {
-            Pattern p = Pattern.compile(pattern);
-            vList = vList.stream().filter(p.asPredicate()).collect(Collectors.toList());
+        Stream<T> versionStream = result.stream().map(versionInfoSupplier);
+        if (versionFilter != null) {
+            versionStream = versionStream.filter(versionFilter);
         }
+        List<T> versionInfoList = versionStream.collect(Collectors.toList());
 
         // Compile the results
         final SortedSet<LibraryVersion<T>> allVersions = new TreeSet<>(versionComparator);
         allVersions.addAll(Arrays.asList(versions));
-        for (String v : vList) {
+        for (T versionInfo : versionInfoList) {
             allVersions.add(new LibraryVersion<T>() {
 
-                private final T versionInfo = versionInfoSupplier.apply(v);
-
                 @Override
                 public String getGroupId() {
                     return groupId;
@@ -255,7 +299,7 @@ public class CachedOptionsContainer {
 
                 @Override
                 public String getVersion() {
-                    return v;
+                    return versionInfo.getVersionString();
                 }
 
                 @Override
@@ -265,7 +309,7 @@ public class CachedOptionsContainer {
 
                 @Override
                 public String toString() {
-                    return v;
+                    return getVersion();
                 }
 
                 @Override
@@ -275,7 +319,7 @@ public class CachedOptionsContainer {
 
                 @Override
                 public int hashCode() {
-                    return Objects.hashCode(v);
+                    return Objects.hashCode(versionInfo.getVersionString());
                 }
 
                 @Override

+ 20 - 7
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/JMEVersionInfo.java

@@ -40,20 +40,23 @@ import java.util.regex.Pattern;
  */
 public final class JMEVersionInfo implements VersionInfo<JMEVersionInfo> {
 
-    private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)-(.*)");
+    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(1));
-            this.minor = Integer.parseInt(m.group(2));
-            this.release = Integer.parseInt(m.group(3));
-            this.type = m.group(4);
+            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;
@@ -62,22 +65,31 @@ public final class JMEVersionInfo implements VersionInfo<JMEVersionInfo> {
         }
     }
 
+    @Override
     public int getMajor() {
         return major;
     }
 
-    public int getMinor() {
+    @Override
+    public Integer getMinor() {
         return minor;
     }
 
-    public int getRelease() {
+    @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);
@@ -92,6 +104,7 @@ public final class JMEVersionInfo implements VersionInfo<JMEVersionInfo> {
         if (result != 0) {
             return result;
         }
+
         return Collator.getInstance().compare(type, o.type);
     }
 

+ 112 - 0
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/SemanticPlusTagVersionInfo.java

@@ -0,0 +1,112 @@
+/*
+ * 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;
+
+/**
+ * Versioning scheme like x.x.x and/or x.x.x+tag
+ */
+public final class SemanticPlusTagVersionInfo implements VersionInfo<SemanticPlusTagVersionInfo> {
+
+    private static final Pattern VERSION_PATTERN = Pattern.compile("(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<release>\\d+)\\+?(?<tag>.*)");
+
+    private final int major;
+    private final int minor;
+    private final int release;
+    private final String tag;
+    private final String versionString;
+
+    public SemanticPlusTagVersionInfo(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"));
+            String t = m.group("tag");
+            this.tag = t.isEmpty() ? null : t;
+        } else {
+            this.major = 0;
+            this.minor = 0;
+            this.release = 0;
+            this.tag = null;
+        }
+    }
+
+    @Override
+    public int getMajor() {
+        return major;
+    }
+
+    @Override
+    public Integer getMinor() {
+        return minor;
+    }
+
+    @Override
+    public Integer getRelease() {
+        return release;
+    }
+
+    @Override
+    public String getType() {
+        return tag;
+    }
+
+    @Override
+    public String getVersionString() {
+        return versionString;
+    }
+
+    @Override
+    public int compareTo(SemanticPlusTagVersionInfo 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(tag != null ? tag : "", o.tag != null ? o.tag : "");
+    }
+
+}

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

@@ -0,0 +1,60 @@
+/*
+ * 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;
+    }
+
+}

+ 36 - 0
jme3-templates/src/com/jme3/gde/templates/gradledesktop/options/VersionInfo.java

@@ -40,4 +40,40 @@ package com.jme3.gde.templates.gradledesktop.options;
  */
 public interface VersionInfo<T extends VersionInfo> extends Comparable<T> {
 
+    /**
+     * Get major version number. Maybe the only version indicator on some
+     * schemes
+     *
+     * @return major version number
+     */
+    int getMajor();
+
+    /**
+     * Get minor version number
+     *
+     * @return minor version number or <code>null</code> if not exists
+     */
+    Integer getMinor();
+
+    /**
+     * Get release version number
+     *
+     * @return release version number or <code>null</code> if not exists
+     */
+    Integer getRelease();
+
+    /**
+     * Get type version type identifier
+     *
+     * @return version type identifier or <code>null</code> if not exists
+     */
+    String getType();
+
+    /**
+     * Get the original or complete version string presentation
+     *
+     * @return version string presentation
+     */
+    String getVersionString();
+
 }