Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe

Commits:

22 changed files:

Changes:

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/save/actions/Start.java
    ... ... @@ -93,7 +93,7 @@ public class Start extends SaveLocalUIActionSupport {
    93 93
                     stepModel.getClientConfig().updateBackupDirectory(backupFile);
    
    94 94
                 }
    
    95 95
                 if (stepModel.containsStepForSave(AdminStep.SYNCHRONIZE)) {
    
    96
    -                saveUnidirectionalSynchronizeReferential();
    
    96
    +                saveUnidirectionalSynchronizeReferential(source);
    
    97 97
                 }
    
    98 98
                 sendMessage(t("observe.ui.datasource.editor.actions.operation.message.done", new Date(), Strings.convertTime(TimeLog.getTime() - t00)));
    
    99 99
             }
    
    ... ... @@ -102,7 +102,7 @@ public class Start extends SaveLocalUIActionSupport {
    102 102
         }
    
    103 103
     
    
    104 104
     
    
    105
    -    private void saveUnidirectionalSynchronizeReferential() {
    
    105
    +    private void saveUnidirectionalSynchronizeReferential(ObserveSwingDataSource source) {
    
    106 106
     
    
    107 107
             SynchronizeModel stepModel = ui.getModel().getSynchronizeReferentielModel();
    
    108 108
     
    
    ... ... @@ -113,8 +113,10 @@ public class Start extends SaveLocalUIActionSupport {
    113 113
                 sendMessage(t("observe.ui.datasource.editor.actions.synchro.referential.message.script.path", referentialSynchronizeContext.getSqlScriptPath()));
    
    114 114
             }
    
    115 115
             sendMessage("Mise à jour de la date de dernière de synchronisation de référentiel simple.");
    
    116
    -        referentialSynchronizeContext.finish(stepModel.getSource().getSynchronizeService());
    
    117
    -        stepModel.getSource().setModified(true);
    
    116
    +        referentialSynchronizeContext.finish(source.getSynchronizeService());
    
    117
    +        if (source.isLocal()) {
    
    118
    +            source.setModified(true);
    
    119
    +        }
    
    118 120
             sendMessage(t("observe.ui.datasource.editor.actions.synchro.referential.message.apply.done", new Date()));
    
    119 121
     
    
    120 122
         }
    

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/DataSynchroModel.java
    ... ... @@ -27,8 +27,10 @@ import fr.ird.observe.client.datasource.actions.AdminStep;
    27 27
     import fr.ird.observe.client.datasource.actions.AdminUIModel;
    
    28 28
     import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePaneModel;
    
    29 29
     import fr.ird.observe.client.datasource.api.data.DataTaskSupport;
    
    30
    +import fr.ird.observe.client.datasource.api.data.TaskSide;
    
    30 31
     import fr.ird.observe.client.datasource.editor.api.wizard.connexion.DataSourceSelectorModel;
    
    31 32
     import fr.ird.observe.datasource.configuration.ObserveDataSourceInformation;
    
    33
    +import io.ultreia.java4all.util.TwoSideContext;
    
    32 34
     import org.apache.logging.log4j.LogManager;
    
    33 35
     import org.apache.logging.log4j.Logger;
    
    34 36
     import org.nuiton.jaxx.runtime.swing.wizard.ext.WizardState;
    
    ... ... @@ -41,11 +43,10 @@ import javax.swing.DefaultListModel;
    41 43
      * @author Tony Chemit - dev@tchemit.fr
    
    42 44
      * @since 5.0
    
    43 45
      */
    
    44
    -public class DataSynchroModel extends AdminActionModel {
    
    46
    +public class DataSynchroModel extends AdminActionModel implements TwoSideContext<TaskSide, DataSelectionTreePaneModel> {
    
    45 47
     
    
    46 48
         public static final String LEFT_MODEL = "leftModel";
    
    47 49
         public static final String RIGHT_MODEL = "rightModel";
    
    48
    -
    
    49 50
         private static final String TASKS_EMPTY_PROPERTY_NAME = "tasksEmpty";
    
    50 51
         private static final Logger log = LogManager.getLogger(DataSynchroModel.class);
    
    51 52
         /**
    
    ... ... @@ -56,6 +57,7 @@ public class DataSynchroModel extends AdminActionModel {
    56 57
          * Right model.
    
    57 58
          */
    
    58 59
         private final DataSelectionTreePaneModel rightModel = new DataSelectionTreePaneModel();
    
    60
    +
    
    59 61
         /**
    
    60 62
          * Registered tasks to apply.
    
    61 63
          */
    
    ... ... @@ -65,15 +67,13 @@ public class DataSynchroModel extends AdminActionModel {
    65 67
             super(AdminStep.DATA_SYNCHRONIZE);
    
    66 68
         }
    
    67 69
     
    
    68
    -    public DataSelectionTreePaneModel getModel(boolean left) {
    
    69
    -        return left ? getLeftModel() : getRightModel();
    
    70
    -    }
    
    71
    -
    
    72
    -    public DataSelectionTreePaneModel getLeftModel() {
    
    70
    +    @Override
    
    71
    +    public DataSelectionTreePaneModel left() {
    
    73 72
             return leftModel;
    
    74 73
         }
    
    75 74
     
    
    76
    -    public DataSelectionTreePaneModel getRightModel() {
    
    75
    +    @Override
    
    76
    +    public DataSelectionTreePaneModel right() {
    
    77 77
             return rightModel;
    
    78 78
         }
    
    79 79
     
    
    ... ... @@ -120,8 +120,10 @@ public class DataSynchroModel extends AdminActionModel {
    120 120
         @Override
    
    121 121
         public void destroy() {
    
    122 122
             super.destroy();
    
    123
    -        leftModel.dispose();
    
    124
    -        rightModel.dispose();
    
    123
    +        left().dispose();
    
    124
    +        right().dispose();
    
    125
    +//        leftModel.dispose();
    
    126
    +//        rightModel.dispose();
    
    125 127
             tasks.clear();
    
    126 128
         }
    
    127 129
     
    
    ... ... @@ -132,9 +134,9 @@ public class DataSynchroModel extends AdminActionModel {
    132 134
             rightModel.finalizeSelectionModel(rightModel.getSelectionDataModel().getRoot(), leftModel.getDataIds());
    
    133 135
         }
    
    134 136
     
    
    135
    -    public void rebuildSelectionModel(boolean left, boolean rebuildFlatModel) {
    
    136
    -        DataSelectionTreePaneModel otherSideModel = getModel(!left);
    
    137
    -        getModel(left).rebuildSelectionModel(rebuildFlatModel, otherSideModel.getDataIds());
    
    137
    +    public void rebuildSelectionModel(TaskSide side, boolean rebuildFlatModel) {
    
    138
    +        DataSelectionTreePaneModel otherSideModel = onOppositeSide(side);
    
    139
    +        onSameSide(side).rebuildSelectionModel(rebuildFlatModel, otherSideModel.getDataIds());
    
    138 140
         }
    
    139 141
     
    
    140 142
         public DefaultListModel<DataTaskSupport> getTasks() {
    

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/DataSynchroUI.jaxx
    ... ... @@ -18,7 +18,7 @@
    18 18
       #L%
    
    19 19
       -->
    
    20 20
     
    
    21
    -<fr.ird.observe.client.datasource.actions.AdminTabUI>
    
    21
    +<fr.ird.observe.client.datasource.actions.AdminTabUI implements="TwoSideContext&lt;TaskSide, DataSelectionTreePane&gt;">
    
    22 22
     
    
    23 23
       <import>
    
    24 24
         fr.ird.observe.client.util.UIHelper
    
    ... ... @@ -26,6 +26,8 @@
    26 26
         fr.ird.observe.client.datasource.actions.AdminStep
    
    27 27
         fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePane
    
    28 28
         fr.ird.observe.client.datasource.api.data.DataTaskSupport
    
    29
    +    fr.ird.observe.client.datasource.api.data.TaskSide
    
    30
    +    io.ultreia.java4all.util.TwoSideContext
    
    29 31
     
    
    30 32
         static io.ultreia.java4all.i18n.I18n.t
    
    31 33
       </import>
    
    ... ... @@ -33,6 +35,16 @@
    33 35
     public static DataSynchroUI get(AdminUI ui) {
    
    34 36
         return get(ui, AdminStep.DATA_SYNCHRONIZE);
    
    35 37
     }
    
    38
    +
    
    39
    +@Override
    
    40
    +public DataSelectionTreePane left() {
    
    41
    +    return leftTreePane;
    
    42
    +}
    
    43
    +
    
    44
    +@Override
    
    45
    +public DataSelectionTreePane right() {
    
    46
    +    return rightTreePane;
    
    47
    +}
    
    36 48
     ]]>
    
    37 49
       </script>
    
    38 50
     
    
    ... ... @@ -53,8 +65,8 @@ public static DataSynchroUI get(AdminUI ui) {
    53 65
             <row>
    
    54 66
               <cell weightx="1">
    
    55 67
                 <JPanel layout="{new GridLayout(1, 0)}">
    
    56
    -              <DataSelectionTreePane id="leftTreePane" constructorParams="UIHelper.initialContext(this, false)"/>
    
    57
    -              <DataSelectionTreePane id="rightTreePane" constructorParams="UIHelper.initialContext(this, true)"/>
    
    68
    +              <DataSelectionTreePane id="leftTreePane" constructorParams="UIHelper.initialContext(this, TaskSide.FROM_LEFT)"/>
    
    69
    +              <DataSelectionTreePane id="rightTreePane" constructorParams="UIHelper.initialContext(this, TaskSide.FROM_RIGHT)"/>
    
    58 70
                 </JPanel>
    
    59 71
               </cell>
    
    60 72
             </row>
    

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/DataSynchroUIHandler.java
    ... ... @@ -26,6 +26,7 @@ import fr.ird.observe.client.datasource.actions.AdminTabUIHandler;
    26 26
     import fr.ird.observe.client.datasource.actions.config.ConfigModel;
    
    27 27
     import fr.ird.observe.client.datasource.actions.config.ConfigUI;
    
    28 28
     import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePaneHandler;
    
    29
    +import fr.ird.observe.client.datasource.api.data.TaskSide;
    
    29 30
     import fr.ird.observe.client.datasource.editor.api.selection.actions.SelectUnselectWithOpposite;
    
    30 31
     import fr.ird.observe.client.datasource.editor.api.wizard.StorageUIModel;
    
    31 32
     import fr.ird.observe.client.util.init.UIInitHelper;
    
    ... ... @@ -48,8 +49,8 @@ class DataSynchroUIHandler extends AdminTabUIHandler<DataSynchroUI> implements U
    48 49
         public void beforeInit(DataSynchroUI ui) {
    
    49 50
             super.beforeInit(ui);
    
    50 51
             DataSynchroModel dataSynchroModel = parentUI.getModel().getDataSynchroModel();
    
    51
    -        ui.setContextValue(dataSynchroModel.getLeftModel(), DataSynchroModel.LEFT_MODEL);
    
    52
    -        ui.setContextValue(dataSynchroModel.getRightModel(), DataSynchroModel.RIGHT_MODEL);
    
    52
    +        ui.setContextValue(dataSynchroModel.onSameSide(TaskSide.FROM_LEFT), DataSelectionTreePaneHandler.MODEL_NAMES.onSameSide(TaskSide.FROM_LEFT));
    
    53
    +        ui.setContextValue(dataSynchroModel.onOppositeSide(TaskSide.FROM_LEFT), DataSelectionTreePaneHandler.MODEL_NAMES.onOppositeSide(TaskSide.FROM_LEFT));
    
    53 54
         }
    
    54 55
     
    
    55 56
         @Override
    

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/actions/Apply.java
    ... ... @@ -77,7 +77,7 @@ public class Apply extends DataSynchroUIActionSupport {
    77 77
         private WizardState doApply() throws BabModelVersionException, DataSourceCreateWithNoReferentialImportException, DatabaseNotFoundException, IncompatibleDataSourceCreateConfigurationException, DatabaseConnexionNotAuthorizedException {
    
    78 78
     
    
    79 79
             DataSynchroModel stepModel = ui.getStepModel();
    
    80
    -        DataSelectionTreePaneModel leftModel = stepModel.getModel(true);
    
    80
    +        DataSelectionTreePaneModel leftModel = stepModel.onSameSide(TaskSide.FROM_LEFT);
    
    81 81
             String moduleName = leftModel.getSelectionDataModel().getConfig().getModuleName();
    
    82 82
             Class<? extends RootOpenableDto> dataType = "ps".equals(moduleName) ? fr.ird.observe.dto.data.ps.common.TripDto.class : fr.ird.observe.dto.data.ll.common.TripDto.class;
    
    83 83
             DefaultListModel<DataTaskSupport> tasks = stepModel.getTasks();
    
    ... ... @@ -112,7 +112,7 @@ public class Apply extends DataSynchroUIActionSupport {
    112 112
             progressModel.setMaximum(stepCount);
    
    113 113
     
    
    114 114
             try (ObserveSwingDataSource leftSource = openSource(leftModel.getSource())) {
    
    115
    -            try (ObserveSwingDataSource rightSource = openSource(stepModel.getModel(false).getSource())) {
    
    115
    +            try (ObserveSwingDataSource rightSource = openSource(stepModel.onOppositeSide(TaskSide.FROM_LEFT).getSource())) {
    
    116 116
                     long t00 = TimeLog.getTime();
    
    117 117
                     progressModel.increments();
    
    118 118
                     try {
    

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/actions/Start.java
    ... ... @@ -29,6 +29,7 @@ import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelect
    29 29
     import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePaneHandler;
    
    30 30
     import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePaneModel;
    
    31 31
     import fr.ird.observe.client.datasource.api.ObserveSwingDataSource;
    
    32
    +import fr.ird.observe.client.datasource.api.data.TaskSide;
    
    32 33
     import org.nuiton.jaxx.runtime.swing.wizard.ext.WizardState;
    
    33 34
     
    
    34 35
     import java.awt.event.ActionEvent;
    
    ... ... @@ -57,11 +58,11 @@ public class Start extends DataSynchroUIActionSupport {
    57 58
             ConfigModel configModel = ui.getModel().getConfigModel();
    
    58 59
     
    
    59 60
             try (ObserveSwingDataSource leftSource = configModel.getLeftSourceModel().getSafeSource(true)) {
    
    60
    -            DataSelectionTreePaneModel leftModel = stepModel.getModel(true);
    
    61
    +            DataSelectionTreePaneModel leftModel = stepModel.onSameSide(TaskSide.FROM_LEFT);
    
    61 62
                 leftModel.setSource(leftSource);
    
    62 63
     
    
    63 64
                 try (ObserveSwingDataSource rightSource = configModel.getRightSourceModel().getSafeSource(true)) {
    
    64
    -                DataSelectionTreePaneModel rightModel = stepModel.getModel(false);
    
    65
    +                DataSelectionTreePaneModel rightModel = stepModel.onOppositeSide(TaskSide.FROM_LEFT);
    
    65 66
                     rightModel.setSource(rightSource);
    
    66 67
     
    
    67 68
                     DataSelectionTreePane leftTreePane = tabUI.getLeftTreePane();
    

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/DataSelectionTreePane.jaxx
    ... ... @@ -20,17 +20,9 @@
    20 20
     <JPanel id='topPanel' layout="{new BorderLayout()}">
    
    21 21
       <import>
    
    22 22
         fr.ird.observe.client.datasource.editor.api.selection.SelectionTreePane
    
    23
    +    fr.ird.observe.client.datasource.api.data.TaskSide
    
    23 24
       </import>
    
    24
    -  <script><![CDATA[
    
    25
    -public boolean isLeft() {
    
    26
    -    return !isRight();
    
    27
    -}
    
    28
    -public boolean isRight() {
    
    29
    -    return Boolean.TRUE.equals(getOpposite());
    
    30
    -}
    
    31
    -]]>
    
    32
    -  </script>
    
    33
    -  <Boolean id='opposite' initializer='getContextValue(Boolean.class)'/>
    
    25
    +  <TaskSide id="side" initializer='getContextValue(TaskSide.class)'/>
    
    34 26
       <DataSelectionTreePaneModel id="model" initializer='DataSelectionTreePaneHandler.getModel(this)'/>
    
    35 27
       <JToolBar id="toolbar">
    
    36 28
         <JSeparator orientation='{JSeparator.VERTICAL}'/>
    
    ... ... @@ -42,5 +34,5 @@ public boolean isRight() {
    42 34
         <JButton id="copy" enabled="false"/>
    
    43 35
         <JButton id="delete" enabled="false"/>
    
    44 36
       </JToolBar>
    
    45
    -  <SelectionTreePane id='tree' constructorParams="isRight()" constraints='BorderLayout.CENTER'/>
    
    37
    +  <SelectionTreePane id='tree' constructorParams="!side.onLeft()" constraints='BorderLayout.CENTER'/>
    
    46 38
     </JPanel>

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/DataSelectionTreePaneHandler.java
    ... ... @@ -39,6 +39,7 @@ import fr.ird.observe.navigation.tree.selection.IdState;
    39 39
     import fr.ird.observe.navigation.tree.selection.SelectionTree;
    
    40 40
     import fr.ird.observe.navigation.tree.selection.SelectionTreeModel;
    
    41 41
     import fr.ird.observe.navigation.tree.selection.SelectionTreeNode;
    
    42
    +import io.ultreia.java4all.util.TwoSideContext;
    
    42 43
     import org.apache.logging.log4j.LogManager;
    
    43 44
     import org.apache.logging.log4j.Logger;
    
    44 45
     import org.nuiton.jaxx.runtime.spi.UIHandler;
    
    ... ... @@ -64,19 +65,30 @@ public class DataSelectionTreePaneHandler implements UIHandler<DataSelectionTree
    64 65
     
    
    65 66
         private static final Logger log = LogManager.getLogger(DataSelectionTreePaneHandler.class);
    
    66 67
     
    
    68
    +    public static final TwoSideContext<TaskSide, String> MODEL_NAMES = new TwoSideContext<>() {
    
    69
    +        @Override
    
    70
    +        public String left() {
    
    71
    +            return DataSynchroModel.LEFT_MODEL;
    
    72
    +        }
    
    73
    +
    
    74
    +        @Override
    
    75
    +        public String right() {
    
    76
    +            return DataSynchroModel.RIGHT_MODEL;
    
    77
    +        }
    
    78
    +    };
    
    79
    +
    
    67 80
         static DataSelectionTreePaneModel getModel(DataSelectionTreePane ui) {
    
    68
    -        return ui.getContextValue(DataSelectionTreePaneModel.class, ui.isLeft() ? DataSynchroModel.LEFT_MODEL : DataSynchroModel.RIGHT_MODEL);
    
    81
    +        return ui.getContextValue(DataSelectionTreePaneModel.class, MODEL_NAMES.onSameSide(ui.getSide()));
    
    69 82
         }
    
    70 83
     
    
    71 84
         //FIXME Maybe we can place this in afterInit method? check this out!
    
    72 85
         public static void init(DataSelectionTreePane ui) {
    
    73
    -        boolean isLeft = ui.isLeft();
    
    74
    -        TaskSide taskSide = isLeft ? TaskSide.FROM_LEFT : TaskSide.FROM_RIGHT;
    
    86
    +        TaskSide taskSide = ui.getSide();
    
    75 87
             SelectionTreePane treePane = ui.getTree();
    
    76 88
             SelectionTree tree = treePane.getTree();
    
    77 89
             UIInitHelper.init(tree);
    
    78
    -        RegisterCopy.init(ui, ui.getCopy(), new RegisterCopy(taskSide));
    
    79
    -        RegisterDelete.init(ui, ui.getDelete(), new RegisterDelete(taskSide));
    
    90
    +        RegisterCopy.install(ui, ui.getCopy(), taskSide);
    
    91
    +        RegisterDelete.install(ui, ui.getDelete(), taskSide);
    
    80 92
             ToggleIdState.install(ui, ui.getToggleAdded(), IdState.ADDED);
    
    81 93
             ToggleIdState.install(ui, ui.getToggleNewer(), IdState.UPDATED);
    
    82 94
             ToggleIdState.install(ui, ui.getToggleOlder(), IdState.OBSOLETE);
    
    ... ... @@ -103,7 +115,7 @@ public class DataSelectionTreePaneHandler implements UIHandler<DataSelectionTree
    103 115
             model.setSelectionDataModel(treeModel);
    
    104 116
             // When model idStates has changed, rebuild the tree (but not the flat model)
    
    105 117
             model.addPropertyChangeListener(DataSelectionTreePaneModel.ID_STATES_PROPERTY_NAME,
    
    106
    -                                        evt-> DataSelectionTreePaneHandler.rebuildTree(parent.getStepModel(), ui, false));
    
    118
    +                                        evt -> DataSelectionTreePaneHandler.rebuildTree(parent.getStepModel(), ui, false));
    
    107 119
     
    
    108 120
             // When tree model has changed, rebuild accessibility to copy and delete action
    
    109 121
             treeModel.addPropertyChangeListener(evt -> {
    
    ... ... @@ -154,7 +166,7 @@ public class DataSelectionTreePaneHandler implements UIHandler<DataSelectionTree
    154 166
     
    
    155 167
         public static void rebuildTree(DataSynchroModel stepModel, DataSelectionTreePane ui, boolean rebuildFlatModel) {
    
    156 168
             ui.getTree().getTree().clearSelection();
    
    157
    -        stepModel.rebuildSelectionModel(ui.isLeft(),rebuildFlatModel);
    
    169
    +        stepModel.rebuildSelectionModel(ui.getSide(), rebuildFlatModel);
    
    158 170
             finalizeTree(ui);
    
    159 171
         }
    
    160 172
     
    

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/DataSelectionTreePaneModel.java
    ... ... @@ -23,6 +23,8 @@ package fr.ird.observe.client.datasource.actions.synchronize.data.tree;
    23 23
      */
    
    24 24
     
    
    25 25
     import fr.ird.observe.client.datasource.api.ObserveSwingDataSource;
    
    26
    +import fr.ird.observe.client.datasource.editor.api.selection.SelectionTreePane;
    
    27
    +import fr.ird.observe.client.datasource.editor.api.selection.SelectionTreePaneHandler;
    
    26 28
     import fr.ird.observe.navigation.tree.io.ToolkitTreeFlatModel;
    
    27 29
     import fr.ird.observe.navigation.tree.selection.IdAndLastUpdateDate;
    
    28 30
     import fr.ird.observe.navigation.tree.selection.IdState;
    
    ... ... @@ -44,6 +46,7 @@ import java.util.Enumeration;
    44 46
     import java.util.LinkedList;
    
    45 47
     import java.util.List;
    
    46 48
     import java.util.Map;
    
    49
    +import java.util.Set;
    
    47 50
     import java.util.function.Function;
    
    48 51
     import java.util.stream.Collectors;
    
    49 52
     
    
    ... ... @@ -54,9 +57,17 @@ import java.util.stream.Collectors;
    54 57
      * @since 9.2.0
    
    55 58
      */
    
    56 59
     public class DataSelectionTreePaneModel extends AbstractJavaBean {
    
    60
    +    public static final String ID_STATES_PROPERTY_NAME = "idStates";
    
    57 61
         private static final Logger log = LogManager.getLogger(DataSelectionTreePaneModel.class);
    
    58 62
         private static final String SOURCE_PROPERTY_NAME = "source";
    
    59
    -    public static final String ID_STATES_PROPERTY_NAME = "idStates";
    
    63
    +    /**
    
    64
    +     * Which id states we use in tree model.
    
    65
    +     */
    
    66
    +    private final EnumSet<IdState> idStates = EnumSet.allOf(IdState.class);
    
    67
    +    /**
    
    68
    +     * Id states count in tree model.
    
    69
    +     */
    
    70
    +    private final EnumMap<IdState, Integer> idStateCount = new EnumMap<>(IdState.class);
    
    60 71
         /**
    
    61 72
          * Data source.
    
    62 73
          */
    
    ... ... @@ -76,14 +87,6 @@ public class DataSelectionTreePaneModel extends AbstractJavaBean {
    76 87
          * All existing ids (computed only once at init).
    
    77 88
          */
    
    78 89
         private List<IdAndLastUpdateDate> dataIds = List.of();
    
    79
    -    /**
    
    80
    -     * Which id states we use in tree model.
    
    81
    -     */
    
    82
    -    private final EnumSet<IdState> idStates = EnumSet.allOf(IdState.class);
    
    83
    -    /**
    
    84
    -     * Id states count in tree model.
    
    85
    -     */
    
    86
    -    private final EnumMap<IdState, Integer> idStateCount = new EnumMap<>(IdState.class);
    
    87 90
     
    
    88 91
         public void dispose() {
    
    89 92
             source = null;
    
    ... ... @@ -96,11 +99,19 @@ public class DataSelectionTreePaneModel extends AbstractJavaBean {
    96 99
             return source;
    
    97 100
         }
    
    98 101
     
    
    102
    +    public void setSource(ObserveSwingDataSource source) {
    
    103
    +        this.source = source;
    
    104
    +        firePropertyChange(SOURCE_PROPERTY_NAME, source);
    
    105
    +    }
    
    99 106
     
    
    100 107
         public SelectionTreeModel getSelectionDataModel() {
    
    101 108
             return selectionDataModel;
    
    102 109
         }
    
    103 110
     
    
    111
    +    public void setSelectionDataModel(SelectionTreeModel selectionTreeModel) {
    
    112
    +        this.selectionDataModel = selectionTreeModel;
    
    113
    +    }
    
    114
    +
    
    104 115
         public List<IdAndLastUpdateDate> getDataIds() {
    
    105 116
             return dataIds;
    
    106 117
         }
    
    ... ... @@ -113,15 +124,6 @@ public class DataSelectionTreePaneModel extends AbstractJavaBean {
    113 124
             return idStateCount;
    
    114 125
         }
    
    115 126
     
    
    116
    -    public void setSource(ObserveSwingDataSource source) {
    
    117
    -        this.source = source;
    
    118
    -        firePropertyChange(SOURCE_PROPERTY_NAME, source);
    
    119
    -    }
    
    120
    -
    
    121
    -    public void setSelectionDataModel(SelectionTreeModel selectionTreeModel) {
    
    122
    -        this.selectionDataModel = selectionTreeModel;
    
    123
    -    }
    
    124
    -
    
    125 127
         public void buildFirstSelectionModel() {
    
    126 128
             SelectionTreeConfig config = selectionDataModel.getConfig();
    
    127 129
             SelectionTreeConfig newConfig = source.newSelectionTreeConfig();
    
    ... ... @@ -258,4 +260,36 @@ public class DataSelectionTreePaneModel extends AbstractJavaBean {
    258 260
                 });
    
    259 261
             }
    
    260 262
         }
    
    263
    +
    
    264
    +    public void removeData(List<SelectionTreeNode> data, SelectionTreePane tree) {
    
    265
    +        SelectionTreeModel selectDataModel = getSelectionDataModel();
    
    266
    +        int removedCount = 0;
    
    267
    +        for (SelectionTreeNode datum : data) {
    
    268
    +            String dataPath = datum.getNodePath().toString();
    
    269
    +            log.debug("Remove {} from flat model.", dataPath);
    
    270
    +            Set<String> paths = treeFlatModel.getMapping().keySet().stream().filter(e -> e.startsWith(dataPath)).collect(Collectors.toSet());
    
    271
    +            for (String path : paths) {
    
    272
    +                removedCount++;
    
    273
    +                log.debug("Removed {} - {} from flat model.", removedCount, path);
    
    274
    +                treeFlatModel.removeMapping(path);
    
    275
    +            }
    
    276
    +            SelectionTreeNode parent = datum.getParent();
    
    277
    +            if (parent != null) {
    
    278
    +                String parentPath = parent.getNodePath().toString();
    
    279
    +                long count = treeFlatModel.getMapping().keySet().stream().filter(e -> e.startsWith(parentPath)).count();
    
    280
    +                if (count == 1) {
    
    281
    +                    removedCount++;
    
    282
    +                    log.debug("Removed {} - {} from flat model.", removedCount, parentPath);
    
    283
    +                    treeFlatModel.removeMapping(parentPath);
    
    284
    +                }
    
    285
    +            }
    
    286
    +        }
    
    287
    +        selectDataModel.removeData(data);
    
    288
    +        if (removedCount > 0) {
    
    289
    +            log.info("Removed {} mapping(s) from flat model.", removedCount);
    
    290
    +            tree.getTree().getModel().updateDataCount(treeFlatModel);
    
    291
    +            SelectionTreePaneHandler.updateStatistics(tree);
    
    292
    +            firePropertyChange(ID_STATES_PROPERTY_NAME, idStates);
    
    293
    +        }
    
    294
    +    }
    
    261 295
     }

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/actions/DataSelectionTreePaneActionSupport.java
    ... ... @@ -26,7 +26,6 @@ import fr.ird.observe.client.datasource.actions.AdminTabUIHandler;
    26 26
     import fr.ird.observe.client.datasource.actions.synchronize.data.DataSynchroModel;
    
    27 27
     import fr.ird.observe.client.datasource.actions.synchronize.data.DataSynchroUI;
    
    28 28
     import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePane;
    
    29
    -import fr.ird.observe.navigation.tree.selection.SelectionTreeModel;
    
    30 29
     import org.nuiton.jaxx.runtime.swing.action.JComponentActionSupport;
    
    31 30
     
    
    32 31
     import javax.swing.KeyStroke;
    
    ... ... @@ -37,41 +36,29 @@ import javax.swing.KeyStroke;
    37 36
      */
    
    38 37
     public abstract class DataSelectionTreePaneActionSupport extends JComponentActionSupport<DataSelectionTreePane> {
    
    39 38
     
    
    40
    -    private final KeyStroke oppositeAcceleratorKey;
    
    39
    +    private final KeyStroke rightAcceleratorKey;
    
    41 40
     
    
    42
    -    DataSelectionTreePaneActionSupport(String label, String shortDescription, String actionIcon, KeyStroke acceleratorKey, KeyStroke oppositeAcceleratorKey) {
    
    41
    +    DataSelectionTreePaneActionSupport(String label, String shortDescription, String actionIcon, KeyStroke acceleratorKey, KeyStroke rightAcceleratorKey) {
    
    43 42
             super(label, shortDescription, actionIcon, acceleratorKey);
    
    44
    -        this.oppositeAcceleratorKey = oppositeAcceleratorKey;
    
    43
    +        this.rightAcceleratorKey = rightAcceleratorKey;
    
    45 44
         }
    
    46 45
     
    
    47
    -    DataSelectionTreePaneActionSupport(String actionCommandKey, String label, String shortDescription, String actionIcon, KeyStroke acceleratorKey, KeyStroke oppositeAcceleratorKey) {
    
    46
    +    DataSelectionTreePaneActionSupport(String actionCommandKey, String label, String shortDescription, String actionIcon, KeyStroke acceleratorKey, KeyStroke rightAcceleratorKey) {
    
    48 47
             super(actionCommandKey, label, shortDescription, actionIcon, acceleratorKey);
    
    49
    -        this.oppositeAcceleratorKey = oppositeAcceleratorKey;
    
    48
    +        this.rightAcceleratorKey = rightAcceleratorKey;
    
    50 49
         }
    
    51 50
     
    
    52 51
         @Override
    
    53 52
         public void init() {
    
    54
    -        if (ui.isRight()) {
    
    55
    -            setKeyStroke(oppositeAcceleratorKey);
    
    53
    +        if (!ui.getSide().onLeft()) {
    
    54
    +            setKeyStroke(rightAcceleratorKey);
    
    56 55
             }
    
    57 56
             super.init();
    
    58 57
         }
    
    59
    -
    
    60
    -    protected DataSynchroModel getDataSynchroModel() {
    
    61
    -        DataSynchroUI parent = ui.getContextValue(DataSynchroUI.class, AdminTabUIHandler.ADMIN_TAB_UI);
    
    62
    -        return parent.getStepModel();
    
    63
    -    }
    
    64
    -
    
    65 58
         protected DataSynchroUI getDataSynchroUI() {
    
    66 59
             return ui.getContextValue(DataSynchroUI.class, AdminTabUIHandler.ADMIN_TAB_UI);
    
    67 60
         }
    
    68
    -
    
    69
    -    protected SelectionTreeModel getSelectionTreeModel() {
    
    70
    -        return ui.getModel().getSelectionDataModel();
    
    71
    -    }
    
    72
    -
    
    73
    -    protected SelectionTreeModel getOppositeSelectionTreeModel() {
    
    74
    -        DataSynchroModel dataSynchroModel = getDataSynchroModel();
    
    75
    -        return dataSynchroModel.getModel(!ui.isLeft()).getSelectionDataModel();
    
    61
    +    protected DataSynchroModel getDataSynchroModel() {
    
    62
    +        return getDataSynchroUI().getStepModel();
    
    76 63
         }
    
    77 64
     }

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/actions/RegisterCopy.java
    ... ... @@ -25,46 +25,53 @@ package fr.ird.observe.client.datasource.actions.synchronize.data.tree.actions;
    25 25
     import fr.ird.observe.client.datasource.actions.ObserveKeyStrokesActions;
    
    26 26
     import fr.ird.observe.client.datasource.actions.synchronize.data.DataSynchroModel;
    
    27 27
     import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePane;
    
    28
    +import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePaneModel;
    
    28 29
     import fr.ird.observe.client.datasource.api.data.CopyDataTask;
    
    29 30
     import fr.ird.observe.client.datasource.api.data.TaskSide;
    
    30 31
     import fr.ird.observe.dto.ToolkitIdLabel;
    
    31 32
     import fr.ird.observe.navigation.tree.selection.SelectionTreeModel;
    
    33
    +import fr.ird.observe.navigation.tree.selection.SelectionTreeNode;
    
    32 34
     
    
    35
    +import javax.swing.JButton;
    
    33 36
     import java.awt.event.ActionEvent;
    
    37
    +import java.util.LinkedList;
    
    38
    +import java.util.List;
    
    34 39
     
    
    35 40
     /**
    
    36 41
      * To register a copy task.
    
    37 42
      * <p>
    
    38
    - * It will copy it {@link #taskSide} side to the other side.
    
    39 43
      *
    
    40 44
      * @author Tony Chemit - dev@tchemit.fr
    
    41 45
      * @since 8.0
    
    42 46
      */
    
    43 47
     public class RegisterCopy extends DataSelectionTreePaneActionSupport {
    
    44 48
     
    
    45
    -    /**
    
    46
    -     * Indicates the side used to copy data.
    
    47
    -     */
    
    48
    -    private final TaskSide taskSide;
    
    49
    +    public static void install(DataSelectionTreePane ui, JButton editor, TaskSide taskSide) {
    
    50
    +        RegisterCopy.init(ui, editor, new RegisterCopy(taskSide));
    
    51
    +    }
    
    49 52
     
    
    50
    -    public RegisterCopy(TaskSide taskSide) {
    
    53
    +    private RegisterCopy(TaskSide taskSide) {
    
    51 54
             super("", taskSide.getCopyTipKey(), taskSide.getCopyIconName(), ObserveKeyStrokesActions.KEY_STROKE_DATA_SYNCHRO_COPY_LEFT, ObserveKeyStrokesActions.KEY_STROKE_DATA_SYNCHRO_COPY_RIGHT);
    
    52
    -        this.taskSide = taskSide;
    
    53 55
         }
    
    54 56
     
    
    55 57
         @Override
    
    56 58
         protected void doActionPerformed(ActionEvent e, DataSelectionTreePane ui) {
    
    59
    +        TaskSide taskSide = ui.getSide();
    
    57 60
             DataSynchroModel stepModel = getDataSynchroModel();
    
    58
    -        SelectionTreeModel treeModel = getSelectionTreeModel();
    
    59
    -        SelectionTreeModel oppositeTreeModel = getOppositeSelectionTreeModel();
    
    60
    -        CopyDataTask.of(taskSide, treeModel).forEach(t -> {
    
    61
    +        DataSelectionTreePaneModel thisSideModel = stepModel.onSameSide(taskSide);
    
    62
    +        DataSelectionTreePaneModel oppositeSideModel = stepModel.onOppositeSide(taskSide);
    
    63
    +        List<SelectionTreeNode> oppositeNodes = new LinkedList<>();
    
    64
    +        SelectionTreeModel thisSideTreeModel = thisSideModel.getSelectionDataModel();
    
    65
    +        SelectionTreeModel oppositeSideTreeModel = oppositeSideModel.getSelectionDataModel();
    
    66
    +        CopyDataTask.of(taskSide, thisSideTreeModel).forEach(t -> {
    
    61 67
                 stepModel.addTask(t);
    
    68
    +            ToolkitIdLabel data = t.getData();
    
    62 69
                 if (t.isDataExistOnOpposite()) {
    
    63
    -                ToolkitIdLabel data = t.getData();
    
    64
    -                oppositeTreeModel.getDataParentNode(data).ifPresent(p -> oppositeTreeModel.removeDataFromParent(p, data));
    
    70
    +                oppositeSideTreeModel.getDataNode(data).ifPresent(oppositeNodes::add);
    
    65 71
                 }
    
    66 72
             });
    
    67
    -        treeModel.removeAllSelectedData();
    
    73
    +        thisSideModel.removeData(thisSideTreeModel.selectedDataNodes(), getDataSynchroUI().onSameSide(taskSide).getTree());
    
    74
    +        oppositeSideModel.removeData(oppositeNodes, getDataSynchroUI().onOppositeSide(taskSide).getTree());
    
    68 75
         }
    
    69 76
     
    
    70 77
     }

  • client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/actions/RegisterDelete.java
    ... ... @@ -25,37 +25,37 @@ package fr.ird.observe.client.datasource.actions.synchronize.data.tree.actions;
    25 25
     import fr.ird.observe.client.datasource.actions.ObserveKeyStrokesActions;
    
    26 26
     import fr.ird.observe.client.datasource.actions.synchronize.data.DataSynchroModel;
    
    27 27
     import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePane;
    
    28
    +import fr.ird.observe.client.datasource.actions.synchronize.data.tree.DataSelectionTreePaneModel;
    
    28 29
     import fr.ird.observe.client.datasource.api.data.DeleteDataTask;
    
    29 30
     import fr.ird.observe.client.datasource.api.data.TaskSide;
    
    30 31
     import fr.ird.observe.navigation.tree.selection.SelectionTreeModel;
    
    31 32
     
    
    33
    +import javax.swing.JButton;
    
    32 34
     import java.awt.event.ActionEvent;
    
    33 35
     
    
    34 36
     /**
    
    35 37
      * To register a delete task.
    
    36 38
      * <p>
    
    37
    - * It will delete it from the {@link #taskSide} side.
    
    38 39
      *
    
    39 40
      * @author Tony Chemit - dev@tchemit.fr
    
    40 41
      * @since 8.0
    
    41 42
      */
    
    42 43
     public class RegisterDelete extends DataSelectionTreePaneActionSupport {
    
    44
    +    public static void install(DataSelectionTreePane ui, JButton editor, TaskSide taskSide) {
    
    45
    +        RegisterDelete.init(ui, editor, new RegisterDelete(taskSide));
    
    46
    +    }
    
    43 47
     
    
    44
    -    /**
    
    45
    -     * Indicates the side used to delete data.
    
    46
    -     */
    
    47
    -    private final TaskSide taskSide;
    
    48
    -
    
    49
    -    public RegisterDelete(TaskSide taskSide) {
    
    48
    +    private RegisterDelete(TaskSide taskSide) {
    
    50 49
             super("", taskSide.getDeleteTipKey(), taskSide.getDeleteIconName(), ObserveKeyStrokesActions.KEY_STROKE_DATA_SYNCHRO_DELETE_LEFT, ObserveKeyStrokesActions.KEY_STROKE_DATA_SYNCHRO_DELETE_RIGHT);
    
    51
    -        this.taskSide = taskSide;
    
    52 50
         }
    
    53 51
     
    
    54 52
         @Override
    
    55 53
         protected void doActionPerformed(ActionEvent e, DataSelectionTreePane ui) {
    
    54
    +        TaskSide taskSide = ui.getSide();
    
    56 55
             DataSynchroModel stepModel = getDataSynchroModel();
    
    57
    -        SelectionTreeModel selectionDataModel = getSelectionTreeModel();
    
    56
    +        DataSelectionTreePaneModel model = stepModel.onSameSide(taskSide);
    
    57
    +        SelectionTreeModel selectionDataModel = model.getSelectionDataModel();
    
    58 58
             DeleteDataTask.of(taskSide, selectionDataModel).forEach(stepModel::addTask);
    
    59
    -        selectionDataModel.removeAllSelectedData();
    
    59
    +        model.removeData(selectionDataModel.selectedDataNodes(), getDataSynchroUI().onOppositeSide(taskSide).getTree());
    
    60 60
         }
    
    61 61
     }

  • core/persistence/report/src/main/resources/META-INF/report/default/ps/psObservationActivitiesByZone.report
    ... ... @@ -42,7 +42,8 @@ From fr.ird.observe.entities.data.ps.common.TripImpl m \
    42 42
     Join m.routeObs r \
    
    43 43
     Join r.activity a With a.currentFpaZone.id = :zoneFpaId \
    
    44 44
     Join a.floatingObject dcp \
    
    45
    -Where m.id In :tripId
    
    45
    +Where m.id In :tripId \
    
    46
    +Group By a.currentFpaZone.code, a.currentFpaZone.@i18nColumnName@
    
    46 47
     request.1.repeat.name=zoneFpaId
    
    47 48
     request.1.repeat.layout=column
    
    48 49
     request.1.comment=visite + peche / visite - peche / Deploiement + peche / Deploiement - peche / Modifie + peche / Modifie - peche / Retire + peche / Retire - peche / Abandonne + peche / Abandonne - peche / Coule + peche / Coule - peche / Remplace + peche / Remplace - peche / Autre ou ancien peche + peche / Autre ou ancien peche - peche / Nombre de tortues
    

  • pom.xml
    ... ... @@ -23,7 +23,7 @@
    23 23
       <parent>
    
    24 24
         <groupId>io.ultreia.maven</groupId>
    
    25 25
         <artifactId>pom</artifactId>
    
    26
    -    <version>2024.13</version>
    
    26
    +    <version>2024.16</version>
    
    27 27
       </parent>
    
    28 28
       <groupId>fr.ird.observe</groupId>
    
    29 29
       <artifactId>ird-observe</artifactId>
    

  • server/core/src/main/java/fr/ird/observe/server/injector/JsonAwareDtoInjector.java
    ... ... @@ -78,6 +78,6 @@ public class JsonAwareDtoInjector extends JsonInjector<JsonAware> {
    78 78
             if (ToolkitRequestFilter.class.isAssignableFrom(type)) {
    
    79 79
                 return gson.fromJson("{}", generic);
    
    80 80
             }
    
    81
    -        return super.buildNullValue(call, name, type, generic);
    
    81
    +        return null;
    
    82 82
         }
    
    83 83
     }

  • toolkit/api/src/main/java/fr/ird/observe/navigation/tree/ToolkitTreeModelSupport.java
    ... ... @@ -114,6 +114,10 @@ public abstract class ToolkitTreeModelSupport<R extends ToolkitTreeNode> extends
    114 114
             populate(flatModel, rootConsumer);
    
    115 115
         }
    
    116 116
     
    
    117
    +    public final void updateDataCount(ToolkitTreeFlatModel flatModel) {
    
    118
    +        dataCount = flatModel.getDataCount();
    
    119
    +    }
    
    120
    +
    
    117 121
         public final ToolkitTreeFlatModelRootRequest getRequest() {
    
    118 122
             return request;
    
    119 123
         }
    

  • toolkit/api/src/main/java/fr/ird/observe/navigation/tree/io/ToolkitTreeFlatModel.java
    ... ... @@ -24,6 +24,7 @@ package fr.ird.observe.navigation.tree.io;
    24 24
     
    
    25 25
     import fr.ird.observe.dto.ObserveDto;
    
    26 26
     import fr.ird.observe.navigation.tree.ToolkitTreeNode;
    
    27
    +import fr.ird.observe.navigation.tree.ToolkitTreeNodeBean;
    
    27 28
     import fr.ird.observe.navigation.tree.ToolkitTreeNodeBeanState;
    
    28 29
     import fr.ird.observe.navigation.tree.states.BooleanState;
    
    29 30
     
    
    ... ... @@ -45,7 +46,8 @@ public class ToolkitTreeFlatModel implements ObserveDto {
    45 46
         private final String path;
    
    46 47
         private final Date lastUpdateDate;
    
    47 48
         private final Map<String, ToolkitTreeNodeStates> mapping;
    
    48
    -    private final long dataCount;
    
    49
    +    private long dataCount;
    
    50
    +
    
    49 51
         public static ToolkitTreeFlatModel of(ToolkitTreeNode node, Date now, long dataCount) {
    
    50 52
             return ToolkitTreeFlatModelWriter.of(node.getNodePath().toString(), now, node, dataCount);
    
    51 53
         }
    
    ... ... @@ -85,4 +87,11 @@ public class ToolkitTreeFlatModel implements ObserveDto {
    85 87
             mapping.entrySet().stream().filter(e -> pathFilter.test(e.getKey())).forEach(e -> state.setValue(e.getValue(), value));
    
    86 88
         }
    
    87 89
     
    
    90
    +    public void removeMapping(String path) {
    
    91
    +        ToolkitTreeNodeStates removed = mapping.remove(path);
    
    92
    +        Integer count = removed.getState(ToolkitTreeNodeBean.STATE_COUNT.name());
    
    93
    +        if (count == null) {
    
    94
    +            dataCount--;
    
    95
    +        }
    
    96
    +    }
    
    88 97
     }

  • toolkit/api/src/main/java/fr/ird/observe/navigation/tree/selection/SelectionTreeModelSupport.java
    ... ... @@ -38,7 +38,6 @@ import java.util.LinkedHashSet;
    38 38
     import java.util.LinkedList;
    
    39 39
     import java.util.List;
    
    40 40
     import java.util.Map;
    
    41
    -import java.util.Objects;
    
    42 41
     import java.util.Optional;
    
    43 42
     import java.util.Set;
    
    44 43
     import java.util.function.BiFunction;
    
    ... ... @@ -139,40 +138,33 @@ public class SelectionTreeModelSupport<R extends SelectionTreeNode> extends Tool
    139 138
             return builder;
    
    140 139
         }
    
    141 140
     
    
    142
    -    public Optional<SelectionTreeNode> getDataParentNode(ToolkitIdLabel data) {
    
    141
    +    public Optional<SelectionTreeNode> getDataNode(ToolkitIdLabel data) {
    
    143 142
             Enumeration<?> children = getRoot().children();
    
    144 143
             while (children.hasMoreElements()) {
    
    145 144
                 SelectionTreeNode topNode = (SelectionTreeNode) children.nextElement();
    
    146 145
                 SelectionTreeNode tripNode = topNode.findPath(data.getId());
    
    147
    -
    
    148 146
                 if (tripNode != null) {
    
    149
    -                return Optional.of(topNode);
    
    147
    +                return Optional.of(tripNode);
    
    150 148
                 }
    
    151 149
             }
    
    152 150
             return Optional.empty();
    
    153 151
         }
    
    154 152
     
    
    155
    -    public void removeDataFromParent(SelectionTreeNode topNode, ToolkitIdLabel data) {
    
    156
    -        SelectionTreeNode tripNode = topNode.findPath(data.getId());
    
    157
    -        Objects.requireNonNull(tripNode, "Could not find program node with id: " + data);
    
    158
    -        removeNodeFromParent(tripNode);
    
    159
    -        if (topNode.isLeaf()) {
    
    160
    -            removeNodeFromParent(topNode);
    
    161
    -        }
    
    162
    -    }
    
    163
    -
    
    164
    -    public void removeAllSelectedData() {
    
    165
    -        for (SelectionTreeNode node : selectedDataNodes()) {
    
    153
    +    public void removeData(List<SelectionTreeNode> data) {
    
    154
    +        for (SelectionTreeNode node : data) {
    
    166 155
                 SelectionTreeNode parent = node.getParent();
    
    167 156
                 if (parent.getParent() == null) {
    
    168 157
                     // This means that the parent was already removed
    
    169 158
                     continue;
    
    170 159
                 }
    
    171
    -            if (parent.isSelected()) {
    
    160
    +            if (parent.isSelected() || data.contains(parent)) {
    
    172 161
                     parent.removeFromParent();
    
    173 162
                 } else {
    
    174 163
                     node.removeFromParent();
    
    175 164
                 }
    
    165
    +            if (parent.isLeaf()) {
    
    166
    +                parent.removeFromParent();
    
    167
    +            }
    
    176 168
             }
    
    177 169
             recomputeSelectedCount();
    
    178 170
         }
    

  • toolkit/plugin/src/main/java/fr/ird/observe/toolkit/maven/plugin/service/ServiceGenerateLocalRunner.java
    ... ... @@ -25,6 +25,7 @@ package fr.ird.observe.toolkit.maven.plugin.service;
    25 25
     import fr.ird.observe.datasource.security.Permission;
    
    26 26
     import fr.ird.observe.services.service.ObserveService;
    
    27 27
     import fr.ird.observe.toolkit.maven.plugin.MojoRunnable;
    
    28
    +import io.ultreia.java4all.http.spi.Nullable;
    
    28 29
     import io.ultreia.java4all.http.spi.model.ImportManager;
    
    29 30
     import io.ultreia.java4all.http.spi.model.MethodDescription;
    
    30 31
     import io.ultreia.java4all.http.spi.model.ServiceMapping;
    
    ... ... @@ -61,35 +62,35 @@ public class ServiceGenerateLocalRunner extends MojoRunnable {
    61 62
                 "    private static final TimeLog TIME_LOG = new TimeLog(%5$s.class, 500, 1000);\n\n" +
    
    62 63
                 "%6$s\n" +
    
    63 64
                 "}";
    
    64
    -    public static final String CALL_BODY_NO_PERSISTENCE = "" +
    
    65
    +    public static final String CALL_BODY_NO_PERSISTENCE = "%1$s" +
    
    65 66
                 "        long t0 = TimeLog.getTime();\n" +
    
    66
    -            "        String methodName = %2$s;\n" +
    
    67
    +            "        String methodName = %3$s;\n" +
    
    67 68
                 "        try {\n" +
    
    68
    -            "            %1$s" +
    
    69
    +            "            %2$s" +
    
    69 70
                 "        } catch (Exception e) {\n" +
    
    70 71
                 "            recordError(e, methodName);\n" +
    
    71 72
                 "            throw e;\n" +
    
    72 73
                 "        } finally {\n" +
    
    73 74
                 "            TIME_LOG.log(t0, String.format(\"invoke method %%s\", methodName));\n" +
    
    74 75
                 "        }";
    
    75
    -    public static final String CALL_BODY_NO_TRANSACTION = "" +
    
    76
    +    public static final String CALL_BODY_NO_TRANSACTION = "%1$s" +
    
    76 77
                 "        long t0 = TimeLog.getTime();\n" +
    
    77
    -            "        String methodName = %2$s;\n" +
    
    78
    +            "        String methodName = %3$s;\n" +
    
    78 79
                 "        initPersistence(methodName);\n" +
    
    79 80
                 "        try {\n" +
    
    80
    -            "            %1$s" +
    
    81
    +            "            %2$s" +
    
    81 82
                 "        } catch (Exception e) {\n" +
    
    82 83
                 "            recordError(e, methodName);\n" +
    
    83 84
                 "            throw e;\n" +
    
    84 85
                 "        } finally {\n" +
    
    85 86
                 "            TIME_LOG.log(t0, String.format(\"invoke method %%s\", methodName));\n" +
    
    86 87
                 "        }";
    
    87
    -    public static final String CALL_BODY_WITH_TRANSACTION = "" +
    
    88
    +    public static final String CALL_BODY_WITH_TRANSACTION = "%1$s" +
    
    88 89
                 "        long t0 = TimeLog.getTime();\n" +
    
    89
    -            "        String methodName = %2$s;\n" +
    
    90
    -            "        boolean newTransaction = %3$s(methodName, Permission.%4$s);\n" +
    
    90
    +            "        String methodName = %3$s;\n" +
    
    91
    +            "        boolean newTransaction = %4$s(methodName, Permission.%5$s);\n" +
    
    91 92
                 "        try {\n" +
    
    92
    -            "            %1$s" +
    
    93
    +            "            %2$s" +
    
    93 94
                 "        } catch (Exception e) {\n" +
    
    94 95
                 "            recordError(e, methodName);\n" +
    
    95 96
                 "            throw e;\n" +
    
    ... ... @@ -212,11 +213,20 @@ public class ServiceGenerateLocalRunner extends MojoRunnable {
    212 213
             }
    
    213 214
             String exceptions = exceptionsBuilder.length() == 0 ? "" : "throws " + exceptionsBuilder.substring(2);
    
    214 215
     
    
    216
    +        StringBuilder checkParametersBuilder = new StringBuilder();
    
    215 217
             StringBuilder parametersBuilder = new StringBuilder();
    
    216 218
             StringBuilder parametersDeclarationBuilder = new StringBuilder();
    
    217 219
             int index = 0;
    
    218 220
             String methodNameClassifier = null;
    
    219 221
             for (String parameterName : methodDescription.getParameterNames()) {
    
    222
    +            parametersDeclarationBuilder.append(", ");
    
    223
    +            if (methodDescription.isNullableParameterName(parameterName)) {
    
    224
    +                importManager.addImport(Nullable.class);
    
    225
    +                parametersDeclarationBuilder.append("@").append(Nullable.class.getSimpleName()).append(" ");
    
    226
    +            } else if (!methodDescription.getMethod().getParameterTypes()[index].isPrimitive()) {
    
    227
    +                importManager.addImport(Objects.class);
    
    228
    +                checkParametersBuilder.append(String.format("        Objects.requireNonNull(%1$s, \"Parameter '%1$s' (in method %2$s#%3$s) can not be null.\");\n",  parameterName, className, methodName));
    
    229
    +            }
    
    220 230
                 String parameterType = methodDescription.getParameterTypes().get(index++);
    
    221 231
                 if (!parameterType.endsWith("[]")) {
    
    222 232
                     parameterType = importAndSimplify(importManager, parameterType);
    
    ... ... @@ -233,11 +243,12 @@ public class ServiceGenerateLocalRunner extends MojoRunnable {
    233 243
     //                }
    
    234 244
                 }
    
    235 245
                 parametersBuilder.append(", ").append(parameterName);
    
    236
    -            parametersDeclarationBuilder.append(", ").append(parameterType).append(" ").append(parameterName);
    
    246
    +            parametersDeclarationBuilder.append(parameterType).append(" ").append(parameterName);
    
    237 247
             }
    
    238 248
     
    
    239 249
             String parameters = index == 0 ? "" : parametersBuilder.substring(2);
    
    240 250
             String parametersDeclaration = index == 0 ? "" : parametersDeclarationBuilder.substring(2);
    
    251
    +        String checkParametersDeclaration = checkParametersBuilder.toString();
    
    241 252
             String returnInvocation = methodDescription.getReturnInvocation();
    
    242 253
             @SuppressWarnings("SpellCheckingInspection") String superCall = String.format("%ssuper.%s(%s);\n", returnInvocation, methodName, parameters);
    
    243 254
     
    
    ... ... @@ -246,7 +257,7 @@ public class ServiceGenerateLocalRunner extends MojoRunnable {
    246 257
             if (noTransaction) {
    
    247 258
                 getLog().debug(String.format("No transaction required on %s for method: %s", className, methodName));
    
    248 259
                 // no transaction in this call
    
    249
    -            bodyContent = String.format(CALL_BODY_NO_PERSISTENCE, superCall, generatedMethodName);
    
    260
    +            bodyContent = String.format(CALL_BODY_NO_PERSISTENCE, checkParametersDeclaration, superCall, generatedMethodName);
    
    250 261
             } else {
    
    251 262
                 boolean noCredential = methodeCredentials == null;
    
    252 263
                 if (noCredential) {
    
    ... ... @@ -254,13 +265,13 @@ public class ServiceGenerateLocalRunner extends MojoRunnable {
    254 265
                 }
    
    255 266
                 if (noCredential) {
    
    256 267
                     // init persistence, but do not open transaction
    
    257
    -                bodyContent = String.format(CALL_BODY_NO_TRANSACTION, superCall, generatedMethodName);
    
    268
    +                bodyContent = String.format(CALL_BODY_NO_TRANSACTION, checkParametersDeclaration, superCall, generatedMethodName);
    
    258 269
     
    
    259 270
                 } else {
    
    260 271
                     // init persistence and create a new transaction if required
    
    261 272
                     String initTransactionMethodName = write ? "initWriteTransaction" : "initReadTransaction";
    
    262 273
                     importManager.importAndSimplify(Permission.class.getName());
    
    263
    -                bodyContent = String.format(CALL_BODY_WITH_TRANSACTION, superCall, generatedMethodName, initTransactionMethodName, methodeCredentials);
    
    274
    +                bodyContent = String.format(CALL_BODY_WITH_TRANSACTION, checkParametersDeclaration, superCall, generatedMethodName, initTransactionMethodName, methodeCredentials);
    
    264 275
                 }
    
    265 276
             }
    
    266 277
             return String.format(METHOD, realReturnType, methodName, parametersDeclaration, exceptions, bodyContent);
    

  • toolkit/plugin/src/main/java/fr/ird/observe/toolkit/maven/plugin/service/ServiceLocalMethodDescriptionImpl.java
    ... ... @@ -24,6 +24,7 @@ package fr.ird.observe.toolkit.maven.plugin.service;
    24 24
     
    
    25 25
     import fr.ird.observe.datasource.security.Permission;
    
    26 26
     import fr.ird.observe.services.service.MethodCredential;
    
    27
    +import io.ultreia.java4all.http.spi.Nullable;
    
    27 28
     import io.ultreia.java4all.http.spi.SpiHelper;
    
    28 29
     import io.ultreia.java4all.http.spi.model.ImportManager;
    
    29 30
     import io.ultreia.java4all.http.spi.model.MethodDescription;
    
    ... ... @@ -50,6 +51,7 @@ public class ServiceLocalMethodDescriptionImpl implements MethodDescription {
    50 51
         private final List<Class<?>> exceptions;
    
    51 52
         private final List<String> parameterNames;
    
    52 53
         private final List<String> parameterTypes;
    
    54
    +    private final List<String> nullableParameterNames;
    
    53 55
         private final Permission methodeCredentials;
    
    54 56
         private final boolean write;
    
    55 57
         private final boolean noTransaction;
    
    ... ... @@ -64,15 +66,17 @@ public class ServiceLocalMethodDescriptionImpl implements MethodDescription {
    64 66
     
    
    65 67
             parameterNames = new LinkedList<>();
    
    66 68
             parameterTypes = new LinkedList<>();
    
    69
    +        nullableParameterNames = new LinkedList<>();
    
    67 70
             for (java.lang.reflect.Parameter parameter : method.getParameters()) {
    
    68 71
                 String name = parameter.getName();
    
    69 72
                 parameterNames.add(name);
    
    70 73
                 parameterTypes.add(importManager.importParameterType(parameter, currentMapping));
    
    74
    +            if (parameter.isAnnotationPresent(Nullable.class)) {
    
    75
    +                nullableParameterNames.add(name);
    
    76
    +            }
    
    71 77
             }
    
    72
    -
    
    73 78
             this.returnInvocation = returnType.contains("void") ? "" : "return ";
    
    74 79
             this.exceptions = MethodDescription.getExceptions(method, importManager);
    
    75
    -
    
    76 80
             this.methodeCredentials = Optional.ofNullable(method.getAnnotation(MethodCredential.class)).map(MethodCredential::value).orElse(null);
    
    77 81
             this.write = SpiHelper.write(method);
    
    78 82
             this.noTransaction = !SpiHelper.getRequestAnnotation(method).isAddAuthenticationToken();
    
    ... ... @@ -127,6 +131,10 @@ public class ServiceLocalMethodDescriptionImpl implements MethodDescription {
    127 131
             return parameterTypes;
    
    128 132
         }
    
    129 133
     
    
    134
    +    public boolean isNullableParameterName(String parameterName) {
    
    135
    +        return nullableParameterNames.contains(parameterName);
    
    136
    +    }
    
    137
    +
    
    130 138
         public boolean isNoTransaction() {
    
    131 139
             return noTransaction;
    
    132 140
         }
    

  • toolkit/server/src/main/java/org/debux/webmotion/server/handler/injector/CollectionInjector.java
    ... ... @@ -54,7 +54,7 @@ public class CollectionInjector extends JsonInjector<Collection> {
    54 54
             }
    
    55 55
             String[] values = (String[]) parameterTree.getValue();
    
    56 56
             String value = values[0];
    
    57
    -        if (value.length() > 0) {
    
    57
    +        if (!value.isEmpty()) {
    
    58 58
                 if (onString) {
    
    59 59
                     if (!value.contains("[")) {
    
    60 60
                         // use values
    

  • toolkit/server/src/main/java/org/debux/webmotion/server/handler/injector/JsonInjector.java
    ... ... @@ -80,7 +80,7 @@ public abstract class JsonInjector<O> implements ExecutorParametersInjectorHandl
    80 80
         }
    
    81 81
     
    
    82 82
         protected O buildNullValue(Call call, String name, Class<?> type, Type generic) {
    
    83
    -        throw new NullPointerException(String.format("By default do not accept null parameterTrees for parameter: %s with type: %s", name, type.getName()));
    
    83
    +        throw new NullPointerException(String.format("By default do not accept null parameterTree for parameter: %s with type: %s", name, type.getName()));
    
    84 84
         }
    
    85 85
     
    
    86 86
     }