package com.constellio.model.services.schemas.validators;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.constellio.model.entities.Language;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.schemas.Metadata;
import com.constellio.model.entities.schemas.MetadataSchemaTypes;
import com.constellio.model.entities.schemas.Schemas;
import com.constellio.model.frameworks.validation.ValidationErrors;
import com.constellio.model.frameworks.validation.Validator;
import com.constellio.model.services.schemas.SchemaUtils;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.StatusFilter;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.model.services.search.query.logical.condition.LogicalSearchCondition;
public class MetadataUniqueValidator implements Validator<Record> {
public static final String NON_UNIQUE_METADATA = "nonUniqueMetadata";
public static final String METADATA_LABEL = "metadataLabel";
public static final String VALUE = "value";
private final List<Metadata> metadatas;
private final SearchServices searchServices;
private final MetadataSchemaTypes schemaTypes;
public MetadataUniqueValidator(List<Metadata> metadatas, MetadataSchemaTypes schemaTypes, SearchServices searchServices) {
this.metadatas = metadatas;
this.searchServices = searchServices;
this.schemaTypes = schemaTypes;
}
@SuppressWarnings("rawtypes")
@Override
public void validate(Record record, ValidationErrors validationErrors) {
if (!record.isActive()) {
return;
}
for (Metadata metadata : metadatas) {
if (metadata.isUniqueValue() && record.isModified(metadata)) {
Object value = record.get(metadata);
if (value != null) {
String schemaCode = new SchemaUtils().getSchemaCode(metadata.getCode());
LogicalSearchCondition condition = from(schemaTypes.getSchema(schemaCode)).where(metadata)
.isEqualTo(value).andWhere(Schemas.IDENTIFIER).isNotEqual(record.getId());
if (searchServices.hasResults(new LogicalSearchQuery(condition).filteredByStatus(StatusFilter.ACTIVES))) {
addValidationErrors(validationErrors, value.toString(), NON_UNIQUE_METADATA, metadata);
}
}
}
}
}
private void addValidationErrors(ValidationErrors validationErrors, String value, String errorCode, Metadata metadata) {
Map<String, Object> parameters = new HashMap<>();
parameters.put(METADATA_CODE, metadata.getCode());
parameters.put(METADATA_LABEL,metadata.getLabelsByLanguageCodes());
parameters.put(VALUE, value);
validationErrors.add(getClass(), errorCode, parameters);
}
}