add polytomous key generation to character matrix (experimental)
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / descriptiveDataSet / matrix / CharacterMatrixBottomToolbar.java
index efe97e8fd1d0e6b4599ef7f9e64bbd3a1386336c..28eac14c416193e32b94700b63cdb186dde07344 100644 (file)
@@ -10,10 +10,8 @@ package eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.UUID;
 import java.util.stream.Collectors;
 
@@ -26,24 +24,35 @@ import org.eclipse.swt.layout.RowLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 
-import eu.etaxonomy.cdm.api.service.IDescriptionService;
 import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
+import eu.etaxonomy.cdm.api.service.IPolytomousKeyService;
 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
 import eu.etaxonomy.cdm.api.service.UpdateResult;
+import eu.etaxonomy.cdm.api.service.config.IdentifiableServiceConfiguratorImpl;
 import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
+import eu.etaxonomy.cdm.api.service.dto.SpecimenRowWrapperDTO;
+import eu.etaxonomy.cdm.api.service.dto.TaxonRowWrapperDTO;
 import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.cdm.model.description.CategoricalData;
-import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
+import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
 import eu.etaxonomy.cdm.model.description.Feature;
+import eu.etaxonomy.cdm.model.description.PolytomousKey;
 import eu.etaxonomy.cdm.model.description.QuantitativeData;
 import eu.etaxonomy.cdm.model.description.SpecimenDescription;
+import eu.etaxonomy.cdm.model.description.TaxonDescription;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
+import eu.etaxonomy.cdm.strategy.generate.PolytomousKeyGenerator;
+import eu.etaxonomy.cdm.strategy.generate.PolytomousKeyGeneratorConfigurator;
+import eu.etaxonomy.taxeditor.editor.l10n.Messages;
 import eu.etaxonomy.taxeditor.model.ImageResources;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.store.StoreUtil;
 import eu.etaxonomy.taxeditor.ui.dialog.selection.TaxonSelectionDialog;
 
 /**
@@ -75,34 +84,34 @@ public class CharacterMatrixBottomToolbar extends Composite{
         btnAddDescription.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
-                String error = "";
+                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
+                    return;
+                }
+                String error = ""; //$NON-NLS-1$
                 SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(matrix.getShell(), matrix);
                 if(dialog.open()==Window.OK){
                     Collection<SpecimenNodeWrapper> wrappers = dialog.getSpecimen();
                     for (SpecimenNodeWrapper wrapper : wrappers) {
-                        SpecimenDescription description = CdmStore.getService(IDescriptiveDataSetService.class)
-                                .findDescriptionForDescriptiveDataSet(matrix.getDescriptiveDataSet().getUuid(),
-                                        wrapper.getUuidAndTitleCache().getUuid());
-                        // description elements
-                        Map<Feature, DescriptionElementBase> featureToElementMap = new HashMap<>();
-                        Set<DescriptionElementBase> elements = description.getElements();
-                        for (DescriptionElementBase descriptionElementBase : elements) {
-                            Feature feature = descriptionElementBase.getFeature();
-                            featureToElementMap.put(feature, descriptionElementBase);
-                        }
-                        RowWrapperDTO rowWrapper = CdmStore.getService(IDescriptiveDataSetService.class).createRowWrapper(wrapper.getTaxonNode(), description, matrix.getDescriptiveDataSet());
+                        SpecimenDescription specimenDescription = CdmStore.getService(IDescriptiveDataSetService.class)
+                                .findSpecimenDescription(matrix.getDescriptiveDataSet().getUuid(),
+                                        wrapper.getUuidAndTitleCache().getUuid(), true);
+                        SpecimenRowWrapperDTO rowWrapper = CdmStore.getService(IDescriptiveDataSetService.class)
+                                .createSpecimenRowWrapper(specimenDescription, matrix.getDescriptiveDataSet());
                         if(rowWrapper==null){
-                            error += description;
+                            error += specimenDescription;
                             continue;
                         }
+                        //add specimen description
                         matrix.getDescriptions().add(rowWrapper);
-                        matrix.getDescriptiveDataSet().addDescription(description);
+                        matrix.getDescriptiveDataSet().addDescription(specimenDescription);
+                        matrix.getCdmEntitiySession().load(specimenDescription, true);
+
                         matrix.setDirty();
                         matrix.getSpecimenCache().remove(wrapper);
                     }
                     if(CdmUtils.isNotBlank(error)){
-                        MessagingUtils.warningDialog("Errors during row creation", this,
-                                String.format("Could not create rows for the following description:\n\n%s", error));
+                        MessagingUtils.warningDialog(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_TITLE, this,
+                                String.format(Messages.CharacterMatrixBottomToolbar_ERROR_ROW_CREATION_MESSAGE, error));
                     }
                 }
             }
@@ -115,6 +124,12 @@ public class CharacterMatrixBottomToolbar extends Composite{
         btnRemoveDescription.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
+                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
+                    return;
+                }
+                if(!MessagingUtils.confirmDialog(Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_TITLE, Messages.CharacterMatrixBottomToolbar_CONFIRM_DELETE_MESSAGE)){
+                    return;
+                }
                 int[] fullySelectedRowPositions = matrix.getBodyLayer().getSelectionLayer().getFullySelectedRowPositions();
                 List<RowWrapperDTO> toRemove = new ArrayList<>();
                 for (int i : fullySelectedRowPositions) {
@@ -123,10 +138,10 @@ public class CharacterMatrixBottomToolbar extends Composite{
                         toRemove.add((RowWrapperDTO) rowObject);
                     }
                 }
-                toRemove.forEach(rowToRemove->{
+                toRemove.forEach(rowToRemove -> {
                     matrix.getDescriptions().remove(rowToRemove);
-                    matrix.getDescriptiveDataSet().removeDescription(rowToRemove.getSpecimenDescription());
-                    matrix.setDirty();
+                    CdmStore.getService(IDescriptiveDataSetService.class).removeDescription(
+                            rowToRemove.getDescription().getUuid(), matrix.getDescriptiveDataSet().getUuid());
                 });
             }
         });
@@ -134,21 +149,22 @@ public class CharacterMatrixBottomToolbar extends Composite{
          * Aggregate button
          */
         Button btnAggregate = new Button(this, SWT.PUSH);
