package com.constellio.app.ui.pages.search.batchProcessing; import static com.constellio.app.ui.i18n.i18n.$; import static com.constellio.model.entities.schemas.MetadataValueType.CONTENT; import java.io.InputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.constellio.app.ui.entities.MetadataVO; import com.constellio.app.ui.entities.RecordVO; import com.constellio.app.ui.framework.buttons.BaseButton; import com.constellio.app.ui.framework.buttons.WindowButton; import com.constellio.app.ui.framework.components.RecordFieldFactory; import com.constellio.app.ui.framework.components.RecordForm; import com.constellio.app.ui.framework.components.ReportViewer; import com.constellio.app.ui.framework.components.fields.lookup.LookupRecordField; import com.constellio.model.frameworks.validation.ValidationException; import com.constellio.model.services.records.RecordServicesException; import com.vaadin.data.Property; import com.vaadin.server.Page; import com.vaadin.server.Resource; import com.vaadin.server.StreamResource; import com.vaadin.ui.Button; import com.vaadin.ui.Component; import com.vaadin.ui.Field; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; public class BatchProcessingButton extends WindowButton { private static final Logger LOGGER = LoggerFactory.getLogger(BatchProcessingButton.class); private BatchProcessingPresenter presenter; private final BatchProcessingView view; //fields LookupRecordField typeField; String currentSchema; BatchProcessingForm form; VerticalLayout vLayout; public BatchProcessingButton(BatchProcessingPresenter presenter, BatchProcessingView view) { super($("AdvancedSearchView.batchProcessing"), $("AdvancedSearchView.batchProcessing"), new WindowConfiguration(true, true, "75%", "75%")); this.presenter = presenter; this.view = view; } @Override protected Component buildWindowContent() { Component windowContent; if (!presenter.hasWriteAccessOnAllRecords()) { windowContent = new Label($("AdvancedSearchView.requireWriteAccess")); } else if (presenter.isSearchResultsSelectionForm()) { windowContent = buildSearchResultsSelectionForm(); } else { windowContent = buildBatchProcessingForm(); } return windowContent; } private Component buildSearchResultsSelectionForm() { getWindow().setHeight("220px"); Panel panel = new Panel(); vLayout = new VerticalLayout(); vLayout.setSizeFull(); vLayout.setSpacing(true); Label questionLabel = new Label($("AdvancedSearch.batchProcessingRecordSelection")); BaseButton allSearchResultsButton = new BaseButton($("AdvancedSearchView.allSearchResults")) { @Override protected void buttonClick(ClickEvent event) { presenter.allSearchResultsButtonClicked(); getWindow().setContent(buildBatchProcessingForm()); getWindow().setHeight(BatchProcessingButton.this.getConfiguration().getHeight()); getWindow().center(); } }; BaseButton selectedSearchResultsButton = new BaseButton($("AdvancedSearchView.selectedSearchResults")) { @Override protected void buttonClick(ClickEvent event) { presenter.selectedSearchResultsButtonClicked(); getWindow().setContent(buildBatchProcessingForm()); getWindow().setHeight(BatchProcessingButton.this.getConfiguration().getHeight()); getWindow().center(); } }; vLayout.addComponents(questionLabel, allSearchResultsButton, selectedSearchResultsButton); panel.setContent(vLayout); panel.setSizeFull(); return panel; } private Component buildBatchProcessingForm() { Panel panel = new Panel(); vLayout = new VerticalLayout(); vLayout.setSpacing(true); String typeSchemaType = presenter.getTypeSchemaType(view.getSchemaType()); typeField = new LookupRecordField(typeSchemaType); // FIXME All schemas don't have a type field typeField.setCaption($("BatchProcessingButton.type")); String originType = presenter.getOriginType(); if (originType != null) { typeField.setValue(originType); } typeField.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(Property.ValueChangeEvent event) { refreshForm(); } }); vLayout.addComponent(typeField); form = newForm(); vLayout.addComponent(form); panel.setContent(vLayout); panel.setSizeFull(); return panel; } private void refreshForm() { BatchProcessingForm newForm = newForm(); vLayout.replaceComponent(form, newForm); form = newForm; } private BatchProcessingForm newForm() { String selectedType = typeField.getValue(); RecordFieldFactory fieldFactory = newFieldFactory(selectedType); String originSchema = presenter.getSchema(view.getSchemaType(), selectedType); return new BatchProcessingForm(presenter.newRecordVO(originSchema, view.getSessionContext()), fieldFactory); } private RecordFieldFactory newFieldFactory(String selectedType) { RecordFieldFactory fieldFactory = presenter.newRecordFieldFactory(view.getSchemaType(), selectedType); return new RecordFieldFactoryWithNoTypeNoContent(fieldFactory); } public class BatchProcessingForm extends RecordForm { Button simulateButton, processButton; public BatchProcessingForm(RecordVO record, RecordFieldFactory recordFieldFactory) { super(record, recordFieldFactory); simulateButton = new Button($("simulate")); simulateButton.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { form.commit(); BatchProcessingView batchProcessingView = BatchProcessingButton.this.view; try { InputStream inputStream = presenter.simulateButtonClicked(typeField.getValue(), viewObject); downloadBatchProcessingResults(inputStream); } catch (RecordServicesException.ValidationException e) { view.showErrorMessage($(e.getErrors())); } catch (Throwable e) { LOGGER.error("Unexpected error while executing batch process", e); batchProcessingView.showErrorMessage($(e.getMessage())); } } }); processButton = new Button($("BatchProcessingButton.process", presenter.getNumberOfRecords())); processButton.addStyleName(ValoTheme.BUTTON_PRIMARY); processButton.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { form.commit(); BatchProcessingView batchProcessingView = BatchProcessingButton.this.view; try { presenter.processBatchButtonClicked(typeField.getValue(), viewObject); getWindow().close(); batchProcessingView.showMessage($("BatchProcessing.endedNormally")); } catch (RecordServicesException.ValidationException e) { view.showErrorMessage($(e.getErrors())); } catch (Throwable e) { LOGGER.error("Unexpected error while executing batch process", e); batchProcessingView.showErrorMessage($(e.getMessage())); } } }); buttonsLayout.addComponent(processButton); buttonsLayout.addComponentAsFirst(simulateButton); buttonsLayout.removeComponent(cancelButton); buttonsLayout.removeComponent(saveButton); } @Override protected void saveButtonClick(RecordVO viewObject) throws ValidationException { } @Override protected void cancelButtonClick(RecordVO viewObject) { getWindow().close(); } private void downloadBatchProcessingResults(final InputStream stream) { Resource resource = new ReportViewer.DownloadStreamResource(new StreamResource.StreamSource() { @Override public InputStream getStream() { return stream; } }, "results.xls"); Page.getCurrent().open(resource, null, false); } } private class RecordFieldFactoryWithNoTypeNoContent extends RecordFieldFactory { final RecordFieldFactory fieldFactory; public RecordFieldFactoryWithNoTypeNoContent(RecordFieldFactory fieldFactory) { this.fieldFactory = fieldFactory; } @Override public Field<?> build(RecordVO recordVO, MetadataVO metadataVO) { if (metadataVO == null || metadataVO.getType().equals(CONTENT) || metadataVO.getLocalCode().equals("type")) { return null; } if (fieldFactory != null) { return fieldFactory.build(recordVO, metadataVO); } return super.build(recordVO, metadataVO); } } }