package com.constellio.app.modules.rm.extensions; import com.constellio.app.api.extensions.PagesComponentsExtension; import com.constellio.app.api.extensions.params.DecorateMainComponentAfterInitExtensionParams; import com.constellio.app.modules.rm.services.RMRecordDeletionServices; import com.constellio.app.modules.rm.services.RMSchemasRecordsServices; import com.constellio.app.modules.rm.wrappers.AdministrativeUnit; import com.constellio.app.modules.rm.wrappers.DecommissioningList; import com.constellio.app.modules.rm.wrappers.RMTask; import com.constellio.app.modules.tasks.services.TasksSchemasRecordsServices; import com.constellio.app.services.factories.AppLayerFactory; import com.constellio.app.ui.entities.RecordVO; import com.constellio.app.ui.framework.buttons.CleanAdministrativeUnitButton; import com.constellio.app.ui.framework.decorators.base.ActionMenuButtonsDecorator; import com.constellio.app.ui.pages.base.BasePresenterUtils; import com.constellio.app.ui.pages.base.BaseView; import com.constellio.app.ui.pages.base.BaseViewImpl; import com.constellio.app.ui.pages.management.taxonomy.TaxonomyManagementViewImpl; import com.constellio.data.dao.services.bigVault.SearchResponseIterator; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.schemas.MetadataSchema; import com.constellio.model.entities.schemas.Schemas; import com.constellio.model.services.search.SearchServices; import com.constellio.model.services.search.query.logical.LogicalSearchQuery; import com.vaadin.ui.Button; import com.vaadin.ui.Component; import org.vaadin.dialogs.ConfirmDialog; import java.util.ArrayList; import java.util.List; import static com.constellio.app.ui.i18n.i18n.$; import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.*; import static java.util.Arrays.asList; /** * Created by Constellio on 2017-03-16. */ public class RMCleanAdministrativeUnitButtonExtension extends PagesComponentsExtension { String collection; AppLayerFactory appLayerFactory; public RMCleanAdministrativeUnitButtonExtension(String collection, AppLayerFactory appLayerFactory) { this.collection = collection; this.appLayerFactory = appLayerFactory; } @Override public void decorateMainComponentBeforeViewAssembledOnViewEntered(DecorateMainComponentAfterInitExtensionParams params) { super.decorateMainComponentAfterViewAssembledOnViewEntered(params); Component mainComponent = params.getMainComponent(); if(mainComponent instanceof TaxonomyManagementViewImpl) { TaxonomyManagementViewImpl view = (TaxonomyManagementViewImpl) mainComponent; if(view.hasCurrentUserAccessToCurrentConcept()) { view.addActionMenuButtonsDecorator(new ActionMenuButtonsDecorator() { @Override public void decorate(final BaseViewImpl view, List<Button> actionMenuButtons) { TaxonomyManagementViewImpl taxonomyView = (TaxonomyManagementViewImpl) view; RecordVO currentConcept = taxonomyView.getCurrentConcept(); User currentUser = getCurrentUser(view); if(AdministrativeUnit.SCHEMA_TYPE.equals(currentConcept.getSchema().getTypeCode())) { actionMenuButtons.add(buildNewMenuButton(currentConcept, currentUser)); } } }); } } } private Button buildNewMenuButton(final RecordVO currentConcept, final User currentUser) { return new CleanAdministrativeUnitButton($("TaxonomyManagementView.cleanAdministrativeUnit")) { @Override protected void confirmButtonClick(ConfirmDialog dialog) { cleanAdministrativeUnitButtonClicked(currentConcept, currentUser); } }; } public void cleanAdministrativeUnitButtonClicked(RecordVO currentConcept, User currentUser) { if(hasCurrentUserRequiredRightsToCleanAdminUnitChilds(currentUser, currentConcept)) { RMRecordDeletionServices.cleanAdministrativeUnit(collection, currentConcept.getId(), appLayerFactory); } } private boolean hasCurrentUserRequiredRightsToCleanAdminUnitChilds(User currentUser, RecordVO currentConcept) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); SearchServices searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); AdministrativeUnit administrativeUnit = rm.wrapAdministrativeUnit(searchServices. searchSingleResult(from(rm.administrativeUnit.schema()).where(Schemas.IDENTIFIER) .isEqualTo(currentConcept.getId()))); boolean hasAllRights = hasCurrentUserDeletionRightsToCleanTasks(administrativeUnit, currentUser); if (hasAllRights) { hasAllRights = hasCurrentUserDeletionRightsToCleanFolders(administrativeUnit, currentUser); } if (hasAllRights) { hasAllRights = hasCurrentUserDeletionRightsToCleanContainers(administrativeUnit, currentUser); } return hasAllRights; } private boolean hasCurrentUserDeletionRightsToCleanFolders(AdministrativeUnit administrativeUnit, User currentUser) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); SearchServices searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); TasksSchemasRecordsServices taskSchemas = new TasksSchemasRecordsServices(collection, appLayerFactory); SearchResponseIterator<Record> documentIterator = searchServices .recordsIterator(new LogicalSearchQuery().setCondition(from(rm.document.schema()) .where(Schemas.PRINCIPAL_PATH).isContainingText(administrativeUnit.getId())) .sortDesc(Schemas.PRINCIPAL_PATH)); SearchResponseIterator<Record> folderIterator = searchServices .recordsIterator(new LogicalSearchQuery().setCondition(from(rm.folder.schema()) .where(Schemas.PRINCIPAL_PATH).isContainingText(administrativeUnit.getId())) .sortDesc(Schemas.PRINCIPAL_PATH)); List<Record> taskList = searchServices.search(new LogicalSearchQuery().setCondition(from(taskSchemas.userTask.schema()) .where(Schemas.PRINCIPAL_PATH).isNot(containingText(administrativeUnit.getId()))) .sortDesc(Schemas.PRINCIPAL_PATH)); while (documentIterator.hasNext()) { Record document = documentIterator.next(); if (!hasCurrentUserWriteRightsToUnlinkDocumentFromDecommissioningLists(document, currentUser)) { return false; } if (!hasCurrentUserWriteRightsToUnlinkDocumentFromTask(document, taskList, currentUser)) { return false; } if (!currentUser.hasDeleteAccess().on(document)) { return false; } } while (folderIterator.hasNext()) { Record folder = folderIterator.next(); if (!hasCurrentUserWriteRightsToUnlinkFolderFromDecommissioningLists(folder, currentUser)) { return false; } if (!hasCurrentUserWriteRightsToUnlinkFolderFromTask(folder, taskList, currentUser)) { return false; } if (!currentUser.hasDeleteAccess().on(folder)) { return false; } } return true; } private boolean hasCurrentUserDeletionRightsToCleanContainers(AdministrativeUnit administrativeUnit, User currentUser) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); SearchServices searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); SearchResponseIterator<Record> containerIterator = searchServices .recordsIterator(new LogicalSearchQuery().setCondition(from(rm.containerRecord.schema()) .where(Schemas.PRINCIPAL_PATH).isContainingText(administrativeUnit.getId())) .sortDesc(Schemas.PRINCIPAL_PATH)); while (containerIterator.hasNext()) { Record container = containerIterator.next(); if (!hasCurrentUserWriteRightsToUnlinkContainerFromDecommissioningLists(container, currentUser)) { return false; } if (!currentUser.hasDeleteAccess().on(container)) { return false; } } return true; } private boolean hasCurrentUserDeletionRightsToCleanTasks(AdministrativeUnit administrativeUnit, User currentUser) { SearchServices searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); TasksSchemasRecordsServices schemas = new TasksSchemasRecordsServices(collection, appLayerFactory); LogicalSearchQuery query = new LogicalSearchQuery().setCondition(from(schemas.userTask.schema()) .where(Schemas.PRINCIPAL_PATH).isContainingText(administrativeUnit.getId())).sortDesc(Schemas.PRINCIPAL_PATH); SearchResponseIterator<Record> userTaskIterator = searchServices.recordsIterator(query); while (userTaskIterator.hasNext()) { Record userTask = userTaskIterator.next(); if (!currentUser.hasDeleteAccess().on(userTask)) { return false; } } return true; } private boolean hasCurrentUserWriteRightsToUnlinkDocumentFromDecommissioningLists(Record document, User currentUser) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); List<DecommissioningList> decommissioningLists = rm.searchDecommissioningLists( where(rm.decommissioningList.documents()).isContaining(asList(document.getId()))); for (DecommissioningList decommissioningList : decommissioningLists) { if (!currentUser.hasWriteAccess().on(decommissioningList)) { return false; } } return true; } private boolean hasCurrentUserWriteRightsToUnlinkFolderFromDecommissioningLists(Record folder, User currentUser) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); List<DecommissioningList> decommissioningLists = rm.searchDecommissioningLists( where(rm.decommissioningList.folders()).isContaining(asList(folder.getId()))); for (DecommissioningList decommissioningList : decommissioningLists) { if (!currentUser.hasWriteAccess().on(decommissioningList)) { return false; } } return true; } private boolean hasCurrentUserWriteRightsToUnlinkContainerFromDecommissioningLists(Record container, User currentUser) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); List<DecommissioningList> decommissioningLists = rm.searchDecommissioningLists( where(rm.decommissioningList.containers()).isContaining(asList(container.getId()))); for (DecommissioningList decommissioningList : decommissioningLists) { if (!currentUser.hasWriteAccess().on(decommissioningList)) { return false; } } return true; } private boolean hasCurrentUserWriteRightsToUnlinkDocumentFromTask(Record document, List<Record> taskList, User currentUser) { for (Record task : taskList) { MetadataSchema curTaskSchema = appLayerFactory.getModelLayerFactory().getMetadataSchemasManager() .getSchemaTypes(collection).getSchema(task.getSchemaCode()); List<String> linkedDocumentsIDs = task.get(curTaskSchema.getMetadata(RMTask.LINKED_DOCUMENTS)); linkedDocumentsIDs = new ArrayList<>(linkedDocumentsIDs); if (linkedDocumentsIDs.contains(document.getId())) { if (!currentUser.hasWriteAccess().on(task)) { return false; } } } return true; } private boolean hasCurrentUserWriteRightsToUnlinkFolderFromTask(Record folder, List<Record> taskList, User currentUser) { for (Record task : taskList) { MetadataSchema curTaskSchema = appLayerFactory.getModelLayerFactory().getMetadataSchemasManager() .getSchemaTypes(collection).getSchema(task.getSchemaCode()); List<String> linkedDocumentsIDs = task.get(curTaskSchema.getMetadata(RMTask.LINKED_DOCUMENTS)); linkedDocumentsIDs = new ArrayList<>(linkedDocumentsIDs); if (linkedDocumentsIDs.contains(folder.getId())) { if (!currentUser.hasWriteAccess().on(task)) { return false; } } } return true; } private User getCurrentUser(BaseView view) { BasePresenterUtils basePresenterUtils = new BasePresenterUtils(view.getConstellioFactories(), view.getSessionContext()); return basePresenterUtils.getCurrentUser(); } }