Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: 08505b7c by Tony CHEMIT at 2017-08-17T16:17:45+02:00 Pouvoir ajouter une connexion directe ou serveur depuis l'écran de gestion des connexions (See #842) - - - - - 26 changed files: - client/src/main/java/fr/ird/observe/client/ui/actions/UIActionSupport.java - client/src/main/java/fr/ird/observe/client/ui/actions/main/global/DeleteDataGlobalUIAction.java - client/src/main/java/fr/ird/observe/client/ui/actions/main/global/NewNextDataGlobalUIAction.java - client/src/main/java/fr/ird/observe/client/ui/actions/main/global/ResetDataGlobalUIAction.java - client/src/main/java/fr/ird/observe/client/ui/actions/main/global/SaveDataGlobalUIAction.java - client/src/main/java/fr/ird/observe/client/ui/actions/storage/SaveCurrentRemoteConfigurationUIAction.java - client/src/main/java/fr/ird/observe/client/ui/actions/storage/SaveCurrentServerConfigurationUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/CreatePresetUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/DeleteRemoteUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/DeleteServerUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/PresetsUIActionSupport.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/QuitPresetsUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/ResetRemoteUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/ResetServerUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/SaveRemoteUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/SaveServerUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/TestRemoteUIAction.java - + client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/TestServerUIAction.java - client/src/main/java/fr/ird/observe/client/ui/storage/StorageUIModel.java - client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUI.jaxx - client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUI.jcss - client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUIHandler.java - client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUIModel.java - client/src/main/resources/i18n/client_en_GB.properties - client/src/main/resources/i18n/client_es_ES.properties - client/src/main/resources/i18n/client_fr_FR.properties Changes: ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/UIActionSupport.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/actions/UIActionSupport.java +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/UIActionSupport.java @@ -53,7 +53,7 @@ public abstract class UIActionSupport extends AbstractAction { private static final long serialVersionUID = 1L; public static final String EDITOR = "editor"; - protected static final String CLIENT_PROPERTY_UI = "ui"; + public static final String CLIENT_PROPERTY_UI = "ui"; private final ObserveMainUI mainUI; ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/main/global/DeleteDataGlobalUIAction.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/actions/main/global/DeleteDataGlobalUIAction.java +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/main/global/DeleteDataGlobalUIAction.java @@ -24,10 +24,12 @@ package fr.ird.observe.client.ui.actions.main.global; import fr.ird.observe.client.ui.ObserveKeyStrokes; import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.ObserveUIMode; import fr.ird.observe.client.ui.actions.UIActionSupport; import fr.ird.observe.client.ui.content.ContentUI; import fr.ird.observe.client.ui.content.ref.ContentReferenceUI; import fr.ird.observe.client.ui.content.table.ContentTableUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; import java.util.Objects; import javax.swing.JButton; @@ -47,19 +49,35 @@ public class DeleteDataGlobalUIAction extends GlobalUIActionSupport { @Override protected UIActionSupport getDelegateAction(ContentUI<?, ?> contentUI) { - JButton button; - if (contentUI instanceof ContentTableUI) { - ContentTableUI ui = (ContentTableUI) contentUI; - button = ui.getDeleteEntry(); - } else if (contentUI instanceof ContentReferenceUI) { - ContentReferenceUI ui = (ContentReferenceUI) contentUI; - if (ui.getModel().isEditing()) { - button = ui.getDeleteFromDetail(); - } else { - button = ui.getDeleteFromList(); + JButton button = null; + if (contentUI == null) { + + if (ObserveUIMode.PRESETS == getMainUI().getModel().getMode()) { + RemotePresetsUI presetsUI = (RemotePresetsUI) getMainUI().getDataSourcePresets().getContentContainer(); + switch (presetsUI.getTabs().getSelectedIndex()) { + case 0: + button = presetsUI.getDeleteRemoteAction(); + break; + case 1: + button = presetsUI.getDeleteServerAction(); + break; + + } } } else { - button = (JButton) contentUI.getObjectById("delete"); + if (contentUI instanceof ContentTableUI) { + ContentTableUI ui = (ContentTableUI) contentUI; + button = ui.getDeleteEntry(); + } else if (contentUI instanceof ContentReferenceUI) { + ContentReferenceUI ui = (ContentReferenceUI) contentUI; + if (ui.getModel().isEditing()) { + button = ui.getDeleteFromDetail(); + } else { + button = ui.getDeleteFromList(); + } + } else { + button = (JButton) contentUI.getObjectById("delete"); + } } Objects.requireNonNull(button); UIActionSupport action = (UIActionSupport) button.getAction(); ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/main/global/NewNextDataGlobalUIAction.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/actions/main/global/NewNextDataGlobalUIAction.java +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/main/global/NewNextDataGlobalUIAction.java @@ -24,12 +24,14 @@ package fr.ird.observe.client.ui.actions.main.global; import fr.ird.observe.client.ui.ObserveKeyStrokes; import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.ObserveUIMode; import fr.ird.observe.client.ui.actions.UIActionSupport; import fr.ird.observe.client.ui.content.ContentUI; import fr.ird.observe.client.ui.content.list.ContentListUI; import fr.ird.observe.client.ui.content.open.ContentOpenableUI; import fr.ird.observe.client.ui.content.ref.ContentReferenceUI; import fr.ird.observe.client.ui.content.table.ContentTableUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; import javax.swing.JButton; /** @@ -49,18 +51,27 @@ public class NewNextDataGlobalUIAction extends GlobalUIActionSupport { @Override protected UIActionSupport getDelegateAction(ContentUI<?, ?> contentUI) { JButton button = null; - if (contentUI instanceof ContentListUI) { - ContentListUI ui = (ContentListUI) contentUI; - button = ui.getCreate(); - } else if (contentUI instanceof ContentOpenableUI) { - ContentOpenableUI ui = (ContentOpenableUI) contentUI; - button = ui.getCloseAndCreate(); - } else if (contentUI instanceof ContentTableUI) { - ContentTableUI ui = (ContentTableUI) contentUI; - button = ui.getNewEntry(); - } else if (contentUI instanceof ContentReferenceUI) { - ContentReferenceUI ui = (ContentReferenceUI) contentUI; - button = ui.getCreate(); + if (contentUI == null) { + + if (ObserveUIMode.PRESETS == getMainUI().getModel().getMode()) { + RemotePresetsUI presetsUI = (RemotePresetsUI) getMainUI().getDataSourcePresets().getContentContainer(); + button = presetsUI.getCreateAction(); + } + } else { + + if (contentUI instanceof ContentListUI) { + ContentListUI ui = (ContentListUI) contentUI; + button = ui.getCreate(); + } else if (contentUI instanceof ContentOpenableUI) { + ContentOpenableUI ui = (ContentOpenableUI) contentUI; + button = ui.getCloseAndCreate(); + } else if (contentUI instanceof ContentTableUI) { + ContentTableUI ui = (ContentTableUI) contentUI; + button = ui.getNewEntry(); + } else if (contentUI instanceof ContentReferenceUI) { + ContentReferenceUI ui = (ContentReferenceUI) contentUI; + button = ui.getCreate(); + } } return button == null ? null : (UIActionSupport) button.getAction(); } ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/main/global/ResetDataGlobalUIAction.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/actions/main/global/ResetDataGlobalUIAction.java +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/main/global/ResetDataGlobalUIAction.java @@ -24,8 +24,10 @@ package fr.ird.observe.client.ui.actions.main.global; import fr.ird.observe.client.ui.ObserveKeyStrokes; import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.ObserveUIMode; import fr.ird.observe.client.ui.actions.UIActionSupport; import fr.ird.observe.client.ui.content.ContentUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; import javax.swing.JButton; /** @@ -45,7 +47,24 @@ public class ResetDataGlobalUIAction extends GlobalUIActionSupport { @Override protected UIActionSupport getDelegateAction(ContentUI<?, ?> contentUI) { UIActionSupport action = null; - JButton button = (JButton) contentUI.getObjectById("reset"); + JButton button = null; + if (contentUI == null) { + + if (ObserveUIMode.PRESETS == getMainUI().getModel().getMode()) { + RemotePresetsUI presetsUI = (RemotePresetsUI) getMainUI().getDataSourcePresets().getContentContainer(); + switch (presetsUI.getTabs().getSelectedIndex()) { + case 0: + button = presetsUI.getResetRemoteAction(); + break; + case 1: + button = presetsUI.getResetServerAction(); + break; + + } + } + } else { + button = (JButton) contentUI.getObjectById("reset"); + } if (button != null) { action = (UIActionSupport) button.getAction(); } ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/main/global/SaveDataGlobalUIAction.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/actions/main/global/SaveDataGlobalUIAction.java +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/main/global/SaveDataGlobalUIAction.java @@ -24,8 +24,10 @@ package fr.ird.observe.client.ui.actions.main.global; import fr.ird.observe.client.ui.ObserveKeyStrokes; import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.ObserveUIMode; import fr.ird.observe.client.ui.actions.UIActionSupport; import fr.ird.observe.client.ui.content.ContentUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; import javax.swing.JButton; /** @@ -45,7 +47,25 @@ public class SaveDataGlobalUIAction extends GlobalUIActionSupport { @Override protected UIActionSupport getDelegateAction(ContentUI<?, ?> contentUI) { UIActionSupport action = null; - JButton button = (JButton) contentUI.getObjectById("save"); + + JButton button = null; + if (contentUI == null) { + + if (ObserveUIMode.PRESETS == getMainUI().getModel().getMode()) { + RemotePresetsUI presetsUI = (RemotePresetsUI) getMainUI().getDataSourcePresets().getContentContainer(); + switch (presetsUI.getTabs().getSelectedIndex()) { + case 0: + button = presetsUI.getSaveRemoteAction(); + break; + case 1: + button = presetsUI.getSaveServerAction(); + break; + + } + } + } else { + button = (JButton) contentUI.getObjectById("save"); + } if (button != null) { action = (UIActionSupport) button.getAction(); } ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/SaveCurrentRemoteConfigurationUIAction.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/actions/storage/SaveCurrentRemoteConfigurationUIAction.java +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/SaveCurrentRemoteConfigurationUIAction.java @@ -24,10 +24,10 @@ package fr.ird.observe.client.ui.actions.storage; import fr.ird.observe.client.ObserveSwingApplicationContext; import fr.ird.observe.client.ui.ObserveMainUI; -import fr.ird.observe.client.ui.util.UIHelper; import fr.ird.observe.client.ui.actions.main.menu.MenuActionSupport; import fr.ird.observe.client.ui.storage.StorageUIModel; import fr.ird.observe.client.ui.storage.tabs.ConfigUI; +import fr.ird.observe.client.ui.util.UIHelper; import fr.ird.observe.services.dto.presets.RemoteDataSourceConfiguration; import java.awt.Dimension; import java.awt.GridLayout; @@ -118,6 +118,6 @@ public class SaveCurrentRemoteConfigurationUIAction extends MenuActionSupport { configuration.setPassword(new String(model.getRemotePassword())); configuration.setUseSsl(model.isUseSsl()); ObserveSwingApplicationContext.get().getConfig().addRemoteDataSourceConfiguration(configuration); - configUI.getHandler().addRemoteConfiguration(configuration); + configUI.getHandler().addRemoteConfiguration(getMainUI(), configuration, configUI.getRemoteMenu().getComponentCount() - 2); } } ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/SaveCurrentServerConfigurationUIAction.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/actions/storage/SaveCurrentServerConfigurationUIAction.java +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/SaveCurrentServerConfigurationUIAction.java @@ -23,10 +23,10 @@ package fr.ird.observe.client.ui.actions.storage; */ import fr.ird.observe.client.ui.ObserveMainUI; -import fr.ird.observe.client.ui.util.UIHelper; import fr.ird.observe.client.ui.actions.main.menu.MenuActionSupport; import fr.ird.observe.client.ui.storage.StorageUIModel; import fr.ird.observe.client.ui.storage.tabs.ConfigUI; +import fr.ird.observe.client.ui.util.UIHelper; import fr.ird.observe.services.dto.presets.ServerDataSourceConfiguration; import java.awt.Dimension; import java.awt.GridLayout; @@ -59,10 +59,6 @@ public class SaveCurrentServerConfigurationUIAction extends MenuActionSupport { super(mainUI, ACTION_NAME, t("observe.storage.serverConfiguration.presets.save"), t("observe.storage.serverConfiguration.presets.save"), "save", 'S'); } - public SaveCurrentServerConfigurationUIAction(ConfigUI mainUI) { - super(null, ACTION_NAME, t("observe.storage.serverConfiguration.presets.save"), t("observe.storage.serverConfiguration.presets.save"), "save", 'S'); - } - @Override protected void doActionPerformed(ActionEvent e) { @@ -122,7 +118,7 @@ public class SaveCurrentServerConfigurationUIAction extends MenuActionSupport { configuration.setDatabaseName(model.getServerDatabase()); getMainUI().getConfig().addServerDataSourceConfiguration(configuration); - configUI.getHandler().addServerConfiguration(configuration); + configUI.getHandler().addServerConfiguration(getMainUI(), configuration, configUI.getServerMenu().getComponentCount() - 2); } } ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/CreatePresetUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/CreatePresetUIAction.java @@ -0,0 +1,76 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ui.ObserveKeyStrokes; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.services.dto.presets.RemoteDataSourceConfiguration; +import fr.ird.observe.services.dto.presets.ServerDataSourceConfiguration; +import java.util.ArrayList; +import java.util.List; + + +import static org.nuiton.i18n.I18n.n; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class CreatePresetUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = CreatePresetUIAction.class.getName(); + + public CreatePresetUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.presets.create"), n("observe.action.presets.create.tip"), "add", ObserveKeyStrokes.KEY_STROKE_NEW_NEXT_DATA); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + switch (ui.getTabs().getSelectedIndex()) { + case 0: { + RemoteDataSourceConfiguration configuration = new RemoteDataSourceConfiguration(); + configuration.setName("Change me"); + List<RemoteDataSourceConfiguration> configurations = new ArrayList<>(ui.getModel().getRemoteDataSourceConfigurations()); + configurations.add(configuration); + ui.getModel().setRemoteDataSourceConfigurations(configurations); + + ui.getRemoteConfigurations().setSelectedValue(configuration, true); + } + break; + case 1: { + ServerDataSourceConfiguration configuration = new ServerDataSourceConfiguration(); + configuration.setName("Change me"); + + List<ServerDataSourceConfiguration> configurations = new ArrayList<>(ui.getModel().getServerDataSourceConfigurations()); + configurations.add(configuration); + ui.getModel().setServerDataSourceConfigurations(configurations); + ui.getServerConfigurations().setSelectedValue(configuration, true); + } + break; + } + + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/DeleteRemoteUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/DeleteRemoteUIAction.java @@ -0,0 +1,75 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ObserveSwingApplicationContext; +import fr.ird.observe.client.ui.ObserveKeyStrokes; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.client.ui.util.UIHelper; +import fr.ird.observe.services.dto.presets.RemoteDataSourceConfiguration; +import fr.ird.observe.services.dto.presets.ServerDataSourceConfiguration; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JOptionPane; +import org.nuiton.decorator.Decorator; + + +import static org.nuiton.i18n.I18n.n; +import static org.nuiton.i18n.I18n.t; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class DeleteRemoteUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = DeleteRemoteUIAction.class.getName(); + + public DeleteRemoteUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.delete"), n("observe.action.delete.remote.tip"), "delete", ObserveKeyStrokes.KEY_STROKE_DELETE_DATA_GLOBAL); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + Decorator<RemoteDataSourceConfiguration> decorator = ObserveSwingApplicationContext.get().getDecoratorService().getDecoratorByType(RemoteDataSourceConfiguration.class); + RemoteDataSourceConfiguration configuration = ui.getModel().getRemoteDataSourceConfiguration(); + int response = UIHelper.askUser(t("observe.storage.presets.delete.title"), + t("observe.storage.presets.delete.message", decorator.toString(configuration)), + JOptionPane.QUESTION_MESSAGE, + new Object[]{t("observe.action.delete"), t("observe.action.cancel")}, + 0); + boolean delete = response == 0; + + if (delete) { + + List<RemoteDataSourceConfiguration> configurations = new ArrayList<>(ui.getModel().getRemoteDataSourceConfigurations()); + configurations.remove(configuration); + ui.getModel().setRemoteDataSourceConfigurations(configurations); + ObserveSwingApplicationContext.get().getConfig().removeRemoteDataSourceConfiguration(configuration); + ui.getModel().setRemoteDataSourceConfiguration(null); + } + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/DeleteServerUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/DeleteServerUIAction.java @@ -0,0 +1,77 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ObserveSwingApplicationContext; +import fr.ird.observe.client.ui.ObserveKeyStrokes; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.client.ui.util.UIHelper; +import fr.ird.observe.services.dto.presets.ServerDataSourceConfiguration; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JOptionPane; +import org.nuiton.decorator.Decorator; + + +import static org.nuiton.i18n.I18n.n; +import static org.nuiton.i18n.I18n.t; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class DeleteServerUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = DeleteServerUIAction.class.getName(); + + public DeleteServerUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.delete"), n("observe.action.delete.server.tip"), "delete", ObserveKeyStrokes.KEY_STROKE_DELETE_DATA_GLOBAL); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + Decorator<ServerDataSourceConfiguration> decorator = ObserveSwingApplicationContext.get().getDecoratorService().getDecoratorByType(ServerDataSourceConfiguration.class); + ServerDataSourceConfiguration configuration = ui.getModel().getServerDataSourceConfiguration(); + + int response = UIHelper.askUser(t("observe.storage.presets.delete.title"), + t("observe.storage.presets.delete.message", decorator.toString(configuration)), + JOptionPane.QUESTION_MESSAGE, + new Object[]{t("observe.action.delete"), t("observe.action.cancel")}, + 0 + ); + boolean delete = response == 0; + + if (delete) { + + List<ServerDataSourceConfiguration> configurations = new ArrayList<>(ui.getModel().getServerDataSourceConfigurations()); + configurations.remove(configuration); + ui.getModel().setServerDataSourceConfigurations(configurations); + ObserveSwingApplicationContext.get().getConfig().removeServerDataSourceConfiguration(configuration); + ui.getModel().setServerDataSourceConfiguration(null); + } + + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/PresetsUIActionSupport.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/PresetsUIActionSupport.java @@ -0,0 +1,58 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.actions.UIActionSupport; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import java.awt.event.ActionEvent; +import javax.swing.KeyStroke; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public abstract class PresetsUIActionSupport extends UIActionSupport { + + PresetsUIActionSupport(ObserveMainUI mainUI, String actionName, String label, String tip, String actionIcon, KeyStroke keyStroke) { + super(mainUI, actionName, label, tip, actionIcon, keyStroke); + } + PresetsUIActionSupport(ObserveMainUI mainUI, String actionName, String label, String tip, String actionIcon, char keyStroke) { + super(mainUI, actionName, label, tip, actionIcon, keyStroke); + } + + protected abstract void doActionPerformed(RemotePresetsUI ui); + + @Override + public void actionPerformed(ActionEvent event) { + if (!getEditor().isShowing()) { + return; + } + + RemotePresetsUI ui = (RemotePresetsUI) getEditor().getClientProperty(CLIENT_PROPERTY_UI); + + doActionPerformed(ui); + + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/QuitPresetsUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/QuitPresetsUIAction.java @@ -0,0 +1,58 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ObserveSwingApplicationContext; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.ObserveUIMode; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import javax.swing.JPanel; + + +import static org.nuiton.i18n.I18n.n; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class QuitPresetsUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = QuitPresetsUIAction.class.getName(); + + public QuitPresetsUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.quit"), n("observe.action.quit.tip"), "exit", 'Q'); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + ObserveMainUI mainUI = ObserveSwingApplicationContext.get().getMainUI(); + mainUI.getDataSourcePresets().setContentContainer(new JPanel()); + if (ObserveSwingApplicationContext.get().getDataSourcesManager().getMainDataSource() == null) { + mainUI.getModel().setMode(ObserveUIMode.NO_DB); + } else { + mainUI.getModel().setMode(ObserveUIMode.DB); + } + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/ResetRemoteUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/ResetRemoteUIAction.java @@ -0,0 +1,55 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ui.ObserveKeyStrokes; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.services.dto.presets.RemoteDataSourceConfiguration; + + +import static org.nuiton.i18n.I18n.n; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class ResetRemoteUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = ResetRemoteUIAction.class.getName(); + + public ResetRemoteUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.reset"), n("observe.action.reset.remote.tip"), "revert", ObserveKeyStrokes.KEY_STROKE_RESET_DATA); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + RemoteDataSourceConfiguration selectedValue = ui.getRemoteConfigurations().getSelectedValue(); + + ui.getModel().setRemoteDataSourceConfiguration(null); + ui.getModel().setRemoteDataSourceConfiguration(selectedValue); + + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/ResetServerUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/ResetServerUIAction.java @@ -0,0 +1,54 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ui.ObserveKeyStrokes; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.services.dto.presets.ServerDataSourceConfiguration; + + +import static org.nuiton.i18n.I18n.n; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class ResetServerUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = ResetServerUIAction.class.getName(); + + public ResetServerUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.reset"), n("observe.action.reset.server.tip"), "revert", ObserveKeyStrokes.KEY_STROKE_RESET_DATA); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + ServerDataSourceConfiguration selectedValue = ui.getServerConfigurations().getSelectedValue(); + ui.getModel().setServerDataSourceConfiguration(null); + ui.getModel().setServerDataSourceConfiguration(selectedValue); + + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/SaveRemoteUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/SaveRemoteUIAction.java @@ -0,0 +1,65 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ObserveSwingApplicationContext; +import fr.ird.observe.client.ui.ObserveKeyStrokes; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.services.dto.presets.RemoteDataSourceConfiguration; + + +import static org.nuiton.i18n.I18n.n; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class SaveRemoteUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = SaveRemoteUIAction.class.getName(); + + public SaveRemoteUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.save"), n("observe.action.save.remote.tip"), "save", ObserveKeyStrokes.KEY_STROKE_SAVE_DATA); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + RemoteDataSourceConfiguration remoteDataSourceConfiguration = ui.getModel().getRemoteDataSourceConfiguration(); + + remoteDataSourceConfiguration.setName(ui.getRemoteName().getText().trim()); + remoteDataSourceConfiguration.setUrl(ui.getRemoteUrl().getText().trim()); + remoteDataSourceConfiguration.setLogin(ui.getRemoteLogin().getText().trim()); + remoteDataSourceConfiguration.setPassword(ui.getRemotePassword().getText().trim()); + remoteDataSourceConfiguration.setUseSsl(ui.getRemoteUseSsl().isSelected()); + + ObserveSwingApplicationContext.get().getConfig().updateRemoteDataSourceConfiguration(remoteDataSourceConfiguration); + + ui.getModel().setRemoteDataSourceConfiguration(null); + ui.getModel().setRemoteDataSourceConfiguration(remoteDataSourceConfiguration); + ui.getModel().setRemoteModified(false); + + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/SaveServerUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/SaveServerUIAction.java @@ -0,0 +1,66 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ObserveSwingApplicationContext; +import fr.ird.observe.client.ui.ObserveKeyStrokes; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.services.dto.presets.ServerDataSourceConfiguration; + + +import static org.nuiton.i18n.I18n.n; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class SaveServerUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = SaveServerUIAction.class.getName(); + + public SaveServerUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.save"), n("observe.action.save.server.tip"), "save", ObserveKeyStrokes.KEY_STROKE_SAVE_DATA); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + ServerDataSourceConfiguration serverDataSourceConfiguration = ui.getModel().getServerDataSourceConfiguration(); + + serverDataSourceConfiguration.setName(ui.getServerName().getText().trim()); + serverDataSourceConfiguration.setUrl(ui.getServerUrl().getText().trim()); + serverDataSourceConfiguration.setLogin(ui.getServerLogin().getText().trim()); + serverDataSourceConfiguration.setPassword(ui.getServerPassword().getText().trim()); + String databaseName = ui.getServerDataBase().getText().trim(); + serverDataSourceConfiguration.setDatabaseName(databaseName.isEmpty() ? null : databaseName); + + ObserveSwingApplicationContext.get().getConfig().updateServerDataSourceConfiguration(serverDataSourceConfiguration); + + ui.getModel().setServerDataSourceConfiguration(null); + ui.getModel().setServerDataSourceConfiguration(serverDataSourceConfiguration); + ui.getModel().setServerModified(false); + + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/TestRemoteUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/TestRemoteUIAction.java @@ -0,0 +1,109 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ObserveSwingApplicationContext; +import fr.ird.observe.client.db.ObserveSwingDataSource; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.client.ui.util.UIHelper; +import fr.ird.observe.services.configuration.ObserveDataSourceInformation; +import fr.ird.observe.services.configuration.topia.ObserveDataSourceConfigurationTopiaPG; +import fr.ird.observe.services.security.BadObserveWebUserPasswordException; +import fr.ird.observe.services.security.UnknownObserveWebUserException; +import fr.ird.observe.services.security.UnknownObserveWebUserForDatabaseException; +import fr.ird.observe.services.security.UserLoginNotFoundException; +import fr.ird.observe.services.security.UserPasswordNotFoundException; +import org.nuiton.version.Version; + + +import static org.nuiton.i18n.I18n.n; +import static org.nuiton.i18n.I18n.t; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class TestRemoteUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = TestRemoteUIAction.class.getName(); + + public TestRemoteUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.test.remote"), n("observe.action.test.remote.tip"), "connect_creating", 'V'); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + ObserveDataSourceConfigurationTopiaPG config = new ObserveDataSourceConfigurationTopiaPG(); + config.setJdbcUrl(ui.getRemoteUrl().getText().trim()); + config.setUsername(ui.getRemoteLogin().getText().trim()); + config.setPassword(ui.getRemotePassword().getText().trim().toCharArray()); + config.setUseSsl(ui.getRemoteUseSsl().isSelected()); + + String connexionStatusError = null; + + Version modelVersion = ObserveSwingApplicationContext.get().getConfig().getModelVersion(); + ObserveSwingDataSource dataSource = ObserveSwingApplicationContext.get().getDataSourcesManager().newDataSource(config); + try { + + ObserveDataSourceInformation dataSourceInformation = dataSource.checkCanConnect(); + + Version versionDataSource = dataSourceInformation.getVersion(); + + // en mise a jour de la base on ne test pas la version + if (!modelVersion.equals(versionDataSource)) { + + connexionStatusError = t("observe.storage.error.dbVersionMismatch", versionDataSource, modelVersion); + } + + } catch (UnknownObserveWebUserException e) { + connexionStatusError = t("observe.storage.error.rest.user.unknown", e.getUserLogin()); + } catch (BadObserveWebUserPasswordException e) { + connexionStatusError = t("observe.storage.error.rest.password.bad", e.getUserLogin()); + } catch (UnknownObserveWebUserForDatabaseException e) { + connexionStatusError = t("observe.storage.error.rest.database.unknownForUser", e.getDatabaseName(), e.getRole()); + } catch (UserLoginNotFoundException e) { + connexionStatusError = t("observe.storage.error.rest.user.required"); + } catch (UserPasswordNotFoundException e) { + connexionStatusError = t("observe.storage.error.rest.password.required"); + } catch (Exception e) { + connexionStatusError = e.getMessage(); + if (connexionStatusError == null || connexionStatusError.isEmpty()) { + connexionStatusError = e.getClass().getName(); + } + } finally { + if (dataSource.isOpen()) { + dataSource.close(); + } + } + + if (connexionStatusError == null) { + UIHelper.displayInfo("Test de connexion", "Le connexion a été établie avec succès."); + } else { + UIHelper.displayWarning("Test de connexion", "Le test de connexion a échoué :\n" + connexionStatusError); + } + + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/TestServerUIAction.java ===================================== --- /dev/null +++ b/client/src/main/java/fr/ird/observe/client/ui/actions/storage/presets/TestServerUIAction.java @@ -0,0 +1,143 @@ +package fr.ird.observe.client.ui.actions.storage.presets; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2017 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ird.observe.client.ObserveSwingApplicationContext; +import fr.ird.observe.client.db.ObserveSwingDataSource; +import fr.ird.observe.client.ui.ObserveMainUI; +import fr.ird.observe.client.ui.storage.presets.RemotePresetsUI; +import fr.ird.observe.client.ui.util.UIHelper; +import fr.ird.observe.services.configuration.ObserveDataSourceInformation; +import fr.ird.observe.services.configuration.rest.ObserveDataSourceConfigurationRest; +import fr.ird.observe.services.security.BadObserveWebUserPasswordException; +import fr.ird.observe.services.security.UnknownObserveWebUserException; +import fr.ird.observe.services.security.UnknownObserveWebUserForDatabaseException; +import fr.ird.observe.services.security.UserLoginNotFoundException; +import fr.ird.observe.services.security.UserPasswordNotFoundException; +import fr.ird.observe.services.service.PingService; +import java.net.MalformedURLException; +import java.net.URL; +import org.nuiton.version.Version; + + +import static org.nuiton.i18n.I18n.n; +import static org.nuiton.i18n.I18n.t; + +/** + * Created by tchemit on 17/08/17. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class TestServerUIAction extends PresetsUIActionSupport { + + public static final String ACTION_NAME = TestServerUIAction.class.getName(); + + public TestServerUIAction(ObserveMainUI mainUI) { + super(mainUI, ACTION_NAME, n("observe.action.test.server"), n("observe.action.test.server.tip"), "connect_creating", 'V'); + } + + @Override + protected void doActionPerformed(RemotePresetsUI ui) { + + String connexionStatusError = null; + ObserveDataSourceConfigurationRest config = new ObserveDataSourceConfigurationRest(); + String url = ui.getServerUrl().getText().trim(); + try { + config.setServerUrl(new URL(url)); + } catch (MalformedURLException e) { + connexionStatusError = t("observe.storage.error.badUrl", url); + } + config.setLogin(ui.getServerLogin().getText().trim()); + config.setPassword(ui.getServerPassword().getText().trim().toCharArray()); + String databaseName = ui.getServerDataBase().getText().trim(); + config.setOptionalDatabaseName(databaseName.isEmpty() ? null : databaseName); + + Version applicationVersion = ObserveSwingApplicationContext.get().getConfig().getVersion(); + Version modelVersion = ObserveSwingApplicationContext.get().getConfig().getModelVersion(); + ObserveSwingDataSource dataSource = ObserveSwingApplicationContext.get().getDataSourcesManager().newDataSource(config); + try { + + PingService pingService = dataSource.getPingService(); + + if (getMainUI().getConfig().isCheckServerVersion()) { + + Version serverVersion = pingService.getServerVersion(); + + if (!applicationVersion.equals(serverVersion)) { + + connexionStatusError = t("observe.storage.error.serverVersionMismatch", serverVersion, applicationVersion); + + } + } + + if (connexionStatusError == null) { + Version modelServerVersion = pingService.getModelVersion(); + + if (!modelVersion.equals(modelServerVersion)) { + + connexionStatusError = t("observe.storage.error.serverVersionModelMismatch", modelServerVersion, modelVersion); + + } + + } + if (connexionStatusError == null) { + + ObserveDataSourceInformation dataSourceInformation = dataSource.checkCanConnect(); + + Version versionDataSource = dataSourceInformation.getVersion(); + + // en mise a jour de la base on ne test pas la version + if (!modelVersion.equals(versionDataSource)) { + + connexionStatusError = t("observe.storage.error.dbVersionMismatch", versionDataSource, modelVersion); + } + } + + } catch (UnknownObserveWebUserException e) { + connexionStatusError = t("observe.storage.error.rest.user.unknown", e.getUserLogin()); + } catch (BadObserveWebUserPasswordException e) { + connexionStatusError = t("observe.storage.error.rest.password.bad", e.getUserLogin()); + } catch (UnknownObserveWebUserForDatabaseException e) { + connexionStatusError = t("observe.storage.error.rest.database.unknownForUser", e.getDatabaseName(), e.getRole()); + } catch (UserLoginNotFoundException e) { + connexionStatusError = t("observe.storage.error.rest.user.required"); + } catch (UserPasswordNotFoundException e) { + connexionStatusError = t("observe.storage.error.rest.password.required"); + } catch (Exception e) { + connexionStatusError = e.getMessage(); + if (connexionStatusError == null || connexionStatusError.isEmpty()) { + connexionStatusError = e.getClass().getName(); + } + } finally { + if (dataSource.isOpen()) { + dataSource.close(); + } + } + + if (connexionStatusError == null) { + UIHelper.displayInfo("Test de connexion", "Le connexion a été établie avec succès."); + } else { + UIHelper.displayWarning("Test de connexion", "Le test de connexion a échoué :\n" + connexionStatusError); + } + } +} ===================================== client/src/main/java/fr/ird/observe/client/ui/storage/StorageUIModel.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/storage/StorageUIModel.java +++ b/client/src/main/java/fr/ird/observe/client/ui/storage/StorageUIModel.java @@ -1764,7 +1764,7 @@ public class StorageUIModel extends WizardModel<StorageStep> { } catch (UserPasswordNotFoundException e) { - connexionStatusError = t("observe.storage.error.rest.pasword.required"); + connexionStatusError = t("observe.storage.error.rest.password.required"); setConnexionStatus(ConnexionStatus.FAILED); } catch (ObserveWebSecurityExceptionSupport e) { ===================================== client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUI.jaxx ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUI.jaxx +++ b/client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUI.jaxx @@ -25,6 +25,17 @@ fr.ird.observe.services.dto.presets.RemoteDataSourceConfiguration fr.ird.observe.services.dto.presets.ServerDataSourceConfiguration + fr.ird.observe.client.ui.actions.storage.presets.CreatePresetUIAction + fr.ird.observe.client.ui.actions.storage.presets.DeleteRemoteUIAction + fr.ird.observe.client.ui.actions.storage.presets.DeleteServerUIAction + fr.ird.observe.client.ui.actions.storage.presets.QuitPresetsUIAction + fr.ird.observe.client.ui.actions.storage.presets.ResetRemoteUIAction + fr.ird.observe.client.ui.actions.storage.presets.ResetServerUIAction + fr.ird.observe.client.ui.actions.storage.presets.SaveRemoteUIAction + fr.ird.observe.client.ui.actions.storage.presets.SaveServerUIAction + fr.ird.observe.client.ui.actions.storage.presets.TestRemoteUIAction + fr.ird.observe.client.ui.actions.storage.presets.TestServerUIAction + org.nuiton.jaxx.widgets.select.BeanComboBox </import> @@ -33,128 +44,130 @@ <JTabbedPane id='tabs' constraints='BorderLayout.CENTER'> <tab id='remoteTab' title="observe.storage.remote.presets.title"> - <JPanel id="remotePanel" layout="{new BorderLayout()}"> - <BeanComboBox id='remoteConfigurations' constructorParams='this' genericType='RemoteDataSourceConfiguration' - constraints='BorderLayout.NORTH'/> - <JLabel id="noRemoteSelected" constraints='BorderLayout.CENTER'/> - <Table id="remoteForm" constraints='BorderLayout.SOUTH' fill="both"> - <row> - <cell anchor='west'> - <JLabel text='observe.storage.remote.name'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="remoteName" onKeyReleased="model.setRemoteModified(true);"/> - </cell> - </row> - <row> - <cell anchor='west'> - <JLabel text='observe.storage.remote.url'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="remoteUrl" onKeyReleased="model.setRemoteModified(true);"/> - </cell> - </row> - <row> - <cell anchor='west'> - <JLabel text='observe.storage.remote.login'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="remoteLogin" onKeyReleased="model.setRemoteModified(true);"/> - </cell> - </row> - <row> - <cell anchor='west'> - <JLabel text='observe.storage.remote.password'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="remotePassword" onKeyReleased="model.setRemoteModified(true);"/> - </cell> - </row> - <row> - <cell columns='2'> - <JCheckBox id="remoteUseSsl" onActionPerformed="model.setRemoteModified(true);"/> - </cell> - </row> + <JSplitPane id="remotePanel"> + <JList id='remoteConfigurations' genericType="RemoteDataSourceConfiguration"/> + <JPanel id="remoteContentPanel" layout="{new BorderLayout()}"> + <JLabel id="noRemoteSelected" constraints='BorderLayout.CENTER'/> + <Table id="remoteForm" constraints='BorderLayout.SOUTH' fill="both"> + <row> + <cell anchor='west'> + <JLabel text='observe.storage.remote.name'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="remoteName" onKeyReleased="model.setRemoteModified(true);"/> + </cell> + </row> + <row> + <cell anchor='west'> + <JLabel text='observe.storage.remote.url'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="remoteUrl" onKeyReleased="model.setRemoteModified(true);"/> + </cell> + </row> + <row> + <cell anchor='west'> + <JLabel text='observe.storage.remote.login'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="remoteLogin" onKeyReleased="model.setRemoteModified(true);"/> + </cell> + </row> + <row> + <cell anchor='west'> + <JLabel text='observe.storage.remote.password'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="remotePassword" onKeyReleased="model.setRemoteModified(true);"/> + </cell> + </row> + <row> + <cell columns='2'> + <JCheckBox id="remoteUseSsl" onActionPerformed="model.setRemoteModified(true);"/> + </cell> + </row> - <!-- tester la connexion --> - <row> - <cell columns='2'> - <JPanel layout="{new GridLayout(1, 0)}"> - <JButton id="saveRemoteAction" onActionPerformed='handler.saveRemote()'/> - <JButton id="deleteRemoteAction" onActionPerformed='handler.deleteRemote()'/> - <JButton id="testRemoteAction" onActionPerformed='handler.testRemote()'/> - </JPanel> - </cell> - </row> - </Table> - </JPanel> + <row> + <cell columns='2'> + <JPanel layout="{new GridLayout(1, 0)}"> + <JButton id="resetRemoteAction"/> + <JButton id="saveRemoteAction"/> + <JButton id="deleteRemoteAction"/> + <JButton id="testRemoteAction"/> + </JPanel> + </cell> + </row> + </Table> + </JPanel> + </JSplitPane> </tab> <tab id='serverTab' title="observe.storage.server.presets.title"> - <JPanel id="serverPanel" layout="{new BorderLayout()}"> - <BeanComboBox id='serverConfigurations' constructorParams='this' genericType='ServerDataSourceConfiguration' - constraints='BorderLayout.NORTH'/> - <JLabel id="noServerSelected" constraints='BorderLayout.CENTER'/> - - <Table id="serverForm" constraints='BorderLayout.SOUTH' fill="both"> - <row> - <cell anchor='west'> - <JLabel text='observe.storage.remote.name'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="serverName" onKeyReleased="model.setServerModified(true);"/> - </cell> - </row> - <row> - <cell anchor='west'> - <JLabel text='observe.storage.remote.url'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="serverUrl" onKeyReleased="model.setServerModified(true);"/> - </cell> - </row> - <row> - <cell anchor='west'> - <JLabel text='observe.storage.remote.login'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="serverLogin" onKeyReleased="model.setServerModified(true);"/> - </cell> - </row> - <row> - <cell anchor='west'> - <JLabel text='observe.storage.remote.password'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="serverPassword" onKeyReleased="model.setServerModified(true);"/> - </cell> - </row> - <row> - <cell anchor='west'> - <JLabel id="serverDataBaseLabel" text='observe.storage.server.dataBase'/> - </cell> - <cell weightx='1' fill="both" anchor='east'> - <JTextField id="serverDataBase" onKeyReleased="model.setServerModified(true);"/> - </cell> - </row> + <JSplitPane id="serverPanel"> + <JList id='serverConfigurations' genericType="ServerDataSourceConfiguration"/> + <JPanel id="serverContentPanel" layout="{new BorderLayout()}"> + <JLabel id="noServerSelected" constraints='BorderLayout.CENTER'/> + <Table id="serverForm" constraints='BorderLayout.SOUTH' fill="both"> + <row> + <cell anchor='west'> + <JLabel text='observe.storage.remote.name'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="serverName" onKeyReleased="model.setServerModified(true);"/> + </cell> + </row> + <row> + <cell anchor='west'> + <JLabel text='observe.storage.remote.url'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="serverUrl" onKeyReleased="model.setServerModified(true);"/> + </cell> + </row> + <row> + <cell anchor='west'> + <JLabel text='observe.storage.remote.login'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="serverLogin" onKeyReleased="model.setServerModified(true);"/> + </cell> + </row> + <row> + <cell anchor='west'> + <JLabel text='observe.storage.remote.password'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="serverPassword" onKeyReleased="model.setServerModified(true);"/> + </cell> + </row> + <row> + <cell anchor='west'> + <JLabel id="serverDataBaseLabel" text='observe.storage.server.dataBase'/> + </cell> + <cell weightx='1' fill="both" anchor='east'> + <JTextField id="serverDataBase" onKeyReleased="model.setServerModified(true);"/> + </cell> + </row> - <!-- tester la connexion --> - <row> - <cell columns='2'> - <JPanel layout="{new GridLayout(1, 0)}"> - <JButton id="saveServerAction" onActionPerformed='handler.saveServer()'/> - <JButton id="deleteServerAction" onActionPerformed='handler.deleteServer()'/> - <JButton id="testServerAction" onActionPerformed='handler.testServer()'/> - </JPanel> - </cell> - </row> - </Table> - </JPanel> + <row> + <cell columns='2'> + <JPanel layout="{new GridLayout(1, 0)}"> + <JButton id="resetServerAction"/> + <JButton id="saveServerAction"/> + <JButton id="deleteServerAction"/> + <JButton id="testServerAction"/> + </JPanel> + </cell> + </row> + </Table> + </JPanel> + </JSplitPane> </tab> </JTabbedPane> <JPanel constraints='BorderLayout.SOUTH' layout="{new GridLayout(1, 0)}"> - <JButton id="quitAction" onActionPerformed='handler.quit()'/> + <JButton id="createAction"/> + <JButton id="quitAction"/> </JPanel> </JPanel> ===================================== client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUI.jcss ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUI.jcss +++ b/client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUI.jcss @@ -19,9 +19,6 @@ * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ -#remoteConfigurations { - selectedItem: {model.getRemoteDataSourceConfiguration()}; -} #noRemoteSelected { visible: true; @@ -54,10 +51,6 @@ selected:{model.getRemoteDataSourceConfiguration().isUseSsl()}; } -#serverConfigurations { - selectedItem: {model.getServerDataSourceConfiguration()}; -} - #noServerSelected { visible: true; text:"observe.storage.presets.no.selected"; @@ -88,49 +81,45 @@ text:{SwingUtil.getStringValue(model.getServerDataSourceConfiguration().getDatabaseName())}; } +#resetRemoteAction { + enabled:{model.isRemoteModified()}; + _observeAction:{ResetRemoteUIAction.ACTION_NAME}; +} + #saveRemoteAction { - text:"observe.action.save"; - actionIcon:"save"; - mnemonic:E; enabled:{model.isRemoteModified()}; + _observeAction:{SaveRemoteUIAction.ACTION_NAME}; } #deleteRemoteAction { - text:"observe.action.delete"; - actionIcon:"delete"; - mnemonic:S; + _observeAction:{DeleteRemoteUIAction.ACTION_NAME}; } #testRemoteAction { - text:"observe.action.test.remote"; - toolTipText:"observe.action.test.remote.tip"; - actionIcon:"connect_creating"; - mnemonic:V; + _observeAction:{TestRemoteUIAction.ACTION_NAME}; +} + +#resetServerAction { + enabled:{model.isServerModified()}; + _observeAction:{ResetServerUIAction.ACTION_NAME}; } #saveServerAction { - text:"observe.action.save"; - actionIcon:"save"; - mnemonic:E; enabled:{model.isServerModified()}; + _observeAction:{SaveServerUIAction.ACTION_NAME}; } #deleteServerAction { - text:"observe.action.delete"; - actionIcon:"delete"; - mnemonic:S; + _observeAction:{DeleteServerUIAction.ACTION_NAME}; } #testServerAction { - text:"observe.action.test.remote"; - toolTipText:"observe.action.test.remote.tip"; - actionIcon:"connect_creating"; - mnemonic:V; + _observeAction:{TestServerUIAction.ACTION_NAME}; } +#createAction { + _observeAction:{CreatePresetUIAction.ACTION_NAME}; +} #quitAction { - text:"observe.action.quit"; - toolTipText:"observe.action.quit.tip"; - actionIcon:"exit"; - mnemonic:Q; + _observeAction:{QuitPresetsUIAction.ACTION_NAME}; } ===================================== client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUIHandler.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUIHandler.java +++ b/client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUIHandler.java @@ -24,38 +24,27 @@ package fr.ird.observe.client.ui.storage.presets; import fr.ird.observe.client.ObserveSwingApplicationContext; import fr.ird.observe.client.configuration.ClientConfig; -import fr.ird.observe.client.db.ObserveSwingDataSource; -import fr.ird.observe.client.ui.ObserveKeyStrokes; -import fr.ird.observe.client.ui.ObserveMainUI; -import fr.ird.observe.client.ui.ObserveUIMode; +import fr.ird.observe.client.ui.actions.UIActionSupport; import fr.ird.observe.client.ui.util.UIHelper; -import fr.ird.observe.services.configuration.ObserveDataSourceInformation; -import fr.ird.observe.services.configuration.rest.ObserveDataSourceConfigurationRest; -import fr.ird.observe.services.configuration.topia.ObserveDataSourceConfigurationTopiaPG; import fr.ird.observe.services.dto.presets.RemoteDataSourceConfiguration; import fr.ird.observe.services.dto.presets.ServerDataSourceConfiguration; -import fr.ird.observe.services.security.BadObserveWebUserPasswordException; -import fr.ird.observe.services.security.UnknownObserveWebUserException; -import fr.ird.observe.services.security.UnknownObserveWebUserForDatabaseException; -import fr.ird.observe.services.security.UserLoginNotFoundException; -import fr.ird.observe.services.security.UserPasswordNotFoundException; -import fr.ird.observe.services.service.PingService; import java.awt.BorderLayout; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; import java.util.List; -import javax.swing.JOptionPane; -import javax.swing.JPanel; +import java.util.Objects; +import javax.swing.AbstractButton; +import javax.swing.ActionMap; +import javax.swing.DefaultListModel; +import javax.swing.InputMap; +import javax.swing.JComponent; import javax.swing.SwingUtilities; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.nuiton.decorator.Decorator; -import org.nuiton.decorator.JXPathDecorator; import org.nuiton.jaxx.runtime.spi.UIHandler; -import org.nuiton.jaxx.widgets.select.BeanComboBox; -import org.nuiton.version.Version; +import org.nuiton.jaxx.runtime.swing.renderer.DecoratorListCellRenderer; -import static org.nuiton.i18n.I18n.t; +import static fr.ird.observe.client.ui.content.ContentUIInitializer.OBSERVE_ACTION; /** * Created on 20/12/16. @@ -65,6 +54,9 @@ import static org.nuiton.i18n.I18n.t; */ public class RemotePresetsUIHandler implements UIHandler<RemotePresetsUI> { + /** Logger. */ + private static final Log log = LogFactory.getLog(RemotePresetsUIHandler.class); + private RemotePresetsUI ui; @Override @@ -80,262 +72,139 @@ public class RemotePresetsUIHandler implements UIHandler<RemotePresetsUI> { @Override public void afterInit(RemotePresetsUI ui) { + ActionMap actionMap = ObserveSwingApplicationContext.get().getActionMap(); + InputMap inputMap = ui.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + for (Object o : ui.get$objectMap().values()) { + + if (o instanceof AbstractButton) { + init(inputMap, actionMap, (AbstractButton) o); + } + + } + Decorator<RemoteDataSourceConfiguration> remoteDecorator = ObserveSwingApplicationContext.get().getDecoratorService().getDecoratorByType(RemoteDataSourceConfiguration.class); - ui.getRemoteConfigurations().init((JXPathDecorator<RemoteDataSourceConfiguration>) remoteDecorator, ui.getModel().getRemoteDataSourceConfigurations()); - Decorator<ServerDataSourceConfiguration> serverDecorator = ObserveSwingApplicationContext.get().getDecoratorService().getDecoratorByType(ServerDataSourceConfiguration.class); - ui.getServerConfigurations().init((JXPathDecorator<ServerDataSourceConfiguration>) serverDecorator, ui.getModel().getServerDataSourceConfigurations()); + ui.getRemoteConfigurations().setCellRenderer(new DecoratorListCellRenderer<>(remoteDecorator)); + DefaultListModel<RemoteDataSourceConfiguration> remoteModel = new DefaultListModel<>(); + ui.getModel().getRemoteDataSourceConfigurations().forEach(remoteModel::addElement); - ui.getModel().addPropertyChangeListener("remoteDataSourceConfigurations", evt -> ui.getRemoteConfigurations().setData((List<RemoteDataSourceConfiguration>) evt.getNewValue())); - ui.getModel().addPropertyChangeListener("serverDataSourceConfigurations", evt -> ui.getServerConfigurations().setData((List<ServerDataSourceConfiguration>) evt.getNewValue())); + ui.getRemoteConfigurations().setModel(remoteModel); - ui.getServerConfigurations().addPropertyChangeListener(BeanComboBox.PROPERTY_SELECTED_ITEM, evt -> { + ui.getRemoteConfigurations().addListSelectionListener(evt -> { - ServerDataSourceConfiguration oldValue = (ServerDataSourceConfiguration) evt.getOldValue(); - ui.getModel().setServerDataSourceConfiguration((ServerDataSourceConfiguration) evt.getNewValue()); + if (ui.getRemoteConfigurations().isSelectionEmpty()) { - if (ui.getModel().getServerDataSourceConfiguration() == null) { - ui.getServerPanel().remove(ui.getServerForm()); - ui.getServerPanel().add(ui.getNoServerSelected(), BorderLayout.CENTER); + ui.getModel().setRemoteDataSourceConfiguration(null); + ui.getModel().setRemoteModified(false); } else { - if (oldValue == null) { - ui.getServerForm().setVisible(true); - ui.getServerPanel().remove(ui.getNoServerSelected()); - ui.getServerPanel().add(ui.getServerForm(), BorderLayout.CENTER); - } - ui.getModel().setServerModified(false); + ui.getModel().setRemoteDataSourceConfiguration(ui.getRemoteConfigurations().getSelectedValue()); } - SwingUtilities.invokeLater(ui::repaint); }); - ui.getRemoteConfigurations().addPropertyChangeListener(BeanComboBox.PROPERTY_SELECTED_ITEM, evt -> { + + ui.getModel().addPropertyChangeListener("remoteDataSourceConfigurations", evt -> { + + List newValue = (List) evt.getNewValue(); + + DefaultListModel<RemoteDataSourceConfiguration> model = (DefaultListModel<RemoteDataSourceConfiguration>) ui.getRemoteConfigurations().getModel(); + model.clear(); + for (Object remoteDataSourceConfiguration : newValue) { + model.addElement((RemoteDataSourceConfiguration) remoteDataSourceConfiguration); + } + + }); + + + ui.getModel().addPropertyChangeListener("remoteDataSourceConfiguration", evt -> { RemoteDataSourceConfiguration oldValue = (RemoteDataSourceConfiguration) evt.getOldValue(); - ui.getModel().setRemoteDataSourceConfiguration((RemoteDataSourceConfiguration) evt.getNewValue()); if (ui.getModel().getRemoteDataSourceConfiguration() == null) { - ui.getRemotePanel().remove(ui.getRemoteForm()); - ui.getRemotePanel().add(ui.getNoRemoteSelected(), BorderLayout.CENTER); + ui.getRemoteContentPanel().remove(ui.getRemoteForm()); + ui.getRemoteContentPanel().add(ui.getNoRemoteSelected(), BorderLayout.CENTER); + UIHelper.askFocus(ui.getCreateAction()); } else { if (oldValue == null) { ui.getRemoteForm().setVisible(true); - ui.getRemotePanel().remove(ui.getNoRemoteSelected()); - ui.getRemotePanel().add(ui.getRemoteForm(), BorderLayout.CENTER); + ui.getRemoteContentPanel().remove(ui.getNoRemoteSelected()); + ui.getRemoteContentPanel().add(ui.getRemoteForm(), BorderLayout.CENTER); + UIHelper.askFocus(ui.getRemoteName()); } ui.getModel().setRemoteModified(false); } SwingUtilities.invokeLater(ui::repaint); }); - ObserveKeyStrokes.addKeyStrokeFromMnemonic(ui); - } - - public void testRemote() { - - ObserveDataSourceConfigurationTopiaPG config = new ObserveDataSourceConfigurationTopiaPG(); - config.setJdbcUrl(ui.getRemoteUrl().getText().trim()); - config.setUsername(ui.getRemoteLogin().getText().trim()); - config.setPassword(ui.getRemotePassword().getText().trim().toCharArray()); - config.setUseSsl(ui.getRemoteUseSsl().isSelected()); - - String connexionStatusError = null; - - Version modelVersion = ObserveSwingApplicationContext.get().getConfig().getModelVersion(); - ObserveSwingDataSource dataSource = ObserveSwingApplicationContext.get().getDataSourcesManager().newDataSource(config); - try { - - ObserveDataSourceInformation dataSourceInformation = dataSource.checkCanConnect(); + Decorator<ServerDataSourceConfiguration> serverDecorator = ObserveSwingApplicationContext.get().getDecoratorService().getDecoratorByType(ServerDataSourceConfiguration.class); + ui.getServerConfigurations().setCellRenderer(new DecoratorListCellRenderer<>(serverDecorator)); + DefaultListModel<ServerDataSourceConfiguration> ServerModel = new DefaultListModel<>(); + ui.getModel().getServerDataSourceConfigurations().forEach(ServerModel::addElement); - Version versionDataSource = dataSourceInformation.getVersion(); + ui.getServerConfigurations().setModel(ServerModel); - // en mise a jour de la base on ne test pas la version - if (!modelVersion.equals(versionDataSource)) { + ui.getServerConfigurations().addListSelectionListener(evt -> { - connexionStatusError = t("observe.storage.error.dbVersionMismatch", versionDataSource, modelVersion); - } + if (ui.getServerConfigurations().isSelectionEmpty()) { - } catch (UnknownObserveWebUserException e) { - connexionStatusError = t("observe.storage.error.rest.user.unknown", e.getUserLogin()); - } catch (BadObserveWebUserPasswordException e) { - connexionStatusError = t("observe.storage.error.rest.password.bad", e.getUserLogin()); - } catch (UnknownObserveWebUserForDatabaseException e) { - connexionStatusError = t("observe.storage.error.rest.database.unknownForUser", e.getDatabaseName(), e.getRole()); - } catch (UserLoginNotFoundException e) { - connexionStatusError = t("observe.storage.error.rest.user.required"); - } catch (UserPasswordNotFoundException e) { - connexionStatusError = t("observe.storage.error.rest.pasword.required"); - } catch (Exception e) { - connexionStatusError = e.getMessage(); - if (connexionStatusError == null || connexionStatusError.isEmpty()) { - connexionStatusError = e.getClass().getName(); - } - } finally { - if (dataSource.isOpen()) { - dataSource.close(); + ui.getModel().setServerDataSourceConfiguration(null); + ui.getModel().setServerModified(false); + } else { + ui.getModel().setServerDataSourceConfiguration(ui.getServerConfigurations().getSelectedValue()); } - } - - if (connexionStatusError == null) { - UIHelper.displayInfo("Test de connexion", "Le connexion a été établie avec succès."); - } else { - UIHelper.displayWarning("Test de connexion", "Le test de connexion a échoué :\n" + connexionStatusError); - } - } - - public void testServer() { - - String connexionStatusError = null; - ObserveDataSourceConfigurationRest config = new ObserveDataSourceConfigurationRest(); - String url = ui.getServerUrl().getText().trim(); - try { - config.setServerUrl(new URL(url)); - } catch (MalformedURLException e) { - connexionStatusError = t("observe.storage.error.badUrl", url); - } - config.setLogin(ui.getServerLogin().getText().trim()); - config.setPassword(ui.getServerPassword().getText().trim().toCharArray()); - String databaseName = ui.getServerDataBase().getText().trim(); - config.setOptionalDatabaseName(databaseName.isEmpty() ? null : databaseName); - - Version modelVersion = ObserveSwingApplicationContext.get().getConfig().getModelVersion(); - ObserveSwingDataSource dataSource = ObserveSwingApplicationContext.get().getDataSourcesManager().newDataSource(config); - try { - - PingService pingService = dataSource.getPingService(); - - Version modelServerVersion = pingService.getModelVersion(); + }); - if (!modelVersion.equals(modelServerVersion)) { + ui.getModel().addPropertyChangeListener("serverDataSourceConfigurations", evt -> { - connexionStatusError = t("observe.storage.error.serverVersionMismatch", modelServerVersion, modelVersion); + List newValue = (List) evt.getNewValue(); + DefaultListModel<ServerDataSourceConfiguration> model = (DefaultListModel<ServerDataSourceConfiguration>) ui.getServerConfigurations().getModel(); + model.clear(); + for (Object ServerDataSourceConfiguration : newValue) { + model.addElement((ServerDataSourceConfiguration) ServerDataSourceConfiguration); } - if (connexionStatusError == null) { + }); - ObserveDataSourceInformation dataSourceInformation = dataSource.checkCanConnect(); - Version versionDataSource = dataSourceInformation.getVersion(); + ui.getModel().addPropertyChangeListener("serverDataSourceConfiguration", evt -> { - // en mise a jour de la base on ne test pas la version - if (!modelVersion.equals(versionDataSource)) { + ServerDataSourceConfiguration oldValue = (ServerDataSourceConfiguration) evt.getOldValue(); - connexionStatusError = t("observe.storage.error.dbVersionMismatch", versionDataSource, modelVersion); + if (ui.getModel().getServerDataSourceConfiguration() == null) { + ui.getServerContentPanel().remove(ui.getServerForm()); + ui.getServerContentPanel().add(ui.getNoServerSelected(), BorderLayout.CENTER); + UIHelper.askFocus(ui.getCreateAction()); + } else { + if (oldValue == null) { + ui.getServerForm().setVisible(true); + ui.getServerContentPanel().remove(ui.getNoServerSelected()); + ui.getServerContentPanel().add(ui.getServerForm(), BorderLayout.CENTER); + UIHelper.askFocus(ui.getServerName()); } + ui.getModel().setServerModified(false); } + SwingUtilities.invokeLater(ui::repaint); + }); - } catch (UnknownObserveWebUserException e) { - connexionStatusError = t("observe.storage.error.rest.user.unknown", e.getUserLogin()); - } catch (BadObserveWebUserPasswordException e) { - connexionStatusError = t("observe.storage.error.rest.password.bad", e.getUserLogin()); - } catch (UnknownObserveWebUserForDatabaseException e) { - connexionStatusError = t("observe.storage.error.rest.database.unknownForUser", e.getDatabaseName(), e.getRole()); - } catch (UserLoginNotFoundException e) { - connexionStatusError = t("observe.storage.error.rest.user.required"); - } catch (UserPasswordNotFoundException e) { - connexionStatusError = t("observe.storage.error.rest.pasword.required"); - } catch (Exception e) { - connexionStatusError = e.getMessage(); - if (connexionStatusError == null || connexionStatusError.isEmpty()) { - connexionStatusError = e.getClass().getName(); - } - } finally { - if (dataSource.isOpen()) { - dataSource.close(); - } - } + UIHelper.askFocus(ui.getCreateAction()); - if (connexionStatusError == null) { - UIHelper.displayInfo("Test de connexion", "Le connexion a été établie avec succès."); - } else { - UIHelper.displayWarning("Test de connexion", "Le test de connexion a échoué :\n" + connexionStatusError); - } } - public void saveRemote() { - - RemoteDataSourceConfiguration remoteDataSourceConfiguration = ui.getModel().getRemoteDataSourceConfiguration(); - - remoteDataSourceConfiguration.setName(ui.getRemoteName().getText().trim()); - remoteDataSourceConfiguration.setUrl(ui.getRemoteUrl().getText().trim()); - remoteDataSourceConfiguration.setLogin(ui.getRemoteLogin().getText().trim()); - remoteDataSourceConfiguration.setPassword(ui.getRemotePassword().getText().trim()); - remoteDataSourceConfiguration.setUseSsl(ui.getRemoteUseSsl().isSelected()); - - ObserveSwingApplicationContext.get().getConfig().updateRemoteDataSourceConfiguration(remoteDataSourceConfiguration); + protected void init(InputMap inputMap, ActionMap actionMap, AbstractButton editor) { + String actionId = (String) editor.getClientProperty(OBSERVE_ACTION); + if (actionId == null) { - ui.getModel().setRemoteDataSourceConfiguration(null); - ui.getModel().setRemoteDataSourceConfiguration(remoteDataSourceConfiguration); - ui.getModel().setRemoteModified(false); - - } - - public void deleteRemote() { - - int response = UIHelper.askUser(t("observe.storage.presets.delete.title"), - t("observe.storage.presets.delete.message"), - JOptionPane.QUESTION_MESSAGE, - new Object[]{t("observe.action.delete"), t("observe.action.cancel")}, - 0); - boolean delete = response == 0; - - if (delete) { - RemoteDataSourceConfiguration remoteDataSourceConfiguration = ui.getModel().getRemoteDataSourceConfiguration(); - List<RemoteDataSourceConfiguration> remoteDataSourceConfigurations = new ArrayList<>(ui.getModel().getRemoteDataSourceConfigurations()); - remoteDataSourceConfigurations.remove(remoteDataSourceConfiguration); - ui.getModel().setRemoteDataSourceConfigurations(remoteDataSourceConfigurations); - ObserveSwingApplicationContext.get().getConfig().removeRemoteDataSourceConfiguration(remoteDataSourceConfiguration); - ui.getModel().setRemoteDataSourceConfiguration(null); + return; } - } - public void saveServer() { + UIActionSupport action = (UIActionSupport) actionMap.get(actionId); + Objects.requireNonNull(action, "action [" + actionId + "] not found for ui " + ui.getClass().getName()); - ServerDataSourceConfiguration serverDataSourceConfiguration = ui.getModel().getServerDataSourceConfiguration(); - - serverDataSourceConfiguration.setName(ui.getServerName().getText().trim()); - serverDataSourceConfiguration.setUrl(ui.getServerUrl().getText().trim()); - serverDataSourceConfiguration.setLogin(ui.getServerLogin().getText().trim()); - serverDataSourceConfiguration.setPassword(ui.getServerPassword().getText().trim()); - String databaseName = ui.getServerDataBase().getText().trim(); - serverDataSourceConfiguration.setDatabaseName(databaseName.isEmpty() ? null : databaseName); - - ObserveSwingApplicationContext.get().getConfig().updateServerDataSourceConfiguration(serverDataSourceConfiguration); - - ui.getModel().setServerDataSourceConfiguration(null); - ui.getModel().setServerDataSourceConfiguration(serverDataSourceConfiguration); - ui.getModel().setServerModified(false); - - } - - public void deleteServer() { - - int response = UIHelper.askUser(t("observe.storage.presets.delete.title"), - t("observe.storage.presets.delete.message"), - JOptionPane.QUESTION_MESSAGE, - new Object[]{t("observe.action.delete"), t("observe.action.cancel")}, - 0 - ); - boolean delete = response == 0; - - if (delete) { - ServerDataSourceConfiguration serverDataSourceConfiguration = ui.getModel().getServerDataSourceConfiguration(); - List<ServerDataSourceConfiguration> serverDataSourceConfigurations = new ArrayList<>(ui.getModel().getServerDataSourceConfigurations()); - serverDataSourceConfigurations.remove(serverDataSourceConfiguration); - ui.getModel().setServerDataSourceConfigurations(serverDataSourceConfigurations); - ObserveSwingApplicationContext.get().getConfig().removeServerDataSourceConfiguration(serverDataSourceConfiguration); - ui.getModel().setServerDataSourceConfiguration(null); + if (log.isDebugEnabled()) { + log.debug("init common action " + actionId); } - } - public void quit() { - - ObserveMainUI mainUI = ObserveSwingApplicationContext.get().getMainUI(); - mainUI.getDataSourcePresets().setContentContainer(new JPanel()); - if (ObserveSwingApplicationContext.get().getDataSourcesManager().getMainDataSource() == null) { - mainUI.getModel().setMode(ObserveUIMode.NO_DB); - } else { - mainUI.getModel().setMode(ObserveUIMode.DB); - } + action.initForMainUi(editor, inputMap, actionMap); + editor.putClientProperty(UIActionSupport.CLIENT_PROPERTY_UI, ui); } } ===================================== client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUIModel.java ===================================== --- a/client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUIModel.java +++ b/client/src/main/java/fr/ird/observe/client/ui/storage/presets/RemotePresetsUIModel.java @@ -66,8 +66,9 @@ public class RemotePresetsUIModel extends AbstractBean { } public void setRemoteDataSourceConfiguration(RemoteDataSourceConfiguration remoteDataSourceConfiguration) { + RemoteDataSourceConfiguration oldValue = getRemoteDataSourceConfiguration(); this.remoteDataSourceConfiguration = remoteDataSourceConfiguration; - firePropertyChange("remoteDataSourceConfiguration", null, remoteDataSourceConfiguration); + firePropertyChange("remoteDataSourceConfiguration", oldValue, remoteDataSourceConfiguration); } public ServerDataSourceConfiguration getServerDataSourceConfiguration() { @@ -75,8 +76,9 @@ public class RemotePresetsUIModel extends AbstractBean { } public void setServerDataSourceConfiguration(ServerDataSourceConfiguration serverDataSourceConfiguration) { + ServerDataSourceConfiguration oldValue = getServerDataSourceConfiguration(); this.serverDataSourceConfiguration = serverDataSourceConfiguration; - firePropertyChange("serverDataSourceConfiguration", null, serverDataSourceConfiguration); + firePropertyChange("serverDataSourceConfiguration", oldValue, serverDataSourceConfiguration); } public boolean isRemoteModified() { ===================================== client/src/main/resources/i18n/client_en_GB.properties ===================================== --- a/client/src/main/resources/i18n/client_en_GB.properties +++ b/client/src/main/resources/i18n/client_en_GB.properties @@ -71,7 +71,9 @@ observe.action.delete.activity.tip=Delete activity observe.action.delete.entry.tip=Delete entry in edition observe.action.delete.floatingObject.tip=Delete floating object observe.action.delete.maree.tip=Delete trip +observe.action.delete.remote.tip=Delete remote configuration observe.action.delete.route.tip=Delete route +observe.action.delete.server.tip=Delete server configuration observe.action.delete.set.tip=Delete set observe.action.delete.tip=Delete observe.action.detail=Details @@ -108,6 +110,8 @@ observe.action.modify=Modify observe.action.new.entry=Add observe.action.new.entry.tip=Create a new entry observe.action.open.screen=Opening screen <%1$s> +observe.action.presets.create=New configuration +observe.action.presets.create.tip=Create a new configuration observe.action.quit=Quit observe.action.quit.tip=Quit manager observe.action.reload.application=reload application @@ -120,12 +124,17 @@ observe.action.reloadResources=Reload i18n observe.action.reloadResources.tip=Reload i18n translations observe.action.remove.floatingObjectReference=Remove as reference observe.action.remove.floatingObjectReference.tip=Remove as reference +observe.action.reset=Reset +observe.action.reset.remote.tip=Cancel modifications on remote configuration +observe.action.reset.server.tip=Cancel modifications on server configuration observe.action.resetComment.tip=Reset comment observe.action.restart.application=Restart observe.action.restart.application.tip=Restart application observe.action.save=Save observe.action.save.all.tip=Save all modifications observe.action.save.entry.tip=Save modifications +observe.action.save.remote.tip=Save remote configuration +observe.action.save.server.tip=Save server configuration observe.action.save.tip=Save modifications observe.action.save.to.file=Backup storage observe.action.save.to.file.tip=Make a backup of opened storage @@ -148,6 +157,8 @@ observe.action.stop.server.mode.tip=Stop server mode on local database observe.action.storage.applyAction=Apply observe.action.test.remote=Test connexion observe.action.test.remote.tip=Click here to validate remote connexion +observe.action.test.server=Test connexion +observe.action.test.server.tip=Click here to validate server connexion observe.action.toFullScreen=Full screen mode observe.action.toFullScreen.tip=Reload application in full screen mode observe.action.toWindowScreen=Window screen mode @@ -1488,7 +1499,7 @@ observe.storage.error.badUrl=The url format is not valid (%s) observe.storage.error.dbVersionMismatch=Version of remote database (%s) is not compliant with the model version (%s) observe.storage.error.rest.database.unknownForUser=Database "%s" is not defined for user "%s" observe.storage.error.rest.password.bad=Password is not valid -observe.storage.error.rest.pasword.required=Password is mandatory +observe.storage.error.rest.password.required=Password is mandatory observe.storage.error.rest.user.required=User login is mandatory observe.storage.error.rest.user.unknown=User "%s" is not defined on server observe.storage.error.serverVersionMismatch=Remote server version (%s) is not compliant with the client version (%s) ===================================== client/src/main/resources/i18n/client_es_ES.properties ===================================== --- a/client/src/main/resources/i18n/client_es_ES.properties +++ b/client/src/main/resources/i18n/client_es_ES.properties @@ -71,7 +71,9 @@ observe.action.delete.activity.tip=Eliminar la actividad observe.action.delete.entry.tip=Cancelar la edición de la entrada actual observe.action.delete.floatingObject.tip=Eliminar el objeto flotante actual observe.action.delete.maree.tip=Eliminar la marea +observe.action.delete.remote.tip=Delete remote configuration \#TODO observe.action.delete.route.tip=Eliminar la ruta +observe.action.delete.server.tip=Delete server configuration \#TODO observe.action.delete.set.tip=Eliminar el lance observe.action.delete.tip=Eliminar observe.action.detail=Ver detalles @@ -108,6 +110,8 @@ observe.action.modify=Modificar observe.action.new.entry=Nuevo observe.action.new.entry.tip=Crear una nueva entrada observe.action.open.screen=Abrir pantalla <%1$s> +observe.action.presets.create=Nouvelle configuration \#TODO +observe.action.presets.create.tip=Créer une nouvelle configuration \#TODO observe.action.quit=Quitter \#TODO observe.action.quit.tip=Quitter le gestionnaire \#TODO observe.action.reload.application=Reinicializar la aplicación @@ -120,12 +124,17 @@ observe.action.reloadResources=Recargar las traducciones observe.action.reloadResources.tip=Recargar las traducciones i18n observe.action.remove.floatingObjectReference=Supprimer la référence \#TODO observe.action.remove.floatingObjectReference.tip=Supprimer la référence \#TODO +observe.action.reset=Reset \#TODO +observe.action.reset.remote.tip=Reset remote configuration \#TODO +observe.action.reset.server.tip=Cancel modifications on server configuration \#TODO observe.action.resetComment.tip=Supprimer le commentaire \#TODO observe.action.restart.application=Reiniciar observe.action.restart.application.tip=Reiniciar la aplicación observe.action.save=Grabar observe.action.save.all.tip=Guardar todas las modificaciones observe.action.save.entry.tip=Guardar la edición en curso +observe.action.save.remote.tip=Save remote configuration \#TODO +observe.action.save.server.tip=Save server configuration \#TODO observe.action.save.tip=Guardar las modificaciones observe.action.save.to.file=Guardar la base de datos observe.action.save.to.file.tip=Hacer una copia de seguridad de la base de datos abierta @@ -148,6 +157,8 @@ observe.action.stop.server.mode.tip=Parar el modo servidor de la base local observe.action.storage.applyAction=Aplicar observe.action.test.remote=Comprobar la conexión observe.action.test.remote.tip=Pulsar para comprobar la conexión con el servidor remoto +observe.action.test.server=Comprobar la conexión +observe.action.test.server.tip=Pulsar para comprobar la conexión con el servidor \#TODO observe.action.toFullScreen=Mode plein écran \#TODO observe.action.toFullScreen.tip=Recharcher l'application en mode plein écran \#TODO observe.action.toWindowScreen=Mode fenêtre \#TODO @@ -1488,7 +1499,7 @@ observe.storage.error.badUrl=Error en el formato de la dirección (URL) %s observe.storage.error.dbVersionMismatch=La versión de la base remota (%s) no es compatible con la versión del modelo (%s). observe.storage.error.rest.database.unknownForUser=La base de datos "%s" no está configurada para el usuario "%s" observe.storage.error.rest.password.bad=Le contraseña es invalida -observe.storage.error.rest.pasword.required=Le contraseña es obligatoria +observe.storage.error.rest.password.required=Le contraseña es obligatoria observe.storage.error.rest.user.required=El usuario es obligatorio observe.storage.error.rest.user.unknown=El usuario "%s" no es conocido del servidor observe.storage.error.serverVersionMismatch=La versión del servidor remoto (%s) no es compatible con la versión del modelo (%s) ===================================== client/src/main/resources/i18n/client_fr_FR.properties ===================================== --- a/client/src/main/resources/i18n/client_fr_FR.properties +++ b/client/src/main/resources/i18n/client_fr_FR.properties @@ -71,7 +71,9 @@ observe.action.delete.activity.tip=Supprimer l'activité observe.action.delete.entry.tip=Supprimer l'entrée en cours d'édition observe.action.delete.floatingObject.tip=Supprimer l'objet flottant courant observe.action.delete.maree.tip=Supprimer la marée +observe.action.delete.remote.tip=Supprimer la configuration observe.action.delete.route.tip=Supprimer la route +observe.action.delete.server.tip=Supprimer la configuration observe.action.delete.set.tip=Supprimer la calée observe.action.delete.tip=Supprimer observe.action.detail=Voir les détails @@ -108,6 +110,8 @@ observe.action.modify=Modifier observe.action.new.entry=Nouveau observe.action.new.entry.tip=Créer une nouvelle entrée observe.action.open.screen=Ouverture de l'écran <%1$s> +observe.action.presets.create=Nouvelle configuration +observe.action.presets.create.tip=Créer une nouvelle configuration observe.action.quit=Quitter observe.action.quit.tip=Quitter le gestionnaire observe.action.reload.application=Redémarrer l'application @@ -120,12 +124,17 @@ observe.action.reloadResources=Ressources par défaut observe.action.reloadResources.tip=Rétablir les ressources par défaut (toute modification sera perdue) observe.action.remove.floatingObjectReference=Supprimer la référence observe.action.remove.floatingObjectReference.tip=Supprimer la référence +observe.action.reset=Réinitialiser +observe.action.reset.remote.tip=Annuler les modifications +observe.action.reset.server.tip=Annuler les modifications observe.action.resetComment.tip=Supprimer le commentaire observe.action.restart.application=Redémarrer observe.action.restart.application.tip=Redémarrer l'application observe.action.save=Enregistrer observe.action.save.all.tip=Sauver toutes les modifications observe.action.save.entry.tip=Sauver l'entrée en cours d'édition +observe.action.save.remote.tip=Enregister la configuration +observe.action.save.server.tip=Enregister la configuration observe.action.save.tip=Sauver les modifications observe.action.save.to.file=Sauver la base observe.action.save.to.file.tip=Effectuer une sauvegarde de la base ouverte @@ -148,6 +157,8 @@ observe.action.stop.server.mode.tip=Arrêter le mode serveur de la base locale observe.action.storage.applyAction=Appliquer observe.action.test.remote=Valider la connexion observe.action.test.remote.tip=Cliquer pour valider la connexion au serveur distant +observe.action.test.server=Valider la connexion +observe.action.test.server.tip=Cliquer pour valider la connexion au serveur observe.action.toFullScreen=Mode plein écran observe.action.toFullScreen.tip=Recharcher l'application en mode plein écran observe.action.toWindowScreen=Mode fenêtre @@ -1488,7 +1499,7 @@ observe.storage.error.badUrl=Erreur dans le format de l'URL %s observe.storage.error.dbVersionMismatch=La version de la base distante (%s) n'est pas compatible avec la version du modèle (%s) observe.storage.error.rest.database.unknownForUser=La base de données "%s" n'est pas définie pour l'utilisateur "%s" observe.storage.error.rest.password.bad=Le mot de passe est invalide -observe.storage.error.rest.pasword.required=Le mot de passe est obligatoire +observe.storage.error.rest.password.required=Le mot de passe est obligatoire observe.storage.error.rest.user.required=L'utilisateur est obligatoire observe.storage.error.rest.user.unknown=L'utilisateur "%s" est inconnu sur le serveur observe.storage.error.serverVersionMismatch=La version du serveur distant (%s) n'est pas compatible avec la version du client (%s) View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/commit/08505b7ca91cbf74a9de7f199a10... --- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/commit/08505b7ca91cbf74a9de7f199a10... You're receiving this email because of your account on gitlab.com.