package com.constellio.app.modules.rm.reports.model.search; import static com.constellio.app.ui.i18n.i18n.$; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; import com.constellio.app.entities.schemasDisplay.MetadataDisplayConfig; import com.constellio.app.entities.schemasDisplay.enums.MetadataInputType; import com.constellio.app.services.factories.AppLayerFactory; import com.constellio.app.services.schemasDisplay.SchemasDisplayManager; import com.constellio.model.entities.Language; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.wrappers.Report; import com.constellio.model.entities.records.wrappers.structure.ReportedMetadata; import com.constellio.model.entities.schemas.Metadata; import com.constellio.model.entities.schemas.MetadataSchemaType; import com.constellio.model.entities.schemas.MetadataValueType; import com.constellio.model.entities.schemas.Schemas; import com.constellio.model.services.factories.ModelLayerFactory; import com.constellio.model.services.reports.ReportServices; import com.constellio.model.services.schemas.MetadataList; import com.constellio.model.services.schemas.MetadataSchemasManager; import com.constellio.model.services.search.SearchServices; import com.constellio.model.services.search.query.ReturnedMetadatasFilter; import com.constellio.model.services.search.query.logical.LogicalSearchQuery; import com.constellio.model.services.search.query.logical.condition.LogicalSearchCondition; public class SearchResultReportPresenter { static int LIMIT = 10000; static int BATCH_SIZE = 100; private final List<String> selectedRecords; private final String schemaTypeCode; private final String collection; private final String username; private final String reportTitle; private final LogicalSearchQuery searchQuery; private final AppLayerFactory appLayerFactory; private final Locale locale; public SearchResultReportPresenter(AppLayerFactory appLayerFactory, List<String> selectedRecords, String schemaType, String collection, String username, String reportTitle, LogicalSearchQuery searchQuery, Locale locale) { this.selectedRecords = selectedRecords; this.schemaTypeCode = schemaType; this.collection = collection; this.username = username; this.reportTitle = reportTitle; this.searchQuery = searchQuery; this.appLayerFactory = appLayerFactory; this.locale = locale; } public SearchResultReportModel buildModel(ModelLayerFactory modelLayerFactory) { SearchResultReportModel resultReportModel = new SearchResultReportModel(); List<Metadata> orderedEnabledReportedMetadataList = getEnabledReportedMetadataList(modelLayerFactory); for (Metadata metadata : orderedEnabledReportedMetadataList) { resultReportModel.addTitle(metadata.getLabel(Language.withCode(locale.getLanguage()))); } List<Record> records; if (selectedRecords == null || selectedRecords.isEmpty()) { records = new ArrayList<>(); int index = 0; boolean allRecordsAdded = false; while (!allRecordsAdded && records.size() < LIMIT) { List<Record> currentRecords = getAllSchemaTypeRecords(index, modelLayerFactory, orderedEnabledReportedMetadataList); records.addAll(currentRecords); index += currentRecords.size(); allRecordsAdded = (currentRecords.size() == 0) ? true : false; } } else { records = getAllSelectedRecordsFromIndex(modelLayerFactory, orderedEnabledReportedMetadataList); } for (Record record : records) { resultReportModel.addLine(getRecordLine(record, orderedEnabledReportedMetadataList)); } return resultReportModel; } private List<Record> getAllSelectedRecordsFromIndex(ModelLayerFactory modelLayerFactory, List<Metadata> orderedEnabledReportedMetadataList) { SearchServices searchServices = modelLayerFactory.newSearchServices(); LogicalSearchCondition newCondition = searchQuery.getCondition().andWhere(Schemas.IDENTIFIER).isIn(selectedRecords); LogicalSearchQuery newSearchQuery = searchQuery.setCondition(newCondition) .setReturnedMetadatas(ReturnedMetadatasFilter.onlyMetadatas(orderedEnabledReportedMetadataList)); return searchServices.query(newSearchQuery).getRecords(); } private List<Record> getAllSchemaTypeRecords(int index, ModelLayerFactory modelLayerFactory, List<Metadata> orderedEnabledReportedMetadataList) { SearchServices searchServices = modelLayerFactory.newSearchServices(); ReturnedMetadatasFilter returnMetadata = ReturnedMetadatasFilter.onlyMetadatas(orderedEnabledReportedMetadataList); LogicalSearchQuery newSearchQuery = searchQuery .setReturnedMetadatas(ReturnedMetadatasFilter.onlyMetadatas(orderedEnabledReportedMetadataList)) .setStartRow(index) .setNumberOfRows(BATCH_SIZE); return searchServices.query(new LogicalSearchQuery(newSearchQuery).setReturnedMetadatas(returnMetadata)).getRecords(); } private List<Object> getRecordLine(Record record, List<Metadata> orderedEnabledReportedMetadataList) { List<Object> returnList = new ArrayList<>(); for (Metadata metadata : orderedEnabledReportedMetadataList) { Object metadataValue = record.get(metadata); if (metadataValue == null) { returnList.add(null); } else { returnList.add(getConvertedValue(metadata, metadataValue)); } } return returnList; } private Object getConvertedValue(Metadata metadata, Object metadataValue) { if (metadata.isMultivalue()) { List<Object> items = (List) metadataValue; List<Object> convertedValue = new ArrayList<>(); for (Object item : items) { convertedValue.add(getConvertedScalarValue(metadata, item)); } if(convertedValue.isEmpty()) { return ""; } return convertedValue; } else { return getConvertedScalarValue(metadata, metadataValue); } } private Object getConvertedScalarValue(Metadata metadata, Object metadataValue) { if (metadata.getType() == MetadataValueType.REFERENCE) { String referenceId = (String) metadataValue; if (referenceId != null) { Record record = appLayerFactory.getModelLayerFactory().newRecordServices().getDocumentById(referenceId); String code = record.get(Schemas.CODE); String title = record.get(Schemas.TITLE); if (code == null || !metadata.isDefaultRequirement()) { return title; } else { return code + "-" + title; } } } else if(metadata.getType() == MetadataValueType.BOOLEAN) { return metadataValue.equals(true)? $("yes"):$("no"); } else if(metadata.getType() == MetadataValueType.TEXT) { SchemasDisplayManager schemasManager = appLayerFactory.getMetadataSchemasDisplayManager(); MetadataDisplayConfig config = schemasManager.getMetadata(collection, metadata.getCode()); if(config.getInputType().equals(MetadataInputType.RICHTEXT)) { String result = metadataValue.toString().replaceAll("<br>", "\n"); result = result.toString().replaceAll("<li>", "\n"); result = result.toString().replaceAll("\\<[^>]*>",""); return result; } } return metadataValue; } private List<ReportedMetadata> getReportedMetadataList(ReportServices reportServices) { Report report = reportServices.getUserReport(username, schemaTypeCode, reportTitle); if (report == null) { report = reportServices.getReport(schemaTypeCode, reportTitle); } if (report == null) { String username = null; if (this.username != null) { username = this.username; } throw new NoSuchReportRuntimeException(username, schemaTypeCode, reportTitle); } if (report.getLinesCount() != 1) { throw new UnsupportedReport(); } return report.getReportedMetadata(); } private List<Metadata> getEnabledReportedMetadataList(ModelLayerFactory modelLayerFactory) { ReportServices reportServices = new ReportServices(modelLayerFactory, collection); List<ReportedMetadata> reportedMetadataList = new ArrayList<>(getReportedMetadataList(reportServices)); orderByPosition(reportedMetadataList); List<Metadata> returnList = new ArrayList<>(); MetadataSchemasManager metadataSchemasManager = modelLayerFactory.getMetadataSchemasManager(); MetadataSchemaType schemaType = metadataSchemasManager.getSchemaTypes(collection).getSchemaType(schemaTypeCode); MetadataList allMetadata = schemaType.getAllMetadatas(); for (ReportedMetadata reportedMetadata : reportedMetadataList) { boolean found = false; for (Metadata metadata : allMetadata) { if (metadata.getLocalCode().equals(reportedMetadata.getMetadataLocaleCode())) { // if (metadata.isEnabled()) { returnList.add(metadata); // } found = true; break; } } if (!found) { throw new InExistingReportedMetadataRuntimeException(reportedMetadata, schemaTypeCode); } } return returnList; } private void orderByPosition(List<ReportedMetadata> reportedMetadataList) { Collections.sort(reportedMetadataList, new Comparator<ReportedMetadata>() { @Override public int compare(ReportedMetadata o1, ReportedMetadata o2) { return o1.getXPosition() - o2.getXPosition(); } }); } }