package com.constellio.app.modules.rm.migrations; import static com.constellio.data.utils.LangUtils.withoutDuplicates; import static com.constellio.data.utils.LangUtils.withoutDuplicatesAndNulls; import static com.constellio.model.entities.security.global.AuthorizationAddRequest.authorizationInCollection; import static com.constellio.model.entities.security.global.AuthorizationDeleteRequest.authorizationDeleteRequest; import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from; import static java.util.Arrays.asList; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import com.constellio.app.entities.modules.MetadataSchemasAlterationHelper; import com.constellio.app.entities.modules.MigrationResourcesProvider; import com.constellio.app.entities.modules.MigrationScript; import com.constellio.app.entities.schemasDisplay.enums.MetadataInputType; import com.constellio.app.modules.rm.RMEmailTemplateConstants; import com.constellio.app.modules.rm.navigation.RMNavigationConfiguration; import com.constellio.app.modules.rm.constants.RMRoles; import com.constellio.app.modules.rm.model.calculators.AdministrativeUnitAncestorsCalculator; import com.constellio.app.modules.rm.model.calculators.FolderCopyStatusCalculator2; import com.constellio.app.modules.rm.model.calculators.decommissioningList.DecomListStatusCalculator2; import com.constellio.app.modules.rm.model.calculators.decommissioningList.PendingValidationCalculator; import com.constellio.app.modules.rm.services.RMSchemasRecordsServices; import com.constellio.app.modules.rm.services.borrowingServices.BorrowingType; import com.constellio.app.modules.rm.wrappers.AdministrativeUnit; import com.constellio.app.modules.rm.wrappers.ContainerRecord; import com.constellio.app.modules.rm.wrappers.DecommissioningList; import com.constellio.app.modules.rm.wrappers.Document; import com.constellio.app.modules.rm.wrappers.FilingSpace; import com.constellio.app.modules.rm.wrappers.Folder; import com.constellio.app.modules.rm.wrappers.RMTask; import com.constellio.app.modules.rm.wrappers.RetentionRule; import com.constellio.app.modules.rm.wrappers.structures.DecomListValidationFactory; import com.constellio.app.modules.tasks.TaskModule; import com.constellio.app.modules.tasks.model.wrappers.Task; import com.constellio.app.services.factories.AppLayerFactory; import com.constellio.app.services.schemasDisplay.SchemaTypesDisplayTransactionBuilder; import com.constellio.app.services.schemasDisplay.SchemasDisplayManager; import com.constellio.data.dao.dto.records.OptimisticLockingResolution; import com.constellio.data.dao.managers.config.ConfigManagerException; import com.constellio.data.dao.services.idGenerator.UniqueIdGenerator; import com.constellio.model.entities.CorePermissions; 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.MetadataSchemaTypes; import com.constellio.model.entities.schemas.MetadataValueType; import com.constellio.model.entities.schemas.Schemas; import com.constellio.model.entities.security.Authorization; import com.constellio.model.entities.security.Role; import com.constellio.model.services.batch.manager.BatchProcessesManager; import com.constellio.model.services.collections.CollectionsListManager; import com.constellio.model.services.extensions.ConstellioModulesManager; import com.constellio.model.services.factories.ModelLayerFactory; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.records.RecordServicesException; import com.constellio.model.services.records.reindexing.ReindexationMode; import com.constellio.model.services.records.reindexing.ReindexingServices; import com.constellio.model.services.schemas.builders.MetadataBuilder; import com.constellio.model.services.schemas.builders.MetadataSchemaBuilder; import com.constellio.model.services.schemas.builders.MetadataSchemaTypeBuilder; import com.constellio.model.services.schemas.builders.MetadataSchemaTypesBuilder; import com.constellio.model.services.search.SearchServices; import com.constellio.model.services.search.query.logical.LogicalSearchQuery; import com.constellio.model.services.search.query.logical.condition.LogicalSearchCondition; import com.constellio.model.services.security.AuthorizationsServices; import com.constellio.model.services.security.AuthorizationsServicesRuntimeException.NoSuchAuthorizationWithId; public class RMMigrationTo5_0_7 implements MigrationScript { public static final String RECENT_FOLDERS = "F"; public static final String RECENT_DOCUMENTS = "D"; public static final String CHECKED_OUT_DOCUMENTS = "C"; public static final String TAXONOMIES = "T"; @Override public String getVersion() { return "5.0.7"; } @Override public void migrate(String collection, MigrationResourcesProvider migrationResourcesProvider, AppLayerFactory appLayerFactory) throws Exception { MetadataSchema taskSchema = appLayerFactory.getModelLayerFactory().getMetadataSchemasManager().getSchemaTypes(collection) .getSchemaType(Task.SCHEMA_TYPE).getDefaultSchema(); if (!taskSchema.hasMetadataWithCode(RMTask.LINKED_DOCUMENTS)) { new SchemaAlterationFor5_0_7(collection, migrationResourcesProvider, appLayerFactory).migrate(); } updateFormAndDisplayConfigs(collection, appLayerFactory, migrationResourcesProvider); setupRoles(collection, appLayerFactory.getModelLayerFactory()); updateUserProfiles(collection, appLayerFactory.getModelLayerFactory()); try { new FilingSpaceMigration(collection, appLayerFactory).run(); } catch (Exception e) { throw new RuntimeException(e); } appLayerFactory.getModelLayerFactory().getBatchProcessesManager().waitUntilAllFinished(); addEmailTemplates(appLayerFactory, migrationResourcesProvider, collection); setupRMFacets(appLayerFactory, migrationResourcesProvider, collection); } private void setupRMFacets(AppLayerFactory appLayerFactory, MigrationResourcesProvider migrationResourcesProvider, String collection) throws RecordServicesException { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, appLayerFactory); RecordServices recordServices = rm.getModelLayerFactory().newRecordServices(); Transaction transaction = new Transaction(); transaction.add(rm.newFacetField().setOrder(2).setFieldDataStoreCode("administrativeUnitId_s") .setTitle(migrationResourcesProvider.get("init.facet.administrativeUnit"))); transaction.add(rm.newFacetField().setOrder(2).setFieldDataStoreCode("categoryId_s") .setTitle(migrationResourcesProvider.get("init.facet.category"))); transaction.add(rm.newFacetField().setOrder(2).setFieldDataStoreCode("archivisticStatus_s") .setTitle(migrationResourcesProvider.get("init.facet.archivisticStatus"))); transaction.add(rm.newFacetField().setOrder(3).setFieldDataStoreCode("copyStatus_s") .setTitle(migrationResourcesProvider.get("init.facet.copyStatus"))); recordServices.execute(transaction); } private void enableTaskModule(String collection, AppLayerFactory appLayerFactory) { TaskModule taskModule = new TaskModule(); CollectionsListManager collectionsListManager = appLayerFactory.getModelLayerFactory().getCollectionsListManager(); ConstellioModulesManager modulesManager = appLayerFactory.getModulesManager(); if (!modulesManager.isInstalled(taskModule)) { modulesManager.installValidModuleAndGetInvalidOnes(taskModule, collectionsListManager); } if (!modulesManager.isModuleEnabled(collection, taskModule)) { modulesManager.enableValidModuleAndGetInvalidOnes(collection, taskModule); } } private void addEmailTemplates(AppLayerFactory appLayerFactory, MigrationResourcesProvider migrationResourcesProvider, String collection) { addEmailTemplate(appLayerFactory, migrationResourcesProvider, collection, "remindReturnBorrowedFolderTemplate.html", RMEmailTemplateConstants.REMIND_BORROW_TEMPLATE_ID); addEmailTemplate(appLayerFactory, migrationResourcesProvider, collection, "approvalRequestForDecomListTemplate.html", RMEmailTemplateConstants.APPROVAL_REQUEST_TEMPLATE_ID); addEmailTemplate(appLayerFactory, migrationResourcesProvider, collection, "validationRequestForDecomListTemplate.html", RMEmailTemplateConstants.VALIDATION_REQUEST_TEMPLATE_ID); addEmailTemplate(appLayerFactory, migrationResourcesProvider, collection, "alertAvailableTemplate.html", RMEmailTemplateConstants.ALERT_AVAILABLE_ID); } private void addEmailTemplate(AppLayerFactory appLayerFactory, MigrationResourcesProvider migrationResourcesProvider, String collection, String templateFileName, String templateId) { InputStream remindReturnBorrowedFolderTemplate = migrationResourcesProvider.getStream(templateFileName); try { appLayerFactory.getModelLayerFactory().getEmailTemplatesManager() .addCollectionTemplateIfInexistent(templateId, collection, remindReturnBorrowedFolderTemplate); } catch (IOException e) { throw new RuntimeException(e); } catch (ConfigManagerException.OptimisticLockingConfiguration optimisticLockingConfiguration) { throw new RuntimeException(optimisticLockingConfiguration); } finally { IOUtils.closeQuietly(remindReturnBorrowedFolderTemplate); } } private void updateFormAndDisplayConfigs(String collection, AppLayerFactory appLayerFactory, MigrationResourcesProvider migrationResourcesProvider) { SchemasDisplayManager manager = appLayerFactory.getMetadataSchemasDisplayManager(); SchemaTypesDisplayTransactionBuilder transactionBuilder = manager.newTransactionBuilderFor(collection); transactionBuilder.in(Folder.SCHEMA_TYPE) .addToDisplay(Folder.BORROWING_TYPE) .beforeMetadata(Folder.LINEAR_SIZE); transactionBuilder .in(Task.SCHEMA_TYPE) .addToForm(RMTask.LINKED_DOCUMENTS, RMTask.LINKED_FOLDERS) .atTheEnd(); transactionBuilder .in(Task.SCHEMA_TYPE) .addToDisplay(RMTask.ADMINISTRATIVE_UNIT, RMTask.LINKED_DOCUMENTS, RMTask.LINKED_FOLDERS) .beforeTheHugeCommentMetadata(); manager.saveMetadata(manager.getMetadata(collection, ContainerRecord.DEFAULT_SCHEMA, ContainerRecord.STORAGE_SPACE) .withInputType(MetadataInputType.LOOKUP)); String detailsTab = migrationResourcesProvider.getDefaultLanguageString("init.userTask.details"); manager.saveMetadata(manager.getMetadata(collection, RMTask.DEFAULT_SCHEMA, RMTask.LINKED_FOLDERS) .withMetadataGroup(detailsTab)); manager.saveMetadata(manager.getMetadata(collection, RMTask.DEFAULT_SCHEMA, RMTask.LINKED_DOCUMENTS) .withMetadataGroup(detailsTab)); transactionBuilder.in(RetentionRule.SCHEMA_TYPE) .addToSearchResult(RetentionRule.CODE) .beforeMetadata(RetentionRule.TITLE); manager.execute(transactionBuilder.build()); } /** * * - Add default role to users * - Migrate default tab * */ private void updateUserProfiles(String collection, ModelLayerFactory modelLayerFactory) { RMSchemasRecordsServices rm = new RMSchemasRecordsServices(collection, modelLayerFactory); SearchServices searchServices = modelLayerFactory.newSearchServices(); MetadataSchema user = rm.userSchema(); Metadata startTab = user.getMetadata(User.START_TAB); Metadata userRoles = user.getMetadata(User.ROLES); Transaction transaction = new Transaction().setOptimisticLockingResolution(OptimisticLockingResolution.EXCEPTION); LogicalSearchQuery query = new LogicalSearchQuery(from(user).where(startTab).isNotNull().orWhere(userRoles).isNull()); for (Record record : searchServices.search(query)) { String startTabValue = record.get(startTab); if (startTabValue != null) { switch (startTabValue) { case RECENT_FOLDERS: transaction.add(record.set(startTab, RMNavigationConfiguration.LAST_VIEWED_FOLDERS)); break; case RECENT_DOCUMENTS: transaction.add(record.set(startTab, RMNavigationConfiguration.LAST_VIEWED_DOCUMENTS)); break; case CHECKED_OUT_DOCUMENTS: transaction.add(record.set(startTab, RMNavigationConfiguration.CHECKED_OUT_DOCUMENTS)); break; case TAXONOMIES: transaction.add(record.set(startTab, RMNavigationConfiguration.TAXONOMIES)); break; } } if (record.getList(userRoles).isEmpty()) { record.set(userRoles, asList(RMRoles.USER)); } } try { modelLayerFactory.newRecordServices().execute(transaction); } catch (RecordServicesException e) { throw new RuntimeException(e); } } class SchemaAlterationFor5_0_7 extends MetadataSchemasAlterationHelper { MetadataSchemaTypes types; protected SchemaAlterationFor5_0_7(String collection, MigrationResourcesProvider migrationResourcesProvider, AppLayerFactory appLayerFactory) { super(collection, migrationResourcesProvider, appLayerFactory); types = appLayerFactory.getModelLayerFactory().getMetadataSchemasManager().getSchemaTypes(collection); } public String getVersion() { return "5.0.7"; } @Override protected void migrate(MetadataSchemaTypesBuilder typesBuilder) { MetadataSchemaTypeBuilder adminUnitSchemaType = typesBuilder.getSchemaType(AdministrativeUnit.SCHEMA_TYPE); MetadataSchemaTypeBuilder folderSchemaType = typesBuilder.getSchemaType(Folder.SCHEMA_TYPE); MetadataSchemaTypeBuilder documentSchemaType = typesBuilder.getSchemaType(Document.SCHEMA_TYPE); //Folder MetadataSchemaBuilder adminUnitSchema = typesBuilder.getSchema(AdministrativeUnit.DEFAULT_SCHEMA); MetadataSchemaBuilder folderSchema = typesBuilder.getSchema(Folder.DEFAULT_SCHEMA); MetadataBuilder folderAdministrativeUnit = folderSchema.get(Folder.ADMINISTRATIVE_UNIT); folderSchema.createUndeletable( Folder.BORROWING_TYPE).defineAsEnum(BorrowingType.class); folderSchema.get(Folder.FILING_SPACE).setEssential(false).setDefaultRequirement(false); folderSchema.get(Folder.FILING_SPACE_ENTERED).setEssential(false).setDefaultRequirement(false); for (MetadataSchemaBuilder aFolderSchema : typesBuilder.getSchemaType(Folder.SCHEMA_TYPE).getAllSchemas()) { aFolderSchema.get(Folder.FILING_SPACE_ENTERED).setEnabled(false); } MetadataBuilder administrativeUnitAncestors = adminUnitSchema.createUndeletable(AdministrativeUnit.ANCESTORS) .setType(MetadataValueType.REFERENCE).setMultivalue(true) .defineReferencesTo(typesBuilder.getSchemaType(AdministrativeUnit.SCHEMA_TYPE)) .defineDataEntry().asCalculated(AdministrativeUnitAncestorsCalculator.class); folderSchema.createUndeletable(Folder.ADMINISTRATIVE_UNIT_ANCESTORS) .setType(MetadataValueType.REFERENCE).setMultivalue(true).setEssential(true) .defineReferencesTo(typesBuilder.getSchemaType(AdministrativeUnit.SCHEMA_TYPE)) .defineDataEntry().asCopied(folderAdministrativeUnit, administrativeUnitAncestors); folderSchema.get(Folder.COPY_STATUS).defineDataEntry().asCalculated(FolderCopyStatusCalculator2.class); folderSchema.createUndeletable(Folder.ALERT_USERS_WHEN_AVAILABLE) .setType(MetadataValueType.REFERENCE) .setMultivalue(true) .defineReferencesTo(typesBuilder.getSchemaType(User.SCHEMA_TYPE)); folderSchema.get(Folder.BORROW_USER_ENTERED).setSystemReserved(true); // DecommissioningList MetadataSchemaBuilder userSchema = typesBuilder.getSchema(User.DEFAULT_SCHEMA); MetadataSchemaBuilder decommissioningSchema = typesBuilder.getSchema(DecommissioningList.DEFAULT_SCHEMA); decommissioningSchema.createUndeletable(DecommissioningList.VALIDATIONS).setType(MetadataValueType.STRUCTURE) .defineStructureFactory(DecomListValidationFactory.class).setMultivalue(true); decommissioningSchema.createUndeletable(DecommissioningList.PENDING_VALIDATIONS) .defineReferencesTo(userSchema).setMultivalue(true) .defineDataEntry().asCalculated(PendingValidationCalculator.class); decommissioningSchema.get(DecommissioningList.STATUS) .defineDataEntry().asCalculated(DecomListStatusCalculator2.class); decommissioningSchema.get(DecommissioningList.VALIDATION_DATE).setEssential(false).setEnabled(false); decommissioningSchema.get(DecommissioningList.VALIDATION_USER).setEssential(false).setEnabled(false); //Document MetadataSchemaBuilder documentSchema = typesBuilder.getSchema(Document.DEFAULT_SCHEMA); documentSchema.createUndeletable(Document.ALERT_USERS_WHEN_AVAILABLE) .setType(MetadataValueType.REFERENCE) .setMultivalue(true) .defineReferencesTo(typesBuilder.getSchemaType(User.SCHEMA_TYPE)); //Task MetadataSchemaBuilder taskSchema = typesBuilder.getSchema(Task.DEFAULT_SCHEMA); taskSchema.create(RMTask.ADMINISTRATIVE_UNIT).defineTaxonomyRelationshipToType(adminUnitSchemaType); taskSchema.create(RMTask.LINKED_FOLDERS).defineReferencesTo(folderSchemaType).setMultivalue(true); taskSchema.create(RMTask.LINKED_DOCUMENTS).defineReferencesTo(documentSchemaType).setMultivalue(true); } } private void setupRoles(String collection, ModelLayerFactory modelLayerFactory) { Role rgdRole = modelLayerFactory.getRolesManager().getRole(collection, RMRoles.RGD); Set<String> newRgdPermissions = new HashSet<>(rgdRole.getOperationPermissions()); newRgdPermissions.add(CorePermissions.MANAGE_FACETS); newRgdPermissions.add(CorePermissions.MANAGE_SEARCH_REPORTS); newRgdPermissions.add(CorePermissions.MANAGE_EMAIL_SERVER); modelLayerFactory.getRolesManager().updateRole( rgdRole.withPermissions(withoutDuplicates(new ArrayList<String>(newRgdPermissions)))); } private static class FilingSpaceMigration { private String collection; private RMSchemasRecordsServices rm; private SearchServices searchServices; private RecordServices recordServices; private AuthorizationsServices authorizationsServices; private Map<ReplacedFilingSpaceKey, String> replacedFilingSpaceMap; private MetadataSchemaTypes types; private BatchProcessesManager batchProcessesManager; private ReindexingServices reindexingServices; private FilingSpaceMigration(String collection, AppLayerFactory appLayerFactory) { this.rm = new RMSchemasRecordsServices(collection, appLayerFactory); this.searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); this.recordServices = appLayerFactory.getModelLayerFactory().newRecordServices(); this.authorizationsServices = appLayerFactory.getModelLayerFactory().newAuthorizationsServices(); this.collection = collection; this.replacedFilingSpaceMap = new HashMap<>(); this.types = appLayerFactory.getModelLayerFactory().getMetadataSchemasManager().getSchemaTypes(collection); this.batchProcessesManager = appLayerFactory.getModelLayerFactory().getBatchProcessesManager(); this.reindexingServices = appLayerFactory.getModelLayerFactory().newReindexingServices(); } private List<Record> search(LogicalSearchCondition condition) { return searchServices.search(new LogicalSearchQuery(condition)); } public void run() throws Exception { Transaction transaction = new Transaction() .setSkippingRequiredValuesValidation(true) .setOptimisticLockingResolution(OptimisticLockingResolution.EXCEPTION) .setSkippingReferenceToLogicallyDeletedValidation(true); createNewAdministrativeUnit(transaction); moveContainersInNewAdministrativeUnits(transaction); moveDecommissioningListInNewAdministrativeUnits(transaction); removeFilingSpacesInAdministrativeUnits(transaction); recordServices.executeHandlingImpactsAsync(transaction); batchProcessesManager.waitUntilAllFinished(); moveFoldersToNewAdministrativeUnits(); boolean hasAdministrativeUnits = searchServices.hasResults(from(rm.administrativeUnit.schemaType()).returnAll()); if (hasAdministrativeUnits) { reindexAll(); physicallyDeleteFilingSpaces(); } } private void reindexAll() { //Reindexation that was planned in 5.0.6 reindexingServices.reindexCollection(collection, ReindexationMode.RECALCULATE_AND_REWRITE); } private List<String> getUsersWithManagerOrRGDRole() { Metadata userRoles = rm.userSchema().get(User.ALL_ROLES); return searchServices.searchRecordIds(new LogicalSearchQuery() .setCondition(from(rm.userSchemaType()).where(userRoles).isIn(asList(RMRoles.MANAGER, RMRoles.RGD)))); } private void createAuthorizationsForFilingSpaceUsersAndAdministrators() { List<String> managersAndRGDs = getUsersWithManagerOrRGDRole(); for (FilingSpace filingSpace : wrapFilingSpaces(search(from(rm.filingSpaceSchemaType()).returnAll()))) { List<String> usersWithReadWrite = withoutDuplicatesAndNulls(filingSpace.getUsers()); List<String> usersWithReadWriteDelete = withoutDuplicatesAndNulls(filingSpace.getAdministrators()); List<String> managersInFilingSpace = new ArrayList<>(withoutDuplicatesAndNulls(filingSpace.getAdministrators())); managersInFilingSpace.removeAll(managersAndRGDs); UniqueIdGenerator uniqueIdGenerator = rm.getModelLayerFactory().getDataLayerFactory() .getSecondaryUniqueIdGenerator(); List<AdministrativeUnit> newUnits = rm.getAdministrativeUnits(getNewUnits(filingSpace.getId())); for (AdministrativeUnit newUnit : newUnits) { addAuthorizationOn(newUnit, usersWithReadWrite, asList(Role.READ, Role.WRITE), uniqueIdGenerator); addAuthorizationOn(newUnit, usersWithReadWriteDelete, asList(Role.READ, Role.WRITE, Role.DELETE), uniqueIdGenerator); addAuthorizationOn(newUnit, managersInFilingSpace, asList(RMRoles.MANAGER), uniqueIdGenerator); } } } private List<FilingSpace> wrapFilingSpaces(List<Record> records) { List<FilingSpace> filingSpaces = new ArrayList<>(); for (Record record : records) { filingSpaces.add(new FilingSpace(record, types)); } return filingSpaces; } private void addAuthorizationOn(AdministrativeUnit newUnit, List<String> users, List<String> roles, UniqueIdGenerator uniqueIdGenerator) { /*if (!users.isEmpty()) { authorizationsServices.add(authorizationInCollection(collection) .giving(roles).forPrincipalsIds(users).on(newUnit)); }*/ } private void physicallyDeleteFilingSpaces() { for (FilingSpace filingSpace : wrapFilingSpaces(search(from(rm.filingSpaceSchemaType()).returnAll()))) { if (Boolean.TRUE.equals(filingSpace.getWrappedRecord().get(Schemas.LOGICALLY_DELETED_STATUS))) { for (AdministrativeUnit newUnit : rm.getAdministrativeUnits(getNewUnits(filingSpace.getId()))) { recordServices.logicallyDelete(newUnit.getWrappedRecord(), User.GOD); } } else { recordServices.logicallyDelete(filingSpace.getWrappedRecord(), User.GOD); } recordServices.physicallyDelete(filingSpace.getWrappedRecord(), User.GOD); } } private void moveFoldersToNewAdministrativeUnits() throws RecordServicesException { Metadata folderFilingspaceEntered = rm.folder.schema().getMetadata(Folder.FILING_SPACE_ENTERED); Iterator<List<Record>> recordsBatchIterator = searchServices.recordsBatchIterator(new LogicalSearchQuery() .setCondition(from(rm.folder.schemaType()).where(folderFilingspaceEntered).isNotNull())); while (recordsBatchIterator.hasNext()) { List<Folder> folders = rm.wrapFolders(recordsBatchIterator.next()); for (Folder folder : folders) { String unit = getNewUnit(folder.getAdministrativeUnitEntered(), folder.getFilingSpaceEntered()); folder.setAdministrativeUnitEntered(unit).setFilingSpaceEntered((String) null); } recordServices.executeHandlingImpactsAsync( Transaction.wrappers(folders).setSkippingRequiredValuesValidation(true)); } batchProcessesManager.waitUntilAllFinished(); } private String getNewUnit(String unitId, String filingSpaceId) { String newUnit = replacedFilingSpaceMap.get( new ReplacedFilingSpaceKey(unitId, filingSpaceId)); return newUnit == null ? unitId : newUnit; } private List<String> getNewUnits(String filingSpaceId) { List<String> newUnits = new ArrayList<>(); for (Map.Entry<ReplacedFilingSpaceKey, String> entry : replacedFilingSpaceMap.entrySet()) { if (filingSpaceId.equals(entry.getKey().filingSpaceId)) { newUnits.add(entry.getValue()); } } return newUnits; } private void moveContainersInNewAdministrativeUnits(Transaction transaction) { for (ContainerRecord container : rm.wrapContainerRecords(search(from(rm.containerRecord.schemaType()).returnAll()))) { String unit = getNewUnit(container.getAdministrativeUnit(), container.getFilingSpace()); transaction.add(container.setFilingSpace((String) null).setAdministrativeUnit(unit)); } } private void moveDecommissioningListInNewAdministrativeUnits(Transaction transaction) { for (DecommissioningList decomList : rm.wrapDecommissioningLists(search( from(rm.decommissioningList.schemaType()).returnAll()))) { String unit = getNewUnit(decomList.getAdministrativeUnit(), decomList.getFilingSpace()); transaction.add(decomList.setFilingSpace((String) null).setAdministrativeUnit(unit)); } } private void removeFilingSpacesInAdministrativeUnits(Transaction transaction) { for (AdministrativeUnit administrativeUnit : rm.wrapAdministrativeUnits( search(from(rm.administrativeUnit.schemaType()).returnAll()))) { if (!administrativeUnit.getFilingSpaces().isEmpty()) { transaction.add(administrativeUnit.setFilingSpaces(new ArrayList<FilingSpace>())); } } } private void createNewAdministrativeUnit(Transaction transaction) { for (FilingSpace filingSpace : wrapFilingSpaces(search(from(rm.filingSpaceSchemaType()).returnAll()))) { List<AdministrativeUnit> units = rm.wrapAdministrativeUnits(search(from(rm.administrativeUnit.schemaType()) .where(rm.administrativeUnit.filingSpaces()).isEqualTo(filingSpace))); for (AdministrativeUnit unit : units) { ReplacedFilingSpaceKey key = new ReplacedFilingSpaceKey(unit.getId(), filingSpace.getId()); AdministrativeUnit newAdministrativeUnit = transaction.add(rm.newAdministrativeUnit()); newAdministrativeUnit.setParent(unit); newAdministrativeUnit.setCode(getNewUnitCode(filingSpace.getCode(), unit.getCode(), units.size() > 1)); newAdministrativeUnit.setTitle(filingSpace.getTitle()); newAdministrativeUnit.setDescription(filingSpace.getDescription()); replacedFilingSpaceMap.put(key, newAdministrativeUnit.getId()); } if (units.isEmpty()) { ReplacedFilingSpaceKey key = new ReplacedFilingSpaceKey(null, filingSpace.getId()); AdministrativeUnit newAdministrativeUnit = transaction.add(rm.newAdministrativeUnit()); newAdministrativeUnit.setCode(toUniqueCode(filingSpace.getCode())); newAdministrativeUnit.setTitle(filingSpace.getTitle()); newAdministrativeUnit.setDescription(filingSpace.getDescription()); replacedFilingSpaceMap.put(key, newAdministrativeUnit.getId()); } } } private String toUniqueCode(String code) { if (rm.getAdministrativeUnitWithCode(code) != null) { return toUniqueCode(code + " (2)"); } return code; } String getNewUnitCode(String filingSpaceCode, String unitCode, boolean multipleUnits) { if (multipleUnits || rm.getAdministrativeUnitWithCode(filingSpaceCode) != null) { return toUniqueCode(unitCode + "-" + filingSpaceCode); } else { return filingSpaceCode; } } } private static class ReplacedFilingSpaceKey { private String unitId; private String filingSpaceId; private ReplacedFilingSpaceKey(String unitId, String filingSpaceId) { this.unitId = unitId; this.filingSpaceId = filingSpaceId; } @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } @Override public boolean equals(Object obj) { return EqualsBuilder.reflectionEquals(this, obj); } } }