From 0eab461918e7b8236beac5e7be71e579c55abc5a Mon Sep 17 00:00:00 2001 From: pkupczyk <pkupczyk> Date: Wed, 6 Feb 2013 13:46:52 +0000 Subject: [PATCH] SP-422 / BIS-280 : Error when performing batch import of material SVN: 28303 --- .../ui/AbstractBatchRegistrationForm.java | 266 ++++++++++++++++++ .../generic/server/AbstractASyncAction.java | 56 ++++ .../dto/AsyncBatchRegistrationResult.java | 49 ++++ .../dto/MaterialBatchUpdateResultMessage.java | 59 ++++ .../web/client/IGenericClientService.java | 6 +- .../client/IGenericClientServiceAsync.java | 9 +- .../client/application/GeneralImportForm.java | 224 +-------------- ...AbstractMaterialBatchRegistrationForm.java | 192 +------------ .../GenericMaterialBatchRegistrationForm.java | 12 +- .../GenericMaterialBatchUpdateForm.java | 13 +- .../web/server/GenericClientService.java | 61 ++-- .../plugin/generic/server/GenericServer.java | 121 +++++--- .../generic/server/GenericServerLogger.java | 26 +- .../plugin/generic/shared/IGenericServer.java | 17 ++ .../web/server/GenericClientServiceTest.java | 6 +- ...atchMaterialRegistrationAndUpdateTest.java | 6 +- 16 files changed, 627 insertions(+), 496 deletions(-) create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AbstractBatchRegistrationForm.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractASyncAction.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AsyncBatchRegistrationResult.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialBatchUpdateResultMessage.java diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AbstractBatchRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AbstractBatchRegistrationForm.java new file mode 100644 index 00000000000..3e80fa63a64 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AbstractBatchRegistrationForm.java @@ -0,0 +1,266 @@ +package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui; + +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.FormEvent; +import com.extjs.gxt.ui.client.event.Listener; +import com.extjs.gxt.ui.client.event.SelectionListener; +import com.extjs.gxt.ui.client.widget.form.CheckBox; +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.extjs.gxt.ui.client.widget.form.TextField; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.ui.AbstractImagePrototype; + +import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; +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.renderer.LinkRenderer; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.file.BasicFileFieldManager; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.WindowUtils; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchRegistrationResult; + +public abstract class AbstractBatchRegistrationForm extends AbstractRegistrationForm +{ + public final class BatchRegistrationCallback extends + AbstractRegistrationForm.AbstractRegistrationCallback<List<BatchRegistrationResult>> + { + public BatchRegistrationCallback(final IViewContext<?> 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(); + } + } + + private static final String FIELD_LABEL_TEMPLATE = "File"; + + private static final int NUMBER_OF_FIELDS = 1; + + protected final String sessionKey; + + protected final LabelField templateField; + + protected final BasicFileFieldManager fileFieldsManager; + + protected final TextField<String> emailField; + + protected final CheckBox asynchronous; + + protected final IViewContext<ICommonClientServiceAsync> viewContext; + + public AbstractBatchRegistrationForm(IViewContext<ICommonClientServiceAsync> viewContext, + String id, String sessionKey) + { + super(viewContext, id); + setResetButtonVisible(true); + this.sessionKey = sessionKey; + this.viewContext = viewContext; + setScrollMode(Scroll.AUTO); + asynchronous = createEmailCheckBox(); + emailField = + createEmailField(viewContext.getModel().getSessionContext().getUser() + .getUserEmail()); + templateField = createTemplateField(); + fileFieldsManager = + new BasicFileFieldManager(sessionKey, NUMBER_OF_FIELDS, FIELD_LABEL_TEMPLATE); + fileFieldsManager.setMandatory(); + addUploadFeatures(sessionKey); + } + + @Override + protected final void onRender(final Element target, final int index) + { + super.onRender(target, index); + addFormFields(); + } + + private CheckBox createEmailCheckBox() + { + final CheckBox checkBox = new CheckBox(); + checkBox.setFieldLabel("Send confirmation?"); + checkBox.setBoxLabel(""); + checkBox.setValue(true); + checkBox.addListener(Events.Change, new Listener<BaseEvent>() + { + @Override + public void handleEvent(BaseEvent be) + { + if (checkBox.getValue()) + { + formPanel.remove(asynchronous); + for (FileUploadField attachmentField : fileFieldsManager.getFields()) + { + formPanel.remove(wrapUnaware((Field<?>) attachmentField).get()); + } + addOnlyFormFields(true); + } else + { + formPanel.remove(emailField); + } + formPanel.layout(); + } + }); + return checkBox; + } + + private TextField<String> createEmailField(String userEmail) + { + TextField<String> field = new TextField<String>(); + field.setAllowBlank(false); + field.setFieldLabel("Email"); + FieldUtil.markAsMandatory(field); + field.setValue(userEmail); + field.setValidateOnBlur(true); + field.setRegex(GenericConstants.EMAIL_REGEX); + field.getMessages().setRegexText("Expected email address format: user@domain.com"); + AbstractImagePrototype infoIcon = + AbstractImagePrototype.create(viewContext.getImageBundle().getInfoIcon()); + FieldUtil.addInfoIcon(field, + "All relevant notifications will be send to this email address", + infoIcon.createImage()); + return field; + } + + protected 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>() + { + @Override + public void handleEvent(BaseEvent be) + { + + WindowUtils.openWindow(createTemplateUrl()); + } + }); + return result; + } + + protected String createTemplateUrl() + { + return null; + } + + @Override + protected void submitValidForm() + { + } + + @Override + protected void resetFieldsAfterSave() + { + for (FileUploadField attachmentField : fileFieldsManager.getFields()) + { + attachmentField.reset(); + } + updateDirtyCheckAfterSave(); + } + + protected void addOnlyFormFields(boolean forceAddEmailField) + { + formPanel.add(asynchronous); + if (forceAddEmailField || asynchronous.getValue()) + { + formPanel.add(emailField); + } + if (templateField != null) + { + formPanel.add(templateField); + } + for (FileUploadField attachmentField : fileFieldsManager.getFields()) + { + formPanel.add(wrapUnaware((Field<?>) attachmentField).get()); + } + } + + private final void addFormFields() + { + addOnlyFormFields(false); + + formPanel.addListener(Events.BeforeSubmit, new Listener<FormEvent>() + { + @Override + public void handleEvent(FormEvent be) + { + infoBox.displayProgress(messageProvider.getMessage(Dict.PROGRESS_UPLOADING)); + } + }); + + formPanel.addListener(Events.Submit, new FormPanelListener(infoBox) + { + @Override + protected void onSuccessfullUpload() + { + infoBox.displayProgress(messageProvider.getMessage(Dict.PROGRESS_PROCESSING)); + save(); + } + + @Override + protected void setUploadEnabled() + { + AbstractBatchRegistrationForm.this.setUploadEnabled(true); + } + }); + redefineSaveListeners(); + } + + void redefineSaveListeners() + { + saveButton.removeAllListeners(); + addSaveButtonConfirmationListener(); + 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(); + } + } + } + }); + } + + protected abstract void save(); + + @Override + protected void setUploadEnabled(boolean enabled) + { + super.setUploadEnabled(enabled); + infoBoxResetListener.setEnabled(enabled); + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractASyncAction.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractASyncAction.java new file mode 100644 index 00000000000..1a935057bcd --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractASyncAction.java @@ -0,0 +1,56 @@ +/* + * Copyright 2013 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.generic.server; + +import java.io.IOException; +import java.io.Writer; + +import ch.systemsx.cisd.common.exceptions.UserFailureException; + +/** + * @author pkupczyk + */ +public abstract class AbstractASyncAction implements IASyncAction +{ + + @Override + public boolean doAction(Writer messageWriter) + { + try + { + doActionOrThrowException(messageWriter); + } catch (RuntimeException ex) + { + try + { + messageWriter.write(getName() + " has failed with a following exception: "); + messageWriter.write(ex.getMessage()); + messageWriter.write("\n\nPlease correct the error or contact your administrator."); + } catch (IOException writingEx) + { + throw new UserFailureException(writingEx.getMessage() + + " when trying to throw exception: " + ex.getMessage(), ex); + } + throw ex; + } + return true; + + } + + protected abstract void doActionOrThrowException(Writer messageWriter); + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AsyncBatchRegistrationResult.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AsyncBatchRegistrationResult.java new file mode 100644 index 00000000000..7246e0361dc --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AsyncBatchRegistrationResult.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013 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.generic.shared.basic.dto; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author pkupczyk + */ +public class AsyncBatchRegistrationResult extends BatchRegistrationResult +{ + + private static final long serialVersionUID = 1L; + + // GWT + @SuppressWarnings("unused") + private AsyncBatchRegistrationResult() + { + } + + public AsyncBatchRegistrationResult(String fileName) + { + super(fileName, + "When the import is complete the confirmation or failure report will be sent by email."); + } + + public static final List<BatchRegistrationResult> singletonList(String fileName) + { + List<BatchRegistrationResult> list = new ArrayList<BatchRegistrationResult>(); + list.add(new AsyncBatchRegistrationResult(fileName)); + return list; + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialBatchUpdateResultMessage.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialBatchUpdateResultMessage.java new file mode 100644 index 00000000000..919cb967089 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialBatchUpdateResultMessage.java @@ -0,0 +1,59 @@ +/* + * Copyright 2013 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.generic.shared.basic.dto; + +import java.util.List; + +/** + * @author pkupczyk + */ +public class MaterialBatchUpdateResultMessage +{ + + private String message; + + public MaterialBatchUpdateResultMessage(List<NewMaterialsWithTypes> materials, int updateCount, + boolean ignoreUnregisteredMaterials) + { + message = updateCount + " material(s) updated"; + if (ignoreUnregisteredMaterials) + { + int ignoredCount = -updateCount; + for (NewMaterialsWithTypes m : materials) + { + ignoredCount += m.getNewEntities().size(); + } + if (ignoredCount > 0) + { + message += ", " + ignoredCount + " ignored."; + } else + { + message += ", non ignored."; + } + } else + { + message += "."; + } + } + + @Override + public String toString() + { + return message; + } + +} 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 a1d1d97c09d..bdd13b1c66f 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 @@ -132,7 +132,8 @@ public interface IGenericClientService extends IClientService * of throwing the exception and breaking the whole operation). */ public List<BatchRegistrationResult> registerMaterials(final MaterialType materialType, - boolean updateExisting, final String sessionKey) throws UserFailureException; + boolean updateExisting, final String sessionKey, boolean async, String userEmail) + throws UserFailureException; /** * Updates materials from a file which has been previously uploaded. @@ -141,7 +142,8 @@ public interface IGenericClientService extends IClientService * be ignored if they are not already registered. */ public List<BatchRegistrationResult> updateMaterials(MaterialType materialType, - String sessionKey, boolean ignoreUnregisteredMaterials) throws UserFailureException; + String sessionKey, boolean ignoreUnregisteredMaterials, boolean async, String userEmail) + throws UserFailureException; /** * Updates 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 96795032980..5466f324721 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 @@ -102,16 +102,17 @@ public interface IGenericClientServiceAsync extends IClientServiceAsync NewExperiment newExp, AsyncCallback<Void> assyncCallback) throws UserFailureException; /** - * @see IGenericClientService#registerMaterials(MaterialType, boolean, String) + * @see IGenericClientService#registerMaterials(MaterialType, boolean, String, boolean, String) */ public void registerMaterials(MaterialType materialType, boolean updateExisting, - String sessionKey, final AsyncCallback<List<BatchRegistrationResult>> asyncCallback); + String sessionKey, boolean async, String userEmail, + final AsyncCallback<List<BatchRegistrationResult>> asyncCallback); /** - * @see IGenericClientService#updateMaterials(MaterialType, String, boolean) + * @see IGenericClientService#updateMaterials(MaterialType, String, boolean, boolean, String) */ public void updateMaterials(MaterialType materialType, String sessionKey, - boolean ignoreUnregisteredMaterials, + boolean ignoreUnregisteredMaterials, boolean async, String userEmail, final AsyncCallback<List<BatchRegistrationResult>> asyncCallback); /** diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/GeneralImportForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/GeneralImportForm.java index ec4f787fbbf..8a836c3a6d6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/GeneralImportForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/GeneralImportForm.java @@ -1,243 +1,35 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application; -import static ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField.wrapUnaware; +import com.extjs.gxt.ui.client.widget.form.LabelField; -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.FormEvent; -import com.extjs.gxt.ui.client.event.Listener; -import com.extjs.gxt.ui.client.event.SelectionListener; -import com.extjs.gxt.ui.client.widget.form.CheckBox; -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.TextField; -import com.google.gwt.user.client.Element; -import com.google.gwt.user.client.ui.AbstractImagePrototype; - -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.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.ui.widget.FieldUtil; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchRegistrationResult; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractBatchRegistrationForm; import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync; -public class GeneralImportForm extends AbstractRegistrationForm +public class GeneralImportForm extends AbstractBatchRegistrationForm { - protected final class RegisterOrUpdateSamplesAndMaterialsCallback extends - AbstractRegistrationForm.AbstractRegistrationCallback<List<BatchRegistrationResult>> - { - RegisterOrUpdateSamplesAndMaterialsCallback( - 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(); - } - } - - private static final String FIELD_LABEL_TEMPLATE = "File"; - - private static final int NUMBER_OF_FIELDS = 1; - - private final String sessionKey; - - private final BasicFileFieldManager fileFieldsManager; - - private final TextField<String> emailField; - private final CheckBox asynchronous; + protected final IViewContext<IGenericClientServiceAsync> genericViewContext; - private final IViewContext<IGenericClientServiceAsync> genericViewContext; - - /** - * @param genericViewContext - * @param id - */ public GeneralImportForm(IViewContext<IGenericClientServiceAsync> genericViewContext, String id, String sessionKey) { - super(genericViewContext, id); - setResetButtonVisible(true); - this.sessionKey = sessionKey; + super(genericViewContext.getCommonViewContext(), id, sessionKey); this.genericViewContext = genericViewContext; - setScrollMode(Scroll.AUTO); - asynchronous = createCheckBox(); - emailField = - createEmailField(genericViewContext.getModel().getSessionContext().getUser() - .getUserEmail()); - fileFieldsManager = - new BasicFileFieldManager(sessionKey, NUMBER_OF_FIELDS, FIELD_LABEL_TEMPLATE); - fileFieldsManager.setMandatory(); - addUploadFeatures(sessionKey); } @Override - protected final void onRender(final Element target, final int index) - { - super.onRender(target, index); - addFormFields(); - } - - private CheckBox createCheckBox() - { - final CheckBox checkBox = new CheckBox(); - checkBox.setFieldLabel("Send confirmation?"); - checkBox.setBoxLabel(""); - checkBox.setValue(true); - checkBox.addListener(Events.Change, new Listener<BaseEvent>() - { - @Override - public void handleEvent(BaseEvent be) - { - if (checkBox.getValue()) - { - formPanel.remove(asynchronous); - for (FileUploadField attachmentField : fileFieldsManager.getFields()) - { - formPanel.remove(wrapUnaware((Field<?>) attachmentField).get()); - } - addOnlyFormFields(true); - } else - { - formPanel.remove(emailField); - } - formPanel.layout(); - } - }); - return checkBox; - } - - private TextField<String> createEmailField(String userEmail) + protected LabelField createTemplateField() { - TextField<String> field = new TextField<String>(); - field.setAllowBlank(false); - field.setFieldLabel("Email"); - FieldUtil.markAsMandatory(field); - field.setValue(userEmail); - field.setValidateOnBlur(true); - field.setRegex(GenericConstants.EMAIL_REGEX); - field.getMessages().setRegexText("Expected email address format: user@domain.com"); - AbstractImagePrototype infoIcon = - AbstractImagePrototype.create(genericViewContext.getImageBundle().getInfoIcon()); - FieldUtil.addInfoIcon(field, - "All relevant notifications will be send to this email address", - infoIcon.createImage()); - return field; + return null; } @Override - protected void submitValidForm() - { - } - - @Override - protected void resetFieldsAfterSave() - { - for (FileUploadField attachmentField : fileFieldsManager.getFields()) - { - attachmentField.reset(); - } - updateDirtyCheckAfterSave(); - } - - private final void addOnlyFormFields(boolean forceAddEmailField) - { - formPanel.add(asynchronous); - if (forceAddEmailField || asynchronous.getValue()) - { - formPanel.add(emailField); - } - for (FileUploadField attachmentField : fileFieldsManager.getFields()) - { - formPanel.add(wrapUnaware((Field<?>) attachmentField).get()); - } - } - - private final void addFormFields() - { - addOnlyFormFields(false); - - formPanel.addListener(Events.BeforeSubmit, new Listener<FormEvent>() - { - @Override - public void handleEvent(FormEvent be) - { - infoBox.displayProgress(messageProvider.getMessage(Dict.PROGRESS_UPLOADING)); - } - }); - - formPanel.addListener(Events.Submit, new FormPanelListener(infoBox) - { - @Override - protected void onSuccessfullUpload() - { - infoBox.displayProgress(messageProvider.getMessage(Dict.PROGRESS_PROCESSING)); - save(); - } - - @Override - protected void setUploadEnabled() - { - GeneralImportForm.this.setUploadEnabled(true); - } - }); - redefineSaveListeners(); - } - - void redefineSaveListeners() - { - saveButton.removeAllListeners(); - addSaveButtonConfirmationListener(); - 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(); - } - } - } - }); - } - protected void save() { genericViewContext.getService().registerOrUpdateSamplesAndMaterials(sessionKey, null, true, asynchronous.getValue(), emailField.getValue(), - new RegisterOrUpdateSamplesAndMaterialsCallback(genericViewContext)); + new BatchRegistrationCallback(genericViewContext)); } - @Override - protected void setUploadEnabled(boolean enabled) - { - super.setUploadEnabled(enabled); - infoBoxResetListener.setEnabled(enabled); - } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/AbstractMaterialBatchRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/AbstractMaterialBatchRegistrationForm.java index cbafc87a185..d26069627c9 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/AbstractMaterialBatchRegistrationForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/AbstractMaterialBatchRegistrationForm.java @@ -16,35 +16,11 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.material; -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.FormEvent; -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.FormPanel; -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.application.ui.AbstractBatchRegistrationForm; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchOperationKind; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchRegistrationResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync; @@ -52,172 +28,30 @@ import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientS /** * @author Franz-Josef Elmer */ -abstract class AbstractMaterialBatchRegistrationForm extends AbstractRegistrationForm +abstract class AbstractMaterialBatchRegistrationForm extends AbstractBatchRegistrationForm { - private static final String FIELD_LABEL_TEMPLATE = "File"; - - private static final int NUMBER_OF_FIELDS = 1; - - private static String createId(String sessionKey) - { - return GenericConstants.ID_PREFIX + sessionKey; - } - protected final MaterialType materialType; - protected final IViewContext<IGenericClientServiceAsync> viewContext; - - private final BasicFileFieldManager fileFieldsManager; - private final BatchOperationKind batchOperationKind; - AbstractMaterialBatchRegistrationForm(IViewContext<IGenericClientServiceAsync> viewContext, - String sessionKey, BatchOperationKind batchOperationKind, MaterialType materialType) + protected final IViewContext<IGenericClientServiceAsync> genericViewContext; + + AbstractMaterialBatchRegistrationForm( + IViewContext<IGenericClientServiceAsync> genericViewContext, String sessionKey, + BatchOperationKind batchOperationKind, MaterialType materialType) { - super(viewContext.getCommonViewContext(), createId(sessionKey)); - this.viewContext = viewContext; + super(genericViewContext.getCommonViewContext(), GenericConstants.ID_PREFIX + sessionKey, + sessionKey); + this.genericViewContext = genericViewContext; this.batchOperationKind = batchOperationKind; this.materialType = materialType; - setScrollMode(Scroll.AUTO); - fileFieldsManager = - new BasicFileFieldManager(sessionKey, NUMBER_OF_FIELDS, FIELD_LABEL_TEMPLATE); - fileFieldsManager.setMandatory(); - addUploadFeatures(sessionKey); - } - - /** - * Adds additional fields to the form panel. File upload field will be added automatically after - * specific fields. - */ - protected void addSpecificFormFields(FormPanel form) - { - } - - /** - * Perform registration on the service - */ - protected abstract void save(); - - @Override - protected void submitValidForm() - { } @Override - protected final void onRender(final Element target, final int index) + protected String createTemplateUrl() { - super.onRender(target, index); - addFormFields(); - } - - private final void addFormFields() - { - addSpecificFormFields(formPanel); - formPanel.add(createTemplateField()); - for (FileUploadField attachmentField : fileFieldsManager.getFields()) - { - formPanel.add(wrapUnaware((Field<?>) attachmentField).get()); - } - - formPanel.addListener(Events.BeforeSubmit, new Listener<FormEvent>() - { - @Override - public void handleEvent(FormEvent be) - { - infoBox.displayProgress(messageProvider.getMessage(Dict.PROGRESS_UPLOADING)); - } - }); - formPanel.addListener(Events.Submit, new FormPanelListener(infoBox) - { - @Override - protected void onSuccessfullUpload() - { - viewContext.log("Save in AbstractMaterialBatchRegistrationForm.addFormFields"); - infoBox.displayProgress(messageProvider.getMessage(Dict.PROGRESS_PROCESSING)); - save(); - } - - @Override - protected void setUploadEnabled() - { - AbstractMaterialBatchRegistrationForm.this.setUploadEnabled(true); - } - }); - redefineSaveListeners(); - } - - 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>() - { - @Override - public void handleEvent(BaseEvent be) - { - WindowUtils.openWindow(UrlParamsHelper.createTemplateURL(EntityKind.MATERIAL, - materialType, false, false, batchOperationKind)); - } - }); - return result; - } - - void redefineSaveListeners() - { - saveButton.removeAllListeners(); - addSaveButtonConfirmationListener(); - 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 - { - viewContext - .log("Save in AbstractMaterialBatchRegistrationForm.redefineSaveListners"); - save(); - } - } - } - }); - } - - @Override - protected void setUploadEnabled(boolean enabled) - { - super.setUploadEnabled(enabled); - infoBoxResetListener.setEnabled(enabled); - } - - protected final class RegisterMaterialsCallback extends - AbstractRegistrationForm.AbstractRegistrationCallback<List<BatchRegistrationResult>> - { - RegisterMaterialsCallback(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(); - } + return UrlParamsHelper.createTemplateURL(EntityKind.MATERIAL, materialType, false, false, + batchOperationKind); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchRegistrationForm.java index ee39eed66f3..5dc42dc8d35 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchRegistrationForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchRegistrationForm.java @@ -16,8 +16,6 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.material; -import com.extjs.gxt.ui.client.widget.form.FormPanel; - import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; @@ -55,16 +53,18 @@ public final class GenericMaterialBatchRegistrationForm extends } @Override - protected void addSpecificFormFields(FormPanel form) + protected void addOnlyFormFields(boolean forceAddEmailField) { - form.add(updateExistingCheckbox); + formPanel.add(updateExistingCheckbox); + super.addOnlyFormFields(forceAddEmailField); } @Override protected void save() { boolean updateExisting = updateExistingCheckbox.getValue(); - viewContext.getService().registerMaterials(materialType, updateExisting, SESSION_KEY, - new RegisterMaterialsCallback(viewContext)); + genericViewContext.getService().registerMaterials(materialType, updateExisting, + SESSION_KEY, asynchronous.getValue(), emailField.getValue(), + new BatchRegistrationCallback(genericViewContext)); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchUpdateForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchUpdateForm.java index f238ca76ab9..1d7c09da8c3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchUpdateForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchUpdateForm.java @@ -16,8 +16,6 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.material; -import com.extjs.gxt.ui.client.widget.form.FormPanel; - import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.CheckBoxField; @@ -47,16 +45,17 @@ public class GenericMaterialBatchUpdateForm extends AbstractMaterialBatchRegistr } @Override - protected void addSpecificFormFields(FormPanel form) + protected void addOnlyFormFields(boolean forceAddEmailField) { - form.add(ignoreUnregisteredMaterialsCheckBox); + formPanel.add(ignoreUnregisteredMaterialsCheckBox); + super.addOnlyFormFields(forceAddEmailField); } @Override protected void save() { - viewContext.getService().updateMaterials(materialType, SESSION_KEY, - ignoreUnregisteredMaterialsCheckBox.getValue(), - new RegisterMaterialsCallback(viewContext)); + genericViewContext.getService().updateMaterials(materialType, SESSION_KEY, + ignoreUnregisteredMaterialsCheckBox.getValue(), asynchronous.getValue(), + emailField.getValue(), new BatchRegistrationCallback(genericViewContext)); } } 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 66323643ee1..ae900189d1f 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 @@ -41,6 +41,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.server.translator.UserFailure import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.exception.SampleUniqueCodeViolationExceptionAbstract; import ch.systemsx.cisd.openbis.generic.shared.IServer; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AsyncBatchRegistrationResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchOperationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchRegistrationResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; @@ -52,6 +53,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentUpdateResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentUpdates; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialBatchUpdateResultMessage; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewDataSetsWithTypes; @@ -239,12 +241,9 @@ public class GenericClientService extends AbstractClientService implements IGene genericServer.registerOrUpdateSamplesAndMaterialsAsync(sessionToken, samplesInfo.getSamples(), materialsInfo.getMaterials(), userEmail); } - List<BatchRegistrationResult> results = new ArrayList<BatchRegistrationResult>(); - results.add(new BatchRegistrationResult(uploadedFiles.iterable().iterator().next() - .getOriginalFilename(), - "When the import is complete the confirmation or failure report will be sent by email.")); - return results; + String fileName = uploadedFiles.iterable().iterator().next().getOriginalFilename(); + return AsyncBatchRegistrationResult.singletonList(fileName); } else { if (materialsInfo.getMaterials().isEmpty()) @@ -403,13 +402,23 @@ public class GenericClientService extends AbstractClientService implements IGene @Override public final List<BatchRegistrationResult> registerMaterials(final MaterialType materialType, - boolean updateExisting, final String sessionKey) + boolean updateExisting, final String sessionKey, boolean async, String userEmail) { String sessionToken = getSessionToken(); BatchMaterialsOperation results = parseMaterials(sessionKey, materialType, null, updateExisting); + String fileName = results.getResultList().get(0).getFileName(); List<NewMaterialsWithTypes> materials = results.getMaterials(); - genericServer.registerOrUpdateMaterials(sessionToken, materials); + + if (async) + { + genericServer.registerOrUpdateMaterialsAsync(sessionToken, materials, userEmail); + return AsyncBatchRegistrationResult.singletonList(fileName); + } else + { + genericServer.registerOrUpdateMaterials(sessionToken, materials); + } + return results.getResultList(); } @@ -428,35 +437,27 @@ public class GenericClientService extends AbstractClientService implements IGene @Override public List<BatchRegistrationResult> updateMaterials(MaterialType materialType, - String sessionKey, boolean ignoreUnregisteredMaterials) + String sessionKey, boolean ignoreUnregisteredMaterials, boolean async, String userEmail) { String sessionToken = getSessionToken(); - BatchMaterialsOperation results = parseMaterials(sessionKey, materialType, null, true); - int updateCount = - genericServer.updateMaterials(sessionToken, results.getMaterials(), - ignoreUnregisteredMaterials); - String message = updateCount + " material(s) updated"; - if (ignoreUnregisteredMaterials) - { - int ignoredCount = -updateCount; - for (NewMaterialsWithTypes m : results.getMaterials()) - { - ignoredCount += m.getNewEntities().size(); - } - if (ignoredCount > 0) - { - message += ", " + ignoredCount + " ignored."; - } else - { - message += ", non ignored."; - } + String fileName = results.getResultList().get(0).getFileName(); + + if (async) + { + genericServer.updateMaterialsAsync(sessionToken, results.getMaterials(), + ignoreUnregisteredMaterials, userEmail); + return AsyncBatchRegistrationResult.singletonList(fileName); } else { - message += "."; + int updateCount = + genericServer.updateMaterials(sessionToken, results.getMaterials(), + ignoreUnregisteredMaterials); + MaterialBatchUpdateResultMessage message = + new MaterialBatchUpdateResultMessage(results.getMaterials(), updateCount, + ignoreUnregisteredMaterials); + return Arrays.asList(new BatchRegistrationResult(fileName, message.toString())); } - return Arrays.asList(new BatchRegistrationResult(results.getResultList().get(0) - .getFileName(), message)); } private ExperimentLoader parseExperiments(String sessionKey) 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 64920eb3707..5983cb5bf2d 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 @@ -33,10 +33,11 @@ import org.springframework.stereotype.Component; import ch.rinn.restrictions.Private; import ch.systemsx.cisd.authentication.ISessionManager; +import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.common.spring.IInvocationLoggerContext; +import ch.systemsx.cisd.openbis.generic.server.AbstractASyncAction; import ch.systemsx.cisd.openbis.generic.server.AbstractServer; -import ch.systemsx.cisd.openbis.generic.server.IASyncAction; import ch.systemsx.cisd.openbis.generic.server.MaterialHelper; import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.AuthorizationGuard; import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.Capability; @@ -76,6 +77,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialBatchUpdateResultMessage; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewBasicExperiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewDataSet; @@ -683,6 +685,45 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen return count; } + @Override + @RolesAllowed(RoleWithHierarchy.INSTANCE_ADMIN) + @Capability("WRITE_MATERIAL") + public void updateMaterialsAsync(final String sessionToken, + final List<NewMaterialsWithTypes> newMaterials, + final boolean ignoreUnregisteredMaterials, final String userEmail) + throws UserFailureException + { + assert sessionToken != null : "Unspecified session token."; + checkSession(sessionToken); + + executeASync(userEmail, new AbstractASyncAction() + { + @Override + public String getName() + { + return "Material Batch Update"; + } + + @Override + protected void doActionOrThrowException(Writer messageWriter) + { + try + { + int updateCount = + genericServer.updateMaterials(sessionToken, newMaterials, + ignoreUnregisteredMaterials); + MaterialBatchUpdateResultMessage message = + new MaterialBatchUpdateResultMessage(newMaterials, updateCount, + ignoreUnregisteredMaterials); + messageWriter.write(message.toString()); + } catch (IOException e) + { + CheckedExceptionTunnel.wrapIfNecessary(e); + } + } + }); + } + @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public AttachmentWithContent getProjectFileAttachment(String sessionToken, @@ -792,6 +833,32 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen } } + @Override + @RolesAllowed(RoleWithHierarchy.INSTANCE_ADMIN) + @Capability("WRITE_MATERIAL") + public void registerOrUpdateMaterialsAsync(final String sessionToken, + final List<NewMaterialsWithTypes> materials, final String userEmail) + throws UserFailureException + { + assert sessionToken != null : "Unspecified session token."; + checkSession(sessionToken); + + executeASync(userEmail, new AbstractASyncAction() + { + @Override + public String getName() + { + return "Material Batch Registration"; + } + + @Override + protected void doActionOrThrowException(Writer messageWriter) + { + genericServer.registerOrUpdateMaterials(sessionToken, materials); + } + }); + } + @Override @RolesAllowed(RoleWithHierarchy.SPACE_USER) @Capability("WRITE_EXPERIMENT_SAMPLE") @@ -957,7 +1024,7 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen final List<NewMaterialsWithTypes> newMaterialsWithType, String userEmail) throws UserFailureException { - executeASync(userEmail, new IASyncAction() + executeASync(userEmail, new AbstractASyncAction() { @Override public String getName() @@ -966,29 +1033,10 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen } @Override - public boolean doAction(Writer messageWriter) + protected void doActionOrThrowException(Writer messageWriter) { - try - { - genericServer.registerOrUpdateSamplesAndMaterials(sessionToken, - newSamplesWithType, newMaterialsWithType); - } catch (RuntimeException ex) - { - try - { - messageWriter.write(getName() - + " has failed with a following exception: "); - messageWriter.write(ex.getMessage()); - messageWriter - .write("\n\nPlease correct the error or contact your administrator."); - } catch (IOException writingEx) - { - throw new UserFailureException(writingEx.getMessage() - + " when trying to throw exception: " + ex.getMessage(), ex); - } - throw ex; - } - return true; + genericServer.registerOrUpdateSamplesAndMaterials(sessionToken, + newSamplesWithType, newMaterialsWithType); } }); } @@ -1001,7 +1049,7 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen final List<NewSamplesWithTypes> newSamplesWithType, String userEmail) throws UserFailureException { - executeASync(userEmail, new IASyncAction() + executeASync(userEmail, new AbstractASyncAction() { @Override public String getName() @@ -1010,28 +1058,9 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen } @Override - public boolean doAction(Writer messageWriter) + protected void doActionOrThrowException(Writer messageWriter) { - try - { - genericServer.registerOrUpdateSamples(sessionToken, newSamplesWithType); - } catch (RuntimeException ex) - { - try - { - messageWriter.write(getName() - + " has failed with a following exception: "); - messageWriter.write(ex.getMessage()); - messageWriter - .write("\n\nPlease correct the error or contact your administrator."); - } catch (IOException writingEx) - { - throw new UserFailureException(writingEx.getMessage() - + " when trying to throw exception: " + ex.getMessage(), ex); - } - throw ex; - } - return true; + genericServer.registerOrUpdateSamples(sessionToken, newSamplesWithType); } }); } 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 7bd50d63cee..8a751d9a928 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 @@ -120,10 +120,21 @@ final class GenericServerLogger extends AbstractServerLogger implements IGeneric public int updateMaterials(String sessionToken, List<NewMaterialsWithTypes> newMaterials, boolean ignoreUnregisteredMaterials) throws UserFailureException { - logTracking(sessionToken, "update_materials", getMaterials(newMaterials)); + logTracking(sessionToken, "update_materials", + "MATERIALS(%S) IGNORE_UNREGISTERED_MATERIALS(%S)", getMaterials(newMaterials), + ignoreUnregisteredMaterials); return 0; } + @Override + public void updateMaterialsAsync(String sessionToken, List<NewMaterialsWithTypes> newMaterials, + boolean ignoreUnregisteredMaterials, String userEmail) throws UserFailureException + { + logTracking(sessionToken, "update_materials_async", + "MATERIALS(%S) IGNORE_UNREGISTERED_MATERIALS(%S) USER_EMAIL(%S)", + getMaterials(newMaterials), ignoreUnregisteredMaterials, userEmail); + } + @Override public AttachmentWithContent getExperimentFileAttachment(final String sessionToken, final TechId experimentId, final String filename, final Integer versionOrNull) @@ -223,6 +234,19 @@ final class GenericServerLogger extends AbstractServerLogger implements IGeneric } } + @Override + public void registerOrUpdateMaterialsAsync(String sessionToken, + List<NewMaterialsWithTypes> materials, String userEmail) + { + for (NewMaterialsWithTypes materialsWithType : materials) + { + logTracking(sessionToken, "registerOrUpdateMaterialsAsync", + "type(%s) numberOfMaterials(%s) userEmail(%s)", materialsWithType + .getEntityType().getCode(), materialsWithType.getNewEntities().size(), + userEmail); + } + } + @Override public void registerOrUpdateSamples(String sessionToken, List<NewSamplesWithTypes> newSamplesWithType) throws UserFailureException 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 ec2afef2575..1f341e64b7d 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 @@ -193,6 +193,14 @@ public interface IGenericServer extends IServer public int updateMaterials(String sessionToken, List<NewMaterialsWithTypes> newMaterials, boolean ignoreUnregisteredMaterials) throws UserFailureException; + /** + * Asynchronously updates materials in batch. + */ + @Transactional + @DatabaseCreateOrDeleteModification(value = ObjectKind.MATERIAL) + public void updateMaterialsAsync(String sessionToken, List<NewMaterialsWithTypes> newMaterials, + boolean ignoreUnregisteredMaterials, String userEmail) throws UserFailureException; + /** * Registers new materials or if they exist updates in batch their properties (properties which * are not mentioned stay unchanged). @@ -202,6 +210,15 @@ public interface IGenericServer extends IServer public void registerOrUpdateMaterials(String sessionToken, List<NewMaterialsWithTypes> materials) throws UserFailureException; + /** + * Asynchronously registers new materials or if they exist updates in batch their properties + * (properties which are not mentioned stay unchanged). + */ + @Transactional + @DatabaseCreateOrDeleteModification(value = ObjectKind.MATERIAL) + public void registerOrUpdateMaterialsAsync(String sessionToken, + List<NewMaterialsWithTypes> materials, String userEmail) throws UserFailureException; + /** * Returns attachment described by given sample identifier, filename and version. */ diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientServiceTest.java index 53d9b14ed5b..752d6d236cb 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientServiceTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientServiceTest.java @@ -615,7 +615,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest List<BatchRegistrationResult> results = genericClientService.updateMaterials(MATERIAL_TYPE, sessionKey, - ignoreUnregisteredMaterials); + ignoreUnregisteredMaterials, false, null); assertEquals(1, results.size()); assertEquals(updateCount + " material(s) updated.", results.get(0).getMessage()); @@ -632,7 +632,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest List<BatchRegistrationResult> results = genericClientService.updateMaterials(MATERIAL_TYPE, sessionKey, - ignoreUnregisteredMaterials); + ignoreUnregisteredMaterials, false, null); assertEquals(1, results.size()); assertEquals(updateCount + " material(s) updated, non ignored.", results.get(0) @@ -650,7 +650,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest List<BatchRegistrationResult> results = genericClientService.updateMaterials(MATERIAL_TYPE, sessionKey, - ignoreUnregisteredMaterials); + ignoreUnregisteredMaterials, false, null); assertEquals(1, results.size()); assertEquals(updateCount + " material(s) updated, 1 ignored.", results.get(0).getMessage()); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/BatchMaterialRegistrationAndUpdateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/BatchMaterialRegistrationAndUpdateTest.java index e212fc98434..5260a073087 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/BatchMaterialRegistrationAndUpdateTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/BatchMaterialRegistrationAndUpdateTest.java @@ -263,7 +263,8 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase uploadFile("my-file", materialBatchData); MaterialType materialType = new MaterialType(); materialType.setCode(materialTypeCode); - return genericClientService.registerMaterials(materialType, false, SESSION_KEY); + return genericClientService + .registerMaterials(materialType, false, SESSION_KEY, false, null); } private List<BatchRegistrationResult> updateMaterials(String materialBatchData, @@ -272,7 +273,8 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase uploadFile("my-file", materialBatchData); MaterialType materialType = new MaterialType(); materialType.setCode(materialTypeCode); - return genericClientService.updateMaterials(materialType, SESSION_KEY, ignoreUnregistered); + return genericClientService.updateMaterials(materialType, SESSION_KEY, ignoreUnregistered, + false, null); } } -- GitLab