[java-shib-profile] branch main updated: JSPROF-14 Tolerate gaps in resource-related module properties

Codeberg noreply at shibboleth.net
Fri Sep 18 09:28:30 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-shib-profile.

View the commit online:
https://codeberg.org/Shibboleth/java-shib-profile/commit/6034b872b5a7d6bbf802dcdd9397ffb3005eabc2

The following commit(s) were added to refs/heads/main by this push:
     new 6034b87  JSPROF-14 Tolerate gaps in resource-related module properties
6034b87 is described below

commit 6034b872b5a7d6bbf802dcdd9397ffb3005eabc2
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Thu Sep 17 20:13:49 2026 +0100

    JSPROF-14 Tolerate gaps in resource-related module properties
    
    https://shibboleth.atlassian.net/browse/JSPROF-14
    
    Add code to infer the versions from the properties.
---
 .../InstallableComponentInfo.java                  | 40 ++++++++++++++++++----
 .../InstallableComponentSupport.java               |  9 +++--
 .../InstallableComponentTests.java                 | 23 +++----------
 3 files changed, 44 insertions(+), 28 deletions(-)

diff --git a/shib-profile-api/src/main/java/net/shibboleth/profile/installablecomponent/InstallableComponentInfo.java b/shib-profile-api/src/main/java/net/shibboleth/profile/installablecomponent/InstallableComponentInfo.java
index 6f9e40b..4b134ea 100644
--- a/shib-profile-api/src/main/java/net/shibboleth/profile/installablecomponent/InstallableComponentInfo.java
+++ b/shib-profile-api/src/main/java/net/shibboleth/profile/installablecomponent/InstallableComponentInfo.java
@@ -16,7 +16,9 @@ package net.shibboleth.profile.installablecomponent;
 
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.regex.Pattern;
@@ -118,10 +120,9 @@ public abstract class InstallableComponentInfo {
      * @param props what to load.
      */
     private void  parse(@Nonnull final Properties props) {
-        final String name = componentId + InstallableComponentSupport.AVAILABLE_VERSIONS_PROPERTY_SUFFIX;
-        final String availableVersions = StringSupport.trim(props.getProperty(name));
-        if (availableVersions == null) {
-            log.warn("Component {}: Could not find {} property.", componentId, name);
+        final List<String> availableVersions = inferVersions(props);
+        if (availableVersions.size() == 0) {
+            log.warn("Component {}: No versions found.", componentId);
             allInfoPresent = false;
         } else {
             handleAvailableVersions(props, availableVersions);
@@ -216,17 +217,42 @@ public abstract class InstallableComponentInfo {
      * @param props the property files for the component we are looking at
      * @param availableVersions a space delimited array of versions
      */
-    private void handleAvailableVersions(@Nonnull final Properties props, @Nonnull final String availableVersions) {
-        final String[] versions = SPACE_CONTAINING.split(availableVersions, 0);
+    private void handleAvailableVersions(@Nonnull final Properties props, @Nonnull final List<String> availableVersions) {
 
         log.debug("Component {}: Available versions : {} ", componentId, availableVersions);
-        for (final String version:versions) {
+        for (final String version:availableVersions) {
             assert version  != null;
             log.debug("Component {}: Considering {}", componentId, version);
             handleAvailableVersion(props, version);
         }
     }
 
+    /** Infer all versions from the provided property file.
+     *
+     * We look for the "supportLevel" property and grab the version
+     * from the end of it.
+     * @param props the properties file which describes us (and others)
+     * @return the list of versions declared
+     */
+    private List<String> inferVersions(@Nonnull final Properties props) {
+        final ArrayList<String> result = new ArrayList<>(props.size());
+        final String start = componentId + InstallableComponentSupport.SUPPORT_LEVEL_INTERFIX;
+
+        for (Object entry: props.keySet()) {
+            // safe to cast - this is a Properties
+            final String key = (String) entry;
+            if (key.startsWith(start)) {
+                final String version = StringSupport.trimOrNull(key.substring(start.length()));
+                if (version == null || "%{version}".equalsIgnoreCase(version)) {
+                    log.warn("Component {}, supportlevel key {} badly formed", componentId, key);
+                } else {
+                    result.add(version);
+                }
+            }
+        }
+        return result;
+    }
+
     /** Look up the key derived from the component, the interfix and the version, but if that
      * fails look for a templated definition.
      * @param props what to look in
diff --git a/shib-profile-api/src/main/java/net/shibboleth/profile/installablecomponent/InstallableComponentSupport.java b/shib-profile-api/src/main/java/net/shibboleth/profile/installablecomponent/InstallableComponentSupport.java
index 2d2c732..c705526 100644
--- a/shib-profile-api/src/main/java/net/shibboleth/profile/installablecomponent/InstallableComponentSupport.java
+++ b/shib-profile-api/src/main/java/net/shibboleth/profile/installablecomponent/InstallableComponentSupport.java
@@ -41,8 +41,13 @@ import net.shibboleth.shared.spring.httpclient.resource.HTTPResource;
  */
 public final class InstallableComponentSupport {
     
-    /** Property Name suffix for available versions inside {@link Plugin#getUpdateURLs()}. */
-    @Nonnull public static final String AVAILABLE_VERSIONS_PROPERTY_SUFFIX = ".versions";
+    /**
+     * Property Name suffix for available versions inside {@link Plugin#getUpdateURLs()}.
+     * @deprecated - will be removed in V6
+     *
+     */
+    @Nonnull @Deprecated(forRemoval = true, since = "5.3") 
+    public static final String AVAILABLE_VERSIONS_PROPERTY_SUFFIX = ".versions";
 
     /** Property Name for Download directory {@link Plugin#getUpdateURLs()}. */
     @Nonnull public static final String DOWNLOAD_URL_INTERFIX = ".downloadURL.";
diff --git a/shib-profile-api/src/test/java/net/shibboleth/profile/installablecomponent/InstallableComponentTests.java b/shib-profile-api/src/test/java/net/shibboleth/profile/installablecomponent/InstallableComponentTests.java
index 6e16eae..3bbd8ed 100644
--- a/shib-profile-api/src/test/java/net/shibboleth/profile/installablecomponent/InstallableComponentTests.java
+++ b/shib-profile-api/src/test/java/net/shibboleth/profile/installablecomponent/InstallableComponentTests.java
@@ -40,19 +40,17 @@ import net.shibboleth.shared.primitive.StringSupport;
  * Tests for {@link InstallableComponentInfo} and {@link InstallableComponentSupport}
  */
 public class InstallableComponentTests {
-    
+
     /** The name of the component we pretend to be. */
     static final private String PLUGIN_NAME = "net.shibboleth.idp.plugin.authn.totp";
-    
+
     /** The properties file we load. */
     private Properties properties;
     
-    
     /** The info we load. */
     private InstallableComponentInfo info;
-    
+
     @Test final void testLoadProperties() throws IOException {
-        
         final ClassPathResource inputAsResource = new ClassPathResource("net/shibboleth/profile/installablecomponent/testfile.properties");
         final String inputAsFQP = inputAsResource.getFile().getAbsolutePath();
 
@@ -61,32 +59,21 @@ public class InstallableComponentTests {
         final String propValue = properties.getProperty(propName);
         assertNotNull(propValue);
         assertTrue("4.1.0".equals(propValue));
-}
+    }
 
     @Test(dependsOnMethods = {"testLoadProperties"}) final void testParseInfo() {
 
-        //
-        // test old semantics
-        //
-        info = new TestInstallableComponent();
-        assertFalse(info.isInfoComplete());
-        assertTrue(info.getAvailableVersions().isEmpty());
-
-        
         // add the version string
         final String versionsAsString = "1.0.0 1.0.1 1.0.2 2.0.0 2.1.0 2.2.0 2.3.0 2.3.1 2.3.2";
         properties.setProperty("net.shibboleth.idp.plugin.authn.totp.versions", versionsAsString);
-        
         info = new TestInstallableComponent();
         assertTrue(info.isInfoComplete());
 
         final List<String> ourVersions = CollectionSupport.listOf(versionsAsString.split(" "));
-        
         for (final String version: ourVersions) {
             assertNotNull(info.getAvailableVersions().get(new InstallableComponentVersion(version)));
         }
         assertNull(info.getAvailableVersions().get(new InstallableComponentVersion(1,2,3)));
-        
     }
     
     @Test(dependsOnMethods = {"testParseInfo"}) final void testGetBestVersion() {
@@ -103,7 +90,6 @@ public class InstallableComponentTests {
         assertEquals(best, new InstallableComponentVersion(2,3,2));
     }
 
-    
     /**
      * Based on the PluginInfo.
      */
@@ -137,6 +123,5 @@ public class InstallableComponentTests {
             }
             return new InstallableComponentVersion(minVersionInfo);
         }
-        
     }
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list