package com.constellio.dev;
import com.constellio.app.modules.rm.services.RMSchemasRecordsServices;
import com.constellio.app.modules.rm.wrappers.Document;
import com.constellio.app.modules.rm.wrappers.type.DocumentType;
import com.constellio.app.services.factories.AppLayerFactory;
import com.constellio.data.dao.dto.records.OptimisticLockingResolution;
import com.constellio.model.entities.records.ActionExecutorInBatch;
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.services.factories.ModelLayerFactory;
import com.constellio.model.services.records.RecordServices;
import com.constellio.model.services.records.RecordServicesException;
import com.constellio.model.services.records.extractions.RecordPopulateServices;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators;
import com.constellio.model.services.search.query.logical.condition.LogicalSearchCondition;
import com.constellio.sdk.SDKScriptUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from;
import static org.assertj.core.api.Assertions.assertThat;
public class DeleteAllDocumentTypesScript {
private static Logger LOG = Logger.getLogger(DeleteAllDocumentTypesScript.class);
static int BATCH_SIZE = 5000;
static String currentCollection;
static AppLayerFactory appLayerFactory;
static ModelLayerFactory modelLayerFactory;
static SearchServices searchServices;
static RecordServices recordServices;
static RMSchemasRecordsServices rm;
private static LogicalSearchQuery documentTypesQuery;
private static void startBackend() {
//TODO
//Only enable this line to run in production
//appLayerFactory = startLayerFactoriesWithoutBackgroundThreads();
//Only enable this line to run on developer workstation
appLayerFactory = SDKScriptUtils.startApplicationWithoutBackgroundProcessesAndAuthentication();
}
private static LogicalSearchQuery getQuery(MetadataSchema metadataSchema) {
//TODO Build a query to find records to modify or to return all records
//return new LogicalSearchQuery(from(rm.folderSchemaType())
// .where(rm.containerAdministrativeUnit()).isEqualTo("42"));
final Metadata documentTypeMetadata = metadataSchema.getMetadata("type");
LogicalSearchCondition condition = LogicalSearchQueryOperators.from(metadataSchema).whereAllConditions(
LogicalSearchQueryOperators.where(documentTypeMetadata).isNotNull(),
LogicalSearchQueryOperators.where(documentTypeMetadata).isNotEqual("__NULL__"));
return new LogicalSearchQuery(from(rm.documentSchemaType()).where(condition));
}
public static LogicalSearchQuery getDocumentTypesQuery() {
final Metadata documentTypeMetadata = rm.documentTypeSchema().getMetadata("code");
LogicalSearchCondition condition = LogicalSearchQueryOperators
.from(rm.documentTypeSchema())
.whereAllConditions(
LogicalSearchQueryOperators.where(documentTypeMetadata).isNotNull(),
LogicalSearchQueryOperators.where(documentTypeMetadata).isNotEqual("__NULL__"));
return new LogicalSearchQuery(from(rm.documentTypeSchema()).where(condition));
}
private static void runScriptForCurrentCollection() throws Exception {
// Delete all document type references from documents
deleteDocumentsDocumentTypeReferences();
//computeAdminId();
// Delete documentTypes logically
deleteDocumentTypes();
}
private static void initDocumentTypeCodes(File file) {
documentTypeCodes = new ArrayList<>();
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
String line = "";
while (StringUtils.isNotBlank(line = bufferedReader.readLine())) {
if (StringUtils.isNotBlank(line)) {
documentTypeCodes.add(line.trim());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void deleteDocumentTypes() throws Exception {
new ActionExecutorInBatch(searchServices, "The name of the task", BATCH_SIZE) {
@Override
public void doActionOnBatch(List<Record> records) {
//TODO Wrap the records
List<DocumentType> documentTypes = rm.wrapDocumentTypes(records);
User adminUser = getAdminUser();
int index = 0;
for (DocumentType document : documentTypes) {
if(documentTypeCodes.contains(document.getCode())){
try {
recordServices.logicallyDelete(records.get(index), adminUser);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
index++;
}
}
}.execute(getDocumentTypesQuery());
}
private static User getAdminUser() {
LogicalSearchCondition condition = LogicalSearchQueryOperators
.from(rm.userSchema())
.whereAllConditions(
LogicalSearchQueryOperators.where(rm.userUsername()).isNotNull(),
LogicalSearchQueryOperators.where(rm.userUsername()).is("admin"));
LogicalSearchQuery query = new LogicalSearchQuery(condition);
List<Record> userRecords = searchServices.search(query);
assertThat(userRecords).isNotEmpty().hasSize(1);
List<User> users = rm.wrapUsers(userRecords);
return users.get(0);
}
private static void deleteDocumentsDocumentTypeReferences() throws Exception {
for (MetadataSchema metadataSchema : rm.documentSchemaType().getAllSchemas()) {
System.out.println("metadataSchema: " + metadataSchema.getCode());
new ActionExecutorInBatch(searchServices, "The name of the task", BATCH_SIZE) {
@Override
public void doActionOnBatch(List<Record> records) {
//TODO Wrap the records
List<Document> documents = rm.wrapDocuments(records);
Transaction transaction = new Transaction();
transaction.setSkippingRequiredValuesValidation(true);
transaction.setOptimisticLockingResolution(OptimisticLockingResolution.EXCEPTION);
for (Document document : documents) {
System.out.println(document.getId() + ":" + document.getTitle());
//TODO Do the modification on a record
Boolean isBorrowed = document.getBorrowed();
document.setBorrowed(false);
String metadataStringValue = document.get("type");
try {
System.out.println("value: " + metadataStringValue);
document.set("type", null);
} catch (Exception e) {
LOG.error("Identififiant document: " + document.getId() + "; valeur: " +
metadataStringValue, e);
e.printStackTrace();
}
if(isBorrowed != null) {
document.setBorrowed(isBorrowed.booleanValue());
}
transaction.add(document);
}
try {
recordServices.execute(transaction);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
}.execute(getQuery(metadataSchema));
}
}
private static List<String> documentTypeCodes;
public static void main(String argv[]) throws Exception {
if(argv.length < 1) {
System.out.println("Sample call 'sudo java -Xmx5120m -classpath ./classes:./lib/* com.constellio.dev.DeleteAllDocumentTypesScript <document_types_codes_file>'");
}
File file = new File(argv[0]);
assertThat(file).exists();
initDocumentTypeCodes(file);
RecordPopulateServices.LOG_CONTENT_MISSING = false;
startBackend();
modelLayerFactory = appLayerFactory.getModelLayerFactory();
searchServices = modelLayerFactory.newSearchServices();
recordServices = modelLayerFactory.newRecordServices();
for (String collection : modelLayerFactory.getCollectionsListManager().getCollections()) {
currentCollection = collection;
rm = new RMSchemasRecordsServices(collection, appLayerFactory);
runScriptForCurrentCollection();
}
}
}