-        btnAggregate.setText("Aggregate");
+        btnAggregate.setText(Messages.CharacterMatrixBottomToolbar_AGGREGATE);
         btnAggregate.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
+                if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
+                    return;
+                }
                 List<TaxonNode> taxonSubtreeFilter = CdmStore.getService(IDescriptiveDataSetService.class).loadFilteredTaxonNodes(matrix.getDescriptiveDataSet(), null);
                 List<TaxonNodeDto> nodeDtos = taxonSubtreeFilter.stream()
                         .map(node -> new TaxonNodeDto(node)).collect(Collectors.toList());
                 TaxonNodeDto parentDto = CdmStore.getService(ITaxonNodeService.class).findCommonParentDto(nodeDtos);
                 UUID taxonUuid = parentDto.getTaxonUuid();
                 int response = MessagingUtils.confirmDialog(
-                        "Choose location for the aggregated description",
-                        String.format("The aggregated description will be stored at "
-                                + "the common parent taxon of this data set:\n%s\n\n"
-                                + "Do you want to use this taxon?"
-                                , parentDto.getTaxonTitleCache()), "Yes", "Choose taxon", "Cancel");
+                        Messages.CharacterMatrixBottomToolbar_AGGREGATION_TITLE,
+                        String.format(Messages.CharacterMatrixBottomToolbar_AGGREGATION_MESSAGE
+                                , parentDto.getTaxonTitleCache()), Messages.CharacterMatrixBottomToolbar_YES, Messages.CharacterMatrixBottomToolbar_CHOOSE_TAXON, Messages.CharacterMatrixBottomToolbar_CANCEL);
                 if(response==2){
                     return;
                 }
@@ -161,40 +177,72 @@ public class CharacterMatrixBottomToolbar extends Composite{
                 }
                 List<UUID> descriptionUuids = new ArrayList<>();
                 matrix.getDescriptiveDataSet().getDescriptions().forEach(desc->descriptionUuids.add(desc.getUuid()));
-                UpdateResult result = CdmStore.getService(IDescriptionService.class).aggregateDescription(taxonUuid, descriptionUuids, matrix.getDescriptiveDataSet().getLabel());
-                matrix.addUpdateResult(result);
-                matrix.setDirty();
+                UpdateResult result = CdmStore.getService(IDescriptiveDataSetService.class).aggregateDescription(taxonUuid, descriptionUuids, matrix.getDescriptiveDataSet().getLabel(), matrix.getDescriptiveDataSet().getUuid());
+                TaxonDescription taxonDescription = (TaxonDescription) result.getCdmEntity();
+                TaxonRowWrapperDTO taxonRowWrapper = CdmStore.getService(IDescriptiveDataSetService.class).createTaxonRowWrapper(taxonDescription.getUuid(), matrix.getDescriptiveDataSet().getUuid());
+                matrix.getDescriptions().add(taxonRowWrapper);
 
                 aggregateCategorcialHistogram(matrix.getFeatureToHistogramMap());
                 aggregateQuantitativeSummary(matrix.getFeatureToQuantDataStatisticsMap());
             }
