diff --git a/.gitattributes b/.gitattributes index 3d1bc142acb..540d4205b1e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1947,8 +1947,6 @@ experiment/src/org/labkey/experiment/DataClassWebPart.java -text experiment/src/org/labkey/experiment/DataURLRelativizer.java -text experiment/src/org/labkey/experiment/DefaultCustomPropertyRenderer.java -text experiment/src/org/labkey/experiment/defaults/DefaultValueServiceImpl.java -text -experiment/src/org/labkey/experiment/DerivedSamplePropertyHelper.java -text -experiment/src/org/labkey/experiment/deriveSamplesChooseTarget.jsp -text experiment/src/org/labkey/experiment/DotGraph.java -text experiment/src/org/labkey/experiment/ExpDataFileListener.java -text experiment/src/org/labkey/experiment/ExperimentAuditProvider.java -text @@ -1988,7 +1986,6 @@ experiment/src/org/labkey/experiment/SampleTypeAuditProvider.java -text experiment/src/org/labkey/experiment/SampleTypeDisplayColumn.java -text experiment/src/org/labkey/experiment/SampleTypeWebPart.java -text experiment/src/org/labkey/experiment/StandardAndCustomPropertiesView.java -text -experiment/src/org/labkey/experiment/summarizeMaterialInputs.jsp -text experiment/src/org/labkey/experiment/types/begin.jsp -text experiment/src/org/labkey/experiment/types/typeDetails.jsp -text experiment/src/org/labkey/experiment/types/types.jsp -text diff --git a/api/src/org/labkey/api/settings/AppProps.java b/api/src/org/labkey/api/settings/AppProps.java index 5a71b15b453..a9c61fff7c4 100644 --- a/api/src/org/labkey/api/settings/AppProps.java +++ b/api/src/org/labkey/api/settings/AppProps.java @@ -46,7 +46,6 @@ public interface AppProps String SCOPE_OPTIONAL_FEATURE = "ExperimentalFeature"; // Startup property prefix for all optional features; "Experimental" for historical reasons. String OPTIONAL_NO_GUESTS = "disableGuestAccount"; String EXPERIMENTAL_BLOCKER = "blockMaliciousClients"; - String DEPRECATED_DERIVE_SAMPLES_NOT_IN_APP = "deriveSamplesNotInApp"; String ADMIN_PROVIDED_ALLOWED_EXTERNAL_RESOURCES = "allowedExternalResources"; String QUANTITY_COLUMN_SUFFIX_TESTING = "quantityColumnSuffixTesting"; String REJECT_CONTROLLER_FIRST_URLS = "rejectControllerFirstUrls"; diff --git a/experiment/src/org/labkey/experiment/DerivedSamplePropertyHelper.java b/experiment/src/org/labkey/experiment/DerivedSamplePropertyHelper.java deleted file mode 100644 index 951bd1da2d5..00000000000 --- a/experiment/src/org/labkey/experiment/DerivedSamplePropertyHelper.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.labkey.experiment; - -import org.jetbrains.annotations.NotNull; -import org.labkey.api.assay.actions.UploadWizardAction; -import org.labkey.api.collections.CaseInsensitiveHashMap; -import org.labkey.api.collections.IntHashMap; -import org.labkey.api.data.Container; -import org.labkey.api.data.DbSequence; -import org.labkey.api.data.NameGenerator; -import org.labkey.api.data.NameGeneratorState; -import org.labkey.api.exp.DuplicateMaterialException; -import org.labkey.api.exp.ExperimentException; -import org.labkey.api.exp.Lsid; -import org.labkey.api.exp.PropertyDescriptor; -import org.labkey.api.exp.SamplePropertyHelper; -import org.labkey.api.exp.XarContext; -import org.labkey.api.exp.XarFormatException; -import org.labkey.api.exp.api.ExpMaterial; -import org.labkey.api.exp.api.ExpSampleType; -import org.labkey.api.exp.api.ExperimentService; -import org.labkey.api.exp.property.DomainProperty; -import org.labkey.api.exp.xar.LsidUtils; -import org.labkey.api.security.User; -import org.labkey.api.util.Pair; -import org.labkey.experiment.api.ExpSampleTypeImpl; -import org.labkey.experiment.api.ExperimentServiceImpl; -import org.labkey.experiment.api.property.DomainPropertyImpl; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Supplier; - -import static org.labkey.api.exp.api.ExpRunItem.PARENT_IMPORT_ALIAS_MAP_PROP; - -/** - * Gets the sample-specific values from user-provided information when creating child samples from an existing set - * of parents. - */ -public class DerivedSamplePropertyHelper extends SamplePropertyHelper -{ - private final List _names; - private final Map> _lsids = new IntHashMap<>(); - private final ExpSampleTypeImpl _sampleType; - private final Container _container; - private final User _user; - - private final DomainProperty _nameProperty; - private final NameGenerator _nameGenerator; - private NameGeneratorState _state; - private Supplier> _genIdFn; - - public DerivedSamplePropertyHelper(ExpSampleTypeImpl sampleType, int sampleCount, Container c, User user) - { - super(Collections.emptyList()); - - _sampleType = sampleType; - if (_sampleType != null) - _nameGenerator = _sampleType.getNameGenerator(c, user); - else - _nameGenerator = null; - - _container = c; - _user = user; - _names = new ArrayList<>(); - for (int i = 1; i <= sampleCount; i++) - { - _names.add("Output Sample " + i); - } - - PropertyDescriptor namePropertyDescriptor = new PropertyDescriptor(ExperimentServiceImpl.get().getTinfoMaterial().getColumn("Name"), c); - namePropertyDescriptor.setRequired(_nameGenerator == null); - _nameProperty = new DomainPropertyImpl(null, namePropertyDescriptor); - - List dps = new ArrayList<>(); - if (sampleType != null) - { - if (sampleType.hasNameAsIdCol()) - { - dps.add(_nameProperty); - } - dps.addAll(sampleType.getDomain().getProperties()); - } - else - { - dps.add(_nameProperty); - } - setDomainProperties(Collections.unmodifiableList(dps)); - } - - public ExpSampleType getSampleType() - { - return _sampleType; - } - - @Override - public List getSampleNames() - { - return _names; - } - - @Override - protected Lsid getObject(int index, @NotNull Map sampleProperties, @NotNull Set parentMaterials) throws ExperimentException - { - return getObjectWithName(index, sampleProperties, parentMaterials).first; - } - - @Override - protected Pair getObjectWithName(int index, @NotNull Map sampleProperties, @NotNull Set parentMaterials) throws ExperimentException - { - Pair lsidName = _lsids.get(index); - Lsid lsid; - String name; - boolean isDuplicate; - if (lsidName == null) - { - name = determineMaterialName(sampleProperties, parentMaterials); - if (_sampleType == null) - { - XarContext context = new XarContext("DeriveSamples", _container, _user); - try - { - String lsidStr = LsidUtils.resolveLsidFromTemplate("${FolderLSIDBase}:" + name, context, ExpMaterial.DEFAULT_CPAS_TYPE); - lsid = Lsid.parse(lsidStr); - isDuplicate = ExperimentService.get().getExpMaterial(lsid.toString()) != null; - } - catch (XarFormatException e) - { - // Shouldn't happen - our template is safe - throw new RuntimeException(e); - } - } - else - { - lsid = _sampleType.generateNextDBSeqLSID().build(); - isDuplicate = _sampleType.getSample(_container, name) != null; - } - - lsidName = new Pair<>(lsid, name); - - if (isDuplicate || _lsids.containsValue(lsidName)) - { - // Default to not showing on a particular column - String colName = "main"; - if (!getNamePDs().isEmpty() && getSampleNames().size() > index) - { - colName = UploadWizardAction.getInputName(getNamePDs().getFirst(), getSampleNames().get(index)); - } - throw new DuplicateMaterialException("Duplicate material name: " + name, colName); - } - _lsids.put(index, lsidName); - } - return lsidName; - } - - public String determineMaterialName(Map sampleProperties, Set parentSamples) throws ExperimentException - { - if (_sampleType != null) - { - if (_state == null) - { - _state = _nameGenerator.createState(true); - DbSequence sequence = _sampleType.genIdSequence(); - _genIdFn = () -> Map.of("genId", sequence.next()); - } - - Map context = new CaseInsensitiveHashMap<>(); - for (Map.Entry entry : sampleProperties.entrySet()) - { - context.put(entry.getKey().getName(), entry.getValue()); - } - try - { - List>> extraPropsFns = new ArrayList<>(); - extraPropsFns.add(_genIdFn); - - try - { - Map importAlias = _sampleType.getImportAliases(); - extraPropsFns.add(() -> - Map.of(PARENT_IMPORT_ALIAS_MAP_PROP, importAlias) - ); - } - catch (IOException e) - { - // do nothing - } - - String generatedName = _nameGenerator.generateName(_state, context, null, parentSamples, extraPropsFns); // todo add alias - _state.cleanUp(); - return generatedName; - } - catch (NameGenerator.NameGenerationException e) - { - throw new ExperimentException(e); - } - } - else - { - assert _domainProperties.getFirst().getName().equals("Name"); - return sampleProperties.get(_nameProperty); - } - } - - @Override - protected boolean isCopyable(DomainProperty pd) - { - return !getNamePDs().contains(pd); - } - - public List getNamePDs() - { - if (_sampleType != null) - { - if (_sampleType.hasNameAsIdCol()) - { - return Collections.singletonList(_nameProperty); - } - - Set idColNames = new HashSet<>(); - for (DomainProperty pd : _sampleType.getIdCols()) - idColNames.add(pd.getName()); - List properties = new ArrayList<>(); - for (DomainProperty dp : _sampleType.getDomain().getProperties()) - { - if (idColNames.contains(dp.getName())) - properties.add(dp); - } - return properties; - } - else - { - assert _domainProperties.getFirst().getName().equals("Name"); - return Collections.singletonList(_domainProperties.getFirst()); - } - } -} diff --git a/experiment/src/org/labkey/experiment/ExperimentModule.java b/experiment/src/org/labkey/experiment/ExperimentModule.java index 79ceba7d51e..a09f3b29403 100644 --- a/experiment/src/org/labkey/experiment/ExperimentModule.java +++ b/experiment/src/org/labkey/experiment/ExperimentModule.java @@ -267,13 +267,6 @@ protected void init() ExperimentService.get().registerNameExpressionType("aliquots", "exp", "MaterialSource", "aliquotnameexpression"); ExperimentService.get().registerNameExpressionType("dataclass", "exp", "DataClass", "nameexpression"); - OptionalFeatureService.get().addFeatureFlag(new OptionalFeatureFlag( - AppProps.DEPRECATED_DERIVE_SAMPLES_NOT_IN_APP, - "Derive Samples in LabKey Server UI", - "Enables the UI for deriving samples in LabKey Server UI from either the samples grids or a sample lineage page. This option will be removed in LabKey Server 26.11", - false, - false, - OptionalFeatureService.FeatureType.Deprecated)); OptionalFeatureService.get().addExperimentalFeatureFlag(SAMPLE_FILES_TABLE, "Manage Unreferenced Sample Files", "Enable 'Unreferenced Sample Files' table to view and delete sample files that are no longer referenced by samples", false); diff --git a/experiment/src/org/labkey/experiment/controllers/exp/ExperimentController.java b/experiment/src/org/labkey/experiment/controllers/exp/ExperimentController.java index 156bfe387b8..2c9ce340300 100644 --- a/experiment/src/org/labkey/experiment/controllers/exp/ExperimentController.java +++ b/experiment/src/org/labkey/experiment/controllers/exp/ExperimentController.java @@ -40,7 +40,6 @@ import org.labkey.api.action.ExportAction; import org.labkey.api.action.FormHandlerAction; import org.labkey.api.action.FormViewAction; -import org.labkey.api.action.HasViewContext; import org.labkey.api.action.Marshal; import org.labkey.api.action.Marshaller; import org.labkey.api.action.MutatingApiAction; @@ -56,7 +55,6 @@ import org.labkey.api.assay.AssayProtocolSchema; import org.labkey.api.assay.AssayProvider; import org.labkey.api.assay.AssayService; -import org.labkey.api.assay.actions.UploadWizardAction; import org.labkey.api.assay.security.DesignAssayPermission; import org.labkey.api.attachments.AttachmentParent; import org.labkey.api.attachments.AttachmentService; @@ -100,7 +98,6 @@ import org.labkey.api.dataiterator.DataIteratorContext; import org.labkey.api.exp.AbstractParameter; import org.labkey.api.exp.DeleteForm; -import org.labkey.api.exp.DuplicateMaterialException; import org.labkey.api.exp.ExperimentDataHandler; import org.labkey.api.exp.ExperimentException; import org.labkey.api.exp.ExperimentRunForm; @@ -120,7 +117,6 @@ import org.labkey.api.exp.api.ExpExperiment; import org.labkey.api.exp.api.ExpLineageOptions; import org.labkey.api.exp.api.ExpMaterial; -import org.labkey.api.exp.api.ExpMaterialRunInput; import org.labkey.api.exp.api.ExpObject; import org.labkey.api.exp.api.ExpProtocol; import org.labkey.api.exp.api.ExpProtocolApplication; @@ -215,7 +211,6 @@ import org.labkey.api.security.roles.Role; import org.labkey.api.settings.AppProps; import org.labkey.api.settings.ConceptURIProperties; -import org.labkey.api.settings.OptionalFeatureService; import org.labkey.api.sql.LabKeySql; import org.labkey.api.study.Dataset; import org.labkey.api.study.StudyService; @@ -262,7 +257,6 @@ import org.labkey.api.view.VBox; import org.labkey.api.view.ViewBackgroundInfo; import org.labkey.api.view.ViewContext; -import org.labkey.api.view.ViewServlet; import org.labkey.api.view.WebPartView; import org.labkey.api.view.template.ClientDependency; import org.labkey.api.view.template.PageConfig; @@ -271,7 +265,6 @@ import org.labkey.experiment.ConfirmDeleteView; import org.labkey.experiment.CustomPropertiesView; import org.labkey.experiment.DataClassWebPart; -import org.labkey.experiment.DerivedSamplePropertyHelper; import org.labkey.experiment.DotGraph; import org.labkey.experiment.ExpDataFileListener; import org.labkey.experiment.ExperimentRunDisplayColumn; @@ -319,7 +312,6 @@ import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.validation.BindException; import org.springframework.validation.Errors; -import org.springframework.validation.ObjectError; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; @@ -341,7 +333,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -1119,16 +1110,7 @@ public ModelAndView getView(Object o, BindException errors) { ExpSchema schema = new ExpSchema(getUser(), getContainer()); QuerySettings settings = schema.getSettings(getViewContext(), "Materials", ExpSchema.TableType.Materials.toString()); - QueryView view = new QueryView(schema, settings, errors) - { - @Override - protected void populateButtonBar(DataView view, ButtonBar bar) - { - super.populateButtonBar(view, bar); - if (OptionalFeatureService.get().isFeatureEnabled(AppProps.DEPRECATED_DERIVE_SAMPLES_NOT_IN_APP)) - bar.add(SampleTypeContentsView.getDeriveSamplesButton(getContainer(),null)); - } - }; + QueryView view = new QueryView(schema, settings, errors); view.setShowDetailsColumn(false); return view; } @@ -1266,16 +1248,6 @@ public VBox getView(ExpObjectForm form, BindException errors) throws Exception } } - if (getContainer().hasPermission(getUser(), InsertPermission.class) && OptionalFeatureService.get().isFeatureEnabled(AppProps.DEPRECATED_DERIVE_SAMPLES_NOT_IN_APP)) - { - ActionURL deriveURL = new ActionURL(DeriveSamplesChooseTargetAction.class, getContainer()); - deriveURL.addParameter("rowIds", _material.getRowId()); - if (st != null) - deriveURL.addParameter("targetSampleTypeId", st.getRowId()); - - updateLinks.append(LinkBuilder.labkeyLink("derive samples from this sample", deriveURL)).append(" "); - } - vbox.addView(new HtmlView(updateLinks)); ExperimentRunListView runListView = ExperimentRunListView.createView(getViewContext(), ExperimentRunType.ALL_RUNS_TYPE, true); @@ -5479,467 +5451,6 @@ public URLHelper getSuccessURL(SetFlagForm form) } } - @RequiresPermission(InsertPermission.class) - public class DeriveSamplesChooseTargetAction extends SimpleViewAction - { - private List _materials; - - @Override - public void addNavTrail(NavTree root) - { - setHelpTopic("sampleSets"); - addRootNavTrail(root); - root.addChild("Sample Types", ExperimentUrlsImpl.get().getShowSampleTypeListURL(getContainer())); - ExpSampleType sampleType = _materials != null && !_materials.isEmpty() ? _materials.getFirst().getSampleType() : null; - if (sampleType != null) - { - root.addChild(sampleType.getName(), ExperimentUrlsImpl.get().getShowSampleTypeURL(sampleType)); - } - root.addChild("Derive Samples"); - } - - @Override - public void validate(DeriveMaterialForm form, BindException errors) - { - _materials = form.lookupMaterials(); - if (_materials.isEmpty()) - { - throw new NotFoundException("Could not find any matching materials"); - } - } - - @Override - public ModelAndView getView(DeriveMaterialForm form, BindException errors) - { - Container c = getContainer(); - PipeRoot root = PipelineService.get().findPipelineRoot(c); - - if (root == null || !root.isValid()) - { - ActionURL pipelineURL = urlProvider(PipelineUrls.class).urlSetup(c); - return new HtmlView(DIV("You must ", - DOM.A(DOM.at(href, pipelineURL), "configure a valid pipeline root for this folder"), - " before deriving samples.")); - } - else - { - Set materialInputRoles = new TreeSet<>(ExperimentService.get().getMaterialInputRoles(getContainer(), getUser())); - Map materialsWithRoles = new LinkedHashMap<>(); - for (ExpMaterial material : _materials) - { - materialsWithRoles.put(material, null); - } - - List sampleTypes = getUploadableSampleTypes(); - - DeriveSamplesChooseTargetBean bean = new DeriveSamplesChooseTargetBean(form.getDataRegionSelectionKey(), form.getTargetSampleTypeId(), sampleTypes, materialsWithRoles, form.getOutputCount(), materialInputRoles, null); - return new JspView<>("/org/labkey/experiment/deriveSamplesChooseTarget.jsp", bean); - } - } - } - - public static class DeriveSamplesChooseTargetBean implements DataRegionSelection.DataSelectionKeyForm - { - private String _dataRegionSelectionKey; - - private final Integer _targetSampleTypeId; - private final List _sampleTypes; - private final Map _sourceMaterials; - private final int _sampleCount; - private final Collection _inputRoles; - private final DerivedSamplePropertyHelper _propertyHelper; - - public static final String CUSTOM_ROLE = "--CUSTOM--"; - - public DeriveSamplesChooseTargetBean(String dataRegionSelectionKey, Integer targetSampleTypeId, List sampleTypes, Map sourceMaterials, int sampleCount, Collection inputRoles, DerivedSamplePropertyHelper helper) - { - _dataRegionSelectionKey = dataRegionSelectionKey; - _targetSampleTypeId = targetSampleTypeId; - _sampleTypes = sampleTypes; - _sourceMaterials = sourceMaterials; - _sampleCount = sampleCount; - _inputRoles = inputRoles; - _propertyHelper = helper; - } - - public Integer getTargetSampleTypeId() - { - return _targetSampleTypeId; - } - - public DerivedSamplePropertyHelper getPropertyHelper() - { - return _propertyHelper; - } - - public int getSampleCount() - { - return _sampleCount; - } - - public Map getSourceMaterials() - { - return _sourceMaterials; - } - - public List getSampleTypes() - { - return _sampleTypes; - } - - public Collection getInputRoles() - { - return _inputRoles; - } - - @Override - public String getDataRegionSelectionKey() - { - return _dataRegionSelectionKey; - } - - @Override - public void setDataRegionSelectionKey(String key) - { - _dataRegionSelectionKey = key; - } - } - - private List getUploadableSampleTypes() - { - // Make a copy so we can modify it - List sampleTypes = new ArrayList<>(SampleTypeService.get().getSampleTypes(getContainer(), true)); - sampleTypes.removeIf(sampleType -> !sampleType.canImportMoreSamples()); - return sampleTypes; - } - - @RequiresPermission(InsertPermission.class) - public class DeriveSamplesAction extends FormViewAction - { - private List _materials; - private ActionURL _successUrl; - private final Map _inputMaterials = new LinkedHashMap<>(); - - @Override - public ModelAndView getView(DeriveMaterialForm form, boolean reshow, BindException errors) - { - _materials = form.lookupMaterials(); - if (_materials.isEmpty()) - { - throw new NotFoundException("Could not find any matching materials"); - } - - Container c = getContainer(); - - if (form.getOutputCount() <= 0) - { - form.setOutputCount(1); - } - - if (form.getTargetSampleTypeId() == 0) - throw new NotFoundException("Target sample type required for the derived samples"); - - ExpSampleTypeImpl sampleType = SampleTypeServiceImpl.get().getSampleType(getContainer(), form.getTargetSampleTypeId(), true); - if (sampleType == null) - throw new NotFoundException("Could not find sample type with rowId " + form.getTargetSampleTypeId()); - - InsertView insertView = new InsertView(new DataRegion(), errors); - - DerivedSamplePropertyHelper helper = new DerivedSamplePropertyHelper(sampleType, form.getOutputCount(), c, getUser()); - helper.addSampleColumns(insertView, getUser()); - - int[] rowIds = form.getRowIds(); - for (int i = 0; i < rowIds.length; i++) - { - insertView.getDataRegion().addHiddenFormField("rowIds", Integer.toString(rowIds[i])); - insertView.getDataRegion().addHiddenFormField("inputRole" + i, form.getInputRole(i) == null ? "" : form.getInputRole(i)); - insertView.getDataRegion().addHiddenFormField("customRole" + i, form.getCustomRole(i) == null ? "" : form.getCustomRole(i)); - } - - insertView.getDataRegion().addHiddenFormField("targetSampleTypeId", Integer.toString(form.getTargetSampleTypeId())); - insertView.getDataRegion().addHiddenFormField("outputCount", Integer.toString(form.getOutputCount())); - if (form.getDataRegionSelectionKey() != null) - insertView.getDataRegion().addHiddenFormField(DataRegionSelection.DATA_REGION_SELECTION_KEY, form.getDataRegionSelectionKey()); - insertView.setInitialValues(ViewServlet.adaptParameterMap(getViewContext().getRequest().getParameterMap())); - ButtonBar bar = new ButtonBar(); - bar.setStyle(ButtonBar.Style.separateButtons); - ActionButton submitButton = new ActionButton(DeriveSamplesAction.class, "Submit"); - submitButton.setActionType(ActionButton.Action.POST); - bar.add(submitButton); - insertView.getDataRegion().setButtonBar(bar); - insertView.setTitle("Output Samples"); - - Map materialsWithRoles = new LinkedHashMap<>(); - List materials = form.lookupMaterials(); - for (int i = 0; i < materials.size(); i++) - { - materialsWithRoles.put(materials.get(i), form.determineLabel(i)); - } - - DeriveSamplesChooseTargetBean bean = new DeriveSamplesChooseTargetBean(form.getDataRegionSelectionKey(), form.getTargetSampleTypeId(), getUploadableSampleTypes(), materialsWithRoles, form.getOutputCount(), Collections.emptyList(), helper); - JspView view = new JspView<>("/org/labkey/experiment/summarizeMaterialInputs.jsp", bean); - view.setTitle("Input Samples"); - - return new VBox(view, insertView); - } - - @Override - public void addNavTrail(NavTree root) - { - setHelpTopic("sampleSets"); - addRootNavTrail(root); - root.addChild("Sample Types", ExperimentUrlsImpl.get().getShowSampleTypeListURL(getContainer())); - ExpSampleType sampleType = _materials != null && !_materials.isEmpty() ? _materials.getFirst().getSampleType() : null; - if (sampleType != null) - { - root.addChild(sampleType.getName(), ExperimentUrlsImpl.get().getShowSampleTypeURL(sampleType)); - } - root.addChild("Derive Samples"); - } - - @Override - public void validateCommand(DeriveMaterialForm form, Errors errors) - { - List materials = form.lookupMaterials(); - - List lockedSamples = new ArrayList<>(); - for (int i = 0; i < materials.size(); i++) - { - ExpMaterial m = materials.get(i); - if (!m.isOperationPermitted(SampleTypeService.SampleOperations.EditLineage)) - { - lockedSamples.add(m); - } - String inputRole = form.determineLabel(i); - if (inputRole == null || inputRole.isEmpty()) - { - ExpSampleType st = m.getSampleType(); - inputRole = st != null ? st.getName() : ExpMaterialRunInput.DEFAULT_ROLE; - } - _inputMaterials.put(materials.get(i), inputRole); - } - - if (!lockedSamples.isEmpty()) - { - errors.reject(ERROR_MSG, SampleTypeService.get().getOperationNotPermittedMessage(lockedSamples, SampleTypeService.SampleOperations.EditLineage)); - } - } - - @Override - public boolean handlePost(DeriveMaterialForm form, BindException errors) - { - ExpSampleTypeImpl sampleType = SampleTypeServiceImpl.get().getSampleType(getContainer(), form.getTargetSampleTypeId(), true); - - DerivedSamplePropertyHelper helper = new DerivedSamplePropertyHelper(sampleType, form.getOutputCount(), getContainer(), getUser()); - - Map, Map> allProperties; - try - { - boolean valid = true; - for (Map.Entry> entry : helper.getPostedPropertyValues(getViewContext().getRequest()).entrySet()) - valid = UploadWizardAction.validatePostedProperties(getViewContext(), entry.getValue(), errors) && valid; - if (!valid) - return false; - - allProperties = helper.getSampleProperties(getViewContext().getRequest(), _inputMaterials.keySet()); - } - catch (DuplicateMaterialException e) - { - errors.addError(new ObjectError(e.getColName(), null, null, e.getMessage())); - return false; - } - catch (ExperimentException e) - { - errors.reject(SpringActionController.ERROR_MSG, e.getMessage()); - return false; - } - - try (DbScope.Transaction tx = ExperimentService.get().ensureTransaction()) - { - Map outputMaterials = new HashMap<>(); - int i = 0; - for (Map.Entry, Map> entry : allProperties.entrySet()) - { - Lsid lsid = entry.getKey().first; - String name = entry.getKey().second; - assert name != null; - - ExpMaterialImpl outputMaterial = ExperimentServiceImpl.get().createExpMaterial(getContainer(), lsid.toString(), name); - if (sampleType != null) - { - outputMaterial.setCpasType(sampleType.getLSID()); - } - outputMaterial.save(getUser()); - - if (sampleType != null) - { - Map pvs = new HashMap<>(); - for (Map.Entry propertyEntry : entry.getValue().entrySet()) - pvs.put(propertyEntry.getKey().getName(), propertyEntry.getValue()); - outputMaterial.setProperties(getUser(), pvs, false); - } - - outputMaterials.put(outputMaterial, helper.getSampleNames().get(i++)); - } - - ExperimentService.get().deriveSamples(_inputMaterials, outputMaterials, getViewBackgroundInfo(), _log); - - tx.commit(); - - // automatically link samples to study, if configured - StudyPublishService.get().autoLinkDerivedSamples(sampleType, outputMaterials.keySet().stream().map(ExpObject::getRowId).collect(toList()), getContainer(), getUser()); - - _successUrl = ExperimentUrlsImpl.get().getShowSampleURL(getContainer(), outputMaterials.keySet().iterator().next()); - - if (form.getDataRegionSelectionKey() != null) - DataRegionSelection.clearAll(getViewContext(), form.getDataRegionSelectionKey()); - } - catch (Exception e) - { - errors.reject(SpringActionController.ERROR_MSG, e.getMessage()); - return false; - } - - return true; - } - - @Override - public URLHelper getSuccessURL(DeriveMaterialForm deriveMaterialForm) - { - return _successUrl; - } - } - - public static class DeriveMaterialForm implements HasViewContext, DataRegionSelection.DataSelectionKeyForm - { - private String _dataRegionSelectionKey; - private int _outputCount = 1; - private int _targetSampleTypeId; - private int[] _rowIds; - private String _name; - - private ViewContext _context; - - @Override - public void setViewContext(ViewContext context) - { - _context = context; - } - - @Override - public ViewContext getViewContext() - { - return _context; - } - - public List lookupMaterials() - { - List result = new ArrayList<>(); - for (int rowId : getRowIds()) - { - ExpMaterial material = ExperimentService.get().getExpMaterial(rowId); - if (material != null) - { - if (material.getContainer().hasPermission(_context.getUser(), ReadPermission.class)) - { - result.add(material); - } - else - { - throw new UnauthorizedException(); - } - } - else - { - throw new NotFoundException("No material with RowId " + rowId); - } - } - result.sort(Comparator.comparing(Identifiable::getName)); - return result; - } - - public String getName() - { - return _name; - } - - public void setName(String name) - { - _name = name; - } - - @Override - public String getDataRegionSelectionKey() - { - return _dataRegionSelectionKey; - } - - @Override - public void setDataRegionSelectionKey(String dataRegionSelectionKey) - { - _dataRegionSelectionKey = dataRegionSelectionKey; - } - - public int[] getRowIds() - { - if (_rowIds == null) - { - _rowIds = PageFlowUtil.toInts(DataRegionSelection.getSelected(getViewContext(), getDataRegionSelectionKey(), false)); - } - return _rowIds; - } - - public void setRowIds(int[] rowIds) - { - _rowIds = rowIds; - } - - public int getOutputCount() - { - return _outputCount; - } - - public void setOutputCount(int outputCount) - { - _outputCount = outputCount; - } - - public int getTargetSampleTypeId() - { - return _targetSampleTypeId; - } - - public void setTargetSampleTypeId(int targetSampleTypeId) - { - _targetSampleTypeId = targetSampleTypeId; - } - - public String getInputRole(int i) - { - return _context.getRequest().getParameter("inputRole" + i); - } - - public String getCustomRole(int i) - { - return _context.getRequest().getParameter("customRole" + i); - } - - public String determineLabel(int index) - { - String result = getInputRole(index); - if (DeriveSamplesChooseTargetBean.CUSTOM_ROLE.equals(result)) - { - result = getCustomRole(index); - } - if (result != null) - { - result = result.trim(); - } - return result; - } - } - - public static class ExpInput { public String role; diff --git a/experiment/src/org/labkey/experiment/controllers/exp/SampleTypeContentsView.java b/experiment/src/org/labkey/experiment/controllers/exp/SampleTypeContentsView.java index c7c3ea5984d..fd4074ef4ec 100644 --- a/experiment/src/org/labkey/experiment/controllers/exp/SampleTypeContentsView.java +++ b/experiment/src/org/labkey/experiment/controllers/exp/SampleTypeContentsView.java @@ -68,18 +68,6 @@ public SampleTypeContentsView(ExpSampleTypeImpl source, SamplesSchema schema, Qu ); } - public static ActionButton getDeriveSamplesButton(@NotNull Container container, @Nullable Long targetSampleTypeId) - { - ActionURL urlDeriveSamples = new ActionURL(ExperimentController.DeriveSamplesChooseTargetAction.class, container); - if (targetSampleTypeId != null) - urlDeriveSamples.addParameter("targetSampleTypeId", targetSampleTypeId); - ActionButton deriveButton = new ActionButton(urlDeriveSamples, "Derive Samples"); - deriveButton.setActionType(ActionButton.Action.POST); - deriveButton.setDisplayPermission(InsertPermission.class); - deriveButton.setRequiresSelection(true); - return deriveButton; - } - @Override public DataView createDataView() { @@ -217,9 +205,6 @@ protected void populateButtonBar(DataView view, ButtonBar bar) { super.populateButtonBar(view, bar); - if (OptionalFeatureService.get().isFeatureEnabled(AppProps.DEPRECATED_DERIVE_SAMPLES_NOT_IN_APP)) - bar.add(getDeriveSamplesButton(getContainer(), _source.getRowId())); - ActionButton linkToStudyButton = getLinkToStudyButton(view); if (linkToStudyButton != null) bar.add(linkToStudyButton); diff --git a/experiment/src/org/labkey/experiment/deriveSamplesChooseTarget.jsp b/experiment/src/org/labkey/experiment/deriveSamplesChooseTarget.jsp deleted file mode 100644 index b606f526966..00000000000 --- a/experiment/src/org/labkey/experiment/deriveSamplesChooseTarget.jsp +++ /dev/null @@ -1,99 +0,0 @@ -<% -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -%> -<%@ page import="org.labkey.api.data.DataRegionSelection" %> -<%@ page import="org.labkey.api.exp.api.ExpMaterial" %> -<%@ page import="org.labkey.api.exp.api.ExpSampleType" %> -<%@ page import="org.labkey.api.view.HttpView" %> -<%@ page import="org.labkey.api.view.JspView" %> -<%@ page import="org.labkey.experiment.controllers.exp.ExperimentController.DeriveSamplesAction" %> -<%@ page import="org.labkey.experiment.controllers.exp.ExperimentController.DeriveSamplesChooseTargetBean" %> -<%@ page import="java.util.LinkedHashMap" %> -<%@ page import="java.util.Map" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib"%> -<% - JspView me = HttpView.currentView(); - DeriveSamplesChooseTargetBean bean = me.getModelBean(); - - Map sampleTypeOptions = new LinkedHashMap<>(); - for (ExpSampleType st : bean.getSampleTypes()) - { - sampleTypeOptions.put(st.getRowId(), st.getName() + " in " + st.getContainer().getPath()); - } -%> - - - <% if (bean.getDataRegionSelectionKey() != null) { %> - - <% } %> - - - - - - - - - - - - - - - - - - -
Source materials: - - - - - - <% - int roleIndex = 0; - for (ExpMaterial material : bean.getSourceMaterials().keySet()) - { %> - "> - - <% addHandler("inputRole" + roleIndex, "change", "document.getElementById('customRole" + roleIndex + "').disabled = this.value !== " + q(DeriveSamplesChooseTargetBean.CUSTOM_ROLE) + ";"); %> - - - <% - roleIndex++; - } - %> -
NameRole<%= helpPopup("Role", "Roles allow you to label an input as being used in a particular way. It serves to disambiguate the purpose of each of the input materials. Each input should have a unique role.")%>
<%= h(material.getName())%>
-
Number of derived samples: - -
Target sample type: - <%=select().name("targetSampleTypeId").addOptions(sampleTypeOptions).selected(bean.getTargetSampleTypeId())%> -
-
diff --git a/experiment/src/org/labkey/experiment/summarizeMaterialInputs.jsp b/experiment/src/org/labkey/experiment/summarizeMaterialInputs.jsp deleted file mode 100644 index 0d553e63360..00000000000 --- a/experiment/src/org/labkey/experiment/summarizeMaterialInputs.jsp +++ /dev/null @@ -1,102 +0,0 @@ -<% -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -%> -<%@ page import="org.labkey.api.data.DisplayColumnGroup" %> -<%@ page import="org.labkey.api.exp.PropertyDescriptor" %> -<%@ page import="org.labkey.api.exp.api.ExpMaterial" %> -<%@ page import="org.labkey.api.exp.property.DomainProperty" %> -<%@ page import="org.labkey.api.view.HttpView" %> -<%@ page import="org.labkey.api.view.JspView" %> -<%@ page import="org.labkey.experiment.DerivedSamplePropertyHelper" %> -<%@ page import="org.labkey.experiment.controllers.exp.ExperimentController" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.List" %> -<%@ page import="java.util.Map" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib"%> -<% - JspView me = HttpView.currentView(); - ExperimentController.DeriveSamplesChooseTargetBean bean = me.getModelBean(); - List sameTypeInputs = new ArrayList<>(); - DerivedSamplePropertyHelper helper = bean.getPropertyHelper(); - if (helper.getSampleType() != null) - { - for (ExpMaterial material : bean.getSourceMaterials().keySet()) - { - if (helper.getSampleType().equals(material.getSampleType())) - { - sameTypeInputs.add(material); - } - } - } -%> - - - - - - <% if (!sameTypeInputs.isEmpty()) { %> - - <% } %> - -<% - int rowCount = 0; - for (Map.Entry entry : bean.getSourceMaterials().entrySet()) - { -%> - "> - - - <% if (sameTypeInputs.contains(entry.getKey())) { %> - - <% } %> - -<% - rowCount++; - } -%> -
Sample NameRole<%= helpPopup("Role", "Roles allow you to label an input as being used in a particular way. It serves to disambiguate the purpose of each of the input materials. Each input should have a unique role.")%>Copy properties to...
<%= h(entry.getKey().getName())%><%= h(entry.getValue()) %> - <% - String separator = ""; - Map groups = helper.getGroups(); - for (int i = 0; i < helper.getSampleNames().size(); i++) - { - StringBuilder handler = new StringBuilder(); - for (Map.Entry propEntry : entry.getKey().getPropertyValues().entrySet()) - { - DisplayColumnGroup group = groups.get(propEntry.getKey()); - if (group != null && group.isCopyable()) - { - String propName = group.getColumns().get(i).getColumnInfo().getName(); - String propValue = String.valueOf(propEntry.getValue()); - handler.append("summarize_setProperty(" + q(propName) + "," + q(propValue) + ");\n"); - } - } - handler.append("return false;"); - %><%=h(separator)%><%=link(helper.getSampleNames().get(i)).onClick(handler.toString())%><% - separator = ","; - } %> -
- \ No newline at end of file