package com.constellio.app.modules.rm.ui.pages.document; import static com.constellio.app.ui.i18n.i18n.$; import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from; import static java.util.Arrays.asList; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.ObjectUtils; import com.constellio.app.modules.rm.constants.RMPermissionsTo; import com.constellio.app.modules.rm.navigation.RMViews; import com.constellio.app.modules.rm.services.RMSchemasRecordsServices; import com.constellio.app.modules.rm.services.events.RMEventsSearchServices; import com.constellio.app.modules.rm.ui.builders.DocumentToVOBuilder; import com.constellio.app.modules.rm.ui.components.breadcrumb.FolderDocumentBreadcrumbTrail; import com.constellio.app.modules.rm.ui.components.document.DocumentActionsPresenterUtils; import com.constellio.app.modules.rm.ui.entities.DocumentVO; import com.constellio.app.modules.rm.wrappers.Cart; import com.constellio.app.modules.rm.wrappers.Document; import com.constellio.app.modules.rm.wrappers.RMTask; import com.constellio.app.modules.tasks.TasksPermissionsTo; import com.constellio.app.modules.tasks.model.wrappers.Task; import com.constellio.app.modules.tasks.model.wrappers.Workflow; import com.constellio.app.modules.tasks.navigation.TaskViews; import com.constellio.app.modules.tasks.services.TasksSchemasRecordsServices; import com.constellio.app.modules.tasks.services.WorkflowServices; import com.constellio.app.ui.entities.ContentVersionVO; import com.constellio.app.ui.entities.MetadataSchemaVO; import com.constellio.app.ui.entities.RecordVO; import com.constellio.app.ui.entities.RecordVO.VIEW_MODE; import com.constellio.app.ui.framework.builders.ContentVersionToVOBuilder; import com.constellio.app.ui.framework.builders.EventToVOBuilder; import com.constellio.app.ui.framework.builders.MetadataSchemaToVOBuilder; import com.constellio.app.ui.framework.builders.RecordToVOBuilder; import com.constellio.app.ui.framework.data.RecordVODataProvider; import com.constellio.app.ui.pages.base.SingleSchemaBasePresenter; import com.constellio.model.entities.CorePermissions; import com.constellio.model.entities.records.Content; import com.constellio.model.entities.records.ContentVersion; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.Transaction; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.schemas.Metadata; import com.constellio.model.entities.schemas.MetadataSchema; import com.constellio.model.entities.schemas.Schemas; import com.constellio.model.services.factories.ModelLayerFactory; import com.constellio.model.services.migrations.ConstellioEIMConfigs; import com.constellio.model.services.records.RecordServicesException; import com.constellio.model.services.records.RecordServicesRuntimeException.NoSuchRecordWithId; import com.constellio.model.services.search.StatusFilter; import com.constellio.model.services.search.query.logical.LogicalSearchQuery; public class DisplayDocumentPresenter extends SingleSchemaBasePresenter<DisplayDocumentView> { protected DocumentToVOBuilder voBuilder; protected ContentVersionToVOBuilder contentVersionVOBuilder; protected DocumentActionsPresenterUtils<DisplayDocumentView> presenterUtils; private MetadataSchemaToVOBuilder schemaVOBuilder = new MetadataSchemaToVOBuilder(); private RecordVODataProvider tasksDataProvider; private RecordVODataProvider eventsDataProvider; private RMSchemasRecordsServices rm; public DisplayDocumentPresenter(final DisplayDocumentView view) { super(view); presenterUtils = new DocumentActionsPresenterUtils<DisplayDocumentView>(view) { @Override public void updateActionsComponent() { super.updateActionsComponent(); view.refreshMetadataDisplay(); updateContentVersions(); } }; contentVersionVOBuilder = new ContentVersionToVOBuilder(modelLayerFactory); voBuilder = new DocumentToVOBuilder(modelLayerFactory); rm = new RMSchemasRecordsServices(collection, appLayerFactory); } @Override protected boolean hasPageAccess(String params, User user) { return true; } public void forParams(String params) { String id = params; String taxonomyCode = view.getUIContext().getAttribute(FolderDocumentBreadcrumbTrail.TAXONOMY_CODE); view.setTaxonomyCode(taxonomyCode); Record record = getRecord(id); final DocumentVO documentVO = voBuilder.build(record, VIEW_MODE.DISPLAY, view.getSessionContext()); view.setDocumentVO(documentVO); presenterUtils.setRecordVO(documentVO); ModelLayerFactory modelLayerFactory = view.getConstellioFactories().getModelLayerFactory(); User user = getCurrentUser(); modelLayerFactory.newLoggingServices().logRecordView(record, user); MetadataSchemaVO tasksSchemaVO = schemaVOBuilder.build(getTasksSchema(), VIEW_MODE.TABLE, view.getSessionContext()); tasksDataProvider = new RecordVODataProvider( tasksSchemaVO, voBuilder, modelLayerFactory, view.getSessionContext()) { @Override protected LogicalSearchQuery getQuery() { TasksSchemasRecordsServices tasks = new TasksSchemasRecordsServices(collection, appLayerFactory); Metadata taskDocumentMetadata = tasks.userTask.schema().getMetadata(RMTask.LINKED_DOCUMENTS); LogicalSearchQuery query = new LogicalSearchQuery(); query.setCondition(from(tasks.userTask.schemaType()).where(taskDocumentMetadata).is(documentVO.getId())); query.filteredByStatus(StatusFilter.ACTIVES); query.filteredWithUser(getCurrentUser()); query.sortDesc(Schemas.MODIFIED_ON); return query; } }; eventsDataProvider = getEventsDataProvider(); } public int getTaskCount() { return tasksDataProvider.size(); } public void backgroundViewMonitor() { DocumentVO documentVO = presenterUtils.getDocumentVO(); try { ContentVersionVO contentVersionVO = documentVO.getContent(); String contentVersionNumber = contentVersionVO != null ? contentVersionVO.getVersion() : null; String checkoutUserId = contentVersionVO != null ? contentVersionVO.getCheckoutUserId() : null; Long length = contentVersionVO != null ? contentVersionVO.getLength() : null; Record currentRecord = getRecord(documentVO.getId()); Document currentDocument = new Document(currentRecord, types()); Content currentContent = currentDocument.getContent(); ContentVersion currentContentVersion = currentContent != null ? currentContent.getCurrentVersionSeenBy(getCurrentUser()) : null; String currentContentVersionNumber = currentContentVersion != null ? currentContentVersion.getVersion() : null; String currentCheckoutUserId = currentContent != null ? currentContent.getCheckoutUserId() : null; Long currentLength = currentContentVersion != null ? currentContentVersion.getLength() : null; if (ObjectUtils.notEqual(contentVersionNumber, currentContentVersionNumber) || ObjectUtils.notEqual(checkoutUserId, currentCheckoutUserId) || ObjectUtils.notEqual(length, currentLength)) { documentVO = voBuilder.build(currentRecord, VIEW_MODE.DISPLAY, view.getSessionContext()); view.setDocumentVO(documentVO); presenterUtils.setRecordVO(documentVO); presenterUtils.updateActionsComponent(); } } catch (NoSuchRecordWithId e) { view.invalidate(); } } @Override protected boolean hasRestrictedRecordAccess(String params, User user, Record restrictedRecord) { return user.hasReadAccess().on(restrictedRecord); } private MetadataSchema getTasksSchema() { return schema(Task.DEFAULT_SCHEMA); } @Override protected List<String> getRestrictedRecordIds(String params) { DocumentVO documentVO = presenterUtils.getDocumentVO(); return Arrays.asList(documentVO.getId()); } public void viewAssembled() { presenterUtils.updateActionsComponent(); view.setTasks(tasksDataProvider); view.setEvents(eventsDataProvider); view.setPublishButtons(presenterUtils.isDocumentPublished()); } public RecordVODataProvider getWorkflows() { MetadataSchemaVO schemaVO = new MetadataSchemaToVOBuilder().build( schema(Workflow.DEFAULT_SCHEMA), VIEW_MODE.TABLE, view.getSessionContext()); return new RecordVODataProvider(schemaVO, new RecordToVOBuilder(), modelLayerFactory, view.getSessionContext()) { @Override protected LogicalSearchQuery getQuery() { return new WorkflowServices(view.getCollection(), appLayerFactory).getWorkflowsQuery(); } }; } public void workflowStartRequested(RecordVO record) { Map<String, List<String>> parameters = new HashMap<>(); parameters.put(RMTask.LINKED_DOCUMENTS, asList(presenterUtils.getDocumentVO().getId())); Workflow workflow = new TasksSchemasRecordsServices(view.getCollection(), appLayerFactory).getWorkflow(record.getId()); new WorkflowServices(view.getCollection(), appLayerFactory).start(workflow, getCurrentUser(), parameters); } private void updateContentVersions() { List<ContentVersionVO> contentVersionVOs = new ArrayList<ContentVersionVO>(); DocumentVO documentVO = presenterUtils.getDocumentVO(); Record record = getRecord(documentVO.getId()); Document document = new Document(record, types()); Content content = document.getContent(); if (content != null) { for (ContentVersion contentVersion : content.getHistoryVersions()) { ContentVersionVO contentVersionVO = contentVersionVOBuilder.build(content, contentVersion); contentVersionVOs.add(contentVersionVO); } ContentVersion currentVersion = content.getCurrentVersionSeenBy(getCurrentUser()); ContentVersionVO currentVersionVO = contentVersionVOBuilder.build(content, currentVersion); contentVersionVOs.remove(currentVersionVO); contentVersionVOs.add(currentVersionVO); } Collections.reverse(contentVersionVOs); view.setContentVersions(contentVersionVOs); } public void backButtonClicked() { view.navigate().to().previousView(); } public boolean isDeleteContentVersionPossible() { return presenterUtils.isDeleteContentVersionPossible(); } public boolean isDeleteContentVersionPossible(ContentVersionVO contentVersionVO) { return presenterUtils.isDeleteContentVersionPossible(contentVersionVO); } public void deleteContentVersionButtonClicked(ContentVersionVO contentVersionVO) { presenterUtils.deleteContentVersionButtonClicked(contentVersionVO); } public void editDocumentButtonClicked() { presenterUtils.editDocumentButtonClicked(); } public void deleteDocumentButtonClicked() { presenterUtils.deleteDocumentButtonClicked(); } public void linkToDocumentButtonClicked() { presenterUtils.linkToDocumentButtonClicked(); } public void addAuthorizationButtonClicked() { presenterUtils.addAuthorizationButtonClicked(); } public void shareDocumentButtonClicked() { presenterUtils.shareDocumentButtonClicked(); } public void createPDFAButtonClicked() { if (!presenterUtils.getDocumentVO().getExtension().toUpperCase().equals("PDF") && !presenterUtils.getDocumentVO() .getExtension().toUpperCase().equals("PDFA")) { presenterUtils.createPDFA(); } else { this.view.showErrorMessage($("DocumentActionsComponent.documentAllreadyPDFA")); } } public void uploadButtonClicked() { presenterUtils.uploadButtonClicked(); } public void checkInButtonClicked() { presenterUtils.checkInButtonClicked(); } public void alertWhenAvailableClicked() { presenterUtils.alertWhenAvailable(); } public void checkOutButtonClicked() { presenterUtils.checkOutButtonClicked(view.getSessionContext()); } public void finalizeButtonClicked() { presenterUtils.finalizeButtonClicked(); } public void updateWindowClosed() { presenterUtils.updateWindowClosed(); } public String getDocumentTitle() { DocumentVO documentVO = presenterUtils.getDocumentVO(); return documentVO.getTitle(); } public void copyContentButtonClicked() { presenterUtils.copyContentButtonClicked(); } public String getContentTitle() { return presenterUtils.getContentTitle(); } public void renameContentButtonClicked(String newContentTitle) { Document document = presenterUtils.renameContentButtonClicked(newContentTitle); if (document != null) { addOrUpdate(document.getWrappedRecord()); view.navigate().to(RMViews.class).displayDocument(document.getId()); } } public RecordVODataProvider getOwnedCartsDataProvider() { final MetadataSchemaVO cartSchemaVO = schemaVOBuilder.build(rm.cartSchema(), VIEW_MODE.TABLE, view.getSessionContext()); return new RecordVODataProvider(cartSchemaVO, new RecordToVOBuilder(), modelLayerFactory, view.getSessionContext()) { @Override protected LogicalSearchQuery getQuery() { return new LogicalSearchQuery(from(rm.cartSchema()).where(rm.cartOwner()) .isEqualTo(getCurrentUser().getId())).sortAsc(Schemas.TITLE); } }; } public RecordVODataProvider getSharedCartsDataProvider() { final MetadataSchemaVO cartSchemaVO = schemaVOBuilder.build(rm.cartSchema(), VIEW_MODE.TABLE, view.getSessionContext()); return new RecordVODataProvider(cartSchemaVO, new RecordToVOBuilder(), modelLayerFactory, view.getSessionContext()) { @Override protected LogicalSearchQuery getQuery() { return new LogicalSearchQuery(from(rm.cartSchema()).where(rm.cartSharedWithUsers()) .isContaining(asList(getCurrentUser().getId()))).sortAsc(Schemas.TITLE); } }; } public boolean hasContent() { return presenterUtils.hasContent(); } public void taskClicked(RecordVO taskVO) { view.navigate().to(TaskViews.class).displayTask(taskVO.getId()); } public void addToCartRequested(RecordVO recordVO) { presenterUtils.addToCartRequested(recordVO); } public InputStream getSignatureInputStream(String certificate, String password) { // TODO: Sign the file ContentVersionVO content = presenterUtils.getDocumentVO().getContent(); return modelLayerFactory.getContentManager().getContentInputStream(content.getHash(), content.getFileName()); } public void publishButtonClicked() { updateAndRefresh(presenterUtils.publishButtonClicked()); } public void unpublishButtonClicked() { updateAndRefresh(presenterUtils.unpublishButtonClicked()); } public String getPublicLink() { String url = modelLayerFactory.getSystemConfigurationsManager().getValue(ConstellioEIMConfigs.CONSTELLIO_URL); return url + "dl?id=" + presenterUtils.getDocumentVO().getId(); } private void updateAndRefresh(Document document) { if (document != null) { addOrUpdate(document.getWrappedRecord()); view.navigate().to(RMViews.class).displayDocument(document.getId()); } } public void createNewCartAndAddToItRequested(String title) { Cart cart = rm.newCart(); cart.setTitle(title); cart.setOwner(getCurrentUser()); try { cart.addDocuments(Arrays.asList(presenterUtils.getDocumentVO().getId())); recordServices().execute(new Transaction(cart.getWrappedRecord()).setUser(getCurrentUser())); view.showMessage($("DocumentActionsComponent.addedToCart")); } catch (RecordServicesException e) { e.printStackTrace(); } } public boolean hasCurrentUserPermissionToPublishOnCurrentDocument() { return getCurrentUser().has(RMPermissionsTo.PUBLISH_AND_UNPUBLISH_DOCUMENTS) .on(getRecord(presenterUtils.getDocumentVO().getId())); } public boolean hasCurrentUserPermissionToUseCart() { return getCurrentUser().has(RMPermissionsTo.USE_CART).globally(); } public RecordVODataProvider getEventsDataProvider() { final RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); final MetadataSchemaVO eventSchemaVO = schemaVOBuilder .build(rm.eventSchema(), VIEW_MODE.TABLE, view.getSessionContext()); return new RecordVODataProvider(eventSchemaVO, new EventToVOBuilder(), modelLayerFactory, view.getSessionContext()) { @Override protected LogicalSearchQuery getQuery() { RMEventsSearchServices rmEventsSearchServices = new RMEventsSearchServices(modelLayerFactory, collection); return rmEventsSearchServices .newFindEventByRecordIDQuery(getCurrentUser(), presenterUtils.getDocumentVO().getId()); } }; } protected boolean hasCurrentUserPermissionToViewEvents() { return getCurrentUser().has(CorePermissions.VIEW_EVENTS).on(getRecord(presenterUtils.getDocumentVO().getId())); } public void refreshEvents() { modelLayerFactory.getDataLayerFactory().newEventsDao().flush(); view.setEvents(getEventsDataProvider()); } public boolean hasPermissionToStartWorkflow() { return getCurrentUser().has(TasksPermissionsTo.START_WORKFLOWS).globally(); } }