package com.constellio.app.ui.framework.data; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.constellio.app.ui.framework.data.trees.RecordTreeNodesDataProvider; import com.constellio.app.ui.util.FileIconUtils; import com.constellio.app.ui.util.SchemaCaptionUtils; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.schemas.Schemas; import com.constellio.model.services.schemas.SchemaUtils; import com.constellio.model.services.taxonomies.FastContinueInfos; import com.constellio.model.services.taxonomies.LinkableTaxonomySearchResponse; import com.constellio.model.services.taxonomies.TaxonomySearchRecord; import com.vaadin.server.Resource; public class BaseRecordTreeDataProvider extends AbstractDataProvider implements LazyTreeDataProvider<String> { private static final Logger LOGGER = LoggerFactory.getLogger(BaseRecordTreeDataProvider.class); private int estimatedRootNodesCount = -1; private Map<String, String> parentCache = new HashMap<>(); private Map<String, RecordDataTreeNode> nodesCache = new HashMap<>(); RecordTreeNodesDataProvider nodesDataProvider; private Map<String, FastContinueInfos> fastContinueInfosMap = new HashMap<>(); public BaseRecordTreeDataProvider(RecordTreeNodesDataProvider recordTreeNodesDataProvider) { this.nodesDataProvider = recordTreeNodesDataProvider; } @Override public final String getTaxonomyCode() { return nodesDataProvider.getTaxonomyCode(); } public final RecordDataTreeNode getNode(String id) { return nodesCache.get(id); } @Override public final String getCaption(String id) { RecordDataTreeNode treeNode = getNode(id); return treeNode == null ? "" : treeNode.getCaption(); } @Override public final String getDescription(String id) { RecordDataTreeNode treeNode = getNode(id); return treeNode == null ? null : treeNode.getDescription(); } @Override public final Resource getIcon(String id, boolean expanded) { RecordDataTreeNode treeNode = getNode(id); return treeNode == null ? null : treeNode.getIcon(expanded); } @Override public final ObjectsResponse<String> getRootObjects(int start, int maxSize) { FastContinueInfos infos = fastContinueInfosMap.get("root-" + start); LinkableTaxonomySearchResponse response = nodesDataProvider.getRootNodes(start, maxSize, infos); List<String> recordIds = new ArrayList<>(); for (TaxonomySearchRecord searchRecord : response.getRecords()) { saveResultInCache(searchRecord); recordIds.add(searchRecord.getId()); } LOGGER.info("getRoot(" + start + ", " + maxSize + ") => " + recordIds); estimatedRootNodesCount = Math.max(estimatedRootNodesCount, (int) response.getNumFound()); int end = start + maxSize; FastContinueInfos responseFastContinueInfos = response.getFastContinueInfos(); if (responseFastContinueInfos != null) { fastContinueInfosMap.put("root-" + end, responseFastContinueInfos); } return new ObjectsResponse<>(recordIds, response.getNumFound()); } @Override public final String getParent(String child) { return parentCache.get(child); } @Override public final ObjectsResponse<String> getChildren(String parent, int start, int maxSize) { FastContinueInfos infos = fastContinueInfosMap.get(parent + "-" + start); LinkableTaxonomySearchResponse response = nodesDataProvider.getChildrenNodes(parent, start, maxSize, infos); List<String> recordIds = new ArrayList<>(); for (TaxonomySearchRecord searchRecord : response.getRecords()) { saveResultInCache(searchRecord); recordIds.add(searchRecord.getId()); parentCache.put(searchRecord.getId(), parent); } LOGGER.info("getChildren(" + parent + ", " + start + ", " + maxSize + ") => " + recordIds); RecordDataTreeNode parentTreeNode = nodesCache.get(parent); // FIXME Francis if (parentTreeNode != null) { parentTreeNode.estimatedChildrenCount = Math.max(parentTreeNode.estimatedChildrenCount, (int) response.getNumFound()); } int end = start + maxSize; FastContinueInfos responseFastContinueInfos = response.getFastContinueInfos(); if (responseFastContinueInfos != null) { fastContinueInfosMap.put(parent + "-" + end, responseFastContinueInfos); } return new ObjectsResponse<>(recordIds, response.getNumFound()); } @Override public final boolean hasChildren(String parent) { return getNode(parent).hasChildren(); } @Override public final boolean isLeaf(String parent) { return !getNode(parent).hasChildren(); } @Override public final int getEstimatedRootNodesCount() { return estimatedRootNodesCount; } @Override public final int getEstimatedChildrenNodesCount(String parent) { RecordDataTreeNode treeNode = getNode(parent); return treeNode == null ? -1 : treeNode.estimatedChildrenCount; } protected RecordDataTreeNode toTreeNode(TaxonomySearchRecord searchRecord) { Record record = searchRecord.getRecord(); String schemaType = new SchemaUtils().getSchemaTypeCode(record.getSchemaCode()); String caption = getCaptionOf(record); String description = record.get(Schemas.DESCRIPTION_STRING); if (description == null) { description = record.get(Schemas.DESCRIPTION_TEXT); } Resource collapsedIcon = getCollapsedIconOf(record); Resource expandedIcon = getExpandedIconOf(record); return new RecordDataTreeNode(searchRecord.getId(), caption, description, schemaType, collapsedIcon, expandedIcon, searchRecord.hasChildren()); } protected String getCaptionOf(Record record) { return SchemaCaptionUtils.getCaptionForRecord(record); } protected Resource getExpandedIconOf(Record record) { return FileIconUtils.getIconForRecordId(record, true); } protected Resource getCollapsedIconOf(Record record) { return FileIconUtils.getIconForRecordId(record, false); } protected void saveResultInCache(TaxonomySearchRecord searchRecord) { RecordDataTreeNode treeNode = toTreeNode(searchRecord); nodesCache.put(searchRecord.getId(), treeNode); } }