From 7859c68290dafd405cd48eefa319da4a2e97e49a Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Thu, 26 Jun 2025 16:11:51 -0700 Subject: [PATCH 1/4] Issue 52339: Change list domain URI construction to not use encoded user-provided names --- api/src/org/labkey/api/exp/LsidManager.java | 11 +++++++++++ .../experiment/api/ExpSampleTypeImpl.java | 3 ++- .../experiment/api/ExperimentServiceImpl.java | 12 +----------- .../defaults/DefaultValueServiceImpl.java | 15 ++++++++++++--- .../org/labkey/list/model/ListDomainKind.java | 19 +++++++++---------- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/api/src/org/labkey/api/exp/LsidManager.java b/api/src/org/labkey/api/exp/LsidManager.java index 2b9a3d74da2..b067fa2446d 100644 --- a/api/src/org/labkey/api/exp/LsidManager.java +++ b/api/src/org/labkey/api/exp/LsidManager.java @@ -23,6 +23,8 @@ import org.labkey.api.assay.AssayUrls; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; +import org.labkey.api.data.DbSequence; +import org.labkey.api.data.DbSequenceManager; import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.Sort; import org.labkey.api.data.TableSelector; @@ -72,6 +74,15 @@ public static LsidManager get() return INSTANCE; } + public static DbSequence getLsidPrefixDbSeq(Container container, String lsidPrefix, int batchSize) + { + Container projectContainer = container; // use DBSeq at project level to avoid duplicate lsid for types in child folder + if (!container.isProject() && container.getProject() != null) + projectContainer = container.getProject(); + + return DbSequenceManager.getPreallocatingSequence(projectContainer, ExperimentService.LSID_COUNTER_DB_SEQUENCE_PREFIX + lsidPrefix, 0, batchSize); + } + public interface LsidHandler { I getObject(Lsid lsid); diff --git a/experiment/src/org/labkey/experiment/api/ExpSampleTypeImpl.java b/experiment/src/org/labkey/experiment/api/ExpSampleTypeImpl.java index 1442b3eab04..289dcdea767 100644 --- a/experiment/src/org/labkey/experiment/api/ExpSampleTypeImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExpSampleTypeImpl.java @@ -34,6 +34,7 @@ import org.labkey.api.exp.ChangePropertyDescriptorException; import org.labkey.api.exp.ExperimentException; import org.labkey.api.exp.Lsid; +import org.labkey.api.exp.LsidManager; import org.labkey.api.exp.PropertyColumn; import org.labkey.api.exp.api.ExpData; import org.labkey.api.exp.api.ExpMaterial; @@ -964,7 +965,7 @@ public Lsid.LsidBuilder generateNextDBSeqLSID() public DbSequence getSampleLsidDbSeq(int batchSize, Container container) { - return ExperimentServiceImpl.getLsidPrefixDbSeq(container, "SampleType-" + getRowId(), batchSize); + return LsidManager.getLsidPrefixDbSeq(container, "SampleType-" + getRowId(), batchSize); } @Override diff --git a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java index c9fa3db80e5..42c47aa994a 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java @@ -71,7 +71,6 @@ import org.labkey.api.data.DbSchema; import org.labkey.api.data.DbSchemaType; import org.labkey.api.data.DbScope; -import org.labkey.api.data.DbSequence; import org.labkey.api.data.DbSequenceManager; import org.labkey.api.data.JdbcType; import org.labkey.api.data.NameGenerator; @@ -1633,20 +1632,11 @@ public static String getNamespacePrefix(Class clazz) private Pair generateLSIDWithDBSeq(Container container, String lsidPrefix) { - String dbSeqStr = String.valueOf(getLsidPrefixDbSeq(container, lsidPrefix, 1).next()); + String dbSeqStr = String.valueOf(LsidManager.getLsidPrefixDbSeq(container, lsidPrefix, 1).next()); String lsid = generateLSID(container, lsidPrefix, dbSeqStr); return new Pair<>(lsid, dbSeqStr); } - public static DbSequence getLsidPrefixDbSeq(Container container, String lsidPrefix, int batchSize) - { - Container projectContainer = container; // use DBSeq at project level to avoid duplicate lsid for types in child folder - if (!container.isProject() && container.getProject() != null) - projectContainer = container.getProject(); - - return DbSequenceManager.getPreallocatingSequence(projectContainer, LSID_COUNTER_DB_SEQUENCE_PREFIX + lsidPrefix, 0, batchSize); - } - private String generateGuidLSID(Container container, String lsidPrefix) { return generateLSID(container, lsidPrefix, GUID.makeGUID()); diff --git a/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java b/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java index 69074bc09bf..8f98b178aa1 100644 --- a/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java +++ b/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java @@ -58,14 +58,23 @@ public class DefaultValueServiceImpl implements DefaultValueService private String getContainerDefaultsLSID(Container container, Domain domain) { + Lsid domainLsid = new Lsid(domain.getTypeURI()); String suffix = "Folder-" + container.getRowId(); - return (new Lsid(DOMAIN_DEFAULT_VALUE_LSID_PREFIX, suffix, domain.getName())).toString(); + if (domain.getDomainKind().isUserCreatedType()) + return (new Lsid(DOMAIN_DEFAULT_VALUE_LSID_PREFIX, suffix, Lsid.decodePart(domainLsid.getObjectId()))).toString(); + else + return (new Lsid(DOMAIN_DEFAULT_VALUE_LSID_PREFIX, suffix, domain.getName())).toString(); + } private String getUserDefaultsParentLSID(Container container, User user, Domain domain) { + Lsid domainLsid = new Lsid(domain.getTypeURI()); String suffix = "Folder-" + container.getRowId() + ".User-" + user.getUserId(); - return (new Lsid(USER_DEFAULT_VALUE_DOMAIN_PARENT, suffix, domain.getName())).toString(); + if (domain.getDomainKind().isUserCreatedType()) + return (new Lsid(USER_DEFAULT_VALUE_DOMAIN_PARENT, suffix, Lsid.decodePart(domainLsid.getObjectId()))).toString(); + else + return (new Lsid(USER_DEFAULT_VALUE_DOMAIN_PARENT, suffix, domain.getName())).toString(); } private static final String WILD_CARD_PLACEHOLDER = "WILDCARD"; @@ -390,4 +399,4 @@ public boolean hasDefaultValues(Container container, Domain domain, User user, S } return false; } -} \ No newline at end of file +} diff --git a/list/src/org/labkey/list/model/ListDomainKind.java b/list/src/org/labkey/list/model/ListDomainKind.java index 2ab3df7912b..e26d0f96467 100644 --- a/list/src/org/labkey/list/model/ListDomainKind.java +++ b/list/src/org/labkey/list/model/ListDomainKind.java @@ -39,6 +39,7 @@ import org.labkey.api.di.DataIntegrationService; import org.labkey.api.exp.DomainNotFoundException; import org.labkey.api.exp.Lsid; +import org.labkey.api.exp.LsidManager; import org.labkey.api.exp.OntologyManager; import org.labkey.api.exp.PropertyDescriptor; import org.labkey.api.exp.PropertyType; @@ -271,17 +272,15 @@ public Set getPropertyIndices(Domain domain) public static Lsid generateDomainURI(String name, Container c, KeyType keyType, @Nullable ListDefinition.Category category) { String type = getType(keyType, category); - StringBuilder typeURI = getBaseURI(name, type, c); - - // Issue 13131: uniqueify the lsid for situations where a preexisting list was renamed - int i = 1; - String sTypeURI = typeURI.toString(); - String uniqueURI = sTypeURI; - while (OntologyManager.getDomainDescriptor(uniqueURI, c) != null) + Lsid lsid; + // assure LSID does not collide with previous lsids that may have had number names + do { - uniqueURI = sTypeURI + '-' + (i++); - } - return new Lsid(uniqueURI); + String dbSeqStr = String.valueOf(LsidManager.getLsidPrefixDbSeq(c, type, 1).next()); + lsid = new Lsid(type, "Folder-" + c.getRowId(), dbSeqStr); + } while (OntologyManager.getDomainDescriptor(lsid.toString(), c) != null); + + return lsid; } public static Lsid createPropertyURI(String listName, String columnName, Container c, ListDefinition.KeyType keyType) From bb3bfb8ae0b5cf36d64d11b74059fde880057755 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Fri, 27 Jun 2025 06:31:40 -0700 Subject: [PATCH 2/4] Check for null domain kind --- api/src/org/labkey/api/exp/property/Domain.java | 2 +- .../experiment/api/property/DomainImpl.java | 2 +- .../api/property/StorageProvisionerImpl.java | 2 +- .../defaults/DefaultValueServiceImpl.java | 15 +++++++++++---- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/api/src/org/labkey/api/exp/property/Domain.java b/api/src/org/labkey/api/exp/property/Domain.java index 9173a5e329d..2fa60f59830 100644 --- a/api/src/org/labkey/api/exp/property/Domain.java +++ b/api/src/org/labkey/api/exp/property/Domain.java @@ -46,7 +46,7 @@ public interface Domain extends IPropertyType Object get_Ts(); Container getContainer(); - DomainKind getDomainKind(); + @Nullable DomainKind getDomainKind(); String getName(); String getTitle(); String getDescription(); diff --git a/experiment/src/org/labkey/experiment/api/property/DomainImpl.java b/experiment/src/org/labkey/experiment/api/property/DomainImpl.java index f5d0bf3c100..990ccc5de1f 100644 --- a/experiment/src/org/labkey/experiment/api/property/DomainImpl.java +++ b/experiment/src/org/labkey/experiment/api/property/DomainImpl.java @@ -177,7 +177,7 @@ public Container getContainer() return _dd.getContainer(); } - @Override + @Override @Nullable public DomainKind getDomainKind() { return _dd.getDomainKind(); diff --git a/experiment/src/org/labkey/experiment/api/property/StorageProvisionerImpl.java b/experiment/src/org/labkey/experiment/api/property/StorageProvisionerImpl.java index b503a4434f9..04ddb0813c5 100644 --- a/experiment/src/org/labkey/experiment/api/property/StorageProvisionerImpl.java +++ b/experiment/src/org/labkey/experiment/api/property/StorageProvisionerImpl.java @@ -1808,7 +1808,7 @@ public Set getReservedPropertyNames(Domain domain, User user) { d = new DomainImpl(c, uri, "test", true) { - @Override + @Override @Nullable public DomainKind getDomainKind() { return k; diff --git a/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java b/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java index 8f98b178aa1..cc962611e37 100644 --- a/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java +++ b/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java @@ -28,6 +28,7 @@ import org.labkey.api.exp.OntologyManager; import org.labkey.api.exp.api.ExperimentService; import org.labkey.api.exp.property.Domain; +import org.labkey.api.exp.property.DomainKind; import org.labkey.api.exp.property.DomainProperty; import org.labkey.api.gwt.client.DefaultValueType; import org.labkey.api.query.ValidationException; @@ -58,10 +59,13 @@ public class DefaultValueServiceImpl implements DefaultValueService private String getContainerDefaultsLSID(Container container, Domain domain) { - Lsid domainLsid = new Lsid(domain.getTypeURI()); String suffix = "Folder-" + container.getRowId(); - if (domain.getDomainKind().isUserCreatedType()) + DomainKind kind = domain.getDomainKind(); + if (kind != null && kind.isUserCreatedType()) + { + Lsid domainLsid = new Lsid(domain.getTypeURI()); return (new Lsid(DOMAIN_DEFAULT_VALUE_LSID_PREFIX, suffix, Lsid.decodePart(domainLsid.getObjectId()))).toString(); + } else return (new Lsid(DOMAIN_DEFAULT_VALUE_LSID_PREFIX, suffix, domain.getName())).toString(); @@ -69,10 +73,13 @@ private String getContainerDefaultsLSID(Container container, Domain domain) private String getUserDefaultsParentLSID(Container container, User user, Domain domain) { - Lsid domainLsid = new Lsid(domain.getTypeURI()); String suffix = "Folder-" + container.getRowId() + ".User-" + user.getUserId(); - if (domain.getDomainKind().isUserCreatedType()) + DomainKind kind = domain.getDomainKind(); + if (kind != null && kind.isUserCreatedType()) + { + Lsid domainLsid = new Lsid(domain.getTypeURI()); return (new Lsid(USER_DEFAULT_VALUE_DOMAIN_PARENT, suffix, Lsid.decodePart(domainLsid.getObjectId()))).toString(); + } else return (new Lsid(USER_DEFAULT_VALUE_DOMAIN_PARENT, suffix, domain.getName())).toString(); } From 077c4ea21bd727d0837674a9a703d52621806c7c Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Fri, 27 Jun 2025 11:00:41 -0700 Subject: [PATCH 3/4] Add comment --- .../labkey/experiment/defaults/DefaultValueServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java b/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java index cc962611e37..d5eaac5cfb3 100644 --- a/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java +++ b/experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java @@ -66,7 +66,7 @@ private String getContainerDefaultsLSID(Container container, Domain domain) Lsid domainLsid = new Lsid(domain.getTypeURI()); return (new Lsid(DOMAIN_DEFAULT_VALUE_LSID_PREFIX, suffix, Lsid.decodePart(domainLsid.getObjectId()))).toString(); } - else + else // for internal domains (such as audit domains), the domain name and objectId are often not the same. return (new Lsid(DOMAIN_DEFAULT_VALUE_LSID_PREFIX, suffix, domain.getName())).toString(); } @@ -80,7 +80,7 @@ private String getUserDefaultsParentLSID(Container container, User user, Domain Lsid domainLsid = new Lsid(domain.getTypeURI()); return (new Lsid(USER_DEFAULT_VALUE_DOMAIN_PARENT, suffix, Lsid.decodePart(domainLsid.getObjectId()))).toString(); } - else + else // for internal domains (such as audit domains), the domain name and objectId are often not the same. return (new Lsid(USER_DEFAULT_VALUE_DOMAIN_PARENT, suffix, domain.getName())).toString(); } From 3ffd027a55fae2e9b4d472fa4203b69004868177 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Mon, 30 Jun 2025 08:43:44 -0700 Subject: [PATCH 4/4] Remove unneeded parameters --- api/src/org/labkey/api/exp/LsidManager.java | 5 +++++ list/src/org/labkey/list/model/ListDefinitionImpl.java | 2 +- list/src/org/labkey/list/model/ListDomainKind.java | 5 +++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/api/src/org/labkey/api/exp/LsidManager.java b/api/src/org/labkey/api/exp/LsidManager.java index b067fa2446d..81fdea4868a 100644 --- a/api/src/org/labkey/api/exp/LsidManager.java +++ b/api/src/org/labkey/api/exp/LsidManager.java @@ -74,6 +74,11 @@ public static LsidManager get() return INSTANCE; } + public static DbSequence getLsidPrefixDbSeq(String lsidPrefix, int batchSize) + { + return getLsidPrefixDbSeq(ContainerManager.getRoot(), lsidPrefix, batchSize); + } + public static DbSequence getLsidPrefixDbSeq(Container container, String lsidPrefix, int batchSize) { Container projectContainer = container; // use DBSeq at project level to avoid duplicate lsid for types in child folder diff --git a/list/src/org/labkey/list/model/ListDefinitionImpl.java b/list/src/org/labkey/list/model/ListDefinitionImpl.java index 9ca3cef6a67..ad0514f0e02 100644 --- a/list/src/org/labkey/list/model/ListDefinitionImpl.java +++ b/list/src/org/labkey/list/model/ListDefinitionImpl.java @@ -106,7 +106,7 @@ public ListDefinitionImpl(Container container, String name, KeyType keyType, @Nu builder.setKeyType(keyType.toString()); builder.setCategory(category); _def = builder; - Lsid lsid = ListDomainKind.generateDomainURI(name, container, keyType, category); + Lsid lsid = ListDomainKind.generateDomainURI(container, keyType, category); _domain = PropertyService.get().createDomain(container, lsid.toString(), name, templateInfo); } diff --git a/list/src/org/labkey/list/model/ListDomainKind.java b/list/src/org/labkey/list/model/ListDomainKind.java index e26d0f96467..327dafecf5a 100644 --- a/list/src/org/labkey/list/model/ListDomainKind.java +++ b/list/src/org/labkey/list/model/ListDomainKind.java @@ -27,6 +27,7 @@ import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.ContainerManager; import org.labkey.api.data.DbScope; import org.labkey.api.data.JdbcType; import org.labkey.api.data.PropertyStorageSpec; @@ -269,14 +270,14 @@ public Set getPropertyIndices(Domain domain) return Collections.emptySet(); // TODO: Allow this to return the Key Column } - public static Lsid generateDomainURI(String name, Container c, KeyType keyType, @Nullable ListDefinition.Category category) + public static Lsid generateDomainURI(Container c, KeyType keyType, @Nullable ListDefinition.Category category) { String type = getType(keyType, category); Lsid lsid; // assure LSID does not collide with previous lsids that may have had number names do { - String dbSeqStr = String.valueOf(LsidManager.getLsidPrefixDbSeq(c, type, 1).next()); + String dbSeqStr = String.valueOf(LsidManager.getLsidPrefixDbSeq(type, 1).next()); lsid = new Lsid(type, "Folder-" + c.getRowId(), dbSeqStr); } while (OntologyManager.getDomainDescriptor(lsid.toString(), c) != null);