diff --git a/api/src/org/labkey/api/dataiterator/DataIteratorUtil.java b/api/src/org/labkey/api/dataiterator/DataIteratorUtil.java index fd1c359788b..813c77e8668 100644 --- a/api/src/org/labkey/api/dataiterator/DataIteratorUtil.java +++ b/api/src/org/labkey/api/dataiterator/DataIteratorUtil.java @@ -247,11 +247,7 @@ protected static Map> _createTableMap(TableInf { String uri = col.getPropertyURI(); if (null != uri) - { targetAliasesMap.put(uri, new Pair<>(col, MatchType.propertyuri)); - String propName = uri.substring(uri.lastIndexOf('#')+1); - targetAliasesMap.put(propName, new Pair<>(col, MatchType.alias)); - } } for (ColumnInfo col : cols) diff --git a/api/src/org/labkey/api/exp/ImportTypesHelper.java b/api/src/org/labkey/api/exp/ImportTypesHelper.java index 811dd90b495..450598e7095 100644 --- a/api/src/org/labkey/api/exp/ImportTypesHelper.java +++ b/api/src/org/labkey/api/exp/ImportTypesHelper.java @@ -29,6 +29,7 @@ import org.labkey.api.data.PHI; import org.labkey.api.data.PropertyStorageSpec; import org.labkey.api.exp.OntologyManager.ImportPropertyDescriptorsList; +import org.labkey.api.exp.property.DomainUtil; import org.labkey.api.exp.property.IPropertyValidator; import org.labkey.api.exp.property.ValidatorKind; import org.labkey.api.gwt.client.DefaultScaleType; @@ -49,6 +50,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Date; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -244,7 +246,7 @@ public static ImportPropertyDescriptorsList getImportPropertyDescriptors(Collect String propertyURI = StringUtils.trimToEmpty(pd.getPropertyURI()); if (propertyURI.isEmpty()) { - pd.setPropertyURI(domainURI + "." + Lsid.encodePart(columnName)); + pd.setPropertyURI(DomainUtil.createUniquePropertyURI(domainURI)); } // try use existing SystemProperty PropertyDescriptor from Shared container. diff --git a/api/src/org/labkey/api/exp/property/Domain.java b/api/src/org/labkey/api/exp/property/Domain.java index 2fa60f59830..3c0d7b1c1c6 100644 --- a/api/src/org/labkey/api/exp/property/Domain.java +++ b/api/src/org/labkey/api/exp/property/Domain.java @@ -75,6 +75,9 @@ public interface Domain extends IPropertyType DomainProperty addProperty(); DomainProperty addProperty(PropertyStorageSpec spec); + @Deprecated // Use addProperty(PropertyStorageSpec) + DomainProperty addProperty(PropertyStorageSpec spec, @Nullable String propSuffix); + List getColumns(TableInfo sourceTable, ColumnInfo lsidColumn, Container container, User user); boolean isMutable(); diff --git a/api/src/org/labkey/api/exp/property/DomainUtil.java b/api/src/org/labkey/api/exp/property/DomainUtil.java index fceafc8b3f3..6b83d805e70 100644 --- a/api/src/org/labkey/api/exp/property/DomainUtil.java +++ b/api/src/org/labkey/api/exp/property/DomainUtil.java @@ -47,6 +47,7 @@ import org.labkey.api.exp.DomainDescriptor; import org.labkey.api.exp.ExperimentException; 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; @@ -1090,7 +1091,7 @@ public static DomainProperty addProperty(Domain domain, GWTPropertyDescriptor pd LOG.debug("Adding property for " + pd.getName()); if (StringUtils.isEmpty(pd.getPropertyURI())) { - String newPropertyURI = createUniquePropertyURI(domain.getTypeURI() + "#" + Lsid.encodePart(pd.getName()), propertyUrisInUse); + String newPropertyURI = createUniquePropertyURI(domain.getTypeURI(), null, propertyUrisInUse); assert !propertyUrisInUse.contains(newPropertyURI) : "Attempting to assign an existing PropertyURI to a new property"; pd.setPropertyURI(newPropertyURI); propertyUrisInUse.add(newPropertyURI); @@ -1107,8 +1108,20 @@ public static DomainProperty addProperty(Domain domain, GWTPropertyDescriptor pd return p; } - private static String createUniquePropertyURI(String base, Set propertyUrisInUse) + public static String createUniquePropertyURI(String typeURI) { + return createUniquePropertyURI(typeURI, null, new CaseInsensitiveHashSet()); + } + + public static String createUniquePropertyURI(String typeURI, @Nullable String propSuffix, Set propertyUrisInUse) + { + // Don't use long property names in URIs as it can create strings that are longer than the DB column length when encoded (Issue 53586) + if (propSuffix == null) + propSuffix = String.valueOf(LsidManager.getLsidPrefixDbSeq("Property", 1).next()); + else + propSuffix = Lsid.encodePart(propSuffix); + + String base = typeURI + "#" + propSuffix; String candidateURI = base; int i = 0; diff --git a/api/src/org/labkey/api/issues/AbstractIssuesListDefDomainKind.java b/api/src/org/labkey/api/issues/AbstractIssuesListDefDomainKind.java index a145e5b3b7e..50bed3bd758 100644 --- a/api/src/org/labkey/api/issues/AbstractIssuesListDefDomainKind.java +++ b/api/src/org/labkey/api/issues/AbstractIssuesListDefDomainKind.java @@ -19,6 +19,7 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerFilter; import org.labkey.api.data.DbSchema; @@ -325,7 +326,7 @@ public Domain createDomain(GWTDomain domain, IssuesDomain Set lowerReservedNames = reservedNames.stream().map(String::toLowerCase).collect(Collectors.toSet()); Set existingProperties = newDomain.getProperties().stream().map(o -> o.getName().toLowerCase()).collect(Collectors.toSet()); Map defaultValues = new HashMap<>(); - Set propertyUris = new HashSet<>(); + Set propertyUris = new CaseInsensitiveHashSet(); for (GWTPropertyDescriptor pd : properties) { diff --git a/api/src/org/labkey/api/query/ExtendedTableDomainKind.java b/api/src/org/labkey/api/query/ExtendedTableDomainKind.java index 902d22a06c7..d0dfec1cfab 100644 --- a/api/src/org/labkey/api/query/ExtendedTableDomainKind.java +++ b/api/src/org/labkey/api/query/ExtendedTableDomainKind.java @@ -17,6 +17,7 @@ import org.apache.commons.lang3.StringUtils; import org.json.JSONObject; +import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.data.Container; import org.labkey.api.exp.ChangePropertyDescriptorException; import org.labkey.api.exp.Handler; @@ -98,7 +99,7 @@ public Domain createDomain(GWTDomain gwtDomain, JSONObjec List properties = gwtDomain.getFields(); Domain newDomain = PropertyService.get().createDomain(container, domainURI, gwtDomain.getName(), templateInfo); - Set propertyUris = new HashSet<>(); + Set propertyUris = new CaseInsensitiveHashSet(); Map defaultValues = new HashMap<>(); try { diff --git a/api/src/org/labkey/api/query/snapshot/AbstractSnapshotProvider.java b/api/src/org/labkey/api/query/snapshot/AbstractSnapshotProvider.java index a08de1e6ec3..61e9efdc79e 100644 --- a/api/src/org/labkey/api/query/snapshot/AbstractSnapshotProvider.java +++ b/api/src/org/labkey/api/query/snapshot/AbstractSnapshotProvider.java @@ -24,6 +24,7 @@ import org.labkey.api.exp.PropertyType; import org.labkey.api.exp.property.Domain; import org.labkey.api.exp.property.DomainProperty; +import org.labkey.api.exp.property.DomainUtil; import org.labkey.api.exp.property.PropertyService; import org.labkey.api.query.CustomView; import org.labkey.api.query.QueryDefinition; @@ -35,6 +36,7 @@ import org.springframework.validation.BindException; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; /* @@ -131,13 +133,15 @@ public static DomainProperty addAsDomainProperty(Domain domain, ColumnInfo colum if (name.contains("/")) name = name.replace('/', '.'); + String propertyURI = DomainUtil.createUniquePropertyURI(domain.getTypeURI()); + if (pd != null) { PropertyDescriptor newProp = pd.clone(); // initialize so the domain doesn't get upset newProp.setContainer(domain.getContainer()); - newProp.setPropertyURI(getPropertyURI(domain, column)); + newProp.setPropertyURI(propertyURI); newProp.setPropertyId(0); newProp.setName(name); newProp.setLabel(column.getLabel()); @@ -161,16 +165,11 @@ public static DomainProperty addAsDomainProperty(Domain domain, ColumnInfo colum prop.setType(PropertyService.get().getType(domain.getContainer(), type.getXmlName())); prop.setDescription(column.getDescription()); prop.setFormat(column.getFormat()); - prop.setPropertyURI(getPropertyURI(domain, column)); + prop.setPropertyURI(propertyURI); } return prop; } - public static String getPropertyURI(Domain domain, ColumnInfo column) - { - return domain.getTypeURI() + "." + column.getName(); - } - @Override public TableInfo getTableInfoQuerySnapshotDef() { diff --git a/api/src/org/labkey/api/reports/model/ReportPropsManager.java b/api/src/org/labkey/api/reports/model/ReportPropsManager.java index d5db42c7537..04708973083 100644 --- a/api/src/org/labkey/api/reports/model/ReportPropsManager.java +++ b/api/src/org/labkey/api/reports/model/ReportPropsManager.java @@ -34,6 +34,7 @@ import org.labkey.api.exp.PropertyType; import org.labkey.api.exp.property.Domain; import org.labkey.api.exp.property.DomainProperty; +import org.labkey.api.exp.property.DomainUtil; import org.labkey.api.exp.property.PropertyService; import org.labkey.api.query.ValidationException; import org.labkey.api.security.User; @@ -46,6 +47,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -84,11 +86,6 @@ public List getProperties(Container container) return properties; } - public void createProperty(Container container, User user, String name, String label, PropertyType type) throws Exception - { - ensureProperty(container, user, name, label, type); - } - private Map getPropertyMap(Container container) { Domain domain = getDomain(container, false); @@ -120,7 +117,7 @@ public synchronized DomainProperty ensureProperty(Container container, User user prop.setName(name); prop.setLabel(label); prop.setType(PropertyService.get().getType(domain.getContainer(), type.getXmlName())); - prop.setPropertyURI(getPropertyURI(name, container)); + prop.setPropertyURI(DomainUtil.createUniquePropertyURI(getDomainURI(container))); dp = prop; } @@ -209,11 +206,6 @@ private String getDomainURI(@NotNull Container container) return new Lsid("urn:lsid:labkey.com:" + NAMESPACE_PREFIX + ".Folder-" + container.getRowId() + ':' + TYPE_PROPERTIES).toString(); } - private String getPropertyURI(String propertyName, Container container) - { - return getDomainURI(container) + '#' + propertyName; - } - @Override public void containerDeleted(Container container, User user) { diff --git a/assay/api-src/org/labkey/api/assay/nab/RenderAssayBean.java b/assay/api-src/org/labkey/api/assay/nab/RenderAssayBean.java index e85c763c80d..2da6f00d071 100644 --- a/assay/api-src/org/labkey/api/assay/nab/RenderAssayBean.java +++ b/assay/api-src/org/labkey/api/assay/nab/RenderAssayBean.java @@ -328,7 +328,6 @@ public Pair getFitError(DilutionAssayRun.SampleResul { try { - Lsid fitErrorURI = new Lsid(DilutionDataHandler.NAB_PROPERTY_LSID_PREFIX, getAssay().getProtocol().getName(), DilutionDataHandler.FIT_ERROR_PROPERTY); PropertyDescriptor fitErrorPd = _assay.getDataHandler().getPropertyDescriptor(container, getAssay().getProtocol(), DilutionDataHandler.FIT_ERROR_PROPERTY, new HashMap<>()); if (null != fitErrorPd) diff --git a/assay/api-src/org/labkey/api/assay/nab/query/CutoffValueTable.java b/assay/api-src/org/labkey/api/assay/nab/query/CutoffValueTable.java index ae5db5c1946..5b39f7235af 100644 --- a/assay/api-src/org/labkey/api/assay/nab/query/CutoffValueTable.java +++ b/assay/api-src/org/labkey/api/assay/nab/query/CutoffValueTable.java @@ -81,7 +81,9 @@ private SQLFragment getSelectedCurveFitIC(boolean oorIndicator) defaultICSQL.append(DilutionManager.getTableInfoNAbSpecimen(), "ns"); defaultICSQL.append(", "); defaultICSQL.append(ExperimentService.get().getTinfoExperimentRun(), "er"); - defaultICSQL.append(" WHERE op.PropertyId = pd.PropertyId AND pd.PropertyURI LIKE '%#" + DilutionAssayProvider.CURVE_FIT_METHOD_PROPERTY_NAME + "' AND ns.RowId = "); + defaultICSQL.append(" WHERE op.PropertyId = pd.PropertyId AND pd.Name = ? "); + defaultICSQL.add(DilutionAssayProvider.CURVE_FIT_METHOD_PROPERTY_NAME); + defaultICSQL.append("AND ns.RowId = "); defaultICSQL.append(ExprColumn.STR_TABLE_ALIAS); defaultICSQL.append(".NAbSpecimenID AND er.LSID = o.ObjectURI AND o.ObjectId = op.ObjectId AND er.RowId = ns.RunId)"); defaultICSQL.append("\nWHEN 'Polynomial' THEN "); diff --git a/assay/api-src/org/labkey/api/assay/nab/query/NAbSpecimenTable.java b/assay/api-src/org/labkey/api/assay/nab/query/NAbSpecimenTable.java index 90be158b111..2b6267c8a0f 100644 --- a/assay/api-src/org/labkey/api/assay/nab/query/NAbSpecimenTable.java +++ b/assay/api-src/org/labkey/api/assay/nab/query/NAbSpecimenTable.java @@ -104,7 +104,8 @@ private SQLFragment getSelectedCurveFitAUC(boolean positive) sql.append(OntologyManager.getTinfoPropertyDescriptor(), "pd"); sql.append(", "); sql.append(ExperimentService.get().getTinfoExperimentRun(), "er"); - sql.append(" WHERE op.PropertyId = pd.PropertyId AND pd.PropertyURI LIKE '%#" + DilutionAssayProvider.CURVE_FIT_METHOD_PROPERTY_NAME + "'"); + sql.append(" WHERE op.PropertyId = pd.PropertyId AND pd.Name = ?"); + sql.add(DilutionAssayProvider.CURVE_FIT_METHOD_PROPERTY_NAME); sql.append(" AND er.LSID = o.ObjectURI AND o.ObjectId = op.ObjectId AND er.RowId = " + ExprColumn.STR_TABLE_ALIAS + ".RunId)"); sql.append("\nWHEN 'Polynomial' THEN "); sql.append(ExprColumn.STR_TABLE_ALIAS + "."); diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index 55f3540f7b7..f4a352411f6 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -2349,7 +2349,7 @@ public Container getPlateMetadataDomainContainer(Container container) if (existingProperties.contains(pd.getName())) throw new IllegalStateException(String.format("Unable to create field: %s on domain: %s. The field already exists.", pd.getName(), metadataDomain.getTypeURI())); - DomainUtil.addProperty(metadataDomain, pd, new HashMap<>(), new HashSet<>(), null); + DomainUtil.addProperty(metadataDomain, pd, new HashMap<>(), new CaseInsensitiveHashSet(), null); } metadataDomain.save(user); tx.commit(); diff --git a/assay/src/org/labkey/assay/plate/PlateMetadataDomainKind.java b/assay/src/org/labkey/assay/plate/PlateMetadataDomainKind.java index 956491f2882..b5a3d7f1684 100644 --- a/assay/src/org/labkey/assay/plate/PlateMetadataDomainKind.java +++ b/assay/src/org/labkey/assay/plate/PlateMetadataDomainKind.java @@ -17,6 +17,7 @@ import org.labkey.api.exp.property.BaseAbstractDomainKind; import org.labkey.api.exp.property.Domain; import org.labkey.api.exp.property.DomainProperty; +import org.labkey.api.exp.property.DomainUtil; import org.labkey.api.exp.property.Lookup; import org.labkey.api.exp.property.PropertyService; import org.labkey.api.gwt.client.model.GWTDomain; @@ -153,7 +154,7 @@ public void ensureDomainProperties(Domain domain, Container container) DomainProperty prop = domain.addProperty(); prop.setName(spec.getName()); - prop.setPropertyURI(getUniqueURI(typeUri + "#" + spec.getName(), propertyURIs)); + prop.setPropertyURI(DomainUtil.createUniquePropertyURI(typeUri, null, propertyURIs)); prop.setRangeURI(spec.getTypeURI()); prop.setScale(spec.getSize()); prop.setRequired(!spec.isNullable()); @@ -168,19 +169,6 @@ public void ensureDomainProperties(Domain domain, Container container) } } - private String getUniqueURI(String uri, Set propertyURIs) - { - String result = uri; - int ordinal = 1; - - while (propertyURIs.contains(result)) - { - result = String.format("%s-%d", uri, ordinal++); - } - propertyURIs.add(result); - return result; - } - @Override public String getStorageSchemaName() { diff --git a/experiment/src/org/labkey/experiment/XarExporter.java b/experiment/src/org/labkey/experiment/XarExporter.java index 74094984a4e..ce98dfa36fe 100644 --- a/experiment/src/org/labkey/experiment/XarExporter.java +++ b/experiment/src/org/labkey/experiment/XarExporter.java @@ -793,7 +793,8 @@ public void addDataClass(ExpDataClass dataClass) throws ExperimentException queueDomain(dataClass.getDomain()); } - // Return the "name" portion of the propertyURI after the hash + // Return the "name" portion of the propertyURI after the hash (Issue 30718) + @Deprecated private String getPropertyName(DomainProperty dp) { String name = dp.getName(); diff --git a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java index 04602fae9a9..f1899691324 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java @@ -7868,7 +7868,7 @@ public ExpDataClassImpl createDataClass( lowerReservedNames = emptySet(); Map defaultValues = new HashMap<>(); - Set propertyUris = new HashSet<>(); + Set propertyUris = new CaseInsensitiveHashSet(); List calculatedFields = new ArrayList<>(); for (GWTPropertyDescriptor pd : properties) { diff --git a/experiment/src/org/labkey/experiment/api/SampleTypeServiceImpl.java b/experiment/src/org/labkey/experiment/api/SampleTypeServiceImpl.java index 7dc15f24429..5b23b5fd785 100644 --- a/experiment/src/org/labkey/experiment/api/SampleTypeServiceImpl.java +++ b/experiment/src/org/labkey/experiment/api/SampleTypeServiceImpl.java @@ -33,6 +33,7 @@ import org.labkey.api.audit.provider.FileSystemAuditProvider; import org.labkey.api.cache.Cache; import org.labkey.api.cache.CacheManager; +import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.collections.LongArrayList; import org.labkey.api.collections.LongHashMap; import org.labkey.api.collections.LongHashSet; @@ -787,7 +788,7 @@ public ExpSampleTypeImpl createSampleType(Container c, User u, String name, Stri boolean hasNameProperty = false; String idUri1 = null, idUri2 = null, idUri3 = null, parentUri = null; Map defaultValues = new HashMap<>(); - Set propertyUris = new HashSet<>(); + Set propertyUris = new CaseInsensitiveHashSet(); List calculatedFields = new ArrayList<>(); for (int i = 0; i < properties.size(); i++) { diff --git a/experiment/src/org/labkey/experiment/api/VocabularyDomainKind.java b/experiment/src/org/labkey/experiment/api/VocabularyDomainKind.java index ed94f605992..daddfde1180 100644 --- a/experiment/src/org/labkey/experiment/api/VocabularyDomainKind.java +++ b/experiment/src/org/labkey/experiment/api/VocabularyDomainKind.java @@ -3,6 +3,7 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; import org.json.JSONObject; +import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerType; import org.labkey.api.data.SQLFragment; @@ -159,12 +160,13 @@ public Domain createDomain(GWTDomain domain, JSONObject arguments, Container con List properties = domain.getFields(); Domain vocabularyDomain = PropertyService.get().createDomain(container, domainURI, domain.getName(), templateInfo); - Set propertyUris = new HashSet<>(); + Set propertyUris = new CaseInsensitiveHashSet(); Map defaultValues = new HashMap<>(); try { for (GWTPropertyDescriptor pd : properties) { + pd.setPropertyURI(DomainUtil.createUniquePropertyURI(vocabularyDomain.getTypeURI(), pd.getName(), propertyUris)); DomainUtil.addProperty(vocabularyDomain, pd, defaultValues, propertyUris, null); } vocabularyDomain.save(user); diff --git a/experiment/src/org/labkey/experiment/api/property/DomainImpl.java b/experiment/src/org/labkey/experiment/api/property/DomainImpl.java index 990ccc5de1f..e275ca559a2 100644 --- a/experiment/src/org/labkey/experiment/api/property/DomainImpl.java +++ b/experiment/src/org/labkey/experiment/api/property/DomainImpl.java @@ -30,6 +30,7 @@ import org.labkey.api.audit.AuditLogService; import org.labkey.api.audit.AuditTypeEvent; import org.labkey.api.collections.CaseInsensitiveHashMap; +import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.collections.Sets; import org.labkey.api.data.*; import org.labkey.api.data.dialect.SqlDialect; @@ -1281,6 +1282,12 @@ public DomainProperty addProperty() @Override public DomainProperty addProperty(PropertyStorageSpec spec) + { + return addProperty(spec, null); + } + + @Override + public DomainProperty addProperty(PropertyStorageSpec spec, @Nullable String propSuffix) { PropertyDescriptor pd = new PropertyDescriptor(); pd.setContainer(getContainer()); @@ -1290,7 +1297,7 @@ public DomainProperty addProperty(PropertyStorageSpec spec) pd.setNullable(spec.isNullable()); // pd.setAutoIncrement(spec.isAutoIncrement()); // always false in PropertyDescriptor pd.setMvEnabled(spec.isMvEnabled()); - pd.setPropertyURI(getTypeURI() + ":field-" + spec.getName()); + pd.setPropertyURI(DomainUtil.createUniquePropertyURI(getTypeURI(), propSuffix, new CaseInsensitiveHashSet())); // Issue 53586 pd.setDescription(spec.getDescription()); pd.setImportAliases(spec.getImportAliases()); pd.setScale(spec.getSize()); diff --git a/experiment/src/org/labkey/experiment/controllers/property/PropertyController.java b/experiment/src/org/labkey/experiment/controllers/property/PropertyController.java index 5a7d624f4c2..35eb30a598f 100644 --- a/experiment/src/org/labkey/experiment/controllers/property/PropertyController.java +++ b/experiment/src/org/labkey/experiment/controllers/property/PropertyController.java @@ -27,7 +27,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.json.JSONObject; +import org.junit.AfterClass; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; import org.labkey.api.action.AbstractFileUploadAction; import org.labkey.api.action.Action; @@ -42,6 +44,7 @@ import org.labkey.api.action.ReadOnlyApiAction; import org.labkey.api.action.SimpleViewAction; import org.labkey.api.action.SpringActionController; +import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.collections.IntHashMap; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerService; @@ -52,6 +55,7 @@ import org.labkey.api.data.SimpleFilter; import org.labkey.api.defaults.DefaultValueService; import org.labkey.api.exp.ChangePropertyDescriptorException; +import org.labkey.api.exp.DomainNotFoundException; import org.labkey.api.exp.Identifiable; import org.labkey.api.exp.Lsid; import org.labkey.api.exp.LsidManager; @@ -548,7 +552,7 @@ public Object execute(DomainApiForm form, BindException errors) { try { - DomainProperty dp = DomainUtil.addProperty(domain, field, new HashMap<>(), new HashSet<>(), results); + DomainProperty dp = DomainUtil.addProperty(domain, field, new HashMap<>(), new CaseInsensitiveHashSet(), results); OntologyManager.validatePropertyDescriptor(dp.getPropertyDescriptor()); } catch (ChangePropertyDescriptorException e) @@ -2196,7 +2200,10 @@ public void setPropertyURIs(List propertyURIs) public static class TestCase extends Assert { - Domain createVocabDomain() throws ValidationException + private static Domain domain; + + @BeforeClass + public static void initialSetUp() throws ValidationException { Container c = JunitUtil.getTestContainer(); User user = TestContext.get().getUser(); @@ -2222,7 +2229,14 @@ Domain createVocabDomain() throws ValidationException gwtDomain.setFields(gwtProps); - return DomainUtil.createDomain(VocabularyDomainKind.KIND_NAME, gwtDomain, null, c, user, domainName, null, false); + domain = DomainUtil.createDomain(VocabularyDomainKind.KIND_NAME, gwtDomain, null, c, user, domainName, null, false); + } + + @AfterClass + public static void tearDown() throws DomainNotFoundException + { + User user = TestContext.get().getUser(); + domain.delete(user); } @Test @@ -2231,14 +2245,12 @@ public void testGetDomains() throws ValidationException Container c = JunitUtil.getTestContainer(); User user = TestContext.get().getUser(); - Domain createdDomain = createVocabDomain(); - Set domainKinds = new HashSet<>(); domainKinds.add(VocabularyDomainKind.KIND_NAME); List vocabDomains = PropertyService.get().getDomains(c, user, domainKinds, null, false); - boolean found = vocabDomains.stream().anyMatch(d -> d.getTypeId() == createdDomain.getTypeId()); + boolean found = vocabDomains.stream().anyMatch(d -> d.getTypeId() == domain.getTypeId()); assertTrue("Vocabulary Domain Not found.", found); } @@ -2248,7 +2260,6 @@ public void testGetProperties() throws ValidationException Container c = JunitUtil.getTestContainer(); User user = TestContext.get().getUser(); - Domain domain = createVocabDomain(); var props = domain.getProperties().stream().map(DomainProperty::getPropertyDescriptor).collect(Collectors.toSet()); // find by domainIds @@ -2297,7 +2308,6 @@ public void testPropertyUsages() throws Exception Container c = JunitUtil.getTestContainer(); User user = TestContext.get().getUser(); - Domain domain = createVocabDomain(); var intProp = domain.getPropertyByName("testIntField"); var stringProp = domain.getPropertyByName("testStringField"); diff --git a/experiment/test/src/org/labkey/test/tests/experiment/VocabularyViewSupportTest.java b/experiment/test/src/org/labkey/test/tests/experiment/VocabularyViewSupportTest.java index 5978ecd687f..df09bbadf80 100644 --- a/experiment/test/src/org/labkey/test/tests/experiment/VocabularyViewSupportTest.java +++ b/experiment/test/src/org/labkey/test/tests/experiment/VocabularyViewSupportTest.java @@ -5,6 +5,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.labkey.api.exp.Lsid; import org.labkey.remoteapi.CommandException; import org.labkey.remoteapi.assay.Run; import org.labkey.remoteapi.assay.SaveAssayBatchCommand; @@ -117,6 +118,12 @@ public void testSampleSetViewSupport() throws IOException, CommandException DomainDetailsResponse domainResponse = createDomain(domainKind, domainName, description, fields); int domainId = domainResponse.getDomain().getDomainId().intValue(); + log("Verify vocab domain propertyURIs use field name in suffix (see changes for Issue 53586)"); + List domainFields = domainResponse.getDomain().getFields(); + assertTrue("Domain field propertyURI suffix is incorrect: " + domainFields.get(0).getPropertyURI(), domainFields.get(0).getPropertyURI().endsWith("#" + prop1Name)); + assertTrue("Domain field propertyURI suffix is incorrect: " + domainFields.get(1).getPropertyURI(), domainFields.get(1).getPropertyURI().endsWith("#" + prop2Name)); + assertTrue("Domain field propertyURI suffix is incorrect: " + domainFields.get(2).getPropertyURI(), domainFields.get(2).getPropertyURI().endsWith("#" + prop3Name)); + log("Create a sampleset"); String sampleSchemaName = "samples"; String sampleSetName = "Cars"; @@ -132,11 +139,11 @@ public void testSampleSetViewSupport() throws IOException, CommandException Map row = new HashMap<>(); row.put("Name", "Tesla"); // value for color vocabulary property - row.put(domainResponse.getDomain().getFields().get(0).getPropertyURI(), prop1Value); + row.put(domainFields.get(0).getPropertyURI(), prop1Value); // value for year vocabulary property - row.put(domainResponse.getDomain().getFields().get(1).getPropertyURI(), prop2Value); + row.put(domainFields.get(1).getPropertyURI(), prop2Value); // value for list lookup property - row.put(domainResponse.getDomain().getFields().get(2).getPropertyURI(), listRow1RowId); + row.put(domainFields.get(2).getPropertyURI(), listRow1RowId); insertRowsCommand.addRow(row); insertRowsCommand.execute(createDefaultConnection(), getProjectName()); @@ -224,6 +231,10 @@ public void testAssayViewSupport() throws IOException, CommandException String vocabDomainPropURI1 = domainResponse.getDomain().getFields().get(0).getPropertyURI(); String vocabDomainPropURI2 = domainResponse.getDomain().getFields().get(1).getPropertyURI(); + log("Verify vocab domain propertyURIs use field name in suffix (see changes for Issue 53586)"); + assertTrue("Vocabulary domain propertyURI suffix is incorrect: " + vocabDomainPropURI1, vocabDomainPropURI1.endsWith("#" + Lsid.encodePart(propNameLab))); + assertTrue("Vocabulary domain propertyURI suffix is incorrect: " + vocabDomainPropURI2, vocabDomainPropURI2.endsWith("#" + propNameLocation)); + Run run = new Run(); run.setName("ViewSupportRun"); run.setProperties(Map.of(vocabDomainPropURI1, propValueLab, vocabDomainPropURI2, listRow1RowId)); diff --git a/issues/src/org/labkey/issue/model/IssueListDef.java b/issues/src/org/labkey/issue/model/IssueListDef.java index 1daec0f046a..6e14ca0cc51 100644 --- a/issues/src/org/labkey/issue/model/IssueListDef.java +++ b/issues/src/org/labkey/issue/model/IssueListDef.java @@ -31,6 +31,7 @@ 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.exp.property.DomainUtil; import org.labkey.api.exp.property.Lookup; import org.labkey.api.exp.property.PropertyService; import org.labkey.api.issues.AbstractIssuesListDefDomainKind; @@ -45,6 +46,7 @@ import org.labkey.issue.query.IssueDefDomainKind; import java.util.Collection; +import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -286,7 +288,7 @@ private void ensureDomainProperties(Domain domain, AbstractIssuesListDefDomainKi DomainProperty prop = domain.addProperty(); prop.setName(spec.getName()); - prop.setPropertyURI(typeUri + "#" + spec.getName()); + prop.setPropertyURI(DomainUtil.createUniquePropertyURI(typeUri)); prop.setRangeURI(spec.getTypeURI()); prop.setScale(spec.getSize()); prop.setRequired(!spec.isNullable()); diff --git a/list/src/org/labkey/list/model/ListDefinitionImpl.java b/list/src/org/labkey/list/model/ListDefinitionImpl.java index ad0514f0e02..07c3b39a477 100644 --- a/list/src/org/labkey/list/model/ListDefinitionImpl.java +++ b/list/src/org/labkey/list/model/ListDefinitionImpl.java @@ -40,6 +40,7 @@ import org.labkey.api.exp.list.ListItem; import org.labkey.api.exp.property.Domain; import org.labkey.api.exp.property.DomainProperty; +import org.labkey.api.exp.property.DomainUtil; import org.labkey.api.exp.property.PropertyService; import org.labkey.api.gwt.client.model.GWTPropertyDescriptor; import org.labkey.api.query.BatchValidationException; @@ -64,6 +65,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; @@ -446,7 +448,7 @@ private void ensureKey() } DomainProperty prop = domain.addProperty(); - prop.setPropertyURI(domain.getTypeURI() + "#" + getKeyName()); + prop.setPropertyURI(DomainUtil.createUniquePropertyURI(domain.getTypeURI())); prop.setName(getKeyName()); prop.setType(PropertyService.get().getType(domain.getContainer(), getKeyType().getPropertyType().getXmlName())); diff --git a/list/src/org/labkey/list/model/ListDomainKind.java b/list/src/org/labkey/list/model/ListDomainKind.java index c04fb2c1640..01ff5caa5b8 100644 --- a/list/src/org/labkey/list/model/ListDomainKind.java +++ b/list/src/org/labkey/list/model/ListDomainKind.java @@ -421,7 +421,7 @@ public Domain createDomain(GWTDomain domain, ListDomainKindProperties listProper Set lowerReservedNames = reservedNames.stream().map(String::toLowerCase).collect(Collectors.toSet()); Map defaultValues = new HashMap<>(); - Set propertyUris = new HashSet<>(); + Set propertyUris = new CaseInsensitiveHashSet(); for (GWTPropertyDescriptor pd : properties) { String propertyName = pd.getName().toLowerCase(); diff --git a/study/src/org/labkey/study/model/DatasetDomainKind.java b/study/src/org/labkey/study/model/DatasetDomainKind.java index eadbb4055f4..c67c068b278 100644 --- a/study/src/org/labkey/study/model/DatasetDomainKind.java +++ b/study/src/org/labkey/study/model/DatasetDomainKind.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.action.ApiUsageException; +import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.compliance.ComplianceService; import org.labkey.api.data.BaseColumnInfo; import org.labkey.api.data.ColumnInfo; @@ -502,7 +503,7 @@ else if (!timepointType.isVisitBased() && getKindName().equals(VisitDatasetDomai Set lowerReservedNames = reservedNames.stream().map(String::toLowerCase).collect(Collectors.toSet()); Set existingProperties = newDomain.getProperties().stream().map(o -> o.getName().toLowerCase()).collect(Collectors.toSet()); Map defaultValues = new HashMap<>(); - Set propertyUris = new HashSet<>(); + Set propertyUris = new CaseInsensitiveHashSet(); for (GWTPropertyDescriptor pd : properties) {