-
         });
+        if(PreferencesUtil.getBooleanValue(IPreferenceKeys.SHOW_EXPERIMENTAL_FEATURES)){
+            /**
+             * Key generation button
+             */
+            Button btnGenerateKey = new Button(this, SWT.PUSH);
+            btnGenerateKey.setText("Generate Polytomous Key");
+            btnGenerateKey.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    if(StoreUtil.promptCheckIsDirty(matrix.getPart())){
+                        return;
+                    }
+                    PolytomousKeyGeneratorConfigurator keyConfig = new PolytomousKeyGeneratorConfigurator();
+                    DescriptiveDataSet descriptiveDataSet = matrix.getDescriptiveDataSet();
+                    keyConfig.setDataSet(descriptiveDataSet);
+                    PolytomousKey key = new PolytomousKeyGenerator().invoke(keyConfig);
+                    IPolytomousKeyService keyService = CdmStore.getService(IPolytomousKeyService.class);
+                    IdentifiableServiceConfiguratorImpl<PolytomousKey> serviceConfig= new IdentifiableServiceConfiguratorImpl<>();
+                    serviceConfig.setTitleSearchString(descriptiveDataSet.getTitleCache());
+                    List<PolytomousKey> list = keyService.findByTitle(serviceConfig).getRecords();
+                    if(list!=null){
+                        // TODO clear old key
+                        System.out.println("Key with same name found for this data set found");
+                    }
+                    key.setTitleCache(descriptiveDataSet.getTitleCache(), true);
+                    keyService.save(key);
+                    key.print(System.out);
+                }
+            });
+        }
     }
 
     @SuppressWarnings("unchecked")
     private void aggregateCategorcialHistogram(Map<Feature, CategoricalDataHistogram> featureToHistogramMap) {
         featureToHistogramMap.clear();
-        matrix.getDescriptions()
-                .forEach(o -> ((RowWrapperDTO) o).getSpecimenDescription().getElements().stream()
-                        .filter(descriptionElement -> descriptionElement instanceof CategoricalData)
-                        .forEach(categoricalData -> {
-                            Feature feature = ((CategoricalData) categoricalData).getFeature();
-                            CategoricalDataHistogram dataHistogram = featureToHistogramMap.get(feature);
-                            if(dataHistogram==null){
-                                dataHistogram = new CategoricalDataHistogram(feature);
-                            }
-                            featureToHistogramMap.put(feature, dataHistogram);
-                            ((CategoricalData) categoricalData).getStateData()
-                                    .forEach(stateData -> featureToHistogramMap.get(feature).addState(stateData.getState()));
-                        }));
+        matrix.getDescriptions().stream()
+        .filter(desc->desc instanceof SpecimenRowWrapperDTO)
+        .forEach(o -> ((SpecimenRowWrapperDTO) o).getDescription().getElements().stream()
+                .filter(descriptionElement -> descriptionElement instanceof CategoricalData)
+                .forEach(categoricalData -> {
+                    Feature feature = ((CategoricalData) categoricalData).getFeature();
+                    CategoricalDataHistogram dataHistogram = featureToHistogramMap.get(feature);
+                    if(dataHistogram==null){
+                        dataHistogram = new CategoricalDataHistogram(feature);
+                    }
+                    featureToHistogramMap.put(feature, dataHistogram);
+                    ((CategoricalData) categoricalData).getStateData()
+                    .forEach(stateData -> featureToHistogramMap.get(feature).addState(stateData.getState()));
+                }));
     }
 
     @SuppressWarnings("unchecked")
     private void aggregateQuantitativeSummary(Map<Feature, QuantitativeDataStatistics> featureToQuantDataStatisticsMap) {
         featureToQuantDataStatisticsMap.clear();
-        matrix.getDescriptions()
-        .forEach(o -> ((RowWrapperDTO) o).getSpecimenDescription().getElements().stream()
+        matrix.getDescriptions().stream()
+        .filter(desc->desc instanceof SpecimenRowWrapperDTO)
+        .forEach(o -> ((SpecimenRowWrapperDTO) o).getDescription().getElements().stream()
                 .filter(descriptionElement -> descriptionElement instanceof QuantitativeData)
                 .forEach(quantData -> {
                     Feature feature = ((QuantitativeData) quantData).getFeature();