package com.constellio.model.extensions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.constellio.data.frameworks.extensions.ExtensionBooleanResult;
import com.constellio.data.frameworks.extensions.ExtensionUtils.BooleanCaller;
import com.constellio.data.frameworks.extensions.VaultBehaviorsList;
import com.constellio.data.utils.KeyListMap;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.RecordUpdateOptions;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.extensions.behaviors.RecordExtension;
import com.constellio.model.extensions.behaviors.RecordExtension.IsRecordModifiableByParams;
import com.constellio.model.extensions.behaviors.RecordImportExtension;
import com.constellio.model.extensions.behaviors.SchemaExtension;
import com.constellio.model.extensions.events.records.RecordCreationEvent;
import com.constellio.model.extensions.events.records.RecordInCreationBeforeSaveEvent;
import com.constellio.model.extensions.events.records.RecordInCreationBeforeValidationAndAutomaticValuesCalculationEvent;
import com.constellio.model.extensions.events.records.RecordInModificationBeforeSaveEvent;
import com.constellio.model.extensions.events.records.RecordInModificationBeforeValidationAndAutomaticValuesCalculationEvent;
import com.constellio.model.extensions.events.records.RecordLogicalDeletionEvent;
import com.constellio.model.extensions.events.records.RecordLogicalDeletionValidationEvent;
import com.constellio.model.extensions.events.records.RecordModificationEvent;
import com.constellio.model.extensions.events.records.RecordPhysicalDeletionEvent;
import com.constellio.model.extensions.events.records.RecordPhysicalDeletionValidationEvent;
import com.constellio.model.extensions.events.records.RecordRestorationEvent;
import com.constellio.model.extensions.events.records.RecordSetCategoryEvent;
import com.constellio.model.extensions.events.records.TransactionExecutionBeforeSaveEvent;
import com.constellio.model.extensions.events.recordsImport.BuildParams;
import com.constellio.model.extensions.events.recordsImport.PrevalidationParams;
import com.constellio.model.extensions.events.recordsImport.ValidationParams;
import com.constellio.model.extensions.events.schemas.SchemaEvent;
public class ModelLayerCollectionExtensions {
private static final Logger LOGGER = LoggerFactory.getLogger(ModelLayerCollectionExtensions.class);
//------------ Extension points -----------
public VaultBehaviorsList<RecordImportExtension> recordImportExtensions = new VaultBehaviorsList<>();
public VaultBehaviorsList<RecordExtension> recordExtensions = new VaultBehaviorsList<>();
public VaultBehaviorsList<SchemaExtension> schemaExtensions = new VaultBehaviorsList<>();
//----------------- Callers ---------------
public void callSetRecordCategory(RecordSetCategoryEvent event) {
for (RecordExtension extension : recordExtensions) {
extension.setRecordCategory(event);
}
}
public void callRecordImportBuild(String schemaType, BuildParams params) {
for (RecordImportExtension extension : recordImportExtensions) {
if (extension.getDecoratedSchemaType().equals(schemaType)) {
extension.build(params);
}
}
}
public void callRecordImportValidate(String schemaType, ValidationParams params) {
for (RecordImportExtension extension : recordImportExtensions) {
if (extension.getDecoratedSchemaType().equals(schemaType)) {
extension.validate(params);
}
}
}
public void callRecordImportPrevalidate(String schemaType, PrevalidationParams params) {
for (RecordImportExtension extension : recordImportExtensions) {
if (extension.getDecoratedSchemaType().equals(schemaType)) {
extension.prevalidate(params);
}
}
}
public void callTransactionExecutionBeforeSave(TransactionExecutionBeforeSaveEvent event, RecordUpdateOptions options) {
for (RecordExtension extension : recordExtensions) {
try {
extension.transactionExecutionBeforeSave(event);
} catch (RuntimeException e) {
if (options.isCatchExtensionsExceptions()) {
LOGGER.warn("Exception while calling extension of class '" + extension.getClass().getName()
+ "' on transaction ", e);
} else {
throw e;
}
}
}
}
public void callRecordInCreationBeforeSave(RecordInCreationBeforeSaveEvent event, RecordUpdateOptions options) {
for (RecordExtension extension : recordExtensions) {
try {
extension.recordInCreationBeforeSave(event);
} catch (RuntimeException e) {
handleException(e, event.getRecord().getId(), extension.getClass().getName(), options);
}
}
}
public void callRecordInModificationBeforeSave(RecordInModificationBeforeSaveEvent event, RecordUpdateOptions options) {
for (RecordExtension extension : recordExtensions) {
try {
extension.recordInModificationBeforeSave(event);
} catch (RuntimeException e) {
handleException(e, event.getRecord().getId(), extension.getClass().getName(), options);
}
}
}
public void callRecordInCreationBeforeValidationAndAutomaticValuesCalculation(
RecordInCreationBeforeValidationAndAutomaticValuesCalculationEvent event, RecordUpdateOptions options) {
for (RecordExtension extension : recordExtensions) {
try {
extension.recordInCreationBeforeValidationAndAutomaticValuesCalculation(event);
} catch (RuntimeException e) {
handleException(e, event.getRecord().getId(), extension.getClass().getName(), options);
}
}
}
public static void handleException(RuntimeException e, String recordId, String extensionClassname,
RecordUpdateOptions options) {
//if (e instanceof ValidationRuntimeException) {
// if (options.isCatchExtensionsValidationsErrors()) {
// LOGGER.warn("Exception while calling extension of class '" + extensionClassname + "' on record " + recordId, e);
// } else {
// throw e;
// }
//} else {
if (options.isCatchExtensionsExceptions()) {
LOGGER.warn("Exception while calling extension of class '" + extensionClassname + "' on record " + recordId, e);
} else {
throw e;
}
//}
}
public void callRecordInModificationBeforeValidationAndAutomaticValuesCalculation(
RecordInModificationBeforeValidationAndAutomaticValuesCalculationEvent event, RecordUpdateOptions options) {
for (RecordExtension extension : recordExtensions) {
try {
extension.recordInModificationBeforeValidationAndAutomaticValuesCalculation(event);
} catch (RuntimeException e) {
handleException(e, event.getRecord().getId(), extension.getClass().getName(), options);
}
}
}
public void callRecordCreated(RecordCreationEvent event, RecordUpdateOptions options) {
for (RecordExtension extension : recordExtensions) {
try {
extension.recordCreated(event);
} catch (RuntimeException e) {
handleException(e, event.getRecord().getId(), extension.getClass().getName(), options);
}
}
}
public void callRecordModified(RecordModificationEvent event, RecordUpdateOptions options) {
for (RecordExtension extension : recordExtensions) {
try {
extension.recordModified(event);
} catch (RuntimeException e) {
handleException(e, event.getRecord().getId(), extension.getClass().getName(), options);
}
}
}
public void callRecordLogicallyDeleted(RecordLogicalDeletionEvent event) {
for (RecordExtension extension : recordExtensions) {
extension.recordLogicallyDeleted(event);
}
}
public void callRecordPhysicallyDeleted(RecordPhysicalDeletionEvent event) {
for (RecordExtension extension : recordExtensions) {
extension.recordPhysicallyDeleted(event);
}
}
public void callRecordRestored(RecordRestorationEvent event) {
for (RecordExtension extension : recordExtensions) {
extension.recordRestored(event);
}
}
public boolean isLogicallyDeletable(final RecordLogicalDeletionValidationEvent event) {
return recordExtensions.getBooleanValue(true, new BooleanCaller<RecordExtension>() {
@Override
public ExtensionBooleanResult call(RecordExtension behavior) {
return behavior.isLogicallyDeletable(event);
}
});
}
public boolean isPhysicallyDeletable(final RecordPhysicalDeletionValidationEvent event) {
return recordExtensions.getBooleanValue(true, new BooleanCaller<RecordExtension>() {
@Override
public ExtensionBooleanResult call(RecordExtension behavior) {
return behavior.isPhysicallyDeletable(event);
}
});
}
public boolean isPutInTrashBeforePhysicalDelete(final SchemaEvent event) {
Boolean inTrashFirst = schemaExtensions.getBooleanValue(null, new BooleanCaller<SchemaExtension>() {
@Override
public ExtensionBooleanResult call(SchemaExtension behavior) {
return behavior.isPutInTrashBeforePhysicalDelete(event);
}
});
return (inTrashFirst == null) ? false : inTrashFirst;
}
@Deprecated
//Use tokens instead
public boolean isRecordModifiableBy(final Record record, final User user) {
return recordExtensions.getBooleanValue(true, new BooleanCaller<RecordExtension>() {
@Override
public ExtensionBooleanResult call(RecordExtension behavior) {
return behavior.isRecordModifiableBy(new IsRecordModifiableByParams(record, user));
}
});
}
}