diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java index 7092f9a89acd54450edb3b9691351e80cc77d72f..09e820600e984be27bea0c227f9e15f7ba70fed3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java @@ -505,6 +505,8 @@ public abstract class Dict public static final String SAMPLE_BATCH_REGISTRATION = "sample_batch_registration"; + public static final String SAMPLE_BATCH_UPDATE = "sample_batch_update"; + public static final String SAMPLE_REGISTRATION = "sample_registration"; public static final String SAMPLE_BROWSER = "sample_broser"; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java index 3c0a18479f182e057bf2d2c9232143fefa3c6157..3223f339c5d582cffcdb2640112af342a612926c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java @@ -42,7 +42,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.propert import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type.PropertyTypeAssignmentGrid; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type.PropertyTypeGrid; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type.PropertyTypeRegistrationForm; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleBatchRegistrationPanel; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleBatchRegisterUpdatePanel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleBrowserGrid; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleRegistrationPanel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleSearchHitGrid; @@ -238,18 +238,39 @@ public final class ComponentProvider public final ITabItemFactory getSampleBatchRegistration() { + final boolean update = false; return new ITabItemFactory() { public ITabItem create() { DatabaseModificationAwareComponent component = - SampleBatchRegistrationPanel.create(viewContext); + SampleBatchRegisterUpdatePanel.create(viewContext, update); return createRegistrationTab(Dict.SAMPLE_BATCH_REGISTRATION, component); } public String getId() { - return SampleBatchRegistrationPanel.ID; + return SampleBatchRegisterUpdatePanel.getId(update); + } + }; + } + + public final ITabItemFactory getSampleBatchUpdate() + { + final boolean update = true; + + return new ITabItemFactory() + { + public ITabItem create() + { + DatabaseModificationAwareComponent component = + SampleBatchRegisterUpdatePanel.create(viewContext, true); + return createRegistrationTab(Dict.SAMPLE_BATCH_UPDATE, component); + } + + public String getId() + { + return SampleBatchRegisterUpdatePanel.getId(update); } }; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java index 353e9a7dc4b0aebed466bd9dc1d32b86ae374df7..7cf304d4a1a6ecbcbc8f598c6f310dd9a4d1493f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java @@ -63,7 +63,7 @@ public class TopMenu extends LayoutContainer MATERIAL_MENU_BROWSE, MATERIAL_MENU_IMPORT, MATERIAL_MENU_TYPES, SAMPLE_MENU_SEARCH, SAMPLE_MENU_BROWSE, SAMPLE_MENU_NEW, SAMPLE_MENU_IMPORT, - SAMPLE_MENU_TYPES, + SAMPLE_MENU_MASS_UPDATE, SAMPLE_MENU_TYPES, PROJECT_MENU_BROWSE, PROJECT_MENU_NEW, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/sample/SampleMenu.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/sample/SampleMenu.java index b77f095add7127729d089cdd83100f65aa85ba64..2abd8fe50eaba68e4e5fb07ab6eb7f0879c07564 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/sample/SampleMenu.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/sample/SampleMenu.java @@ -47,6 +47,8 @@ public class SampleMenu extends TopMenuItem componentProvider.getSampleRegistration())); submenu.add(new ActionMenu(TopMenu.ActionMenuKind.SAMPLE_MENU_IMPORT, messageProvider, componentProvider.getSampleBatchRegistration())); + submenu.add(new ActionMenu(TopMenu.ActionMenuKind.SAMPLE_MENU_MASS_UPDATE, messageProvider, + componentProvider.getSampleBatchUpdate())); submenu.add(new ActionMenu(TopMenu.ActionMenuKind.SAMPLE_MENU_TYPES, messageProvider, componentProvider.getSampleTypeBrowser())); setMenu(submenu); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/ClientPluginAdapter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/ClientPluginAdapter.java index fb6064003778333d89b4a98787463807095178f3..00c72592206c5658c41257719f603d8d200470bd 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/ClientPluginAdapter.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/ClientPluginAdapter.java @@ -42,6 +42,11 @@ public class ClientPluginAdapter<E extends EntityType, I extends IIdentifiable> throw new UnsupportedOperationException("Not yet implemented."); } + public Widget createBatchUpdateForEntityType(E entityType) + { + throw new UnsupportedOperationException("Not yet implemented."); + } + public ITabItemFactory createEntityViewer(final I identifiable) { throw new UnsupportedOperationException("Not yet implemented."); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/IClientPlugin.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/IClientPlugin.java index e8c4918c585e0e98fb3628d617f515e4e7f1228b..f5b8116d3474b9ea3e1a0ea734f668d641d3165b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/IClientPlugin.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/IClientPlugin.java @@ -52,6 +52,11 @@ public interface IClientPlugin<T extends EntityType, I extends IIdentifiable> */ public Widget createBatchRegistrationForEntityType(final T entityType); + /** + * Shows a batch update form for entities of given <var>entityType</var>. + */ + public Widget createBatchUpdateForEntityType(final T entityType); + /** * Shows a editor of the specified entity.. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBatchRegistrationPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBatchRegisterUpdatePanel.java similarity index 74% rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBatchRegistrationPanel.java rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBatchRegisterUpdatePanel.java index fc4e3368226a4d27708d45cf1df963f01b68fbd1..f89ceba7d80d85e7df256c533fd032378da8732b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBatchRegistrationPanel.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBatchRegisterUpdatePanel.java @@ -22,6 +22,7 @@ import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; +import com.google.gwt.user.client.ui.Widget; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; @@ -36,31 +37,39 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; /** - * The {@link LayoutContainer} extension for batch registering a sample. + * The {@link LayoutContainer} extension for batch registration and update of samples of certain + * type. * * @author Christian Ribeaud */ -public final class SampleBatchRegistrationPanel extends LayoutContainer +public final class SampleBatchRegisterUpdatePanel extends LayoutContainer { private static final String ID_SUFFIX = "sample-batch-registration"; - public static final String ID = GenericConstants.ID_PREFIX + ID_SUFFIX; + private static final String ID = GenericConstants.ID_PREFIX + ID_SUFFIX; private final SampleTypeSelectionWidget sampleTypeSelection; private final IViewContext<ICommonClientServiceAsync> viewContext; + public static String getId(final boolean update) + { + return ID + "_" + (update == true ? "update" : "registration"); + } + public static DatabaseModificationAwareComponent create( - final IViewContext<ICommonClientServiceAsync> viewContext) + final IViewContext<ICommonClientServiceAsync> viewContext, final boolean update) { - SampleBatchRegistrationPanel panel = new SampleBatchRegistrationPanel(viewContext); + SampleBatchRegisterUpdatePanel panel = + new SampleBatchRegisterUpdatePanel(viewContext, update); return new DatabaseModificationAwareComponent(panel, panel.sampleTypeSelection); } - private SampleBatchRegistrationPanel(final IViewContext<ICommonClientServiceAsync> viewContext) + private SampleBatchRegisterUpdatePanel( + final IViewContext<ICommonClientServiceAsync> viewContext, final boolean update) { this.viewContext = viewContext; - setId(ID); + setId(getId(update)); setScrollMode(Scroll.AUTO); sampleTypeSelection = new SampleTypeSelectionWidget(viewContext, ID_SUFFIX, false, false, true); @@ -89,8 +98,19 @@ public final class SampleBatchRegistrationPanel extends LayoutContainer viewContext.getClientPluginFactoryProvider() .getClientPluginFactory(entityKind, sampleType) .createClientPlugin(entityKind); - add(createClientPlugin - .createBatchRegistrationForEntityType(sampleType)); + final Widget batchOperationWidget; + if (update) + { + batchOperationWidget = + createClientPlugin + .createBatchUpdateForEntityType(sampleType); + } else + { + batchOperationWidget = + createClientPlugin + .createBatchRegistrationForEntityType(sampleType); + } + add(batchOperationWidget); layout(); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SampleBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SampleBO.java index cd8f86dbfa698938a6098982bdf1dd6ea54dac8f..b23f93305e7bd573056fbacd908cbd37547e4075 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SampleBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SampleBO.java @@ -269,10 +269,16 @@ public final class SampleBO extends AbstractSampleBusinessObject implements ISam public void update(SampleUpdatesDTO updates) { - loadDataByTechId(updates.getSampleId()); - if (updates.getVersion().equals(sample.getModificationDate()) == false) + if (updates.getSampleIdOrNull() != null) { - throwModifiedEntityException("Sample"); + loadDataByTechId(updates.getSampleIdOrNull()); + if (updates.getVersion().equals(sample.getModificationDate()) == false) + { + throwModifiedEntityException("Sample"); + } + } else + { + loadBySampleIdentifier(updates.getOldSampleIdentifierOrNull()); } updateProperties(updates.getProperties()); updateGroup(updates.getSampleIdentifier()); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/SampleUpdatesPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/SampleUpdatesPredicate.java index ae0a920a75bea7adf20c405774dde1ae5f30cdee..1174ac7bd2090bc014b03d3e6e150e0762568e3d 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/SampleUpdatesPredicate.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/SampleUpdatesPredicate.java @@ -65,7 +65,7 @@ public class SampleUpdatesPredicate extends AbstractPredicate<SampleUpdatesDTO> {// TODO 2009-07-27, IA: tests needed assert sampleTechIdPredicate.initialized : "Predicate has not been initialized"; Status status; - status = sampleTechIdPredicate.doEvaluation(person, allowedRoles, updates.getSampleId()); + status = sampleTechIdPredicate.doEvaluation(person, allowedRoles, updates.getSampleIdOrNull()); if (status.equals(Status.OK) == false) { return status; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/BasicSampleUpdates.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/BasicSampleUpdates.java index 4f82526752a53e8772691c7954f80d9011cc17a9..142d32a569775b5cbe966f76ba17d8d79b5d7519 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/BasicSampleUpdates.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/BasicSampleUpdates.java @@ -32,7 +32,8 @@ public class BasicSampleUpdates implements IsSerializable, Serializable private static final long serialVersionUID = ServiceVersionHolder.VERSION; - private TechId sampleId; + // if technical id is null old identifier must be provided by subclass + private TechId sampleIdOrNull; private List<IEntityProperty> properties; @@ -69,21 +70,21 @@ public class BasicSampleUpdates implements IsSerializable, Serializable public BasicSampleUpdates(TechId sampleId, List<IEntityProperty> properties, Date version, String parentIdentifierOrNull, String containerIdentifierOrNull) { - this.sampleId = sampleId; + this.sampleIdOrNull = sampleId; this.properties = properties; this.version = version; this.parentIdentifierOrNull = parentIdentifierOrNull; this.containerIdentifierOrNull = containerIdentifierOrNull; } - public TechId getSampleId() + public TechId getSampleIdOrNull() { - return sampleId; + return sampleIdOrNull; } public void setSampleId(TechId sampleId) { - this.sampleId = sampleId; + this.sampleIdOrNull = sampleId; } public List<IEntityProperty> getProperties() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleUpdatesDTO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleUpdatesDTO.java index 0a82f0e2d99019712e39cdb10be5d8d37a6c149c..b3854f6d2760a082f7d760b8328e319050ed102b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleUpdatesDTO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleUpdatesDTO.java @@ -39,6 +39,8 @@ public class SampleUpdatesDTO extends BasicSampleUpdates private SampleIdentifier sampleIdentifier; + private SampleIdentifier oldSampleIdentifierOrNull; + private Collection<NewAttachment> attachments; public SampleUpdatesDTO(TechId sampleId, List<IEntityProperty> properties, @@ -52,6 +54,18 @@ public class SampleUpdatesDTO extends BasicSampleUpdates this.sampleIdentifier = sampleIdentifier; } + public SampleUpdatesDTO(SampleIdentifier oldSampleIdentifier, List<IEntityProperty> properties, + ExperimentIdentifier experimentIdentifierOrNull, Collection<NewAttachment> attachments, + Date version, SampleIdentifier sampleIdentifier, String parentIdentifierOrNull, + String containerIdentifierOrNull) + { + super(null, properties, version, parentIdentifierOrNull, containerIdentifierOrNull); + this.experimentIdentifierOrNull = experimentIdentifierOrNull; + this.attachments = attachments; + this.sampleIdentifier = sampleIdentifier; + this.oldSampleIdentifierOrNull = oldSampleIdentifier; + } + public SampleIdentifier getSampleIdentifier() { return sampleIdentifier; @@ -62,6 +76,16 @@ public class SampleUpdatesDTO extends BasicSampleUpdates this.sampleIdentifier = sampleIdentifier; } + public SampleIdentifier getOldSampleIdentifierOrNull() + { + return oldSampleIdentifierOrNull; + } + + public void setOldSampleIdentifier(SampleIdentifier sampleIdentifier) + { + this.oldSampleIdentifierOrNull = sampleIdentifier; + } + public ExperimentIdentifier getExperimentIdentifierOrNull() { return experimentIdentifierOrNull; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/client/web/client/application/ClientPluginFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/client/web/client/application/ClientPluginFactory.java index 38c91e61753993176302e23010f96a3a1a8b4d3b..caf810f297976f689b610a149558351f9948274f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/client/web/client/application/ClientPluginFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/client/web/client/application/ClientPluginFactory.java @@ -143,6 +143,11 @@ public final class ClientPluginFactory extends AbstractClientPluginFactory<IDemo return new DummyComponent(); } + public final Widget createBatchUpdateForEntityType(final SampleType sampleType) + { + return new DummyComponent(); + } + public ITabItemFactory createEntityEditor(final IIdentifiable identifiable) { return new ITabItemFactory() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientService.java index 2131af6008b5a132c5bda43ad10597563a8fb9f6..65d301d23eadb19eb69b01b1ccfa6a1c9d003e3a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientService.java @@ -47,7 +47,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; * unexpected exception. * </p> * - * @author Franz-Josef Elmer + * @author Franz-Josef Elmer */ public interface IGenericClientService extends IClientService { @@ -78,6 +78,15 @@ public interface IGenericClientService extends IClientService public List<BatchRegistrationResult> registerSamples(final SampleType sampleType, final String sessionKey, String defaultGroupIdentifier) throws UserFailureException; + /** + * Updates samples from files which have been previously uploaded. + * <p> + * Uploaded files can be found as session attribute under given <var>sessionKey</var>. + * </p> + */ + public List<BatchRegistrationResult> updateSamples(final SampleType sampleType, + final String sessionKey) throws UserFailureException; + /** * For given <var>experimentIdentifier</var> returns corresponding {@link Experiment}. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientServiceAsync.java index 8c7284e25c7db936a21ce1004bee0437f683f77f..a66fe36870ff04c4303f583e9560af966649feeb 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientServiceAsync.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientServiceAsync.java @@ -44,7 +44,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; /** * Asynchronous version of {@link IGenericClientService}. * - * @author Franz-Josef Elmer + * @author Franz-Josef Elmer */ public interface IGenericClientServiceAsync extends IClientServiceAsync { @@ -73,6 +73,13 @@ public interface IGenericClientServiceAsync extends IClientServiceAsync final AsyncCallback<List<BatchRegistrationResult>> asyncCallback) throws UserFailureException; + /** + * @see IGenericClientService#updateSamples(SampleType, String) + */ + public void updateSamples(final SampleType sampleType, final String sessionKey, + final AsyncCallback<List<BatchRegistrationResult>> asyncCallback) + throws UserFailureException; + /** * @see IGenericClientService#getExperimentInfo(String) */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java index 56db96e27004287349c399486f2c37e5f2d7ef65..0c109c8b6e7a3de90f3b6da51314e8bc45a4d669 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java @@ -52,6 +52,7 @@ import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.mat import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.material.GenericMaterialEditForm; import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.material.GenericMaterialViewer; import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleBatchRegistrationForm; +import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleBatchUpdateForm; import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleEditForm; import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleRegistrationForm; import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleViewer; @@ -169,6 +170,11 @@ public final class ClientPluginFactory extends return new GenericSampleBatchRegistrationForm(getViewContext(), sampleType); } + public final Widget createBatchUpdateForEntityType(final SampleType sampleType) + { + return new GenericSampleBatchUpdateForm(getViewContext(), sampleType); + } + public ITabItemFactory createEntityEditor(final IIdentifiable identifiable) { return new ITabItemFactory() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchUpdateForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchUpdateForm.java new file mode 100644 index 0000000000000000000000000000000000000000..3d128cfe861eff75ad5c56dc4236f5084af77ef0 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchUpdateForm.java @@ -0,0 +1,201 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample; + +import static ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField.wrapUnaware; + +import java.util.List; + +import com.extjs.gxt.ui.client.Style.Scroll; +import com.extjs.gxt.ui.client.event.BaseEvent; +import com.extjs.gxt.ui.client.event.ButtonEvent; +import com.extjs.gxt.ui.client.event.Events; +import com.extjs.gxt.ui.client.event.Listener; +import com.extjs.gxt.ui.client.event.SelectionListener; +import com.extjs.gxt.ui.client.widget.form.Field; +import com.extjs.gxt.ui.client.widget.form.FileUploadField; +import com.extjs.gxt.ui.client.widget.form.LabelField; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.Event; + +import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.FormPanelListener; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.UrlParamsHelper; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.LinkRenderer; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.file.BasicFileFieldManager; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.WindowUtils; +import ch.systemsx.cisd.openbis.generic.client.web.client.dto.BatchRegistrationResult; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; +import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync; + +/** + * The <i>generic</i> sample batch update panel. + * + * @author Piotr Buczek + */ +public final class GenericSampleBatchUpdateForm extends AbstractRegistrationForm +{ + private static final String PREFIX = "sample-batch-update"; + + public final static String ID = GenericConstants.ID_PREFIX + PREFIX; + + private static final String SESSION_KEY = PREFIX; + + private static final String FIELD_LABEL_TEMPLATE = "File"; + + private static final int DEFAULT_NUMBER_OF_FILES = 1; + + private final BasicFileFieldManager fileFieldsManager; + + private final IViewContext<IGenericClientServiceAsync> viewContext; + + private final SampleType sampleType; + + public GenericSampleBatchUpdateForm(final IViewContext<IGenericClientServiceAsync> viewContext, + final SampleType sampleType) + { + super(viewContext.getCommonViewContext(), ID); + this.viewContext = viewContext; + this.sampleType = sampleType; + fileFieldsManager = + new BasicFileFieldManager(SESSION_KEY, DEFAULT_NUMBER_OF_FILES, + FIELD_LABEL_TEMPLATE); + fileFieldsManager.setMandatory(); + setScrollMode(Scroll.AUTO); + addUploadFeatures(SESSION_KEY); + } + + @Override + protected void resetFieldsAfterSave() + { + for (FileUploadField attachmentField : fileFieldsManager.getFields()) + { + attachmentField.reset(); + } + } + + private final void addFormFields() + { + for (FileUploadField attachmentField : fileFieldsManager.getFields()) + { + formPanel.add(wrapUnaware((Field<?>) attachmentField).get()); + } + formPanel.add(createTemplateField()); + formPanel.addListener(Events.Submit, new FormPanelListener(infoBox) + { + @Override + protected void onSuccessfullUpload() + { + save(); + } + + @Override + protected void setUploadEnabled() + { + GenericSampleBatchUpdateForm.this.setUploadEnabled(true); + } + }); + redefineSaveListeners(); + } + + protected void save() + { + viewContext.getService().updateSamples(sampleType, SESSION_KEY, + new RegisterSamplesCallback(viewContext)); + } + + void redefineSaveListeners() + { + saveButton.removeAllListeners(); + saveButton.addSelectionListener(new SelectionListener<ButtonEvent>() + { + @Override + public final void componentSelected(final ButtonEvent ce) + { + if (formPanel.isValid()) + { + if (fileFieldsManager.filesDefined() > 0) + { + setUploadEnabled(false); + formPanel.submit(); + } else + { + save(); + } + } + } + }); + } + + private final class RegisterSamplesCallback extends + AbstractRegistrationForm.AbstractRegistrationCallback<List<BatchRegistrationResult>> + { + RegisterSamplesCallback(final IViewContext<IGenericClientServiceAsync> viewContext) + { + super(viewContext); + } + + @Override + protected String createSuccessfullRegistrationInfo( + final List<BatchRegistrationResult> result) + { + final StringBuilder builder = new StringBuilder(); + for (final BatchRegistrationResult batchRegistrationResult : result) + { + builder.append("<b>" + batchRegistrationResult.getFileName() + "</b>:"); + builder.append(batchRegistrationResult.getMessage()); + builder.append("<br />"); + } + return builder.toString(); + } + + } + + @Override + protected final void submitValidForm() + { + } + + @Override + protected final void onRender(final Element target, final int index) + { + super.onRender(target, index); + addFormFields(); + } + + private LabelField createTemplateField() + { + LabelField result = + new LabelField(LinkRenderer.renderAsLink(viewContext + .getMessage(Dict.FILE_TEMPLATE_LABEL))); + result.sinkEvents(Event.ONCLICK); + result.addListener(Events.OnClick, new Listener<BaseEvent>() + { + public void handleEvent(BaseEvent be) + { + WindowUtils.openWindow(UrlParamsHelper.createTemplateURL(EntityKind.SAMPLE, + sampleType, false, true)); + } + }); + return result; + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientService.java index c64afd596f11816be19a02a13a3703a7cf504e0a..29f2d1a4e79bf406d9715cae5dfb4ff4b85eebd6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientService.java @@ -162,7 +162,7 @@ public final class GenericClientService extends AbstractClientService implements { BatchSamplesRegistration info = parseSamples(sampleType, sessionKey, defaultGroupIdentifier, - defaultGroupIdentifier != null, true); + defaultGroupIdentifier != null, true, "registered"); try { final String sessionToken = getSessionToken(); @@ -175,6 +175,24 @@ public final class GenericClientService extends AbstractClientService implements } + public final List<BatchRegistrationResult> updateSamples(final SampleType sampleType, + final String sessionKey) + throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException + { + BatchSamplesRegistration info = + parseSamples(sampleType, sessionKey, null, false, true, "updated"); + try + { + final String sessionToken = getSessionToken(); + genericServer.updateSamples(sessionToken, info.getSamples()); + return info.getResultList(); + } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) + { + throw UserFailureExceptionTranslator.translate(e); + } + + } + public final Experiment getExperimentInfo(final String experimentIdentifier) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { @@ -247,7 +265,7 @@ public final class GenericClientService extends AbstractClientService implements parseSamples(experiment.getSampleType(), samplesSessionKey, new GroupIdentifier(identifier.getDatabaseInstanceCode(), identifier .getGroupCode()).toString(), experiment.isGenerateCodes(), - false); + false, "registered"); experiment.setNewSamples(result.getSamples()); experiment.setSamples(result.getCodes()); } @@ -263,7 +281,7 @@ public final class GenericClientService extends AbstractClientService implements private BatchSamplesRegistration parseSamples(final SampleType sampleType, final String sessionKey, String defaultGroupIdentifier, - final boolean isAutoGenerateCodes, final boolean allowExperiments) + final boolean isAutoGenerateCodes, final boolean allowExperiments, String operation) { HttpSession httpSession = getHttpSession(); UploadedFilesBean uploadedFiles = null; @@ -273,7 +291,7 @@ public final class GenericClientService extends AbstractClientService implements tryGetSampleCodeGenerator(isAutoGenerateCodes); uploadedFiles = getUploadedFiles(sessionKey, httpSession); return SampleUploadSectionsParser.prepareSamples(sampleType, uploadedFiles, - defaultGroupIdentifier, sampleCodeGeneratorOrNull, allowExperiments); + defaultGroupIdentifier, sampleCodeGeneratorOrNull, allowExperiments, operation); } catch (final UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); @@ -394,7 +412,7 @@ public final class GenericClientService extends AbstractClientService implements } Date date = genericServer.updateSample(sessionToken, new SampleUpdatesDTO(updates - .getSampleId(), updates.getProperties(), + .getSampleIdOrNull(), updates.getProperties(), convExperimentIdentifierOrNull, attachments, updates .getVersion(), sampleOwner, updates .getParentIdentifierOrNull(), updates @@ -430,7 +448,8 @@ public final class GenericClientService extends AbstractClientService implements BatchSamplesRegistration info = parseSamples(updates.getSampleType(), updates.getSamplesSessionKey(), new GroupIdentifier(newProject.getDatabaseInstanceCode(), newProject - .getGroupCode()).toString(), updates.isGenerateCodes(), false); + .getGroupCode()).toString(), updates.isGenerateCodes(), false, + "registered"); updates.setNewSamples(info.getSamples()); updates.setSampleCodes(info.getCodes()); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/parser/SampleUploadSectionsParser.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/parser/SampleUploadSectionsParser.java index ab098768f5f4055deecfb853b55926b08cc05a52..1ea04297f1d3556eed0ea11c59596e76b8fb3fb6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/parser/SampleUploadSectionsParser.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/parser/SampleUploadSectionsParser.java @@ -87,13 +87,14 @@ public class SampleUploadSectionsParser public static BatchSamplesRegistration prepareSamples(final SampleType sampleType, final UploadedFilesBean uploadedFiles, String defaultGroupIdentifier, - final SampleCodeGenerator sampleCodeGeneratorOrNull, final boolean allowExperiments) + final SampleCodeGenerator sampleCodeGeneratorOrNull, final boolean allowExperiments, + String operation) { final List<NewSamplesWithTypes> newSamples = new ArrayList<NewSamplesWithTypes>(); boolean isAutoGenerateCodes = (sampleCodeGeneratorOrNull != null); final List<BatchRegistrationResult> results = loadSamplesFromFiles(uploadedFiles, sampleType, isAutoGenerateCodes, newSamples, - allowExperiments); + allowExperiments, operation); generateIdentifiersIfNecessary(defaultGroupIdentifier, sampleCodeGeneratorOrNull, isAutoGenerateCodes, newSamples); return new BatchSamplesRegistration(newSamples, results, parseCodes(newSamples)); @@ -112,6 +113,7 @@ public class SampleUploadSectionsParser return codes.toArray(new String[0]); } + // TODO private static BisTabFileLoader<NewSample> createSampleLoader(final SampleType sampleType, final boolean isAutoGenerateCodes, final boolean allowExperiments) { @@ -215,7 +217,7 @@ public class SampleUploadSectionsParser private static List<BatchRegistrationResult> loadSamplesFromFiles( UploadedFilesBean uploadedFiles, SampleType sampleType, boolean isAutoGenerateCodes, - final List<NewSamplesWithTypes> newSamples, boolean allowExperiments) + final List<NewSamplesWithTypes> newSamples, boolean allowExperiments, String operation) { final List<BatchRegistrationResult> results = @@ -253,7 +255,7 @@ public class SampleUploadSectionsParser } } results.add(new BatchRegistrationResult(multipartFile.getOriginalFilename(), String - .format("%d sample(s) found and registered.", sampleCounter))); + .format("%d sample(s) found and %s.", sampleCounter, operation))); } return results; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java index 8bb2d1dce3603ae56955eee2de7ad70bc4064ff6..01c40b6f5e61eec0d96cf5b1563ce46c7b199315 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.plugin.generic.server; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashSet; @@ -67,8 +68,11 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.IdentifierHelper; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory; import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.translator.AttachmentTranslator; import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator; @@ -246,6 +250,17 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen } } + public void updateSamples(String sessionToken, List<NewSamplesWithTypes> newSamplesWithType) + throws UserFailureException + { + assert sessionToken != null : "Unspecified session token."; + final Session session = getSession(sessionToken); + for (NewSamplesWithTypes samples : newSamplesWithType) + { + updateSamples(session, samples); + } + } + private void registerSamples(final Session session, final NewSamplesWithTypes newSamplesWithType) { final SampleType sampleType = newSamplesWithType.getSampleType(); @@ -280,6 +295,74 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen getSampleTypeSlaveServerPlugin(sampleTypePE).registerSamples(session, newSamples); } + private void updateSamples(final Session session, + final NewSamplesWithTypes updatedSamplesWithType) + { + final SampleType sampleType = updatedSamplesWithType.getSampleType(); + final List<NewSample> updatedSamples = updatedSamplesWithType.getNewSamples(); + assert sampleType != null : "Unspecified sample type."; + assert updatedSamples != null : "Unspecified new samples."; + + // Does nothing if samples list is empty. + if (updatedSamples.size() == 0) + { + return; + } + // Check uniqueness of given list based on sample identifier. + final HashSet<NewSample> sampleSet = new HashSet<NewSample>(updatedSamples); + if (sampleSet.size() != updatedSamples.size()) + { + for (NewSample s : sampleSet) + { + updatedSamples.remove(s); + } + throw UserFailureException.fromTemplate("Following samples '%s' are duplicated.", + CollectionUtils.abbreviate(updatedSamples, 20)); + } + final String sampleTypeCode = sampleType.getCode(); + final SampleTypePE sampleTypePE = + getDAOFactory().getSampleTypeDAO().tryFindSampleTypeByCode(sampleTypeCode); + if (sampleTypePE == null) + { + throw UserFailureException.fromTemplate("Sample type with code '%s' does not exist.", + sampleTypeCode); + } + + for (NewSample updatedSample : updatedSamples) + { + final SampleIdentifier oldSampleIdentifier = + SampleIdentifierFactory.parse(updatedSample.getIdentifier()); + final List<IEntityProperty> properties = Arrays.asList(updatedSample.getProperties()); + final ExperimentIdentifier experimentIdentifierOrNull; + final SampleIdentifier newSampleIdentifier; + if (updatedSample.getExperimentIdentifier() != null) + { + // experiment is provided - new sample identifier takes experiment group + experimentIdentifierOrNull = + new ExperimentIdentifierFactory(updatedSample.getExperimentIdentifier()) + .createIdentifier(); + newSampleIdentifier = + new SampleIdentifier(new GroupIdentifier(experimentIdentifierOrNull + .getDatabaseInstanceCode(), experimentIdentifierOrNull + .getGroupCode()), oldSampleIdentifier.getSampleCode()); // subcode? + } else + { + // FIXME looses experiment, parent and container information if there is no column + // no experiment - leave sample identifier unchanged + experimentIdentifierOrNull = null; + newSampleIdentifier = oldSampleIdentifier; + } + final Collection<NewAttachment> attachments = new ArrayList<NewAttachment>(0); // empty + final Date version = null; // no version check + final String parentIdentifierOrNull = updatedSample.getParentIdentifier(); + final String containerIdentifierOrNull = updatedSample.getContainerIdentifier(); + + updateSample(session, new SampleUpdatesDTO(oldSampleIdentifier, properties, + experimentIdentifierOrNull, attachments, version, newSampleIdentifier, + parentIdentifierOrNull, containerIdentifierOrNull)); + } + } + public void registerExperiment(String sessionToken, NewExperiment newExperiment, final Collection<NewAttachment> attachments) { @@ -435,6 +518,11 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen public Date updateSample(String sessionToken, SampleUpdatesDTO updates) { final Session session = getSession(sessionToken); + return updateSample(session, updates); + } + + private Date updateSample(Session session, SampleUpdatesDTO updates) + { final ISampleBO sampleBO = businessObjectFactory.createSampleBO(session); sampleBO.update(updates); sampleBO.save(); @@ -465,4 +553,5 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen } return codes; } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java index 74101158389eaa9b864e8b05e52954a8306a4842..6f356586e2ee60686e9d185eff8ef313c8494afc 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java @@ -40,7 +40,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSamplesWithTypes; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; @@ -52,7 +51,7 @@ import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer; /** * Logger class for {@link GenericServer} which creates readable logs of method invocations. * - * @author Franz-Josef Elmer + * @author Franz-Josef Elmer */ final class GenericServerLogger extends AbstractServerLogger implements IGenericServer { @@ -116,13 +115,6 @@ final class GenericServerLogger extends AbstractServerLogger implements IGeneric return null; } - public final void registerSamples(final String sessionToken, final SampleType sampleType, - final List<NewSample> newSamples) throws UserFailureException - { - logAccess(sessionToken, "register_samples", "SAMPLE_TYPE(%s) SAMPLES(%s)", sampleType, - CollectionUtils.abbreviate(newSamples, 20)); - } - public void registerExperiment(String sessionToken, NewExperiment experiment, final Collection<NewAttachment> attachments) { @@ -188,7 +180,7 @@ final class GenericServerLogger extends AbstractServerLogger implements IGeneric public Date updateSample(String sessionToken, SampleUpdatesDTO updates) { logTracking(sessionToken, "edit_sample", - "SAMPLE(%s), CHANGE_TO_EXPERIMENT(%s) ATTACHMENTS(%s)", updates.getSampleId(), + "SAMPLE(%s), CHANGE_TO_EXPERIMENT(%s) ATTACHMENTS(%s)", updates.getSampleIdOrNull(), updates.getExperimentIdentifierOrNull(), updates.getAttachments().size()); return null; } @@ -217,4 +209,19 @@ final class GenericServerLogger extends AbstractServerLogger implements IGeneric } + public void updateSamples(String sessionToken, List<NewSamplesWithTypes> updatedSamplesWithType) + throws UserFailureException + { + StringBuilder sb = new StringBuilder(); + for (NewSamplesWithTypes s : updatedSamplesWithType) + { + if (sb.length() > 0) + { + sb.append(","); + } + sb.append(s.getSampleType().getCode() + ":" + s.getNewSamples().size()); + } + logAccess(sessionToken, "update_samples", sb.toString()); + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java index 3ac508922dbfa3963b87785f869687f9b9fe120c..c3562cb4be17ffc95611ae34b1ac3c48bc6e7e14 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java @@ -60,7 +60,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifi /** * Definition of the client-server interface. * - * @author Franz-Josef Elmer + * @author Franz-Josef Elmer */ public interface IGenericServer extends IPluginCommonServer { @@ -117,6 +117,17 @@ public interface IGenericServer extends IPluginCommonServer @AuthorizationGuard(guardClass = NewSamplesWithTypePredicate.class) final List<NewSamplesWithTypes> newSamplesWithType) throws UserFailureException; + /** + * Updates samples of different types in batches. + */ + @Transactional + @RolesAllowed(RoleSet.USER) + @DatabaseUpdateModification(value = ObjectKind.SAMPLE) + public void updateSamples( + final String sessionToken, + @AuthorizationGuard(guardClass = NewSamplesWithTypePredicate.class) final List<NewSamplesWithTypes> newSamplesWithType) + throws UserFailureException; + /** * Registers experiment. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java index 3e5459ea16be1da816dafa51608944666748669b..9c530becb9350a510e6f9fb6ce825fdba9418d94 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java @@ -149,6 +149,11 @@ public final class ClientPluginFactory extends return new DummyComponent(); } + public final Widget createBatchUpdateForEntityType(final SampleType sampleType) + { + return new DummyComponent(); + } + public ITabItemFactory createEntityEditor(final IIdentifiable identifiable) { return new ITabItemFactory() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js index 299abad6a68823e6169ccb12735c62177ea4c95c..e1054f16ad5c62edcfcbba8dd25684deb3f5f37c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js +++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js @@ -268,6 +268,7 @@ var common = { SAMPLE_MENU_BROWSE: "Browse", SAMPLE_MENU_NEW: "New", SAMPLE_MENU_IMPORT: "Import", + SAMPLE_MENU_MASS_UPDATE: "Mass Update", SAMPLE_MENU_TYPES: "Types", menu_project: "Project", @@ -308,8 +309,9 @@ var common = { property_type_registration: "Property Type Registration", property_types: "Property Types", experiment_browser: "Experiment Browser", - vocabulary_registration: "Vocabulary Registration", - sample_batch_registration: "Sample Batch Registration", + vocabulary_registration: "Vocabulary Registration", + sample_batch_registration: "Sample Batch Registration", + sample_batch_update: "Sample Batch Update", sample_registration: "Sample Registration", sample_broser: "Sample Browser", list_groups: "Groups Browser", diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java.expected index cb6350a1d40b040b8c987bc04f0e61eab936ef65..c3562cb4be17ffc95611ae34b1ac3c48bc6e7e14 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java.expected +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java.expected @@ -117,6 +117,17 @@ public interface IGenericServer extends IPluginCommonServer @AuthorizationGuard(guardClass = NewSamplesWithTypePredicate.class) final List<NewSamplesWithTypes> newSamplesWithType) throws UserFailureException; + /** + * Updates samples of different types in batches. + */ + @Transactional + @RolesAllowed(RoleSet.USER) + @DatabaseUpdateModification(value = ObjectKind.SAMPLE) + public void updateSamples( + final String sessionToken, + @AuthorizationGuard(guardClass = NewSamplesWithTypePredicate.class) final List<NewSamplesWithTypes> newSamplesWithType) + throws UserFailureException; + /** * Registers experiment. */