From e9a540a6cd0bdc7f8df5d1951e20c641236f06cb Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Mon, 17 Nov 2025 16:41:00 -0800 Subject: [PATCH 1/2] Fix primary product resolution when no product explicitly set --- .../org/labkey/api/products/ProductRegistry.java | 15 ++++++++++++++- .../labkey/api/settings/ProductConfiguration.java | 4 ++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/api/src/org/labkey/api/products/ProductRegistry.java b/api/src/org/labkey/api/products/ProductRegistry.java index a8743cb55c8..f57d6b8c646 100644 --- a/api/src/org/labkey/api/products/ProductRegistry.java +++ b/api/src/org/labkey/api/products/ProductRegistry.java @@ -15,6 +15,7 @@ */ package org.labkey.api.products; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -219,7 +220,9 @@ public String getPrimaryProductIdForContainer(@NotNull Container container) public ProductMenuProvider getPrimaryProductMenuForContainer(@NotNull Container container) { List productIds = getProductIdsForContainer(container); + _logger.debug("Product Ids in container '{}' of type '{}' are {}", container.getPath(), container.getFolderType().getName(), StringUtils.join(productIds)); List providers = getRegisteredProducts().stream().filter(provider -> productIds.contains(provider.getProductId())).toList(); + _logger.debug("Menu providers: {}", providers.stream().map(ProductMenuProvider::getProductId).collect(Collectors.toList())); if (providers.isEmpty()) return null; @@ -229,16 +232,26 @@ public ProductMenuProvider getPrimaryProductMenuForContainer(@NotNull Container // see if there's a provider that matches the folder type (need to check this first so if LabKey LIMS or LKB is the configured product you can still show LKSM folders) Optional optionalProvider = providers.stream().filter(provider -> provider.getFolderTypeName() != null && provider.getFolderTypeName().equals(container.getFolderType().getName())).findFirst(); if (optionalProvider.isPresent()) + { + _logger.debug("Found product menu provider for folder type '{}'", container.getFolderType().getName()); return optionalProvider.get(); + } List orderedProducts = getProducts(true, false).stream().filter(Product::isEnabled).map(Product::getProductGroupId).toList(); - ProductMenuProvider highestProvider = providers.stream().min(Comparator.comparing(provider -> orderedProducts.indexOf(provider.getProductId()))).orElse(null); + _logger.debug("Products are {}", _products.keySet()); + _logger.debug("Ordered products are {}", orderedProducts); + ProductMenuProvider highestProvider = providers.stream().filter(p -> orderedProducts.contains(p.getProductId())).min(Comparator.comparing(provider -> orderedProducts.indexOf(provider.getProductId()))).orElse(null); + _logger.debug("Highest product menu provider: {}", highestProvider.getProductId()); // then see if there's a provider that matches the configured product Product product = new ProductConfiguration().getCurrentProduct(); if (product == null) + { + _logger.debug("Using highest product menu provider."); return highestProvider; + } optionalProvider = providers.stream().filter(provider -> provider.getProductId().equals(product.getProductGroupId())).findFirst(); + _logger.debug("Product from product group: {}", optionalProvider.isPresent() ? optionalProvider.get() : "null"); // if neither of those is true (when can this happen?), use the highest provider return optionalProvider.orElseGet(() -> highestProvider); } diff --git a/api/src/org/labkey/api/settings/ProductConfiguration.java b/api/src/org/labkey/api/settings/ProductConfiguration.java index 77ffbf22902..41b957a9b2b 100644 --- a/api/src/org/labkey/api/settings/ProductConfiguration.java +++ b/api/src/org/labkey/api/settings/ProductConfiguration.java @@ -1,11 +1,13 @@ package org.labkey.api.settings; +import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.data.ContainerManager; import org.labkey.api.module.ModuleLoader; import org.labkey.api.products.Product; import org.labkey.api.products.ProductRegistry; +import org.labkey.api.util.logging.LogHelper; import java.util.Collection; @@ -13,6 +15,7 @@ public class ProductConfiguration extends AbstractWriteableSettingsGroup impleme { public static final String SCOPE_PRODUCT_CONFIGURATION = "ProductConfiguration"; public static final String PROPERTY_NAME = "productKey"; + private static final Logger _logger = LogHelper.getLogger(ProductConfiguration.class, "Product Configuration properties"); @Override protected String getGroupName() @@ -54,6 +57,7 @@ public String getCurrentProductKey() public Product getCurrentProduct() { String productKey = getCurrentProductKey(); + _logger.debug("Current product key: {}", productKey); if (productKey == null) return null; return ProductRegistry.getProduct(productKey); From 2fe71d2a171cbc8e6cffc07708d0a4c25d1e0fcb Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Mon, 17 Nov 2025 17:05:25 -0800 Subject: [PATCH 2/2] Remove filter in favor of updated isEnabled logic --- api/src/org/labkey/api/products/ProductRegistry.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/org/labkey/api/products/ProductRegistry.java b/api/src/org/labkey/api/products/ProductRegistry.java index f57d6b8c646..49599278727 100644 --- a/api/src/org/labkey/api/products/ProductRegistry.java +++ b/api/src/org/labkey/api/products/ProductRegistry.java @@ -240,7 +240,8 @@ public ProductMenuProvider getPrimaryProductMenuForContainer(@NotNull Container List orderedProducts = getProducts(true, false).stream().filter(Product::isEnabled).map(Product::getProductGroupId).toList(); _logger.debug("Products are {}", _products.keySet()); _logger.debug("Ordered products are {}", orderedProducts); - ProductMenuProvider highestProvider = providers.stream().filter(p -> orderedProducts.contains(p.getProductId())).min(Comparator.comparing(provider -> orderedProducts.indexOf(provider.getProductId()))).orElse(null); + ProductMenuProvider highestProvider = providers.stream() + .min(Comparator.comparing(provider -> orderedProducts.indexOf(provider.getProductId()))).orElse(null); _logger.debug("Highest product menu provider: {}", highestProvider.getProductId()); // then see if there's a provider that matches the configured product Product product = new ProductConfiguration().getCurrentProduct();