mirror of
https://github.com/klmp200/PQT_Gestionnaire_vente_stock.git
synced 2024-11-22 00:03:20 +00:00
Merge branch 'feature/#1_développement_code_métier_partie_client' into develop
This commit is contained in:
commit
d697c1b123
@ -11,7 +11,6 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
</component>
|
||||
|
39
Workspace/client/dependency-reduced-pom.xml
Normal file
39
Workspace/client/dependency-reduced-pom.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>Main</artifactId>
|
||||
<groupId>com.pqt</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>client</artifactId>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer>
|
||||
<manifestEntries>
|
||||
<Main-Class>com.pqt.client.Main</Main-Class>
|
||||
<Build-Number>1.0-SNAPSHOT</Build-Number>
|
||||
<Author>Guillaume 'Cess' Prost</Author>
|
||||
<Last-Update>26/10/2017</Last-Update>
|
||||
</manifestEntries>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -17,6 +17,35 @@
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<manifestEntries>
|
||||
<!-- TODO faire un script pour update les data du manifest -->
|
||||
<Main-Class>com.pqt.client.Main</Main-Class>
|
||||
<Build-Number>1.0-SNAPSHOT</Build-Number>
|
||||
<Author>Guillaume 'Cess' Prost</Author>
|
||||
<Last-Update>26/10/2017</Last-Update>
|
||||
</manifestEntries>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -1,21 +1,21 @@
|
||||
package com.pqt.client;
|
||||
|
||||
import com.pqt.client.gui.main_frame.MainFrame;
|
||||
import com.pqt.client.gui.main_frame.listeners.IMainFrameModelListener;
|
||||
import com.pqt.client.gui.modules.account_screen.AccountScreen;
|
||||
import com.pqt.client.gui.modules.sale_screen.SaleScreen;
|
||||
import com.pqt.client.gui.modules.stat_screen.StatScreen;
|
||||
import com.pqt.client.gui.modules.stock_screen.StockScreen;
|
||||
import com.pqt.client.gui.ressources.components.generics.others.SideBar;
|
||||
import com.pqt.client.gui.ressources.components.generics.others.listeners.ISideBarListener;
|
||||
import com.pqt.client.gui.ressources.components.generics.toast.ToastFactory;
|
||||
import com.pqt.client.gui.ressources.css.GUICssTool;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.sale.SaleService;
|
||||
import com.pqt.client.module.stat.StatService;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
import com.pqt.client.gui.startup_frame.StartupFrame;
|
||||
import com.pqt.client.gui.startup_frame.listeners.frame.IStartupFrameModelListener;
|
||||
import com.pqt.client.module.ClientBackEndModuleManager;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class Main extends Application{
|
||||
@ -26,25 +26,53 @@ public class Main extends Application{
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
SaleService saleService = new SaleService();
|
||||
StockService stockService = new StockService();
|
||||
AccountService accountService = new AccountService();
|
||||
StatService statService = new StatService();
|
||||
|
||||
MainFrame mainFrame = new MainFrame(accountService);
|
||||
mainFrame.addModule(new SaleScreen(accountService, stockService, saleService), true);
|
||||
mainFrame.addModule(new StockScreen(stockService, accountService));
|
||||
mainFrame.addModule(new StatScreen(statService));
|
||||
mainFrame.addModule(new AccountScreen(accountService));
|
||||
ClientBackEndModuleManager moduleManager = new ClientBackEndModuleManager(null);
|
||||
|
||||
|
||||
Scene scene = new Scene(mainFrame.getPane(), 800, 600);
|
||||
scene.getStylesheets().clear();
|
||||
scene.getStylesheets().addAll(getClass().getResource(GUICssTool.getCssFilePath()).toExternalForm());
|
||||
MainFrame mainFrame = new MainFrame(moduleManager.getAccountService());
|
||||
mainFrame.addModule(new SaleScreen(moduleManager.getAccountService(), moduleManager.getStockService(), moduleManager.getSaleService()), true);
|
||||
mainFrame.addModule(new StockScreen(moduleManager.getStockService(), moduleManager.getAccountService()));
|
||||
mainFrame.addModule(new StatScreen(moduleManager.getStatService()));
|
||||
mainFrame.addModule(new AccountScreen(moduleManager.getAccountService()));
|
||||
Scene mainFrameScene = initScene(mainFrame.getPane());
|
||||
|
||||
StartupFrame startupFrame = new StartupFrame(moduleManager.getAccountService(), moduleManager.getNetworkService());
|
||||
Scene startupFrameScene = initScene(startupFrame.getPane());
|
||||
|
||||
mainFrame.addFrameModelListener(getMainFrameListener(primaryStage, startupFrameScene));
|
||||
startupFrame.addFrameModelListener(getStartupFrameListener(primaryStage, mainFrameScene));
|
||||
|
||||
ToastFactory.init(primaryStage);
|
||||
primaryStage.setTitle(GUIStringTool.getAppTitle());
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.setScene(startupFrameScene);
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
private Scene initScene(Pane pane){
|
||||
Scene scene = new Scene(pane);
|
||||
scene.getStylesheets().clear();
|
||||
scene.getStylesheets().addAll(getClass().getResource(GUICssTool.getCssFilePath()).toExternalForm());
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
private IStartupFrameModelListener getStartupFrameListener(Stage primaryStage, Scene sceneToDisplay){
|
||||
return () -> trySwitchScene(primaryStage, sceneToDisplay, true);
|
||||
}
|
||||
|
||||
private IMainFrameModelListener getMainFrameListener(Stage primaryStage, Scene sceneToDisplay){
|
||||
return () -> trySwitchScene(primaryStage, sceneToDisplay, false);
|
||||
}
|
||||
|
||||
private void trySwitchScene(Stage primaryStage, Scene sceneToDisplay, boolean maximize){
|
||||
if(sceneToDisplay!=null) {
|
||||
primaryStage.hide();
|
||||
primaryStage.setScene(sceneToDisplay);
|
||||
primaryStage.setMaximized(maximize);
|
||||
primaryStage.show();
|
||||
}else{
|
||||
Platform.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.pqt.client.gui.main_frame;
|
||||
|
||||
import com.pqt.client.gui.main_frame.listeners.IMainFrameModelListener;
|
||||
import com.pqt.client.gui.modules.IGuiModule;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.startup_frame.listeners.frame.IStartupFrameModelListener;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
@ -9,9 +11,10 @@ public class MainFrame implements IFXComponent {
|
||||
|
||||
private MainFrameView view;
|
||||
private MainFrameController ctrl;
|
||||
private MainFrameModel model;
|
||||
|
||||
public MainFrame(AccountService accountService) {
|
||||
MainFrameModel model = new MainFrameModel(accountService);
|
||||
model = new MainFrameModel(accountService);
|
||||
ctrl = new MainFrameController(model);
|
||||
model.addListener(ctrl);
|
||||
|
||||
@ -28,6 +31,10 @@ public class MainFrame implements IFXComponent {
|
||||
ctrl.addModule(module, false);
|
||||
}
|
||||
|
||||
public void addFrameModelListener(IMainFrameModelListener l){
|
||||
model.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
|
@ -2,17 +2,12 @@ package com.pqt.client.gui.main_frame;
|
||||
|
||||
import com.pqt.client.gui.main_frame.listeners.IMainFrameModelListener;
|
||||
import com.pqt.client.gui.modules.IGuiModule;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.event.Event;
|
||||
|
||||
class MainFrameController implements IMainFrameModelListener {
|
||||
|
||||
private MainFrameModel model;
|
||||
private MainFrameView view;
|
||||
private IValidatorComponentListener accountManagerAccountListener;
|
||||
|
||||
MainFrameController(MainFrameModel model) {
|
||||
this.model = model;
|
||||
@ -23,7 +18,6 @@ class MainFrameController implements IMainFrameModelListener {
|
||||
}
|
||||
|
||||
void updateView(){
|
||||
view.feedAccountCollectionToManager(model.getAccounts());
|
||||
view.setCurrentAccount(model.getCurrentAccount());
|
||||
if(model.getCurrentAccount()!=null)
|
||||
view.updateModuleButtonLock(model.getCurrentAccount().getPermissionLevel());
|
||||
@ -38,57 +32,12 @@ class MainFrameController implements IMainFrameModelListener {
|
||||
this.view.addGuiModule(module.getModuleName(),module.getPane(), module.getLowestRequiredAccountLevel(), activate);
|
||||
}
|
||||
|
||||
IValidatorComponentListener getAccountManagerValidatorListener() {
|
||||
return new IValidatorComponentListener() {
|
||||
@Override
|
||||
public void onValidationEvent() {
|
||||
if(view.isAccountCreationPossible())
|
||||
model.connectAccount(view.create());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelEvent() {
|
||||
public void onAccountDisconnectionRequested() {
|
||||
model.disconnectCurrentAccount();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
IAccountComponentListener getAccountManagerAccountListener() {
|
||||
return new IAccountComponentListener() {
|
||||
@Override
|
||||
public void onRefreshContentRequestEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContentClickEvent(Event event, Account eventTarget) {
|
||||
public void onAccountDisconnectedEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAddContentRequestEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveContentRequestEvent(Account content) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetailContentRequestEvent(Account content) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
updateView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountCollectionChangedEvent() {
|
||||
updateView();
|
||||
}
|
||||
}
|
||||
|
@ -20,37 +20,30 @@ class MainFrameModel {
|
||||
this.accountService.addListener(new IAccountListener() {
|
||||
@Override
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
MainFrameModel.this.fireAccountStatusChangedEvent(status);
|
||||
if(!status){
|
||||
MainFrameModel.this.fireAccountDisconnectedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountStatusNotChangedEvent(Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountListChangedEvent() {
|
||||
MainFrameModel.this.fireAccountCollectionChangedEvent();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fireAccountCollectionChangedEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IMainFrameModelListener.class)).forEach(IMainFrameModelListener::onAccountCollectionChangedEvent);
|
||||
}
|
||||
|
||||
private void fireAccountStatusChangedEvent(boolean status) {
|
||||
Arrays.stream(listenerList.getListeners(IMainFrameModelListener.class)).forEach(l->l.onAccountStatusChangedEvent(status));
|
||||
}
|
||||
|
||||
void connectAccount(Account account) {
|
||||
accountService.setCurrentAccount(account);
|
||||
accountService.logInCurrentAccount(account.getPassword());
|
||||
private void fireAccountDisconnectedEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IMainFrameModelListener.class)).forEach(IMainFrameModelListener::onAccountDisconnectedEvent);
|
||||
}
|
||||
|
||||
void disconnectCurrentAccount() {
|
||||
accountService.logOutCurrentAccount();
|
||||
}
|
||||
|
||||
Collection<Account> getAccounts(){
|
||||
return accountService.getAllAccounts();
|
||||
}
|
||||
|
||||
void addListener(IMainFrameModelListener listener){
|
||||
listenerList.add(IMainFrameModelListener.class, listener);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.pqt.client.gui.main_frame;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.AccountManager;
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.others.SideBar;
|
||||
import com.pqt.client.gui.ressources.components.generics.others.listeners.ISideBarListener;
|
||||
@ -10,11 +9,9 @@ import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ToolBar;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
@ -22,16 +19,14 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class MainFrameView implements IFXComponent{
|
||||
|
||||
private final MainFrameController ctrl;
|
||||
|
||||
private BorderPane mainPane;
|
||||
private AccountManager accountManager;
|
||||
private VBox buttonHolder;
|
||||
private ObjectProperty<AccountLevel> currentAccountLevel;
|
||||
private Label accountNameLabel;
|
||||
|
||||
MainFrameView(MainFrameController ctrl) {
|
||||
this.ctrl = ctrl;
|
||||
@ -51,11 +46,10 @@ class MainFrameView implements IFXComponent{
|
||||
buttonHolder.prefWidthProperty().bind(sidebar.widthProperty());
|
||||
sidebar.getChildren().add(buttonHolder);
|
||||
|
||||
accountManager = new AccountManager();
|
||||
accountManager.addListener(ctrl.getAccountManagerValidatorListener());
|
||||
accountManager.addListener(ctrl.getAccountManagerAccountListener());
|
||||
accountManager.getPane().prefWidthProperty().bind(sidebar.widthProperty());
|
||||
sidebar.getChildren().add(accountManager.getPane());
|
||||
accountNameLabel = new Label();
|
||||
Button disconnectionButton = new Button(GUIStringTool.getLogoutButtonLabel());
|
||||
disconnectionButton.setOnAction((event -> ctrl.onAccountDisconnectionRequested()));
|
||||
sidebar.getChildren().addAll(accountNameLabel, disconnectionButton);
|
||||
|
||||
mainPane.setLeft(sidebar);
|
||||
|
||||
@ -120,20 +114,8 @@ class MainFrameView implements IFXComponent{
|
||||
buttonHolder.getChildren().add(button);
|
||||
}
|
||||
|
||||
boolean isAccountCreationPossible(){
|
||||
return accountManager.isCreationPossible();
|
||||
}
|
||||
|
||||
Account create(){
|
||||
return accountManager.create();
|
||||
}
|
||||
|
||||
void setCurrentAccount(Account account){
|
||||
accountManager.setCurrentAccount(account);
|
||||
}
|
||||
|
||||
void feedAccountCollectionToManager(Collection<Account> accounts){
|
||||
accountManager.display(accounts);
|
||||
accountNameLabel.setText(GUIStringTool.getAccountStringConverter().toString(account));
|
||||
}
|
||||
|
||||
void updateModuleButtonLock(AccountLevel level) {
|
||||
|
@ -3,6 +3,5 @@ package com.pqt.client.gui.main_frame.listeners;
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IMainFrameModelListener extends EventListener{
|
||||
void onAccountStatusChangedEvent(boolean status);
|
||||
void onAccountCollectionChangedEvent();
|
||||
void onAccountDisconnectedEvent();
|
||||
}
|
||||
|
@ -37,8 +37,6 @@ class AccountScreenModel {
|
||||
}
|
||||
|
||||
Collection<AccountLevel> getLevels() {
|
||||
//TODO régler ça aussi
|
||||
//return accountService.getAvailableLevels();
|
||||
return EnumSet.allOf(AccountLevel.class);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import javafx.scene.layout.Pane;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
//TODO à faire
|
||||
public class AccountManagerScreen implements IFXValidatorComponent, IFXCreatorComponent<Account>{
|
||||
|
||||
private AccountManagerScreenModel model;
|
||||
|
@ -13,7 +13,9 @@ import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.event.Event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class SaleScreenController {
|
||||
|
||||
@ -45,7 +47,7 @@ class SaleScreenController {
|
||||
|
||||
@Override
|
||||
public void onAccountListUpdatedEvent() {
|
||||
view.setAccounts(model.getAccountList());
|
||||
view.setAccounts(new ArrayList<>(model.getAccountList()));
|
||||
}
|
||||
|
||||
|
||||
@ -99,7 +101,7 @@ class SaleScreenController {
|
||||
return model.getProductList();
|
||||
}
|
||||
private List<Account> fetchAccountList(){
|
||||
return model.getAccountList();
|
||||
return new ArrayList<>(model.getAccountList());
|
||||
}
|
||||
private List<SaleType> fetchSaleTypeList(){
|
||||
return model.getSaleTypeList();
|
||||
|
@ -17,6 +17,7 @@ import com.pqt.core.entities.user_account.AccountLevel;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -104,6 +105,11 @@ class SaleScreenModel {
|
||||
fireAccountConnectedStatusUpdateEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountStatusNotChangedEvent(Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountListChangedEvent() {
|
||||
fireAccountListUpdatedEvent();
|
||||
@ -138,7 +144,7 @@ class SaleScreenModel {
|
||||
.forEach(ISaleScreenModelListener::onAccountConnectedStateUpdatedEvent);
|
||||
}
|
||||
|
||||
List<Account> getAccountList() {
|
||||
Collection<Account> getAccountList() {
|
||||
return accountService.getAllAccounts();
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,11 @@ class StockScreenModel {
|
||||
StockScreenModel.this.fireConnectedStatusChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountStatusNotChangedEvent(Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountListChangedEvent() {
|
||||
|
||||
|
@ -1,162 +0,0 @@
|
||||
package com.pqt.client.gui.ressources.components;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.creators.IFXCreatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.IFXValidatorComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.IValidatorComponentListener;
|
||||
import com.pqt.client.gui.ressources.components.generics.validators.listeners.SimpleValidatorComponentFirerer;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.IFXAccountsDisplayerComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.listeners.SimpleAccountComponentFirerer;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class AccountManager implements IFXAccountsDisplayerComponent, IFXValidatorComponent, IFXCreatorComponent<Account> {
|
||||
|
||||
private Pane mainPane;
|
||||
|
||||
private VBox mainDisconnectedPane, mainConnectedPane;
|
||||
private TextField connectedUsernameField;
|
||||
private ChoiceBox<Account> disconnectedUsernameField;
|
||||
private PasswordField passwordField;
|
||||
|
||||
private SimpleAccountComponentFirerer accountEventFirerer;
|
||||
private SimpleValidatorComponentFirerer validatorEventFirerer;
|
||||
|
||||
private Account currentAccount;
|
||||
|
||||
public AccountManager() {
|
||||
accountEventFirerer = new SimpleAccountComponentFirerer();
|
||||
validatorEventFirerer = new SimpleValidatorComponentFirerer();
|
||||
|
||||
currentAccount = null;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mainPane = new Pane();
|
||||
|
||||
mainConnectedPane = new VBox();
|
||||
mainDisconnectedPane = new VBox();
|
||||
|
||||
connectedUsernameField = new TextField();
|
||||
connectedUsernameField.setEditable(false);
|
||||
|
||||
Button disconnectButton = new Button(GUIStringTool.getLogoutButtonLabel());
|
||||
disconnectButton.setOnMouseClicked(event->validatorEventFirerer.fireCancelEvent());
|
||||
disconnectButton.setOnKeyTyped(event->{if(event.getCode().equals(KeyCode.ENTER)) validatorEventFirerer.fireCancelEvent();});
|
||||
|
||||
mainConnectedPane.getChildren().addAll(connectedUsernameField, disconnectButton);
|
||||
|
||||
|
||||
disconnectedUsernameField = new ChoiceBox<>();
|
||||
disconnectedUsernameField.setConverter(GUIStringTool.getAccountStringConverter());
|
||||
|
||||
passwordField = new PasswordField();
|
||||
passwordField.setPromptText(GUIStringTool.getPasswordFieldPromptText());
|
||||
|
||||
Button validationButton = new Button(GUIStringTool.getLoginButtonLabel());
|
||||
validationButton.setOnMouseClicked(event-> validatorEventFirerer.fireValidationEvent());
|
||||
validationButton.setOnKeyTyped(event->{if(event.getCode().equals(KeyCode.ENTER)) validatorEventFirerer.fireValidationEvent();});
|
||||
|
||||
mainDisconnectedPane.getChildren().addAll(disconnectedUsernameField, passwordField, validationButton);
|
||||
|
||||
refreshMainPane();
|
||||
display(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(Collection<Account> content) {
|
||||
Platform.runLater(()->{
|
||||
if(content!=null && content.size()>0)
|
||||
disconnectedUsernameField.setItems(FXCollections.observableArrayList(content));
|
||||
else{
|
||||
disconnectedUsernameField.getItems().clear();
|
||||
disconnectedUsernameField.getItems().add(new Account("null", "", AccountLevel.getLowest()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setCurrentAccount(Account account){
|
||||
currentAccount = account;
|
||||
Platform.runLater(()->connectedUsernameField.setText(GUIStringTool.getAccountStringConverter().toString(currentAccount)));
|
||||
refreshMainPane();
|
||||
}
|
||||
|
||||
private void refreshMainPane() {
|
||||
if(currentAccount!=null)
|
||||
Platform.runLater(
|
||||
()->{
|
||||
mainPane.getChildren().clear();
|
||||
mainPane.getChildren().add(mainConnectedPane);
|
||||
}
|
||||
);
|
||||
else
|
||||
Platform.runLater(
|
||||
()->{
|
||||
mainPane.getChildren().clear();
|
||||
mainPane.getChildren().add(mainDisconnectedPane);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public Account getCurrentAccount() {
|
||||
return currentAccount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IAccountComponentListener l) {
|
||||
accountEventFirerer.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IAccountComponentListener l) {
|
||||
accountEventFirerer.removeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IValidatorComponentListener l) {
|
||||
validatorEventFirerer.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IValidatorComponentListener l) {
|
||||
validatorEventFirerer.removeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account create() {
|
||||
if(!isCreationPossible())
|
||||
return null;
|
||||
|
||||
return new Account(disconnectedUsernameField.getValue().getUsername(), passwordField.getText(), disconnectedUsernameField.getValue().getPermissionLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreationPossible() {
|
||||
return currentAccount==null
|
||||
&& disconnectedUsernameField.getAccessibleText()!=null
|
||||
&& !disconnectedUsernameField.getAccessibleText().isEmpty()
|
||||
&& passwordField.getText()!=null
|
||||
&& !passwordField.getText().isEmpty();
|
||||
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.account;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.IFXDisplayerComponent;
|
||||
import com.pqt.client.gui.ressources.components.specifics.account.listeners.IAccountComponentListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface IFXAccountsDisplayerComponent extends IFXDisplayerComponent<Collection<Account>, IAccountComponentListener> {
|
||||
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.account.listeners;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.IDisplayerComponentListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
public interface IAccountComponentListener extends IDisplayerComponentListener<Account>{
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.pqt.client.gui.ressources.components.specifics.account.listeners;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.displayers.listeners.SimpleDisplayerComponentFirerer;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
public class SimpleAccountComponentFirerer extends SimpleDisplayerComponentFirerer<Account, IAccountComponentListener> {
|
||||
public SimpleAccountComponentFirerer() {
|
||||
super(IAccountComponentListener.class);
|
||||
}
|
||||
}
|
@ -331,6 +331,35 @@ public class GUIStringTool {
|
||||
public static String getAccountLevelColumnHeaderLabel() {
|
||||
return "Niveau d'accréditation";
|
||||
}
|
||||
|
||||
public static String getServerSectionTitleLabel() {
|
||||
return "Serveur";
|
||||
}
|
||||
|
||||
public static String getAccountSectionTitleLabel() {
|
||||
return "Compte";
|
||||
}
|
||||
|
||||
public static String getErrorConsoleSectionTitleLabel() {
|
||||
return "Informations";
|
||||
}
|
||||
|
||||
public static String getServerHostLabel() {
|
||||
return "Host : ";
|
||||
}
|
||||
|
||||
public static String getServerPortLabel() {
|
||||
return "Port : ";
|
||||
}
|
||||
|
||||
public static IObjectStringRenderer<Exception> getExceptionFormatter() {
|
||||
return e->{
|
||||
if(e.getMessage()==null || e.getMessage().isEmpty())
|
||||
return String.format("%s", e.getClass().getName());
|
||||
else
|
||||
return String.format("%s : %s", e.getClass().getName(), e.getMessage());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,32 @@
|
||||
package com.pqt.client.gui.startup_frame;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.startup_frame.listeners.frame.IStartupFrameModelListener;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.network.NetworkService;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class StartupFrame implements IFXComponent{
|
||||
|
||||
private StartupFrameView view;
|
||||
private StartupFrameModel model;
|
||||
|
||||
public StartupFrame(AccountService accountService, NetworkService networkService) {
|
||||
model = new StartupFrameModel(accountService, networkService);
|
||||
StartupFrameController ctrl = new StartupFrameController(model);
|
||||
model.addListener(ctrl);
|
||||
|
||||
view = new StartupFrameView(ctrl);
|
||||
ctrl.setView(view);
|
||||
ctrl.updateView();
|
||||
}
|
||||
|
||||
public void addFrameModelListener(IStartupFrameModelListener l){
|
||||
model.addListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return view.getPane();
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.pqt.client.gui.startup_frame;
|
||||
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import com.pqt.client.gui.startup_frame.listeners.frame.IStartupFrameModelListener;
|
||||
|
||||
public class StartupFrameController implements IStartupFrameModelListener {
|
||||
|
||||
private final StartupFrameModel model;
|
||||
private StartupFrameView view;
|
||||
|
||||
public StartupFrameController(StartupFrameModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void setView(StartupFrameView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public void updateView() {
|
||||
view.setValidationButtonEnable(enableValidationButton());
|
||||
}
|
||||
|
||||
private boolean enableValidationButton() {
|
||||
return !view.getAccountUsernameTextFieldContent().isEmpty()
|
||||
&& !view.getServerPortTextFieldContent().isEmpty()
|
||||
&& !view.getServerPortTextFieldContent().isEmpty();
|
||||
}
|
||||
|
||||
public void onValidation() {
|
||||
if(!model.isStartupProcessRunning()){
|
||||
try {
|
||||
model.beginStartupProcess(
|
||||
view.getServerHostTextFieldContent(),
|
||||
view.getServerPortTextFieldContent(),
|
||||
view.getAccountUsernameTextFieldContent(),
|
||||
view.getAccountPasswordTextFieldContent()
|
||||
);
|
||||
}catch(NullPointerException | IllegalArgumentException e){
|
||||
view.displayError(GUIStringTool.getExceptionFormatter().render(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartupValidated() {
|
||||
view.clearPasswordField();
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.pqt.client.gui.startup_frame;
|
||||
|
||||
import com.pqt.client.gui.startup_frame.listeners.frame.IStartupFrameModelEventFirerer;
|
||||
import com.pqt.client.gui.startup_frame.listeners.frame.IStartupFrameModelListener;
|
||||
import com.pqt.client.gui.startup_frame.listeners.frame.SimpleStartupFrameModelEventFirerer;
|
||||
import com.pqt.client.gui.startup_frame.listeners.procedure.IStartupProcedureListener;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.network.NetworkService;
|
||||
|
||||
public class StartupFrameModel {
|
||||
|
||||
private final AccountService accountService;
|
||||
private final NetworkService networkService;
|
||||
private final IStartupFrameModelEventFirerer firerer;
|
||||
|
||||
private boolean startupProcessBegan;
|
||||
|
||||
public StartupFrameModel(AccountService accountService, NetworkService networkService) {
|
||||
this.accountService = accountService;
|
||||
this.networkService = networkService;
|
||||
firerer = new SimpleStartupFrameModelEventFirerer();
|
||||
startupProcessBegan = false;
|
||||
}
|
||||
|
||||
public void addListener(IStartupFrameModelListener ctrl) {
|
||||
firerer.addListener(ctrl);
|
||||
}
|
||||
|
||||
public boolean isStartupProcessRunning() {
|
||||
return startupProcessBegan;
|
||||
}
|
||||
|
||||
public void beginStartupProcess(String requiredHost, String requiredPort, String username, String password) {
|
||||
if(!startupProcessBegan){
|
||||
checkParameters(requiredHost, requiredPort, username, password);
|
||||
startupProcessBegan = true;
|
||||
|
||||
Integer requiredIntPort = Integer.parseInt(requiredPort);
|
||||
|
||||
new StartupProcedureHandler(networkService, accountService)
|
||||
.init(requiredHost, requiredIntPort, username, password)
|
||||
.addListener(new IStartupProcedureListener() {
|
||||
@Override
|
||||
public void onServerFoundEvent(String URL, Integer Port) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserAccountUnknownEvent(String username) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserAccountConnectedEvent(String username) {
|
||||
firerer.fireStartupValidated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserAccountDisconnectedEvent(String username) {
|
||||
|
||||
}
|
||||
})
|
||||
.handle();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkParameters(String host, String port, String username, String password) {
|
||||
if(host==null || port == null || username == null || password == null)
|
||||
throw new NullPointerException("Null parameters are not allowed on startup");
|
||||
|
||||
if(username.isEmpty() || host.isEmpty() || port.isEmpty())
|
||||
throw new IllegalArgumentException("The following parameters must be filled : host, port, username");
|
||||
|
||||
if(!port.matches("^\\d+$"))
|
||||
throw new IllegalArgumentException("Given port is not a positive integer");
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
package com.pqt.client.gui.startup_frame;
|
||||
|
||||
import com.pqt.client.gui.ressources.components.generics.IFXComponent;
|
||||
import com.pqt.client.gui.ressources.strings.GUIStringTool;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class StartupFrameView implements IFXComponent{
|
||||
|
||||
private VBox mainPane;
|
||||
private final StartupFrameController ctrl;
|
||||
|
||||
private TextField serverHostTextField;
|
||||
private TextField serverPortTextField;
|
||||
private TextField usernameTextField;
|
||||
private TextField passwordTextField;
|
||||
|
||||
private Button validationButton;
|
||||
private Text infoText;
|
||||
|
||||
public StartupFrameView(StartupFrameController ctrl) {
|
||||
this.ctrl = ctrl;
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
try {
|
||||
mainPane = new VBox();
|
||||
|
||||
Label serverHostLabel = new Label(GUIStringTool.getServerHostLabel());
|
||||
serverHostTextField = makeTextField(TextField.class);
|
||||
Label serverPortLabel = new Label(GUIStringTool.getServerPortLabel());
|
||||
serverPortTextField = makeTextField(TextField.class);
|
||||
|
||||
GridPane serverFieldGridPane = new GridPane();
|
||||
serverFieldGridPane.add(serverHostLabel, 0, 0);
|
||||
serverFieldGridPane.add(serverHostTextField, 1, 0);
|
||||
serverFieldGridPane.add(serverPortLabel, 0, 1);
|
||||
serverFieldGridPane.add(serverPortTextField, 1, 1);
|
||||
|
||||
TitledPane serverTitledPane = new TitledPane(GUIStringTool.getServerSectionTitleLabel(), serverFieldGridPane);
|
||||
|
||||
|
||||
Label usernameLabel = new Label(GUIStringTool.getUsernameLabel());
|
||||
usernameTextField = makeTextField(TextField.class);
|
||||
Label passwordLabel = new Label(GUIStringTool.getPasswordLabel());
|
||||
passwordTextField = makeTextField(PasswordField.class);
|
||||
|
||||
GridPane accountFieldGridPane = new GridPane();
|
||||
accountFieldGridPane.add(usernameLabel, 0, 0);
|
||||
accountFieldGridPane.add(usernameTextField, 1, 0);
|
||||
accountFieldGridPane.add(passwordLabel, 0, 1);
|
||||
accountFieldGridPane.add(passwordTextField, 1, 1);
|
||||
|
||||
TitledPane accountTitledPane = new TitledPane(GUIStringTool.getAccountSectionTitleLabel(), accountFieldGridPane);
|
||||
|
||||
validationButton = new Button(GUIStringTool.getValidationButtonLabel());
|
||||
validationButton.setOnAction((event) -> {
|
||||
ctrl.onValidation();
|
||||
});
|
||||
|
||||
infoText = new Text("");
|
||||
infoText.getStyleClass().add("text-displayer");
|
||||
TitledPane errorConsoleTitledPane = new TitledPane(GUIStringTool.getErrorConsoleSectionTitleLabel(), infoText);
|
||||
infoText.textProperty().addListener((obs, oldValue, newValue)->errorConsoleTitledPane.setExpanded(true));
|
||||
|
||||
mainPane.getChildren().addAll(serverTitledPane, accountTitledPane, errorConsoleTitledPane, validationButton);
|
||||
}catch(Exception e){
|
||||
//TODO Shutdown software on exception
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends TextField> T makeTextField(Class<T> clazz) throws IllegalAccessException, InstantiationException {
|
||||
T ntf = clazz.newInstance();
|
||||
ntf.textProperty().addListener((obs, oldVal, newVal)->{
|
||||
ctrl.updateView();
|
||||
});
|
||||
return ntf;
|
||||
}
|
||||
|
||||
String getServerHostTextFieldContent(){
|
||||
return serverHostTextField.getText();
|
||||
}
|
||||
|
||||
String getServerPortTextFieldContent(){
|
||||
return serverPortTextField.getText();
|
||||
}
|
||||
|
||||
String getAccountUsernameTextFieldContent(){
|
||||
return usernameTextField.getText();
|
||||
}
|
||||
|
||||
String getAccountPasswordTextFieldContent(){
|
||||
return passwordTextField.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getPane() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
public void setValidationButtonEnable(boolean enable) {
|
||||
this.validationButton.setDisable(!enable);
|
||||
}
|
||||
|
||||
public void clearPasswordField() {
|
||||
passwordTextField.setText("");
|
||||
}
|
||||
|
||||
public void displayError(String errorMsg) {
|
||||
infoText.setText(errorMsg);
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package com.pqt.client.gui.startup_frame;
|
||||
|
||||
import com.pqt.client.gui.startup_frame.listeners.procedure.IStartupProcedureEventFirerer;
|
||||
import com.pqt.client.gui.startup_frame.listeners.procedure.IStartupProcedureListener;
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.account.listeners.AccountListenerAdapter;
|
||||
import com.pqt.client.module.account.listeners.IAccountListener;
|
||||
import com.pqt.client.module.network.NetworkService;
|
||||
import com.pqt.client.module.network.listeners.INetworkServiceListener;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
class StartupProcedureHandler {
|
||||
|
||||
private NetworkService networkService;
|
||||
private AccountService accountService;
|
||||
|
||||
private String host, username, password;
|
||||
private Integer port;
|
||||
|
||||
private IStartupProcedureEventFirerer firerer;
|
||||
|
||||
StartupProcedureHandler(NetworkService networkService, AccountService accountService) {
|
||||
this.networkService = networkService;
|
||||
this.accountService = accountService;
|
||||
}
|
||||
|
||||
StartupProcedureHandler init(String host, Integer port, String username, String password){
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void handle(){
|
||||
testConnection();
|
||||
}
|
||||
|
||||
private void testConnection(){
|
||||
networkService.addListener(getPingListener());
|
||||
networkService.sendPQTPing(host, port);
|
||||
}
|
||||
|
||||
private void useRequestedServer(){
|
||||
//Server found
|
||||
firerer.fireServerFoundEvent(host, port);
|
||||
networkService.setActiveServer(host, port);
|
||||
accountService.addListener(getUpdateAccountListListener());
|
||||
accountService.refreshAccounts();
|
||||
}
|
||||
|
||||
private void connectAccount(){
|
||||
Account match = accountService.getAllAccounts().stream()
|
||||
.filter(account -> account.getUsername().equals(username))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if(match==null){
|
||||
//Compte spécifié inconnu
|
||||
firerer.fireUserAccountUnknownEvent(username);
|
||||
}else{
|
||||
accountService.setCurrentAccount(match);
|
||||
accountService.addListener(getConnectAccountListener());
|
||||
accountService.logInCurrentAccount(StartupProcedureHandler.this.password);
|
||||
}
|
||||
}
|
||||
|
||||
private INetworkServiceListener getPingListener(){
|
||||
return new INetworkServiceListener() {
|
||||
@Override
|
||||
public void onPQTPingSuccessEvent(String host, Integer port) {
|
||||
if(StartupProcedureHandler.this.host.equals(host)
|
||||
&& StartupProcedureHandler.this.port.equals(port)){
|
||||
useRequestedServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPQTPingFailureEvent(String host, Integer port, Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewServerConfigData() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IAccountListener getUpdateAccountListListener(){
|
||||
return new AccountListenerAdapter(){
|
||||
@Override
|
||||
public void onAccountListChangedEvent(){
|
||||
connectAccount();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IAccountListener getConnectAccountListener(){
|
||||
return new AccountListenerAdapter(){
|
||||
@Override
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
if(status){
|
||||
//Compte connecté
|
||||
firerer.fireUserAccountConnectedEvent(username);
|
||||
}else{
|
||||
//Compte non-connecté
|
||||
firerer.fireUserAccountDisconnectedEvent(username);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public StartupProcedureHandler addListener(IStartupProcedureListener l){
|
||||
firerer.addListener(l);
|
||||
return this;
|
||||
}
|
||||
|
||||
public StartupProcedureHandler removeListener(IStartupProcedureListener l){
|
||||
firerer.removeListener(l);
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.pqt.client.gui.startup_frame.listeners.frame;
|
||||
|
||||
public interface IStartupFrameModelEventFirerer {
|
||||
void fireStartupValidated();
|
||||
|
||||
void addListener(IStartupFrameModelListener l);
|
||||
void removeListener(IStartupFrameModelListener l);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.gui.startup_frame.listeners.frame;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IStartupFrameModelListener extends EventListener {
|
||||
void onStartupValidated();
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.pqt.client.gui.startup_frame.listeners.frame;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SimpleStartupFrameModelEventFirerer implements IStartupFrameModelEventFirerer {
|
||||
|
||||
private final EventListenerList listenerList;
|
||||
|
||||
public SimpleStartupFrameModelEventFirerer() {
|
||||
this.listenerList = new EventListenerList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireStartupValidated() {
|
||||
Arrays.stream(listenerList.getListeners(IStartupFrameModelListener.class))
|
||||
.forEach(IStartupFrameModelListener::onStartupValidated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IStartupFrameModelListener l) {
|
||||
listenerList.add(IStartupFrameModelListener.class, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IStartupFrameModelListener l) {
|
||||
listenerList.remove(IStartupFrameModelListener.class, l);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.pqt.client.gui.startup_frame.listeners.procedure;
|
||||
|
||||
public interface IStartupProcedureEventFirerer {
|
||||
|
||||
void fireServerFoundEvent(String URL, Integer Port);
|
||||
void fireUserAccountUnknownEvent(String username);
|
||||
void fireUserAccountConnectedEvent(String username);
|
||||
void fireUserAccountDisconnectedEvent(String username);
|
||||
|
||||
void addListener(IStartupProcedureListener l );
|
||||
void removeListener(IStartupProcedureListener l );
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.pqt.client.gui.startup_frame.listeners.procedure;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IStartupProcedureListener extends EventListener{
|
||||
|
||||
void onServerFoundEvent(String URL, Integer Port);
|
||||
void onUserAccountUnknownEvent(String username);
|
||||
void onUserAccountConnectedEvent(String username);
|
||||
void onUserAccountDisconnectedEvent(String username);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.pqt.client.gui.startup_frame.listeners.procedure;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SimpleStartupProcedureEventFirerer implements IStartupProcedureEventFirerer {
|
||||
|
||||
private final EventListenerList listenerList;
|
||||
|
||||
public SimpleStartupProcedureEventFirerer() {
|
||||
this.listenerList = new EventListenerList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireServerFoundEvent(String URL, Integer port) {
|
||||
Arrays.stream(listenerList.getListeners(IStartupProcedureListener.class))
|
||||
.forEach(l->l.onServerFoundEvent(URL, port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUserAccountUnknownEvent(String username) {
|
||||
Arrays.stream(listenerList.getListeners(IStartupProcedureListener.class))
|
||||
.forEach(l->l.onUserAccountUnknownEvent(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUserAccountConnectedEvent(String username) {
|
||||
Arrays.stream(listenerList.getListeners(IStartupProcedureListener.class))
|
||||
.forEach(l->l.onUserAccountConnectedEvent(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUserAccountDisconnectedEvent(String username) {
|
||||
Arrays.stream(listenerList.getListeners(IStartupProcedureListener.class))
|
||||
.forEach(l->l.onUserAccountDisconnectedEvent(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(IStartupProcedureListener l) {
|
||||
listenerList.add(IStartupProcedureListener.class, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(IStartupProcedureListener l) {
|
||||
listenerList.remove(IStartupProcedureListener.class, l);
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.pqt.client.module;
|
||||
|
||||
import com.pqt.client.module.account.AccountService;
|
||||
import com.pqt.client.module.connection.ConnectionService;
|
||||
import com.pqt.client.module.network.NetworkService;
|
||||
import com.pqt.client.module.query.QueryExecutor;
|
||||
import com.pqt.client.module.sale.SaleService;
|
||||
import com.pqt.client.module.stat.StatService;
|
||||
import com.pqt.client.module.stock.StockService;
|
||||
|
||||
public class ClientBackEndModuleManager {
|
||||
|
||||
private final SaleService saleService;
|
||||
private final StockService stockService;
|
||||
private final AccountService accountService;
|
||||
private final StatService statService;
|
||||
private final NetworkService networkService;
|
||||
|
||||
public ClientBackEndModuleManager(String serverUrl) {
|
||||
ConnectionService connectionService = new ConnectionService(serverUrl);
|
||||
QueryExecutor queryExecutor = new QueryExecutor(connectionService);
|
||||
saleService = new SaleService(queryExecutor);
|
||||
stockService = new StockService(queryExecutor);
|
||||
accountService = new AccountService(queryExecutor);
|
||||
statService = new StatService(queryExecutor);
|
||||
networkService = new NetworkService(queryExecutor, connectionService);
|
||||
}
|
||||
|
||||
public SaleService getSaleService() {
|
||||
return saleService;
|
||||
}
|
||||
|
||||
public StockService getStockService() {
|
||||
return stockService;
|
||||
}
|
||||
|
||||
public AccountService getAccountService() {
|
||||
return accountService;
|
||||
}
|
||||
|
||||
public StatService getStatService() {
|
||||
return statService;
|
||||
}
|
||||
|
||||
public NetworkService getNetworkService() {
|
||||
return networkService;
|
||||
}
|
||||
}
|
@ -1,48 +1,123 @@
|
||||
package com.pqt.client.module.account;
|
||||
|
||||
import com.pqt.client.module.query.QueryExecutor;
|
||||
import com.pqt.client.module.query.query_callback.ICollectionItemMessageCallback;
|
||||
import com.pqt.client.module.query.query_callback.INoItemMessageCallback;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
import com.pqt.client.module.account.listeners.IAccountListener;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
//TODO écrire contenu méthodes
|
||||
//TODO écrire javadoc
|
||||
//TODO add log lines
|
||||
//TODO supporter la modif de comptes
|
||||
public class AccountService {
|
||||
|
||||
private QueryExecutor executor;
|
||||
private Account currentAccount;
|
||||
private boolean connected;
|
||||
private Collection<Account> accounts;
|
||||
private EventListenerList listenerList;
|
||||
|
||||
public AccountService(QueryExecutor executor){
|
||||
this.executor = executor;
|
||||
listenerList = new EventListenerList();
|
||||
accounts = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Account getCurrentAccount() {
|
||||
return null;
|
||||
return currentAccount;
|
||||
}
|
||||
|
||||
public void setCurrentAccount(Account account) {
|
||||
|
||||
if(connected)
|
||||
logOutCurrentAccount();
|
||||
this.currentAccount = account;
|
||||
}
|
||||
|
||||
public boolean isCurrentAccountLoggedIn() {
|
||||
return false;
|
||||
return connected;
|
||||
}
|
||||
|
||||
public void logInCurrentAccount(String password) {
|
||||
|
||||
setCurrentAccountState(password, true);
|
||||
}
|
||||
|
||||
public void logOutCurrentAccount() {
|
||||
|
||||
setCurrentAccountState(null, false);
|
||||
}
|
||||
|
||||
public List<Account> getRecentAccounts() {
|
||||
return null;
|
||||
private void setCurrentAccountState(String password, boolean state){
|
||||
if(currentAccount!=null && connected!=state) {
|
||||
Account acc = new Account(currentAccount);
|
||||
acc.setPassword(password);
|
||||
executor.executeConnectAccountQuery(acc, state, new INoItemMessageCallback() {
|
||||
@Override
|
||||
public void ack() {
|
||||
if (currentAccount != null
|
||||
&& connected != state
|
||||
&& currentAccount.getUsername().equals(acc.getUsername())
|
||||
&& currentAccount.getPermissionLevel().equals(acc.getPermissionLevel())) {
|
||||
connected = state;
|
||||
Arrays.stream(listenerList.getListeners(IAccountListener.class))
|
||||
.forEach(l->l.onAccountStatusChangedEvent(connected));
|
||||
}else
|
||||
Arrays.stream(listenerList.getListeners(IAccountListener.class))
|
||||
.forEach(l->l.onAccountStatusNotChangedEvent(
|
||||
new IllegalStateException("Account service not in the right state")
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void err(Throwable cause) {
|
||||
Arrays.stream(listenerList.getListeners(IAccountListener.class))
|
||||
.forEach(l->l.onAccountStatusNotChangedEvent(cause));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ref(Throwable cause) {
|
||||
Arrays.stream(listenerList.getListeners(IAccountListener.class))
|
||||
.forEach(l->l.onAccountStatusNotChangedEvent(cause));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void addListener(IAccountListener listener) {
|
||||
|
||||
listenerList.add(IAccountListener.class, listener);
|
||||
}
|
||||
|
||||
public void removeListener(IAccountListener listener) {
|
||||
listenerList.remove(IAccountListener.class, listener);
|
||||
}
|
||||
|
||||
public Collection<Account> getAllAccounts() {
|
||||
return accounts;
|
||||
}
|
||||
|
||||
public void refreshAccounts(){
|
||||
executor.executeAccountListQuery(new ICollectionItemMessageCallback<Account>() {
|
||||
@Override
|
||||
public void err(Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
public List<Account> getAllAccounts() {
|
||||
return null;
|
||||
@Override
|
||||
public void ref(Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ack(Collection<Account> obj) {
|
||||
accounts = obj;
|
||||
Arrays.stream(listenerList.getListeners(IAccountListener.class))
|
||||
.forEach(IAccountListener::onAccountListChangedEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,23 @@ public class AccountListenerAdapter implements IAccountListener {
|
||||
/**
|
||||
* @see com.pqt.client.module.account.listeners.IAccountListener#onAccountStatusChangedEvent(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void onAccountStatusChangedEvent(boolean status) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.account.listeners.IAccountListener#onAccountStatusNotChangedEvent(Throwable)
|
||||
*/
|
||||
@Override
|
||||
public void onAccountStatusNotChangedEvent(Throwable cause) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.account.listeners.IAccountListener#onAccountListChangedEvent()
|
||||
*/
|
||||
@Override
|
||||
public void onAccountListChangedEvent() {
|
||||
|
||||
}
|
||||
|
@ -5,5 +5,6 @@ import java.util.EventListener;
|
||||
public interface IAccountListener extends EventListener {
|
||||
|
||||
void onAccountStatusChangedEvent(boolean status);
|
||||
void onAccountStatusNotChangedEvent(Throwable cause);
|
||||
void onAccountListChangedEvent();
|
||||
}
|
||||
|
@ -1,46 +1,66 @@
|
||||
package com.pqt.client.module.connection;
|
||||
|
||||
import com.pqt.client.module.connection.listeners.IConnectionListener;
|
||||
import com.pqt.client.module.connection.senders.HttpTextSender;
|
||||
import com.pqt.client.module.connection.senders.ITextSender;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
//TODO écrire contenu méthodes
|
||||
//TODO écrire javadoc
|
||||
//TODO add log lines?
|
||||
public class ConnectionService {
|
||||
|
||||
public boolean isConnectedToServer() {
|
||||
return false;
|
||||
private String serverUrl;
|
||||
private ExecutorService executor;
|
||||
private ITextSender textSender;
|
||||
|
||||
public ConnectionService(String serverUrl) {
|
||||
executor = new ThreadPoolExecutor(1, 1, 1000,
|
||||
TimeUnit.SECONDS, new LinkedBlockingQueue<>());
|
||||
this.serverUrl = serverUrl;
|
||||
this.textSender = new HttpTextSender();
|
||||
}
|
||||
|
||||
public void connectToServer(String ip_address) {
|
||||
|
||||
public String getServerUrl() {
|
||||
return serverUrl;
|
||||
}
|
||||
|
||||
public void disconnectFromServer() {
|
||||
|
||||
public void setServerUrl(String url){
|
||||
this.serverUrl = url;
|
||||
}
|
||||
|
||||
public String getCurrentServerIpAddress() {
|
||||
return null;
|
||||
/**
|
||||
* Arrête le service d'envoi.
|
||||
* <p/>
|
||||
* <b>Si ce service est arrêté, il ne sera plus possible de l'utiliser, et ne pourra pas être redémarré</b>. Une
|
||||
* autre isntance devra être utilisée pour pouvoir recommencer à se servir de ce service.
|
||||
* <p/>
|
||||
* Si {@code force} vaut true, le service tentera d'interrompre tous les envois de texte en cours, même s'il ne
|
||||
* sont pas terminés. Sinon, le service attendra que tous les envois en cours soient terminé avant de s'arrêter, mais
|
||||
* n'acceptera pas de nouveaux envois.
|
||||
* @param force {@code true} si l'arrêt du service doit être forcé, {@code false} sinon
|
||||
*/
|
||||
public void stop(boolean force) {
|
||||
if(executor!=null)
|
||||
if(force)
|
||||
executor.shutdownNow();
|
||||
else
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
||||
/**
|
||||
* Envoie la chaîne de caractères {@code text} au serveur de donnée correspondant à l'URL {@link #getServerUrl()}, et
|
||||
* utilise {@code listener} pour notifier l'avancement de l'envoi.
|
||||
*
|
||||
* @param text texte à envoyer
|
||||
* @param listener listener à utiliser pour notifier l'avancement de l'envoi (voir {@link IConnectionListener})
|
||||
* @throws IllegalStateException Si l'url du serveur vaut {@code null} (à spécifier à la constructyion ou avec
|
||||
* {@link #setServerUrl(String)}, ou si le service à été arrêté via la méthode {@link #stop(boolean)}.
|
||||
*/
|
||||
public void sendText(String text, IConnectionListener listener) throws IllegalStateException{
|
||||
if(serverUrl==null)
|
||||
throw new IllegalStateException("No url specified for data server");
|
||||
if(executor.isShutdown() || executor.isTerminated())
|
||||
throw new IllegalStateException("Service was shut down : unable to send text");
|
||||
executor.submit(()->textSender.send(serverUrl, text, listener));
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
|
||||
public void sendText(String text) {
|
||||
|
||||
}
|
||||
|
||||
public void addListener(IConnectionListener listener) {
|
||||
|
||||
}
|
||||
|
||||
public void removeListener(IConnectionListener listener) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package com.pqt.client.module.connection.listeners;
|
||||
|
||||
//TODO écrire contenu méthodes
|
||||
//TODO écrire javadoc
|
||||
public class ConnectionListenerAdapter implements IConnectionListener {
|
||||
|
||||
|
||||
@ -10,6 +8,7 @@ public class ConnectionListenerAdapter implements IConnectionListener {
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void onMessageReceivedEvent(String msg) {
|
||||
|
||||
}
|
||||
@ -20,6 +19,7 @@ public class ConnectionListenerAdapter implements IConnectionListener {
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void onConnectedEvent() {
|
||||
|
||||
}
|
||||
@ -30,8 +30,20 @@ public class ConnectionListenerAdapter implements IConnectionListener {
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void onDisconnectedEvent() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.connection.listeners.IConnectionListener#onTimeOutEvent()
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void onTimeOutEvent() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,14 +2,16 @@ package com.pqt.client.module.connection.listeners;
|
||||
|
||||
public interface IConnectionFirerer {
|
||||
|
||||
public abstract void fireMessageReceivedEvent(String msg);
|
||||
void fireMessageReceivedEvent(String msg);
|
||||
|
||||
public abstract void fireConnectedEvent();
|
||||
void fireConnectedEvent();
|
||||
|
||||
public abstract void fireDisconnectedEvent();
|
||||
void fireDisconnectedEvent();
|
||||
|
||||
public abstract void addListener(IConnectionListener listener);
|
||||
void fireTimeOutEvent();
|
||||
|
||||
public abstract void removeListener(IConnectionListener listener);
|
||||
void addListener(IConnectionListener listener);
|
||||
|
||||
void removeListener(IConnectionListener listener);
|
||||
|
||||
}
|
||||
|
@ -4,10 +4,12 @@ import java.util.EventListener;
|
||||
|
||||
public interface IConnectionListener extends EventListener {
|
||||
|
||||
public abstract void onMessageReceivedEvent(String msg);
|
||||
void onMessageReceivedEvent(String msg);
|
||||
|
||||
public abstract void onConnectedEvent();
|
||||
void onConnectedEvent();
|
||||
|
||||
public abstract void onDisconnectedEvent();
|
||||
void onDisconnectedEvent();
|
||||
|
||||
void onTimeOutEvent();
|
||||
|
||||
}
|
||||
|
@ -1,49 +1,67 @@
|
||||
package com.pqt.client.module.connection.listeners;
|
||||
|
||||
//TODO écrire contenu méthodes
|
||||
//TODO écrire javadoc
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SimpleConnectionFirerer implements IConnectionFirerer {
|
||||
|
||||
private EventListenerList listenerList;
|
||||
|
||||
public SimpleConnectionFirerer() {
|
||||
listenerList = new EventListenerList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.connection.listeners.IConnectionFirerer#fireMessageReceivedEvent(String)
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void fireMessageReceivedEvent(String msg) {
|
||||
|
||||
Arrays.stream(listenerList.getListeners(IConnectionListener.class)).forEach(listener->listener.onMessageReceivedEvent(msg));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.connection.listeners.IConnectionFirerer#fireConnectedEvent()
|
||||
*/
|
||||
@Override
|
||||
public void fireConnectedEvent() {
|
||||
|
||||
Arrays.stream(listenerList.getListeners(IConnectionListener.class)).forEach(IConnectionListener::onConnectedEvent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.connection.listeners.IConnectionFirerer#fireDisconnectedEvent()
|
||||
*/
|
||||
@Override
|
||||
public void fireDisconnectedEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IConnectionListener.class)).forEach(IConnectionListener::onDisconnectedEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.connection.listeners.IConnectionFirerer#fireTimeOutEvent()
|
||||
*/
|
||||
@Override
|
||||
public void fireTimeOutEvent() {
|
||||
Arrays.stream(listenerList.getListeners(IConnectionListener.class)).forEach(IConnectionListener::onDisconnectedEvent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.connection.listeners.IConnectionFirerer#addListener(com.pqt.client.module.connection.listeners.IConnectionListener)
|
||||
*/
|
||||
@Override
|
||||
public void addListener(IConnectionListener listener) {
|
||||
|
||||
listenerList.add(IConnectionListener.class, listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see com.pqt.client.module.connection.listeners.IConnectionFirerer#removeListener(com.pqt.client.module.connection.listeners.IConnectionListener)
|
||||
*/
|
||||
@Override
|
||||
public void removeListener(IConnectionListener listener) {
|
||||
|
||||
listenerList.remove(IConnectionListener.class, listener);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
package com.pqt.client.module.connection.senders;
|
||||
|
||||
import com.pqt.client.module.connection.listeners.IConnectionListener;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class HttpTextSender implements ITextSender{
|
||||
@Override
|
||||
public void send(String url, String text, IConnectionListener listener) {
|
||||
try {
|
||||
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
con.setRequestProperty("Content-Type", "application/json");
|
||||
con.setConnectTimeout(5000);
|
||||
con.setReadTimeout(5000);
|
||||
con.setInstanceFollowRedirects(true);
|
||||
|
||||
String params = URLEncoder.encode("message="+text, "UTF-8");
|
||||
con.setDoOutput(true);
|
||||
try(DataOutputStream out = new DataOutputStream(con.getOutputStream())) {
|
||||
out.writeBytes(params);
|
||||
out.flush();
|
||||
}
|
||||
con.connect();
|
||||
listener.onConnectedEvent();
|
||||
|
||||
try(BufferedReader in = new BufferedReader(
|
||||
new InputStreamReader(con.getInputStream()))) {
|
||||
StringBuilder content = new StringBuilder();
|
||||
String inputLine;
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
content.append(inputLine);
|
||||
}
|
||||
listener.onMessageReceivedEvent(content.toString());
|
||||
}
|
||||
|
||||
con.disconnect();
|
||||
|
||||
}catch (java.net.SocketTimeoutException e){
|
||||
listener.onTimeOutEvent();
|
||||
}catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
listener.onDisconnectedEvent();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.module.connection.senders;
|
||||
|
||||
import com.pqt.client.module.connection.listeners.IConnectionListener;
|
||||
|
||||
public interface ITextSender {
|
||||
void send(String url, String text, IConnectionListener listener);
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package com.pqt.client.module.network;
|
||||
|
||||
import com.pqt.client.module.connection.ConnectionService;
|
||||
import com.pqt.client.module.network.listeners.INetworkServiceListener;
|
||||
import com.pqt.client.module.query.QueryExecutor;
|
||||
import com.pqt.client.module.query.query_callback.IMapItemMessageCallback;
|
||||
import com.pqt.client.module.query.query_callback.INoItemMessageCallback;
|
||||
import com.pqt.core.entities.server_config.ConfigFields;
|
||||
import com.pqt.core.entities.server_config.ServerConfig;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.util.*;
|
||||
|
||||
//TODO ajout javadoc
|
||||
|
||||
/*
|
||||
* Ce service doit permettre de faire des ping et de récupérer la config d'un serveur distant
|
||||
*/
|
||||
public class NetworkService {
|
||||
|
||||
private final QueryExecutor queryExecutor;
|
||||
private final ConnectionService connectionService;
|
||||
private final EventListenerList listenerList;
|
||||
private final ServerConfigCache configCache;
|
||||
|
||||
public NetworkService(QueryExecutor queryExecutor, ConnectionService connectionService) {
|
||||
this.queryExecutor = queryExecutor;
|
||||
this.connectionService = connectionService;
|
||||
listenerList = new EventListenerList();
|
||||
configCache = new ServerConfigCache();
|
||||
}
|
||||
|
||||
public void addListener(INetworkServiceListener l){
|
||||
listenerList.add(INetworkServiceListener.class, l);
|
||||
}
|
||||
|
||||
public void removeListener(INetworkServiceListener l){
|
||||
listenerList.remove(INetworkServiceListener.class, l);
|
||||
}
|
||||
|
||||
public void sendPQTPing(String host, Integer port){
|
||||
checkData(host, port);
|
||||
queryExecutor.executePingQuery(new INoItemMessageCallback() {
|
||||
@Override
|
||||
public void ack() {
|
||||
Arrays.stream(listenerList.getListeners(INetworkServiceListener.class))
|
||||
.forEach(l->l.onPQTPingSuccessEvent(host, port));
|
||||
sendConfigRequest(host, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void err(Throwable cause) {
|
||||
Arrays.stream(listenerList.getListeners(INetworkServiceListener.class))
|
||||
.forEach(l->l.onPQTPingFailureEvent(host, port, cause));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ref(Throwable cause) {
|
||||
Arrays.stream(listenerList.getListeners(INetworkServiceListener.class))
|
||||
.forEach(l->l.onPQTPingFailureEvent(host, port, cause));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean hasServerConfig(String host, Integer port){
|
||||
checkData(host, port);
|
||||
return configCache.hasConfig(host, port);
|
||||
}
|
||||
|
||||
public ServerConfig getServerConfig(String host, Integer port){
|
||||
checkData(host, port);
|
||||
return configCache.getConfig(host, port);
|
||||
}
|
||||
|
||||
public void setActiveServer(String host, Integer port){
|
||||
connectionService.setServerUrl(String.format("%s:%s", host, port));
|
||||
}
|
||||
|
||||
private void sendConfigRequest(String host, Integer port){
|
||||
queryExecutor.executeConfigListQuery(new IMapItemMessageCallback<String, String>(){
|
||||
|
||||
@Override
|
||||
public void err(Throwable cause) {
|
||||
//TODO ajouter log erreur
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ref(Throwable cause) {
|
||||
//TODO ajouter log erreur
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ack(Map<String, String> obj) {
|
||||
configCache.addServerConfig(host, port, convertToServerConfig(obj));
|
||||
Arrays.stream(listenerList.getListeners(INetworkServiceListener.class))
|
||||
.forEach(INetworkServiceListener::onNewServerConfigData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ServerConfig convertToServerConfig(Map<String, String> data){
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
List<String> allowedFields = new ArrayList<>();
|
||||
EnumSet.allOf(ConfigFields.class).forEach(e->allowedFields.add(e.name()));
|
||||
|
||||
data.keySet()
|
||||
.stream()
|
||||
.filter(allowedFields::contains)
|
||||
.filter(key->isBoolean(data.get(key)))
|
||||
.forEach(key->serverConfig.add(getMatchingConfigFields(key), Boolean.parseBoolean(data.get(key))));
|
||||
|
||||
return serverConfig;
|
||||
}
|
||||
|
||||
private boolean isBoolean(String str){
|
||||
return str.equals("true") || str.equals("false");
|
||||
}
|
||||
|
||||
private ConfigFields getMatchingConfigFields(String str){
|
||||
ConfigFields match = null;
|
||||
|
||||
EnumSet<ConfigFields> enumSet = EnumSet.allOf(ConfigFields.class);
|
||||
for(ConfigFields field : enumSet){
|
||||
if(str.equals(field.name()))
|
||||
match = field;
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
private void checkData(String host, Integer port){
|
||||
if(host==null || port == null)
|
||||
throw new NullPointerException("Null value as server data is not allowed");
|
||||
if(host.isEmpty())
|
||||
throw new IllegalArgumentException("host cannot be empty");
|
||||
if(port<1 || port>65535)
|
||||
throw new IllegalArgumentException("port number must be an unsigned 16-bit integer (0<n<65536)");
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.pqt.client.module.network;
|
||||
|
||||
import com.pqt.core.entities.server_config.ServerConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ServerConfigCache {
|
||||
|
||||
private final Map<ServerData, ServerConfig> cache;
|
||||
|
||||
public ServerConfigCache() {
|
||||
cache = new HashMap<>();
|
||||
}
|
||||
|
||||
public void addServerConfig(String host, Integer port, ServerConfig config){
|
||||
ServerData match = cache.keySet().stream().filter(key->key.getHost().equals(host)&&key.getPort().equals(port)).findFirst().orElse(null);
|
||||
if(match==null){
|
||||
cache.put(new ServerData(host, port), config);
|
||||
}else{
|
||||
cache.replace(match, config);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeServerData(String host, Integer port){
|
||||
ServerData data = new ServerData(host, port);
|
||||
if(cache.containsKey(data))
|
||||
cache.remove(data);
|
||||
}
|
||||
|
||||
public boolean hasConfig(String host, Integer port){
|
||||
return cache.containsKey(new ServerData(host, port));
|
||||
}
|
||||
|
||||
public ServerConfig getConfig(String host, Integer port){
|
||||
if(hasConfig(host, port))
|
||||
return cache.get(new ServerData(host, port));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private class ServerData{
|
||||
private String host;
|
||||
private Integer port;
|
||||
|
||||
public ServerData(String host, Integer port) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ServerData that = (ServerData) o;
|
||||
|
||||
if (host != null ? !host.equals(that.host) : that.host != null) return false;
|
||||
return port != null ? port.equals(that.port) : that.port == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = host != null ? host.hashCode() : 0;
|
||||
result = 31 * result + (port != null ? port.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.pqt.client.module.network.listeners;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface INetworkServiceListener extends EventListener {
|
||||
void onPQTPingSuccessEvent(String host, Integer port);
|
||||
void onPQTPingFailureEvent(String host, Integer port, Throwable cause);
|
||||
void onNewServerConfigData();
|
||||
}
|
@ -1,35 +1,170 @@
|
||||
package com.pqt.client.module.query;
|
||||
|
||||
import com.pqt.client.module.query.query_callback.IIdQueryCallback;
|
||||
import com.pqt.core.entities.query.IQuery;
|
||||
import com.pqt.client.module.query.query_callback.ISimpleQueryCallback;
|
||||
import com.pqt.client.module.query.query_callback.IStatQueryCallback;
|
||||
import com.pqt.client.module.query.query_callback.IStockQueryCallback;
|
||||
import com.pqt.client.module.connection.ConnectionService;
|
||||
import com.pqt.client.module.connection.listeners.IConnectionListener;
|
||||
import com.pqt.client.module.query.exceptions.HeaderNotFoundException;
|
||||
import com.pqt.client.module.query.exceptions.MessageTimeoutException;
|
||||
import com.pqt.client.module.query.query_callback.*;
|
||||
import com.pqt.core.communication.GSonMessageToolFactory;
|
||||
import com.pqt.core.communication.IMessageToolFactory;
|
||||
import com.pqt.core.entities.messages.Message;
|
||||
import com.pqt.core.entities.messages.MessageType;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.product.ProductUpdate;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//TODO écrire contenu méthodes
|
||||
//TODO écrire javadoc
|
||||
public class QueryExecutor {
|
||||
|
||||
public static final QueryExecutor INSTANCE = new QueryExecutor();
|
||||
private IMessageToolFactory messageToolFactory;
|
||||
private ConnectionService connectionService;
|
||||
private QueryMessageFactory messageFactory;
|
||||
|
||||
private QueryExecutor(){
|
||||
public QueryExecutor(ConnectionService connectionService){
|
||||
messageToolFactory = new GSonMessageToolFactory();
|
||||
this.connectionService = connectionService;
|
||||
this.messageFactory = new QueryMessageFactory(messageToolFactory);
|
||||
}
|
||||
|
||||
public void executeSaleQuery(Sale sale, INoItemMessageCallback callback) {
|
||||
sendMessage(messageFactory.newSaleMessage(sale), callback, MessageType.ACK_SALE);
|
||||
}
|
||||
|
||||
public void executePingQuery(INoItemMessageCallback callback){
|
||||
sendMessage(messageFactory.newPingMessage(), callback, MessageType.ACK_PING);
|
||||
}
|
||||
|
||||
public void executeUpdateQuery(List<ProductUpdate> updates, INoItemMessageCallback callback) {
|
||||
sendMessage(messageFactory.newUpdateMessage(updates), callback, MessageType.ACK_UPDATE);
|
||||
}
|
||||
|
||||
public void executeConnectAccountQuery(Account account, boolean desiredState, INoItemMessageCallback callback){
|
||||
sendMessage(messageFactory.newConnectAccountMessage(account,desiredState), callback, MessageType.ACK_CONNECT_ACCOUNT);
|
||||
}
|
||||
|
||||
private void sendMessage(Message message, INoItemMessageCallback callback, MessageType responseType){
|
||||
connectionService.sendText(messageToolFactory.getObjectFormatter(Message.class).format(message), new IConnectionListener() {
|
||||
@Override
|
||||
public void onMessageReceivedEvent(String msg) {
|
||||
Message response = messageToolFactory.getObjectParser(Message.class).parse(msg);
|
||||
if(response.getType().equals(responseType))
|
||||
callback.ack();
|
||||
else
|
||||
handleUnexpectedTypeInResponse(response, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedEvent() {
|
||||
|
||||
}
|
||||
|
||||
public long execute(IQuery query, ISimpleQueryCallback callback) {
|
||||
return 0;
|
||||
@Override
|
||||
public void onDisconnectedEvent() {
|
||||
|
||||
}
|
||||
|
||||
public long execute(IQuery query, IStatQueryCallback callback) {
|
||||
return 0;
|
||||
@Override
|
||||
public void onTimeOutEvent() {
|
||||
callback.err(new MessageTimeoutException());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public long execute(IQuery query, IStockQueryCallback callback) {
|
||||
return 0;
|
||||
public void executeStockQuery(ICollectionItemMessageCallback<Product> callback) {
|
||||
sendMessage(messageFactory.newStockMessage(), callback, Product.class, MessageType.MSG_STOCK, "stock");
|
||||
}
|
||||
|
||||
public long execute(IQuery query, IIdQueryCallback callback) {
|
||||
return 0;
|
||||
public void executeAccountListQuery(ICollectionItemMessageCallback<Account> callback){
|
||||
sendMessage(messageFactory.newAccountListMessage(), callback, Account.class, MessageType.MSG_ACCOUNT_LIST, "accounts");
|
||||
}
|
||||
|
||||
private <T> void sendMessage(Message message, ICollectionItemMessageCallback<T> callback, Class<T> clazz, MessageType responseType, String itemHeader){
|
||||
connectionService.sendText(messageToolFactory.getObjectFormatter(Message.class).format(message), new IConnectionListener() {
|
||||
@Override
|
||||
public void onMessageReceivedEvent(String msg) {
|
||||
Message response = messageToolFactory.getObjectParser(Message.class).parse(msg);
|
||||
if(response.getType().equals(responseType)) {
|
||||
String item = response.getField(itemHeader);
|
||||
if (item != null)
|
||||
callback.ack(messageToolFactory.getListParser(clazz).parse(item));
|
||||
else
|
||||
callback.err(new HeaderNotFoundException("Missing expected header \""+
|
||||
itemHeader+"\" in response \""+responseType.name()+"\""));
|
||||
}else
|
||||
handleUnexpectedTypeInResponse(response, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnectedEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeOutEvent() {
|
||||
callback.err(new MessageTimeoutException());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void executeStatQuery(IMapItemMessageCallback<String, String> callback) {
|
||||
sendMessage(messageFactory.newStatMessage(), callback, MessageType.MSG_STAT);
|
||||
}
|
||||
|
||||
public void executeConfigListQuery(IMapItemMessageCallback<String, String> callback){
|
||||
sendMessage(messageFactory.newConfigListMessage(), callback, MessageType.MSG_CONFIG_LIST);
|
||||
}
|
||||
|
||||
//TODO à rendre générique pour toute Map<T, U> au lieu de Map<String, String>
|
||||
private void sendMessage(Message message, IMapItemMessageCallback<String, String> callback, MessageType responseType){
|
||||
connectionService.sendText(messageToolFactory.getObjectFormatter(Message.class).format(message), new IConnectionListener() {
|
||||
@Override
|
||||
public void onMessageReceivedEvent(String msg) {
|
||||
Message response = messageToolFactory.getObjectParser(Message.class).parse(msg);
|
||||
if(response.getType().equals(responseType)){
|
||||
callback.ack(response.getFields());
|
||||
}else
|
||||
handleUnexpectedTypeInResponse(response, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnectedEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeOutEvent() {
|
||||
callback.err(new MessageTimeoutException());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleUnexpectedTypeInResponse(Message response, IMessageCallback callback){
|
||||
switch (response.getType()) {
|
||||
case ERROR_QUERY:
|
||||
callback.err(messageToolFactory.getObjectParser(Throwable.class).parse(response.getField("Detail_erreur")));
|
||||
break;
|
||||
case REFUSED_QUERY:
|
||||
callback.ref(messageToolFactory.getObjectParser(Throwable.class).parse(response.getField("Detail_refus")));
|
||||
break;
|
||||
default:
|
||||
callback.err(new IllegalArgumentException(
|
||||
"Illegal message type for response : " +
|
||||
"expected \"ACK_SALE\"`, found \"" + response.getType().name() + "\""
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
package com.pqt.client.module.query;
|
||||
|
||||
import com.pqt.core.entities.product.ProductUpdate;
|
||||
import com.pqt.core.entities.query.IQuery;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//TODO écrire contenu méthodes
|
||||
//TODO écrire javadoc
|
||||
public class QueryFactory {
|
||||
|
||||
public static IQuery newConnectQuery(String serverAddress) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IQuery newSaleQuery(Sale sale) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IQuery newStockQuery() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IQuery newStatQuery() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IQuery newLogQuery(Account account, boolean state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IQuery newUpdateQuery(List<ProductUpdate> updates) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.pqt.client.module.query;
|
||||
|
||||
import com.pqt.core.communication.IMessageToolFactory;
|
||||
import com.pqt.core.entities.messages.Message;
|
||||
import com.pqt.core.entities.messages.MessageType;
|
||||
import com.pqt.core.entities.product.ProductUpdate;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.core.entities.user_account.Account;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
//TODO écrire javadoc
|
||||
class QueryMessageFactory {
|
||||
|
||||
private final IMessageToolFactory messageToolFactory;
|
||||
|
||||
QueryMessageFactory(IMessageToolFactory messageToolFactory) {
|
||||
this.messageToolFactory = messageToolFactory;
|
||||
}
|
||||
|
||||
Message newSaleMessage(Sale sale) {
|
||||
Map<String, String> fields = new HashMap<>();
|
||||
fields.put("sale", messageToolFactory.getObjectFormatter(Sale.class).format(sale));
|
||||
return newSimpleMessage(MessageType.QUERY_SALE, fields);
|
||||
}
|
||||
|
||||
Message newStockMessage() {
|
||||
return newSimpleMessage(MessageType.QUERY_STOCK);
|
||||
}
|
||||
|
||||
Message newStatMessage() {
|
||||
return newSimpleMessage(MessageType.QUERY_STAT);
|
||||
}
|
||||
|
||||
Message newUpdateMessage(List<ProductUpdate> updates) {
|
||||
Map<String, String> fields = new HashMap<>();
|
||||
fields.put("updates", messageToolFactory.getListFormatter(ProductUpdate.class).format(updates));
|
||||
return newSimpleMessage(MessageType.QUERY_UPDATE, fields);
|
||||
}
|
||||
|
||||
Message newAccountListMessage(){
|
||||
return newSimpleMessage(MessageType.QUERY_ACCOUNT_LIST);
|
||||
}
|
||||
|
||||
Message newConnectAccountMessage(Account account, boolean desiredState){
|
||||
Map<String, String> fields = new HashMap<>();
|
||||
fields.put("account", messageToolFactory.getObjectFormatter(Account.class).format(account));
|
||||
fields.put("desired_state", messageToolFactory.getObjectFormatter(Boolean.class).format(desiredState));
|
||||
return newSimpleMessage(MessageType.QUERY_CONNECT_ACCOUNT, fields);
|
||||
}
|
||||
|
||||
Message newPingMessage(){
|
||||
return newSimpleMessage(MessageType.QUERY_PING);
|
||||
}
|
||||
|
||||
Message newConfigListMessage(){
|
||||
return newSimpleMessage(MessageType.QUERY_CONFIG_LIST);
|
||||
}
|
||||
|
||||
private Message newSimpleMessage(MessageType type, Map<String, String> fields){
|
||||
return new Message(type, null, null, null, null, fields);
|
||||
}
|
||||
|
||||
private Message newSimpleMessage(MessageType type){
|
||||
return newSimpleMessage(type, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.pqt.client.module.query.exceptions;
|
||||
|
||||
public class HeaderNotFoundException extends Exception {
|
||||
public HeaderNotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HeaderNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public HeaderNotFoundException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public HeaderNotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.pqt.client.module.query.exceptions;
|
||||
|
||||
public class MessageTimeoutException extends Exception {
|
||||
public MessageTimeoutException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MessageTimeoutException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MessageTimeoutException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public MessageTimeoutException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface ICollectionItemMessageCallback<T> extends IItemMessageCallback<Collection<T>> {
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
public interface IIdQueryCallback {
|
||||
public void ack(long id);
|
||||
public void err(long id, Throwable cause);
|
||||
public void ref(long id, Throwable cause);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
public interface IItemMessageCallback<T> extends IMessageCallback {
|
||||
void ack(T obj);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface IMapItemMessageCallback<T, U> extends IItemMessageCallback<Map<T, U>> {
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
public interface IMessageCallback {
|
||||
void err(Throwable cause);
|
||||
void ref(Throwable cause);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
public interface INoItemMessageCallback extends IMessageCallback {
|
||||
void ack();
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
public interface ISimpleQueryCallback {
|
||||
public void ack();
|
||||
public void err(Throwable cause);
|
||||
public void ref(Throwable cause);
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface IStatQueryCallback {
|
||||
public void ack(Map<String,String> stats);
|
||||
public void err(Throwable cause);
|
||||
public void ref(Throwable cause);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.pqt.client.module.query.query_callback;
|
||||
|
||||
import com.pqt.core.entities.product.Product;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IStockQueryCallback {
|
||||
public void ack(List<Product> products);
|
||||
public void err(Throwable cause);
|
||||
public void ref(Throwable cause);
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
package com.pqt.client.module.sale;
|
||||
|
||||
import com.pqt.client.module.query.QueryExecutor;
|
||||
import com.pqt.client.module.query.QueryFactory;
|
||||
import com.pqt.client.module.query.query_callback.IIdQueryCallback;
|
||||
import com.pqt.client.module.query.query_callback.INoItemMessageCallback;
|
||||
import com.pqt.client.module.sale.listeners.ISaleFirerer;
|
||||
import com.pqt.client.module.sale.listeners.ISaleListener;
|
||||
import com.pqt.client.module.sale.listeners.SimpleSaleFirerer;
|
||||
@ -14,10 +13,14 @@ import java.util.List;
|
||||
//TODO add log lines
|
||||
public class SaleService {
|
||||
|
||||
private long saleId;
|
||||
private ISaleFirerer eventFirerer;
|
||||
private QueryExecutor executor;
|
||||
|
||||
public SaleService() {
|
||||
public SaleService(QueryExecutor executor) {
|
||||
saleId = 0;
|
||||
eventFirerer = new SimpleSaleFirerer();
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public SaleBuilder getNewSaleBuilder() {
|
||||
@ -25,22 +28,30 @@ public class SaleService {
|
||||
}
|
||||
|
||||
public long commitSale(SaleBuilder saleBuilder) {
|
||||
return QueryExecutor.INSTANCE.execute(QueryFactory.newSaleQuery(saleBuilder.build()), new IIdQueryCallback() {
|
||||
final long currentSaleId = saleId;
|
||||
if(saleId<Long.MAX_VALUE)
|
||||
saleId++;
|
||||
else
|
||||
saleId = 0;
|
||||
|
||||
executor.executeSaleQuery(saleBuilder.build(), new INoItemMessageCallback() {
|
||||
@Override
|
||||
public void ack(long id) {
|
||||
eventFirerer.fireSaleValidationSuccess(id);
|
||||
public void ack() {
|
||||
eventFirerer.fireSaleValidationSuccess(currentSaleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void err(long id, Throwable cause) {
|
||||
eventFirerer.fireSaleValidationError(id, cause);
|
||||
public void err(Throwable cause) {
|
||||
eventFirerer.fireSaleValidationError(currentSaleId, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ref(long id, Throwable cause) {
|
||||
eventFirerer.fireSaleValidationRefused(id, cause);
|
||||
public void ref(Throwable cause) {
|
||||
eventFirerer.fireSaleValidationRefused(currentSaleId, cause);
|
||||
}
|
||||
});
|
||||
|
||||
return currentSaleId;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,8 +1,7 @@
|
||||
package com.pqt.client.module.stat;
|
||||
|
||||
import com.pqt.client.module.query.QueryExecutor;
|
||||
import com.pqt.client.module.query.QueryFactory;
|
||||
import com.pqt.client.module.query.query_callback.IStatQueryCallback;
|
||||
import com.pqt.client.module.query.query_callback.IMapItemMessageCallback;
|
||||
import com.pqt.client.module.stat.listeners.IStatFirerer;
|
||||
import com.pqt.client.module.stat.listeners.IStatListener;
|
||||
import com.pqt.client.module.stat.listeners.SimpleStatFirerer;
|
||||
@ -15,11 +14,13 @@ public class StatDao {
|
||||
private Date lastRefreshTimestamp;
|
||||
private Map<String, String> stats;
|
||||
private IStatFirerer eventFirerer;
|
||||
private QueryExecutor executor;
|
||||
|
||||
public StatDao() {
|
||||
public StatDao(QueryExecutor executor) {
|
||||
eventFirerer = new SimpleStatFirerer();
|
||||
stats = new HashMap<>();
|
||||
lastRefreshTimestamp = null;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public synchronized Map<String, String> getStats() {
|
||||
@ -27,14 +28,7 @@ public class StatDao {
|
||||
}
|
||||
|
||||
public void refreshStats() {
|
||||
QueryExecutor.INSTANCE.execute(QueryFactory.newStockQuery(), new IStatQueryCallback() {
|
||||
@Override
|
||||
public void ack(Map<String, String> stats) {
|
||||
replaceStats(stats);
|
||||
eventFirerer.fireGetStatSuccess();
|
||||
//TODO add log line
|
||||
}
|
||||
|
||||
executor.executeStatQuery(new IMapItemMessageCallback<String, String>() {
|
||||
@Override
|
||||
public void err(Throwable cause) {
|
||||
eventFirerer.fireGetStatError(cause);
|
||||
@ -46,6 +40,13 @@ public class StatDao {
|
||||
eventFirerer.fireGetStatRefused(cause);
|
||||
//TODO add log line
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ack(Map<String, String> stats) {
|
||||
replaceStats(stats);
|
||||
eventFirerer.fireGetStatSuccess();
|
||||
//TODO add log line
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.pqt.client.module.stat;
|
||||
|
||||
import com.pqt.client.module.query.QueryExecutor;
|
||||
import com.pqt.client.module.stat.listeners.IStatListener;
|
||||
|
||||
import java.util.Map;
|
||||
@ -10,8 +11,8 @@ public class StatService {
|
||||
|
||||
private StatDao dao;
|
||||
|
||||
public StatService() {
|
||||
dao = new StatDao();
|
||||
public StatService(QueryExecutor executor) {
|
||||
dao = new StatDao(executor);
|
||||
}
|
||||
|
||||
public Map<String,String> getStats() {
|
||||
|
@ -1,9 +1,8 @@
|
||||
package com.pqt.client.module.stock;
|
||||
|
||||
import com.pqt.client.module.query.QueryExecutor;
|
||||
import com.pqt.client.module.query.QueryFactory;
|
||||
import com.pqt.client.module.query.query_callback.IStockQueryCallback;
|
||||
import com.pqt.client.module.query.query_callback.IIdQueryCallback;
|
||||
import com.pqt.client.module.query.query_callback.ICollectionItemMessageCallback;
|
||||
import com.pqt.client.module.query.query_callback.INoItemMessageCallback;
|
||||
import com.pqt.client.module.stock.Listeners.IStockFirerer;
|
||||
import com.pqt.client.module.stock.Listeners.IStockListener;
|
||||
import com.pqt.client.module.stock.Listeners.SimpleStockFirerer;
|
||||
@ -11,18 +10,22 @@ import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.product.ProductUpdate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
//TODO écrire javadoc
|
||||
public class StockDao {
|
||||
|
||||
private long updateId;
|
||||
private IStockFirerer eventFirerer;
|
||||
private Date lastRefreshTimestamp;
|
||||
private List<Product> products;
|
||||
private QueryExecutor executor;
|
||||
|
||||
public StockDao() {
|
||||
public StockDao(QueryExecutor executor) {
|
||||
this.executor = executor;
|
||||
updateId = 0;
|
||||
eventFirerer = new SimpleStockFirerer();
|
||||
products = new ArrayList<>();
|
||||
lastRefreshTimestamp = null;
|
||||
@ -37,9 +40,9 @@ public class StockDao {
|
||||
}
|
||||
|
||||
public void refreshProductList() {
|
||||
QueryExecutor.INSTANCE.execute(QueryFactory.newStockQuery(), new IStockQueryCallback() {
|
||||
executor.executeStockQuery(new ICollectionItemMessageCallback<Product>() {
|
||||
@Override
|
||||
public void ack(List<Product> products) {
|
||||
public void ack(Collection<Product> obj) {
|
||||
replaceProductList(products);
|
||||
eventFirerer.fireGetProductListSuccessEvent();
|
||||
//TODO add log line
|
||||
@ -71,27 +74,33 @@ public class StockDao {
|
||||
}
|
||||
|
||||
public long commitUpdate(List<ProductUpdate> updates){
|
||||
return QueryExecutor.INSTANCE.execute(QueryFactory.newUpdateQuery(updates),new IIdQueryCallback(){
|
||||
|
||||
final long currentUpdateId = updateId;
|
||||
if(updateId<Long.MAX_VALUE)
|
||||
updateId++;
|
||||
else
|
||||
updateId = 0;
|
||||
executor.executeUpdateQuery(updates, new INoItemMessageCallback() {
|
||||
@Override
|
||||
public void ack(long id) {
|
||||
public void ack() {
|
||||
//TODO add log line
|
||||
refreshProductList();
|
||||
eventFirerer.fireProductListUpdateSuccessEvent(id);
|
||||
eventFirerer.fireProductListUpdateSuccessEvent(currentUpdateId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void err(long id, Throwable cause) {
|
||||
public void err(Throwable cause) {
|
||||
//TODO add log line
|
||||
eventFirerer.fireProductListUpdateErrorEvent(id, cause);
|
||||
eventFirerer.fireProductListUpdateErrorEvent(currentUpdateId, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ref(long id, Throwable cause) {
|
||||
public void ref(Throwable cause) {
|
||||
//TODO add log line
|
||||
eventFirerer.fireProductListUpdateRefusedEvent(id, cause);
|
||||
eventFirerer.fireProductListUpdateRefusedEvent(currentUpdateId, cause);
|
||||
}
|
||||
});
|
||||
|
||||
return currentUpdateId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.pqt.client.module.stock;
|
||||
|
||||
import com.pqt.client.module.query.QueryExecutor;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.client.module.stock.Listeners.IStockListener;
|
||||
|
||||
@ -9,12 +10,10 @@ import java.util.List;
|
||||
//TODO Add log lines
|
||||
public class StockService {
|
||||
|
||||
public static final StockService INSTANCE = new StockService();
|
||||
|
||||
private StockDao dao;
|
||||
|
||||
public StockService() {
|
||||
dao = new StockDao();
|
||||
public StockService(QueryExecutor executor) {
|
||||
dao = new StockDao(executor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,13 +2,6 @@
|
||||
-fx-background-color: #1d1d1d;
|
||||
}
|
||||
|
||||
.label {
|
||||
-fx-font-size: 11pt;
|
||||
-fx-font-family: "Segoe UI Semibold";
|
||||
-fx-text-fill: white;
|
||||
-fx-opacity: 0.8;
|
||||
}
|
||||
|
||||
.label-bright {
|
||||
-fx-font-size: 11pt;
|
||||
-fx-font-family: "Segoe UI Semibold";
|
||||
@ -127,15 +120,32 @@
|
||||
.context-menu {
|
||||
-fx-background-color: derive(#1d1d1d,5%);
|
||||
}
|
||||
.text-field, .password-field, .choice-box, .text-area, .combo-box, .button {
|
||||
-fx-font-size: 12pt;
|
||||
-fx-font-family: "Segoe UI Semibold";
|
||||
|
||||
.titled-pane, .titled-pane > .title, .titled-pane > *.content, .text-field,
|
||||
.password-field, .choice-box, .text-area, .combo-box, .button, .label, .text-displayer {
|
||||
-fx-font: 12pt "Segoe UI Semibold";
|
||||
-fx-background-color: #1d1d1d;
|
||||
-fx-text-fill: #d8d8d8;
|
||||
}
|
||||
|
||||
.text-displayer {
|
||||
-fx-fill: #d8d8d8;
|
||||
}
|
||||
|
||||
.titled-pane, .titled-pane > .title, .titled-pane > *.content {
|
||||
-fx-border-width: 0;
|
||||
}
|
||||
|
||||
.text-field, .password-field, .choice-box, .text-area, .combo-box, .button{
|
||||
-fx-pref-width: 150;
|
||||
-fx-pref-height: 30;
|
||||
-fx-background-color: #1d1d1d;
|
||||
-fx-border-color: #e2e2e2;
|
||||
-fx-border-width: 2;
|
||||
-fx-text-fill: #d8d8d8;
|
||||
}
|
||||
|
||||
.label{
|
||||
-fx-pref-width: 150;
|
||||
-fx-pref-height: 30;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
|
@ -21,6 +21,5 @@
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
</component>
|
||||
</module>
|
@ -1,5 +0,0 @@
|
||||
package com.pqt.core.entities.query;
|
||||
|
||||
public interface IQuery {
|
||||
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package com.pqt.core.entities.query;
|
||||
|
||||
public enum QueryType {
|
||||
|
||||
CONNECT, SALE, STOCK, STAT, LOG, UPDATE
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.pqt.core.entities.query;
|
||||
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
|
||||
public class SaleQuery extends SimpleQuery {
|
||||
|
||||
private Sale sale;
|
||||
|
||||
public SaleQuery(Sale sale) {
|
||||
super(QueryType.SALE);
|
||||
this.sale = sale;
|
||||
}
|
||||
|
||||
public Sale getSale() {
|
||||
return sale;
|
||||
}
|
||||
|
||||
public void setSale(Sale sale) {
|
||||
this.sale = sale;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.pqt.core.entities.query;
|
||||
|
||||
public class SimpleQuery implements IQuery {
|
||||
|
||||
private QueryType type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type
|
||||
* @throws NullPointerException if type is null
|
||||
*/
|
||||
public SimpleQuery(QueryType type) {
|
||||
if(type==null) throw new NullPointerException("null value not allowed as query type");
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public QueryType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.pqt.core.entities.query;
|
||||
|
||||
import com.pqt.core.entities.product.ProductUpdate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UpdateQuery extends SimpleQuery {
|
||||
|
||||
private List<ProductUpdate> updates;
|
||||
|
||||
public UpdateQuery(List<ProductUpdate> updates) {
|
||||
super(QueryType.UPDATE);
|
||||
this.updates = updates;
|
||||
}
|
||||
|
||||
public List<ProductUpdate> getUpdates() {
|
||||
return updates;
|
||||
}
|
||||
|
||||
public void setUpdates(List<ProductUpdate> updates) {
|
||||
this.updates = updates;
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ public class ServerConfig {
|
||||
private Map<ConfigFields, Boolean> fields;
|
||||
|
||||
public ServerConfig() {
|
||||
fields = new HashMap<>();
|
||||
}
|
||||
|
||||
public ServerConfig(Map<ConfigFields, Boolean> fields) {
|
||||
|
@ -25,10 +25,6 @@
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: javax:javaee-api:7.0" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sun.mail:javax.mail:1.5.0" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.activation:activation:1.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-io:commons-io:2.4" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: javax:javaee-api:7.0" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sun.mail:javax.mail:1.5.0" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.activation:activation:1.1" level="project" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-io:commons-io:2.4" level="project" />
|
||||
|
@ -1,30 +0,0 @@
|
||||
package com.pqt.server.tools.security;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5HashTool implements IHashTool{
|
||||
@Override
|
||||
public String hashAndSalt(String input, String salt) {
|
||||
String md5 = null;
|
||||
|
||||
if(input == null || salt == null) return null;
|
||||
|
||||
try {
|
||||
String str = salt+input;
|
||||
//Create MessageDigest object for MD5
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
|
||||
//Update input string in message digest
|
||||
digest.update(str.getBytes(), 0, str.length());
|
||||
|
||||
//Converts message digest value in base 16 (hex)
|
||||
md5 = new BigInteger(1, digest.digest()).toString(16);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import com.pqt.core.entities.user_account.AccountLevel;
|
||||
import com.pqt.server.tools.io.ISerialFileManager;
|
||||
import com.pqt.server.tools.io.SimpleSerialFileManagerFactory;
|
||||
import com.pqt.server.tools.security.IHashTool;
|
||||
import com.pqt.server.tools.security.MD5HashTool;
|
||||
import com.pqt.server.tools.security.SHA256HashTool;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@ -19,7 +19,7 @@ import java.util.stream.Collectors;
|
||||
* Cette classe n'est pas faite pour gérer les accès concurentiels au fichier assurant la persistance, et n'est donc pas
|
||||
* thread-safe. Elle est conçue pour que tous les accès soient effectués depuis un même thread et depuis un unique objet.
|
||||
* <p/>
|
||||
* Cette classe manipule les mot de passe sous forme chiffrée via un système de hash (md5) + salt, et ne fait pas
|
||||
* Cette classe manipule les mot de passe sous forme chiffrée via un système de hash (SHA-256) + salt, et ne fait pas
|
||||
* persister les mots de passes non-chiffrées. Les noms d'utilisateurs sont stockés sans chiffrage.
|
||||
*/
|
||||
class FileAccountDao implements IAccountDao {
|
||||
@ -34,7 +34,7 @@ class FileAccountDao implements IAccountDao {
|
||||
FileAccountDao() {
|
||||
accountEntries = new HashSet<>();
|
||||
connectedAccount = new HashSet<>();
|
||||
hashTool = new MD5HashTool();
|
||||
hashTool = new SHA256HashTool();
|
||||
fileManager = SimpleSerialFileManagerFactory.getFileManager(AccountEntry.class, ACCOUNT_FILE_NAME);
|
||||
loadFromFile();
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package com.pqt.server.module.sale;
|
||||
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.server.exception.ServerQueryException;
|
||||
import com.pqt.server.module.sale.listeners.ISaleFirerer;
|
||||
import com.pqt.server.module.sale.listeners.ISaleListener;
|
||||
import com.pqt.server.module.sale.listeners.SimpleSaleFirerer;
|
@ -4,8 +4,6 @@ import com.pqt.core.entities.members.DataServer;
|
||||
import com.pqt.core.entities.server_config.ConfigFields;
|
||||
import com.pqt.core.entities.server_config.ServerConfig;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Cette classe correspond au service interne du serveur, chargé de conserver les données propres au serveur, comme
|
||||
* son adresse IP ou encore les différents aspects de la configuration actuelle. Il permet également de récupérer un
|
@ -3,12 +3,10 @@ package com.pqt.server.module.statistics;
|
||||
import com.pqt.core.entities.product.LightweightProduct;
|
||||
import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.core.entities.sale.Sale;
|
||||
import com.pqt.server.module.sale.listeners.ISaleListener;
|
||||
import com.pqt.server.module.sale.listeners.SaleListenerAdapter;
|
||||
import com.pqt.server.module.stock.StockService;
|
||||
import com.pqt.server.module.sale.SaleService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
@ -4,7 +4,6 @@ import com.pqt.core.entities.product.Product;
|
||||
import com.pqt.server.tools.entities.SaleContent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interface définissant les méthodes requises pour tout DAO du service de gestion des commandes {@link StockService}.
|
@ -6,7 +6,6 @@ import com.pqt.server.exception.ServerQueryException;
|
||||
import com.pqt.server.tools.entities.SaleContent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
//TODO ajouter logs
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user