Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe
Commits:
-
23507f24
by Tony Chemit at 2024-03-21T14:54:48+01:00
-
4e2aa441
by Tony Chemit at 2024-03-21T14:54:48+01:00
-
edd00f7a
by Tony Chemit at 2024-03-21T14:54:48+01:00
-
1cf5f9f1
by Tony Chemit at 2024-03-21T14:54:48+01:00
-
f64c2710
by Tony Chemit at 2024-03-21T14:54:48+01:00
-
cf32dd6f
by Tony Chemit at 2024-03-21T14:54:48+01:00
22 changed files:
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/save/actions/Start.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/DataSynchroModel.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/DataSynchroUI.jaxx
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/DataSynchroUIHandler.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/actions/Apply.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/actions/Start.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/DataSelectionTreePane.jaxx
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/DataSelectionTreePaneHandler.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/DataSelectionTreePaneModel.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/actions/DataSelectionTreePaneActionSupport.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/actions/RegisterCopy.java
- client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/actions/RegisterDelete.java
- core/persistence/report/src/main/resources/META-INF/report/default/ps/psObservationActivitiesByZone.report
- pom.xml
- server/core/src/main/java/fr/ird/observe/server/injector/JsonAwareDtoInjector.java
- toolkit/api/src/main/java/fr/ird/observe/navigation/tree/ToolkitTreeModelSupport.java
- toolkit/api/src/main/java/fr/ird/observe/navigation/tree/io/ToolkitTreeFlatModel.java
- toolkit/api/src/main/java/fr/ird/observe/navigation/tree/selection/SelectionTreeModelSupport.java
- toolkit/plugin/src/main/java/fr/ird/observe/toolkit/maven/plugin/service/ServiceGenerateLocalRunner.java
- toolkit/plugin/src/main/java/fr/ird/observe/toolkit/maven/plugin/service/ServiceLocalMethodDescriptionImpl.java
- toolkit/server/src/main/java/org/debux/webmotion/server/handler/injector/CollectionInjector.java
- toolkit/server/src/main/java/org/debux/webmotion/server/handler/injector/JsonInjector.java
Changes:
| ... | ... | @@ -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 | }
|
| ... | ... | @@ -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() {
|
| ... | ... | @@ -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<TaskSide, DataSelectionTreePane>">
|
|
| 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>
|
| ... | ... | @@ -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
|
| ... | ... | @@ -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 {
|
| ... | ... | @@ -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();
|
| ... | ... | @@ -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> |
| ... | ... | @@ -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 |
| ... | ... | @@ -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 | } |
| ... | ... | @@ -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 | } |
| ... | ... | @@ -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 | } |
| ... | ... | @@ -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 | } |
| ... | ... | @@ -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
|
| ... | ... | @@ -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>
|
| ... | ... | @@ -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 | } |
| ... | ... | @@ -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 | }
|
| ... | ... | @@ -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 | } |
| ... | ... | @@ -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 | }
|
| ... | ... | @@ -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);
|
| ... | ... | @@ -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 | }
|
| ... | ... | @@ -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
|
| ... | ... | @@ -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 | } |