package com.kritsit.casetracker.client.domain.ui.controller; import com.itextpdf.text.Chunk; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Font; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Phrase; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.kritsit.casetracker.client.domain.services.Export; import com.kritsit.casetracker.client.domain.services.IAdministratorService; import com.kritsit.casetracker.client.domain.services.IMenuService; import com.kritsit.casetracker.client.domain.services.IExportService; import com.kritsit.casetracker.client.domain.services.InputToModelParseResult; import com.kritsit.casetracker.shared.domain.model.Permission; import com.kritsit.casetracker.shared.domain.model.Staff; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; import javafx.collections.transformation.SortedList; import javafx.event.Event; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.TableView; import javafx.scene.control.TableView.TableViewSelectionModel; import javafx.scene.control.MenuItem; import javafx.scene.control.SelectionModel; import javafx.scene.control.SingleSelectionModel; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.control.TableColumn; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; import javafx.stage.FileChooser; import javafx.stage.Stage; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class AdministratorController implements IController { private ObservableList<Staff> staffList; private FilteredList<Staff> filteredStaff; private IAdministratorService administratorService; private IMenuService menuService; private IExportService exportService; private Stage stage; private final Logger logger = LoggerFactory.getLogger(AdministratorController.class); public void setAdministratorService(IAdministratorService administratorService) { this.administratorService = administratorService; } public void setMenuService(IMenuService menuService){ this.menuService = menuService; } public void setExportService(IExportService exportService){ this.exportService = exportService; } public void initFrame(){ logger.info("Initiating frame"); if (administratorService.getUser().getPermission() == Permission.ADMIN) { initStaffTable(); initPermissionCombobox(); initSearchCombobox(); } else { logger.debug("Administrator view disabled"); } } public void initialize(){ changePasswordItem.setOnAction(event->{ menuService.changePasswordFrame(); }); newUserItem.setOnAction(event->{ SingleSelectionModel<Tab> selection = tabPane.getSelectionModel(); selection.select(addUserTab); }); editUserItem.setOnAction(event->{ editUser(); }); deleteUserItem.setOnAction(event->{ deleteUser(); }); resetPasswordItem.setOnAction(event->{ resetPassword(); }); logoutItem.setOnAction(event->{ stage.close(); menuService.restart(); }); exitItem.setOnAction(event->{ menuService.closeConnection(); stage.close(); }); helpItem.setOnAction(event->{ showHelpFrame(); }); aboutItem.setDisable(true); btnResetPassword.setOnAction(event->{ resetPassword(); }); btnDelete.setOnAction(event->{ deleteUser(); }); btnAddUser.setOnAction(event->{ addUser(); }); btnEdit.setOnAction(event->{ editUser(); }); exportItem.setOnAction(event->{ export(); }); aboutItem.setOnAction(event->{ menuService.aboutFrame(); }); } private void export() { exportService = new Export(); List<String> headers = new ArrayList<String>(); headers.add("First name"); headers.add("Last name"); headers.add("Username"); headers.add("Department"); headers.add("Position"); headers.add("Permissions"); List<String[]> cells = new ArrayList<String[]>(); for(Staff s : filteredStaff){ String[] row = new String[6]; row[0] = s.getFirstName(); row[1] = s.getLastName(); row[2] = s.getUsername(); row[3] = s.getDepartment(); row[4] = s.getPosition(); row[5] = s.getPermission().toString(); cells.add(row); } FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Save report"); File file = fileChooser.showSaveDialog(stage); if(file==null){ logger.info("cancelling PDF export"); return; } if(!(file.getName().endsWith(".pdf"))){ File fileWithExtension = new File(file.getAbsolutePath()+".pdf"); exportService.exportToPDF(headers, cells, fileWithExtension); } else{ exportService.exportToPDF(headers, cells, file); } } private void addUser() { Map<String, Object> inputMap = new HashMap<String, Object>(); inputMap.put("username", txfAddUsername.getText()); inputMap.put("firstname", txfAddFirstName.getText()); inputMap.put("lastname", txfAddLastName.getText()); inputMap.put("department", cbxAddDepartment.getValue()); inputMap.put("position", txfAddPosition.getText()); inputMap.put("permission", cbxAddPermission.getValue()); InputToModelParseResult result = administratorService.addUser(inputMap); if(result.isSuccessful()){ Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle("Adding a new user"); alert.setHeaderText("New user added succesfully"); alert.setContentText("Click OK to proceed"); alert.showAndWait(); resetPassword(txfAddUsername.getText()); resetAddUserTab(); initStaffTable(); } else{ Alert alert = new Alert(AlertType.ERROR); alert.setTitle("Error"); alert.setHeaderText("Error adding new user"); alert.setContentText(result.getReason()); alert.showAndWait(); } } private void showHelpFrame(){ AnchorPane helpFrame = null; FXMLLoader fxmlLoader = new FXMLLoader(getClass() .getResource("/ui/fxml/AdministratorHelpFrame.fxml")); fxmlLoader.setRoot(helpFrame); try{ helpFrame = (AnchorPane) fxmlLoader.load(); } catch(IOException e){ logger.error("Error loading help frame.", e); return; } Scene scene = new Scene(helpFrame); Stage stage = new Stage(); stage.setTitle("Help"); stage.setResizable(false); stage.setScene(scene); stage.show(); } private void editUser(){ TableViewSelectionModel<Staff> selection = tblStaff.getSelectionModel(); if(selection.getSelectedItem()==null){ Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle("Editing user"); alert.setHeaderText("Information"); alert.setContentText("Select a user to edit"); alert.showAndWait(); return; } Staff s = selection.getSelectedItem(); EditUserController c = new EditUserController(s, administratorService, this); AnchorPane EditUserPane = null; FXMLLoader fxmlLoader = new FXMLLoader(getClass() .getResource("/ui/fxml/EditUser.fxml")); fxmlLoader.setController(c); fxmlLoader.setRoot(EditUserPane); try{ EditUserPane= (AnchorPane) fxmlLoader.load(); } catch(IOException e){ logger.error("Error loading frame to edit user.", e); return; } Scene scene = new Scene(EditUserPane); Stage stage = new Stage(); stage.setTitle("Editing user "+s.getUsername()); stage.setResizable(false); stage.setScene(scene); stage.show(); } private void deleteUser() { Alert alert; TableViewSelectionModel<Staff> selection = tblStaff.getSelectionModel(); if(selection.getSelectedItem()==null){ alert = new Alert(AlertType.INFORMATION); alert.setTitle("Deleting user"); alert.setHeaderText("Information"); alert.setContentText("Select a user to delete"); alert.showAndWait(); return; } String selectedUsername = selection.getSelectedItem().getUsername(); Map<String, Object> inputMap = new HashMap<String, Object>(); inputMap.put("username", selectedUsername); int result = administratorService.deleteUser(inputMap); switch(result){ case 200 : staffList = FXCollections.observableArrayList(administratorService.getStaff()); alert = new Alert(AlertType.INFORMATION); alert.setTitle("Deleting user"); alert.setHeaderText("User deleted succesfully"); alert.setContentText("Click OK to proceed"); alert.showAndWait(); break; case 500 : alert = new Alert(AlertType.ERROR); alert.setTitle("Deleting user"); alert.setHeaderText("Error while deleting user"); alert.setContentText("Error occured on the server side"); alert.showAndWait(); break; } initStaffTable(); } public void setStage(Stage stage) { this.stage = stage; } @SuppressWarnings("unchecked") protected void initStaffTable(){ logger.info("Initiating staff list table"); staffList = FXCollections.observableArrayList(administratorService.getStaff()); filteredStaff = new FilteredList<>(staffList, p -> true); txfFilterUsers.textProperty().addListener((observable, oldValue, newValue) -> { filteredStaff.setPredicate(s -> { if (newValue == null || newValue.isEmpty() || newValue.equals("All")) { return true; } String lowerCaseFilter = newValue.toLowerCase(); if (s.getUsername().toLowerCase().contains(lowerCaseFilter)) { return true; } return false; }); }); cbxFilterPermissions.valueProperty().addListener((observable, oldValue, newValue) -> { filteredStaff.setPredicate(s -> { if (newValue == null || newValue.isEmpty() || newValue.equals("All")) { return true; } if (s.getPermission().toString().equals(newValue)) { return true; } return false; }); }); SortedList<Staff> sortedStaff = new SortedList<>(filteredStaff); sortedStaff.comparatorProperty().bind(tblStaff.comparatorProperty()); tblStaff.setItems(sortedStaff); colFirstName.setCellValueFactory(new PropertyValueFactory("firstName")); colLastName.setCellValueFactory(new PropertyValueFactory("lastName")); colUsername.setCellValueFactory(new PropertyValueFactory("username")); colDepartment.setCellValueFactory(new PropertyValueFactory("department")); colPermission.setCellValueFactory(new PropertyValueFactory("permission")); } private void resetAddUserTab(){ txfAddFirstName.setText(""); txfAddLastName.setText(""); cbxAddDepartment.setValue(""); txfAddPosition.setText(""); txfAddUsername.setText(""); cbxAddPermission.setValue(""); } private void initPermissionCombobox(){ ObservableList<String> permissions = FXCollections.observableArrayList(Permission.ADMIN.toString(), Permission.EDITOR.toString(), Permission.VIEWER.toString()); cbxAddPermission.setItems(permissions); } private void initSearchCombobox(){ ObservableList<String> permissions = FXCollections.observableArrayList("All", Permission.ADMIN.toString(), Permission.EDITOR.toString(), Permission.VIEWER.toString()); cbxFilterPermissions.setItems(permissions); cbxFilterPermissions.setValue("All"); } private void resetPassword(){ SelectionModel<Staff> selection = tblStaff.getSelectionModel(); Alert alert; if (selection.getSelectedItem() == null) { alert = new Alert(AlertType.INFORMATION); alert.setTitle("Reseting password"); alert.setHeaderText("Information"); alert.setContentText("Select a user"); alert.showAndWait(); return; } String username = selection.getSelectedItem().getUsername(); String randomPass = administratorService.randomPassword(); int hashedRandomPass = randomPass.hashCode(); int result = administratorService.resetPassword( username, hashedRandomPass); switch (result) { case 200 : alert = new Alert(AlertType.INFORMATION); alert.setTitle("Password reset"); alert.setHeaderText("Password reset succesfully"); alert.setContentText("new password: "+randomPass); alert.showAndWait(); break; case 500 : alert = new Alert(AlertType.ERROR); alert.setTitle("Password reset"); alert.setHeaderText("Error during password reset"); alert.setContentText("Error occured on the server side"); alert.showAndWait(); break; } } private void resetPassword(String username){ Alert alert; String randomPass = administratorService.randomPassword(); int hashedRandomPass = randomPass.hashCode(); int result = administratorService.resetPassword( username, hashedRandomPass); switch (result) { case 200 : alert = new Alert(AlertType.INFORMATION); alert.setTitle("Password"); alert.setHeaderText("Password for user "+username+" set succesfully"); alert.setContentText("new password: "+randomPass); alert.showAndWait(); break; case 500 : alert = new Alert(AlertType.ERROR); alert.setTitle("Password reset"); alert.setHeaderText("Error during password reset"); alert.setContentText("Error occured on the server side"); alert.showAndWait(); break; } } @FXML private TextField txfFilterUsers; @FXML private ComboBox<String> cbxFilterPermissions; @FXML private Button btnResetPassword; @FXML private Button btnEdit; @FXML private Button btnDelete; @FXML private TableView<Staff> tblStaff; @FXML private TextField txfAddFirstName; @FXML private TextField txfAddLastName; @FXML private ComboBox<String> cbxAddDepartment; @FXML private TextField txfAddPosition; @FXML private TextField txfAddUsername; @FXML private ComboBox<String> cbxAddPermission; @FXML private Button btnAddUser; @FXML private TableColumn<Staff, String> colFirstName; @FXML private TableColumn<Staff, String> colLastName; @FXML private TableColumn<Staff, String> colUsername; @FXML private TableColumn<Staff, String> colDepartment; @FXML private TableColumn<Staff, String> colPermission; @FXML private MenuItem changePasswordItem; @FXML private MenuItem exportItem; @FXML private MenuItem logoutItem; @FXML private MenuItem exitItem; @FXML private MenuItem newUserItem; @FXML private MenuItem editUserItem; @FXML private MenuItem deleteUserItem; @FXML private MenuItem resetPasswordItem; @FXML private MenuItem aboutItem; @FXML private MenuItem helpItem; @FXML private TabPane tabPane; @FXML private Tab addUserTab; }