package com.constellio.app.ui.pages.management.facet; import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import com.constellio.app.ui.entities.MetadataSchemaVO; import com.constellio.app.ui.entities.MetadataVO; import com.constellio.app.ui.entities.RecordVO; import com.constellio.app.ui.entities.RecordVO.VIEW_MODE; import com.constellio.app.ui.framework.builders.MetadataSchemaToVOBuilder; import com.constellio.app.ui.framework.builders.RecordToVOBuilder; import com.constellio.app.ui.framework.data.RecordVODataProvider; import com.constellio.app.ui.pages.base.BasePresenter; import com.constellio.data.utils.ImpossibleRuntimeException; import com.constellio.model.entities.CorePermissions; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.Transaction; import com.constellio.model.entities.records.wrappers.Facet; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.records.wrappers.structure.FacetType; import com.constellio.model.entities.schemas.MetadataSchema; import com.constellio.model.entities.structures.MapStringStringStructure; import com.constellio.model.services.records.RecordServicesException; import com.constellio.model.services.search.query.logical.LogicalSearchQuery; import com.constellio.model.services.search.query.logical.ongoing.OngoingLogicalSearchConditionWithDataStoreFields; public class AddEditFacetConfigurationPresenter extends BasePresenter<AddEditFacetConfigurationView> { private RecordVO recordVO; private FacetType facetType; private String dataFieldCode; private FacetConfigurationPresenterService service; private boolean edit; private Map<Integer, Map<String, String>> values; public AddEditFacetConfigurationPresenter(AddEditFacetConfigurationView view) { super(view); init(); } public void forParams(String recordId, boolean edit) { if (recordId != null && !recordId.isEmpty() && edit) { this.recordVO = service.getVOForRecord(recordServices().getDocumentById(recordId)); this.facetType = recordVO.get(Facet.FACET_TYPE); this.dataFieldCode = recordVO.get(Facet.FIELD_DATA_STORE_CODE); } this.edit = edit; } private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); init(); } private void init() { service = new FacetConfigurationPresenterService(view.getConstellioFactories(), view.getSessionContext()); recordVO = service.getVOForType(FacetType.FIELD); facetType = FacetType.FIELD; values = new HashMap<>(); } public void setFacetType(FacetType type) { this.facetType = type; if (!edit) { recordVO = service.getVOForType(type); } } public FacetType getFacetType() { return facetType; } public void setDataFieldCode(String dataFieldCode) { this.dataFieldCode = dataFieldCode; } public String getDataFieldCode() { return dataFieldCode; } void reloadForm() { if (!edit) { RecordVO newRecordVO = service.getVOForType(facetType); view.getForm().commit(); for (MetadataVO metadataVO : recordVO.getMetadatas()) { if (recordVO.getMetadataValue(metadataVO) != null && recordVO.getMetadataValue(metadataVO).getValue() != null) { newRecordVO.set(metadataVO, recordVO.getMetadataValue(metadataVO).getValue()); } } recordVO = newRecordVO; view.getForm().reload(); } } public void reloadForm(String dataFieldCode) { this.dataFieldCode = dataFieldCode; reloadForm(); } public String getTypePostfix() { return facetType.getCode(); } @Override protected boolean hasPageAccess(String params, User user) { return user.has(CorePermissions.MANAGE_FACETS).globally(); } public Map<Integer, Map<String, String>> getValues() { return values; } public Map<String, String> getValueForFacet() { Map<String, String> values = new HashMap<>(); MapStringStringStructure valuesMap; switch (facetType) { case FIELD: valuesMap = recordVO.get(Facet.FIELD_VALUES_LABEL); break; case QUERY: valuesMap = recordVO.get(Facet.LIST_QUERIES); break; default: throw new ImpossibleRuntimeException("Unknown type"); } if (valuesMap != null) { for (String key : valuesMap.keySet()) { Map<String, String> tmp = new HashMap<>(); tmp.put(valuesMap.get(key), key); values.put(key, valuesMap.get(key)); } } return values; } public Map<String, String> getAutomaticValueForFacet(String dataFieldCode, List<String> valuesInTable) { Map<String, String> valuesMap = new HashMap<>(); List<String> values = new ArrayList<>(); switch (facetType) { case FIELD: values = service.getFieldFacetValues(dataFieldCode); break; case QUERY: break; default: throw new ImpossibleRuntimeException("Unknown type"); } for (String value : values) { if (!valuesInTable.contains(value)) { valuesMap.put(value, ""); } } return valuesMap; } public void removeValue(int index) { values.remove(index); } public void addValue(String label, String value, int id) { Map<String, String> map = new HashMap<>(); map.put(label, value); values.put(id, map); } public RecordVODataProvider getDataProvider() { RecordVODataProvider dataProvider; final MetadataSchema defaultSchema = schema(Facet.DEFAULT_SCHEMA); MetadataSchemaVO facetDefaultVO = new MetadataSchemaToVOBuilder() .build(defaultSchema, VIEW_MODE.FORM, view.getSessionContext()); dataProvider = new RecordVODataProvider(facetDefaultVO, new RecordToVOBuilder(), modelLayerFactory, view.getSessionContext()) { @Override protected LogicalSearchQuery getQuery() { LogicalSearchQuery query = new LogicalSearchQuery(); OngoingLogicalSearchConditionWithDataStoreFields condition = from(schema(Facet.FIELD_SCHEMA)) .where(defaultSchema.get(Facet.FACET_TYPE)); switch (facetType) { case FIELD: query.setCondition(condition.isEqualTo(FacetType.FIELD)); break; case QUERY: query.setCondition(condition.isEqualTo(FacetType.QUERY)); break; default: throw new ImpossibleRuntimeException("Unknown type"); } return query; } }; return dataProvider; } public RecordVO getRecordVO() { return recordVO; } public void saveButtonClicked(RecordVO recordVO) { filterValues(values); switch (facetType) { case FIELD: if (recordVO.get(Facet.FIELD_DATA_STORE_CODE) == null) { throw new RuntimeException("no data field"); } recordVO.set(Facet.FIELD_VALUES_LABEL, service.getStructureValue(values)); break; case QUERY: List<Integer> invalidQuery = service.getInvalidQuery(values); if (invalidQuery.isEmpty()) recordVO.set(Facet.LIST_QUERIES, service.getStructureValue(values)); else { view.displayInvalidQuery(invalidQuery); return; } break; default: throw new ImpossibleRuntimeException("Unknown type"); } if (!edit) { recordVO.set(Facet.ORDER, service.getNextOrderValue()); } Record recordToSave = service.toRecord(recordVO); Transaction transaction = new Transaction(); transaction.addUpdate(recordToSave); try { recordServices().execute(transaction); this.recordVO = service.getVOForRecord(recordToSave); view.navigate().to().listFacetConfiguration(); } catch (RecordServicesException ex) { throw new RuntimeException(); } } private void filterValues(Map<Integer, Map<String, String>> values) { List<Integer> valuesToRemove = new ArrayList<>(); for (Integer integer : values.keySet()) { for (Entry<String, String> entry : values.get(integer).entrySet()) { if (StringUtils.isBlank(entry.getKey()) || StringUtils.isBlank(entry.getValue())) { valuesToRemove.add(integer); } } } for (Integer integer : valuesToRemove) { values.remove(integer); } } public List<AvailableFacetFieldMetadata> getAvailableDataStoreCodes() { return service.getAvailableDataStoreCodes(); } public boolean isDataStoreCodeNeeded() { return !edit && facetType == FacetType.FIELD; } public boolean isDataStoreCodeSupportingLabelValues(String datastoreCode) { return service.isDataStoreCodeSupportingLabelValues(datastoreCode); } public void cancelButtonClicked() { view.navigate().to().listFacetConfiguration(); } public static class AvailableFacetFieldMetadata { private String code; private String label; public AvailableFacetFieldMetadata(String code, String label) { this.code = code; this.label = label; } public String getCode() { return code; } public String getLabel() { return label; } } }