package com.constellio.app.modules.rm.services; 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.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.records.RecordPhysicalDeleteOptions; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.records.RecordServicesException; import com.constellio.model.services.search.SearchServices; import com.constellio.model.services.search.query.logical.LogicalSearchQuery; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.*; import static java.util.Arrays.asList; /** * Created by Constelio on 2016-10-31. */ public class RMRecordDeletionServices { private static final Logger LOGGER = LoggerFactory.getLogger(RMRecordDeletionServices.class); static public void cleanAllAdministrativeUnits(String collection, AppLayerFactory appLayerFactory) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); List<AdministrativeUnit> administrativeUnitList = rm.searchAdministrativeUnits(ALL); for (AdministrativeUnit administrativeUnit : administrativeUnitList) { cleanAdministrativeUnit(collection, administrativeUnit, appLayerFactory); } } static public void cleanAdministrativeUnit(String collection, AdministrativeUnit administrativeUnit, AppLayerFactory appLayerFactory) { cleanTaskInAdministrativeUnitRecursively(collection, administrativeUnit, appLayerFactory); cleanFoldersInAdministrativeUnitRecursively(collection, administrativeUnit, appLayerFactory); cleanContainersInAdministrativeUnitRecursively(collection, administrativeUnit, appLayerFactory); cleanDecommissioningListInAdministrativeUnit(collection, administrativeUnit, appLayerFactory); } static public void cleanAdministrativeUnit(String collection, String administrativeUnitID, AppLayerFactory appLayerFactory) { 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(administrativeUnitID))); cleanAdministrativeUnit(collection, administrativeUnit, appLayerFactory); } static private void cleanFoldersInAdministrativeUnitRecursively(String collection, AdministrativeUnit administrativeUnit, AppLayerFactory appLayerFactory) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); SearchServices searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); 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)); Set<String> recordIDs = new HashSet<>(); while (documentIterator.hasNext()) { Record document = documentIterator.next(); unlinkDocumentFromDecommissioningLists(document, collection, appLayerFactory); unlinkDocumentFromTasks(document, taskList, collection, appLayerFactory); if(recordIDs.add(document.getId())) { try { recordServices.physicallyDeleteNoMatterTheStatus(document, User.GOD, new RecordPhysicalDeleteOptions()); } catch (Exception e) { LOGGER.info("Could not delete document " + document.getId()); } } } while (folderIterator.hasNext()) { Record folder = folderIterator.next(); unlinkFolderFromDecommissioningLists(folder, collection, appLayerFactory); unlinkFolderFromTasks(folder, taskList, collection, appLayerFactory); if(recordIDs.add(folder.getId())) { try { recordServices.physicallyDeleteNoMatterTheStatus(folder, User.GOD, new RecordPhysicalDeleteOptions()); } catch (Exception e) { LOGGER.info("Could not delete folder " + folder.getId()); } } } } static private void cleanContainersInAdministrativeUnitRecursively(String collection, AdministrativeUnit administrativeUnit, AppLayerFactory appLayerFactory) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); SearchServices searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); SearchResponseIterator<Record> containerIterator = searchServices.recordsIterator(new LogicalSearchQuery().setCondition(from(rm.containerRecord.schema()) .where(Schemas.PRINCIPAL_PATH).isContainingText(administrativeUnit.getId())).sortDesc(Schemas.PRINCIPAL_PATH)); Set<String> recordIDs = new HashSet<>(); while(containerIterator.hasNext()) { Record container = containerIterator.next(); unlinkContainerFromDecommissioningLists(container, collection, appLayerFactory); if(recordIDs.add(container.getId())) { try { recordServices.physicallyDeleteNoMatterTheStatus(container, User.GOD, new RecordPhysicalDeleteOptions()); } catch (Exception e) { LOGGER.info("Could not delete container " + container.getId()); } } } } static private void cleanTaskInAdministrativeUnitRecursively(String collection, AdministrativeUnit administrativeUnit, AppLayerFactory appLayerFactory) { SearchServices searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); 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); Set<String> recordIDs = new HashSet<>(); while(userTaskIterator.hasNext()) { Record userTask = userTaskIterator.next(); if(recordIDs.add(userTask.getId())) { try { recordServices.physicallyDeleteNoMatterTheStatus(userTask, User.GOD, new RecordPhysicalDeleteOptions()); } catch (Exception e) { LOGGER.info("Could not delete task " + userTask.getId()); } } } } static private void cleanDecommissioningListInAdministrativeUnit(String collection, AdministrativeUnit administrativeUnit, AppLayerFactory appLayerFactory) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); SearchServices searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); LogicalSearchQuery query = new LogicalSearchQuery().setCondition(from(rm.decommissioningList.schemaType()) .where(rm.decommissioningList.administrativeUnit()).isEqualTo(administrativeUnit.getId())); SearchResponseIterator<Record> decommissioningListIterator = searchServices.recordsIterator(query); Set<String> recordIDs = new HashSet<>(); while(decommissioningListIterator.hasNext()) { Record decommissioningList = decommissioningListIterator.next(); if(recordIDs.add(decommissioningList.getId())) { try { recordServices.physicallyDeleteNoMatterTheStatus(decommissioningList, User.GOD, new RecordPhysicalDeleteOptions()); } catch (Exception e) { LOGGER.info("Could not delete decommissioningList " + decommissioningList.getId()); } } } } static private void unlinkDocumentFromDecommissioningLists(Record document, String collection, AppLayerFactory appLayerFactory) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); List<DecommissioningList> decommissioningLists = rm.searchDecommissioningLists( where(rm.decommissioningList.documents()).isContaining(asList(document.getId()))); for(DecommissioningList decommissioningList: decommissioningLists) { ArrayList<String> decommissioningListDocuments = new ArrayList<>(decommissioningList.getDocuments()); decommissioningListDocuments.remove(document.getId()); decommissioningList.setDocuments(decommissioningListDocuments); try { recordServices.update(decommissioningList.getWrappedRecord()); } catch (RecordServicesException e) { LOGGER.info("Could not unlink document from decommissioningList"); } } } static private void unlinkFolderFromDecommissioningLists(Record folder, String collection, AppLayerFactory appLayerFactory) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); List<DecommissioningList> decommissioningLists = rm.searchDecommissioningLists( where(rm.decommissioningList.folders()).isContaining(asList(folder.getId()))); for(DecommissioningList decommissioningList: decommissioningLists) { decommissioningList.removeFolderDetail(folder.getId()); try { recordServices.update(decommissioningList.getWrappedRecord()); } catch (RecordServicesException e) { LOGGER.info("Could not unlink folder from decommissioningList"); } } } static private void unlinkContainerFromDecommissioningLists(Record container, String collection, AppLayerFactory appLayerFactory) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); List<DecommissioningList> decommissioningLists = rm.searchDecommissioningLists( where(rm.decommissioningList.containers()).isContaining(asList(container.getId()))); for(DecommissioningList decommissioningList: decommissioningLists) { decommissioningList.removeContainerDetail(container.getId()); try { recordServices.update(decommissioningList.getWrappedRecord()); } catch (RecordServicesException e) { LOGGER.info("Could not unlink container from decommissioningList"); } } } static private void unlinkDocumentFromTasks(Record document, List<Record> taskList, String collection, AppLayerFactory appLayerFactory) { RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); 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())) { linkedDocumentsIDs.remove(document.getId()); task.set(curTaskSchema.getMetadata(RMTask.LINKED_DOCUMENTS), linkedDocumentsIDs); try { recordServices.update(task); } catch (RecordServicesException e) { LOGGER.info("Could not unlink document from task"); } } } } static private void unlinkFolderFromTasks(Record folder, List<Record> taskList, String collection, AppLayerFactory appLayerFactory) { RecordServices recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); 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())) { linkedDocumentsIDs.remove(folder.getId()); task.set(curTaskSchema.getMetadata(RMTask.LINKED_DOCUMENTS), linkedDocumentsIDs); try { recordServices.update(task); } catch (RecordServicesException e) { LOGGER.info("Could not unlink folder from task"); } } } } }