package com.constellio.model.services.records.populators; import com.constellio.data.utils.KeyListMap; import com.constellio.model.conf.FoldersLocator; import com.constellio.model.conf.FoldersLocatorMode; import com.constellio.model.entities.records.Content; import com.constellio.model.entities.records.ContentVersion; import com.constellio.model.entities.records.ParsedContent; import com.constellio.model.entities.records.Record; 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.services.contents.ContentManagerRuntimeException.ContentManagerRuntimeException_NoSuchContent; import com.constellio.model.services.contents.ParsedContentProvider; import com.constellio.model.services.records.FieldsPopulator; import com.constellio.model.services.records.RecordUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; public class SearchFieldsPopulator extends SeparatedFieldsPopulator implements FieldsPopulator { private static final Logger LOGGER = LoggerFactory.getLogger(SearchFieldsPopulator.class); //LanguageDetectionManager languageDectionServices; ParsedContentProvider parsedContentProvider; List<String> collectionLanguages; public SearchFieldsPopulator(MetadataSchemaTypes types, boolean fullRewrite, ParsedContentProvider parsedContentProvider, List<String> collectionLanguages) { super(types, fullRewrite); // this.languageDectionServices = languageDectionServices; this.parsedContentProvider = parsedContentProvider; this.collectionLanguages = collectionLanguages; } @Override public Map<String, Object> populateCopyfields(MetadataSchema schema, Record record) { Map<String, Object> fields = super.populateCopyfields(schema, record); Metadata idMetadata = schema.getMetadata("id"); if (idMetadata.isSearchable()) { String id = record.getId(); String idWithoutZeros = RecordUtils.removeZerosInId(id); List<String> searchableValues = new ArrayList<>(); searchableValues.add(id); if (!idWithoutZeros.equals(id)) { searchableValues.add(idWithoutZeros); } for (String collectionLanguage : collectionLanguages) { fields.put("id_txt_" + collectionLanguage, searchableValues); } } return fields; } @Override public Map<String, Object> populateCopyfields(Metadata metadata, Object value) { if (metadata.isSearchable() && !"id".equals(metadata.getLocalCode())) { String dataStoreCode = metadata.getDataStoreCode(); String copiedMetadataCodePrefix; if (dataStoreCode.endsWith("_txt")) { copiedMetadataCodePrefix = dataStoreCode.replace("_txt", "_txt_"); } else { copiedMetadataCodePrefix = dataStoreCode.replace("_t", "_t_").replace("_ss", "_txt_").replace("_s", "_t_"); } if (metadata.isMultivalue() && metadata.getType().isStringOrText()) { List<String> values = asNotNullList(value); return populateCopyFieldsOfMultivalueSearchableTextMetadata(values, copiedMetadataCodePrefix); } else if (metadata.isMultivalue() && metadata.getType().equals(MetadataValueType.CONTENT)) { List<Content> values = asNotNullList(value); return populateCopyFieldsOfMultivalueSearchableContentMetadata(values, metadata.getLocalCode()); } else if (metadata.isMultivalue() && metadata.getType().equals(MetadataValueType.DATE)) { List<String> values = asNotNullList(value); return populateCopyFieldsOfMultivalueSearchableDateMetadata(values, metadata.getLocalCode()); } else if (metadata.isMultivalue() && metadata.getType().isIntegerOrFloatingPoint()) { List<String> values = asNotNullList(value); return populateCopyFieldsOfMultivalueSearchableNumberMetadata(values, metadata.getLocalCode()); } else if (!metadata.isMultivalue() && metadata.getType().isStringOrText()) { return populateCopyFieldsOfSinglevalueSearchableTextMetadata((String) value, copiedMetadataCodePrefix); } else if (!metadata.isMultivalue() && metadata.getType().equals(MetadataValueType.DATE)) { return populateCopyFieldsOfSinglevalueSearchableDateMetadata(value, copiedMetadataCodePrefix); } else if (!metadata.isMultivalue() && metadata.getType().isIntegerOrFloatingPoint()) { return populateCopyFieldsOfSinglevalueSearchableNumberMetadata("" + value, copiedMetadataCodePrefix); } else if (!metadata.isMultivalue() && metadata.getType().equals(MetadataValueType.CONTENT)) { return populateCopyFieldsOfSinglevalueSearchableContentMetadata((Content) value, metadata.getLocalCode()); } else { return Collections.emptyMap(); } } else { return Collections.emptyMap(); } } private void addFilenameAndParsedContent(ContentVersion currentVersion, KeyListMap<String, Object> keyListMap, String code) { try { ParsedContent parsedContent = parsedContentProvider.getParsedContentParsingIfNotYetDone(currentVersion.getHash()); String contentLanguage = null; if (collectionLanguages.size() == 1) { contentLanguage = collectionLanguages.get(0); } else if (parsedContent != null && collectionLanguages.contains(parsedContent.getLanguage())) { contentLanguage = parsedContent.getLanguage(); } if (parsedContent == null || contentLanguage == null) { for (String collectionLanguage : collectionLanguages) { keyListMap.add(code + "_" + collectionLanguage + "_ss", currentVersion.getFilename()); } } else { keyListMap.add(code + "_" + contentLanguage + "_ss", currentVersion.getFilename()); } if (parsedContent != null && contentLanguage != null) { keyListMap.add(code + "_txt_" + contentLanguage, parsedContent.getParsedContent()); } } catch (ContentManagerRuntimeException_NoSuchContent e) { if (new FoldersLocator().getFoldersLocatorMode() != FoldersLocatorMode.PROJECT) { LOGGER.warn("Parsed content of '" + currentVersion.getHash() + "' was not found in vault"); } } } private Map<String, Object> populateCopyFieldsOfSinglevalueSearchableContentMetadata(Content value, String copiedMetadataCode) { KeyListMap<String, Object> keyListMap = new KeyListMap<>(); if (value != null) { ContentVersion currentVersion = value.getCurrentVersion(); addFilenameAndParsedContent(currentVersion, keyListMap, copiedMetadataCode); } addEmptyValuesToOtherFields(copiedMetadataCode, keyListMap); return (Map) keyListMap.getNestedMap(); } private void addEmptyValuesToOtherFields(String copiedMetadataCode, KeyListMap<String, Object> keyListMap) { for (String collectionLanguage : collectionLanguages) { String fieldCode = copiedMetadataCode + "_txt_" + collectionLanguage; if (!keyListMap.getNestedMap().containsKey(fieldCode)) { keyListMap.add(fieldCode, ""); } fieldCode = copiedMetadataCode + "_" + collectionLanguage + "_ss"; if (!keyListMap.getNestedMap().containsKey(fieldCode)) { keyListMap.add(fieldCode, ""); } } } private Map<String, Object> populateCopyFieldsOfSinglevalueSearchableTextMetadata(String value, String copiedMetadataCodePrefix) { String valueLanguage = collectionLanguages.get(0); Map<String, Object> copyfields = new HashMap<>(); for (String collectionLanguage : collectionLanguages) { String fieldCode = copiedMetadataCodePrefix + collectionLanguage; if (collectionLanguage.equals(valueLanguage) && value != null) { copyfields.put(fieldCode, value); } else { copyfields.put(fieldCode, ""); } } return copyfields; } private Map<String, Object> populateCopyFieldsOfSinglevalueSearchableNumberMetadata(String value, String copiedMetadataCodePrefix) { String prefix = copiedMetadataCodePrefix; String valueLanguage = collectionLanguages.get(0); if(!prefix.endsWith("_")) { prefix += "_"; } int index = prefix.lastIndexOf("d_"); if(prefix.endsWith("d_")) { prefix = new StringBuilder(prefix).replace(index, index+2,"t_").toString(); } Map<String, Object> copyfields = new HashMap<>(); for (String collectionLanguage : collectionLanguages) { String fieldCode = prefix + collectionLanguage; if (collectionLanguage.equals(valueLanguage) && value != null && !"null".equals(value)) { copyfields.put(fieldCode, Double.parseDouble(value)); } else { copyfields.put(fieldCode, ""); } } return copyfields; } private Map<String, Object> populateCopyFieldsOfSinglevalueSearchableDateMetadata(Object value, String copiedMetadataCodePrefix) { String prefix = copiedMetadataCodePrefix; String valueLanguage = collectionLanguages.get(0); if(!prefix.endsWith("_")) { prefix += "_"; } int index = prefix.lastIndexOf("da_"); if(prefix.endsWith("da_")) { prefix = new StringBuilder(prefix).replace(index, index+3,"t_").toString(); } Map<String, Object> copyfields = new HashMap<>(); for (String collectionLanguage : collectionLanguages) { String fieldCode = prefix + collectionLanguage; if (collectionLanguage.equals(valueLanguage) && value != null) { copyfields.put(fieldCode, value); } else { copyfields.put(fieldCode, ""); } } return copyfields; } private Map<String, Object> populateCopyFieldsOfMultivalueSearchableDateMetadata(List<String> values, String copiedMetadataCodePrefix) { String prefix = copiedMetadataCodePrefix; String valueLanguage = collectionLanguages.get(0); if(!prefix.contains("_")) { prefix += "_txt_"; } if(!prefix.endsWith("_")) { prefix += "_"; } int index = prefix.lastIndexOf("da_"); if(prefix.endsWith("da_")) { prefix = new StringBuilder(prefix).replace(index, index+3,"txt_").toString(); } KeyListMap<String, Object> keyListMap = new KeyListMap<>(); for (Object value : values) { String language = collectionLanguages.get(0); if (language != null && collectionLanguages.contains(language)) { String fieldCode = prefix + language; keyListMap.add(fieldCode, value); } } for (String collectionLanguage : collectionLanguages) { String fieldCode = prefix + collectionLanguage; if (!keyListMap.getNestedMap().containsKey(fieldCode)) { keyListMap.add(fieldCode, ""); } } return (Map) keyListMap.getNestedMap(); } private Map<String, Object> populateCopyFieldsOfMultivalueSearchableNumberMetadata(List<String> values, String copiedMetadataCodePrefix) { String prefix = copiedMetadataCodePrefix; String valueLanguage = collectionLanguages.get(0); if(!prefix.contains("_")) { prefix += "_txt_"; } if(!prefix.endsWith("_")) { prefix += "_"; } int index = prefix.lastIndexOf("d_"); if(prefix.endsWith("d_")) { prefix = new StringBuilder(prefix).replace(index, index+2,"txt_").toString(); } KeyListMap<String, Object> keyListMap = new KeyListMap<>(); for (Object value : values) { String language = collectionLanguages.get(0); if (language != null && collectionLanguages.contains(language)) { String fieldCode = prefix + language; keyListMap.add(fieldCode, Double.parseDouble(String.valueOf(value))); } } for (String collectionLanguage : collectionLanguages) { String fieldCode = prefix + collectionLanguage; if (!keyListMap.getNestedMap().containsKey(fieldCode)) { keyListMap.add(fieldCode, ""); } } return (Map) keyListMap.getNestedMap(); } private Map<String, Object> populateCopyFieldsOfMultivalueSearchableTextMetadata(List<String> values, String copiedMetadataCodePrefix) { KeyListMap<String, Object> keyListMap = new KeyListMap<>(); for (String value : values) { String language = collectionLanguages.get(0); if (language != null && collectionLanguages.contains(language)) { String fieldCode = copiedMetadataCodePrefix + language; keyListMap.add(fieldCode, value); } } for (String collectionLanguage : collectionLanguages) { String fieldCode = copiedMetadataCodePrefix + collectionLanguage; if (!keyListMap.getNestedMap().containsKey(fieldCode)) { keyListMap.add(fieldCode, ""); } } return (Map) keyListMap.getNestedMap(); } private Map<String, Object> populateCopyFieldsOfMultivalueSearchableContentMetadata(List<Content> values, String copiedMetadataCode) { KeyListMap<String, Object> keyListMap = new KeyListMap<>(); for (Content value : values) { ContentVersion currentVersion = value.getCurrentVersion(); try { ParsedContent parsedContent = parsedContentProvider.getParsedContentParsingIfNotYetDone(currentVersion.getHash()); String contentLanguage = null; if (collectionLanguages.size() == 1) { contentLanguage = collectionLanguages.get(0); } else if (parsedContent != null && collectionLanguages.contains(parsedContent.getLanguage())) { contentLanguage = parsedContent.getLanguage(); } if (parsedContent == null || contentLanguage == null) { for (String collectionLanguage : collectionLanguages) { keyListMap.add(copiedMetadataCode + "_" + collectionLanguage + "_ss", currentVersion.getFilename()); } } else { keyListMap.add(copiedMetadataCode + "_" + contentLanguage + "_ss", currentVersion.getFilename()); } if (parsedContent != null && contentLanguage != null) { keyListMap.add(copiedMetadataCode + "_txt_" + contentLanguage, parsedContent.getParsedContent()); } } catch (ContentManagerRuntimeException_NoSuchContent e) { if (new FoldersLocator().getFoldersLocatorMode() != FoldersLocatorMode.PROJECT) { LOGGER.warn("Parsed content of '" + currentVersion.getHash() + "' was not found in vault"); } } } addEmptyValuesToOtherFields(copiedMetadataCode, keyListMap); return (Map) keyListMap.getNestedMap(); } private <T> List<T> asNotNullList(Object value) { if (value == null) { return Collections.emptyList(); } else { return (List) value; } } }